Compare commits
No commits in common. "master" and "feature/zy" have entirely different histories.
master
...
feature/zy
93
README.md
Executable file
93
README.md
Executable file
|
|
@ -0,0 +1,93 @@
|
||||||
|
FastAdmin是一款基于ThinkPHP+Bootstrap的极速后台开发框架。
|
||||||
|
|
||||||
|
|
||||||
|
## 主要特性
|
||||||
|
|
||||||
|
* 基于`Auth`验证的权限管理系统
|
||||||
|
* 支持无限级父子级权限继承,父级的管理员可任意增删改子级管理员及权限设置
|
||||||
|
* 支持单管理员多角色
|
||||||
|
* 支持管理子级数据或个人数据
|
||||||
|
* 强大的一键生成功能
|
||||||
|
* 一键生成CRUD,包括控制器、模型、视图、JS、语言包、菜单、回收站等
|
||||||
|
* 一键压缩打包JS和CSS文件,一键CDN静态资源部署
|
||||||
|
* 一键生成控制器菜单和规则
|
||||||
|
* 一键生成API接口文档
|
||||||
|
* 完善的前端功能组件开发
|
||||||
|
* 基于`AdminLTE`二次开发
|
||||||
|
* 基于`Bootstrap`开发,自适应手机、平板、PC
|
||||||
|
* 基于`RequireJS`进行JS模块管理,按需加载
|
||||||
|
* 基于`Less`进行样式开发
|
||||||
|
* 强大的插件扩展功能,在线安装卸载升级插件
|
||||||
|
* 通用的会员模块和API模块
|
||||||
|
* 共用同一账号体系的Web端会员中心权限验证和API接口会员权限验证
|
||||||
|
* 二级域名部署支持,同时域名支持绑定到应用插件
|
||||||
|
* 多语言支持,服务端及客户端支持
|
||||||
|
* 支持大文件分片上传、剪切板粘贴上传、拖拽上传,进度条显示,图片上传前压缩
|
||||||
|
* 支持表格固定列、固定表头、跨页选择、Excel导出、模板渲染等功能
|
||||||
|
* 强大的第三方应用模块支持([CMS](https://www.fastadmin.net/store/cms.html)、[CRM](https://www.fastadmin.net/store/facrm.html)、[企业网站管理系统](https://www.fastadmin.net/store/ldcms.html)、[知识库文档系统](https://www.fastadmin.net/store/knowbase.html)、[在线投票系统](https://www.fastadmin.net/store/vote.html)、[B2C商城](https://www.fastadmin.net/store/shopro.html)、[B2B2C商城](https://www.fastadmin.net/store/wanlshop.html))
|
||||||
|
* 整合第三方短信接口(阿里云、腾讯云短信)
|
||||||
|
* 无缝整合第三方云存储(七牛云、阿里云OSS、腾讯云存储、又拍云)功能,支持云储存分片上传
|
||||||
|
* 第三方富文本编辑器支持(Summernote、百度编辑器)
|
||||||
|
* 第三方登录(QQ、微信、微博)整合
|
||||||
|
* 第三方支付(微信、支付宝)无缝整合,微信支持PC端扫码支付
|
||||||
|
* 丰富的插件应用市场
|
||||||
|
|
||||||
|
## 安装使用
|
||||||
|
|
||||||
|
https://doc.fastadmin.net
|
||||||
|
|
||||||
|
## 在线演示
|
||||||
|
|
||||||
|
https://demo.fastadmin.net
|
||||||
|
|
||||||
|
用户名:admin
|
||||||
|
|
||||||
|
密 码:123456
|
||||||
|
|
||||||
|
提 示:演示站数据无法进行修改,请下载源码安装体验全部功能
|
||||||
|
|
||||||
|
## 界面截图
|
||||||
|

|
||||||
|
|
||||||
|
## 问题反馈
|
||||||
|
|
||||||
|
在使用中有任何问题,请使用以下联系方式联系我们
|
||||||
|
|
||||||
|
问答社区: https://ask.fastadmin.net
|
||||||
|
|
||||||
|
Github: https://github.com/karsonzhang/fastadmin
|
||||||
|
|
||||||
|
Gitee: https://gitee.com/karson/fastadmin
|
||||||
|
|
||||||
|
## 特别鸣谢
|
||||||
|
|
||||||
|
感谢以下的项目,排名不分先后
|
||||||
|
|
||||||
|
ThinkPHP:http://www.thinkphp.cn
|
||||||
|
|
||||||
|
AdminLTE:https://adminlte.io
|
||||||
|
|
||||||
|
Bootstrap:http://getbootstrap.com
|
||||||
|
|
||||||
|
jQuery:http://jquery.com
|
||||||
|
|
||||||
|
Bootstrap-table:https://github.com/wenzhixin/bootstrap-table
|
||||||
|
|
||||||
|
Nice-validator: https://validator.niceue.com
|
||||||
|
|
||||||
|
SelectPage: https://github.com/TerryZ/SelectPage
|
||||||
|
|
||||||
|
Layer: https://layuion.com/layer/
|
||||||
|
|
||||||
|
DropzoneJS: https://www.dropzonejs.com
|
||||||
|
|
||||||
|
|
||||||
|
## 版权信息
|
||||||
|
|
||||||
|
FastAdmin遵循Apache2开源协议发布,并提供免费使用。
|
||||||
|
|
||||||
|
本项目包含的第三方源码和二进制文件之版权信息另行标注。
|
||||||
|
|
||||||
|
版权所有Copyright © 2017-2024 by FastAdmin (https://www.fastadmin.net)
|
||||||
|
|
||||||
|
All rights reserved。
|
||||||
|
|
@ -108,7 +108,7 @@ return [
|
||||||
'title' => '上传有效时长',
|
'title' => '上传有效时长',
|
||||||
'type' => 'string',
|
'type' => 'string',
|
||||||
'content' => [],
|
'content' => [],
|
||||||
'value' => 60 * 60 * 2,
|
'value' => '3000',
|
||||||
'rule' => 'required',
|
'rule' => 'required',
|
||||||
'msg' => '',
|
'msg' => '',
|
||||||
'tip' => '用户停留页面上传有效时长,单位秒',
|
'tip' => '用户停留页面上传有效时长,单位秒',
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,7 @@ class Order extends Backend
|
||||||
protected $items = null;
|
protected $items = null;
|
||||||
protected $itemsformattedTree = null;
|
protected $itemsformattedTree = null;
|
||||||
|
|
||||||
protected $noNeedRight = ['smart','export','orderRemark'];
|
protected $noNeedRight = ['smart'];
|
||||||
|
|
||||||
public function _initialize()
|
public function _initialize()
|
||||||
{
|
{
|
||||||
|
|
@ -170,7 +170,6 @@ class Order extends Backend
|
||||||
'source', 'source_shop', 'source_uid', 'source', 'item_title', 'item_id', 'work_tel_id',
|
'source', 'source_shop', 'source_uid', 'source', 'item_title', 'item_id', 'work_tel_id',
|
||||||
'detail', 'remark', 'images', 'create_time', 'update_time', 'admin_id', 'dispatch_type',
|
'detail', 'remark', 'images', 'create_time', 'update_time', 'admin_id', 'dispatch_type',
|
||||||
'receive_type',
|
'receive_type',
|
||||||
'order_remark',
|
|
||||||
'plan_time',
|
'plan_time',
|
||||||
'coupon_id',
|
'coupon_id',
|
||||||
'is_overtime',
|
'is_overtime',
|
||||||
|
|
@ -537,9 +536,6 @@ class Order extends Backend
|
||||||
$res = Admin::where('area_ids', 'like', '%' . $area_id . '%')
|
$res = Admin::where('area_ids', 'like', '%' . $area_id . '%')
|
||||||
->column('id');
|
->column('id');
|
||||||
|
|
||||||
$dispatch_admin = AuthGroupAccess::where('group_id', 6)
|
|
||||||
->column('uid');
|
|
||||||
$res = array_values(array_intersect($res, $dispatch_admin));
|
|
||||||
|
|
||||||
$insert = [];
|
$insert = [];
|
||||||
foreach ($res as $re) {
|
foreach ($res as $re) {
|
||||||
|
|
@ -557,18 +553,6 @@ class Order extends Backend
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public function orderRemark($ids = null)
|
|
||||||
{
|
|
||||||
|
|
||||||
$order = $this->model->where('id', $ids)->find();
|
|
||||||
$params = $this->request->post();
|
|
||||||
$remark = $params['remark'] ?? '';
|
|
||||||
$order->order_remark = $remark;
|
|
||||||
$order->save();
|
|
||||||
$this->success($order['order_no']);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public function warning($ids = null)
|
public function warning($ids = null)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
@ -658,8 +642,8 @@ class Order extends Backend
|
||||||
'update_time' => now()->format('Y-m-d H:m:s'),
|
'update_time' => now()->format('Y-m-d H:m:s'),
|
||||||
];
|
];
|
||||||
|
|
||||||
$orderDispatch = OrderDispatch::where('order_id', $order->id)
|
$orderDispatch = OrderDispatch::where('order_id', $order->id)->whereBetween('status', '>=', 0)->find();
|
||||||
->where('status', '>=', 0)->find();
|
|
||||||
if ($params['abnormal_id'] == 2 || $params['abnormal_id'] == 3) {
|
if ($params['abnormal_id'] == 2 || $params['abnormal_id'] == 3) {
|
||||||
|
|
||||||
$order->status = \app\admin\model\Order::STATUS_CANCEL;
|
$order->status = \app\admin\model\Order::STATUS_CANCEL;
|
||||||
|
|
@ -712,7 +696,6 @@ class Order extends Backend
|
||||||
$result = \model('order_abnormal')->insert($insert);
|
$result = \model('order_abnormal')->insert($insert);
|
||||||
Db::commit();
|
Db::commit();
|
||||||
} catch (ValidateException|PDOException|Exception $e) {
|
} catch (ValidateException|PDOException|Exception $e) {
|
||||||
throw $e;
|
|
||||||
Db::rollback();
|
Db::rollback();
|
||||||
$this->error($e->getMessage());
|
$this->error($e->getMessage());
|
||||||
}
|
}
|
||||||
|
|
@ -1208,5 +1191,44 @@ class Order extends Backend
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected function streamCsv(array $columns, \Generator $rows, string $filename)
|
||||||
|
{
|
||||||
|
set_time_limit(0);
|
||||||
|
ini_set('memory_limit', '-1');
|
||||||
|
ignore_user_abort(true);
|
||||||
|
|
||||||
|
header('Content-Type: text/csv; charset=UTF-8');
|
||||||
|
header('Content-Disposition: attachment;filename="' . $filename . '"');
|
||||||
|
header('Cache-Control: max-age=0');
|
||||||
|
header('Pragma: public');
|
||||||
|
|
||||||
|
// 防止 Excel 打开乱码
|
||||||
|
echo "\xEF\xBB\xBF";
|
||||||
|
|
||||||
|
$output = fopen('php://output', 'w');
|
||||||
|
|
||||||
|
$fields = array_column($columns, 'field');
|
||||||
|
$titles = array_column($columns, 'title');
|
||||||
|
|
||||||
|
// 写入表头
|
||||||
|
fputcsv($output, $titles);
|
||||||
|
|
||||||
|
// 逐行写入数据
|
||||||
|
foreach ($rows as $row) {
|
||||||
|
$line = [];
|
||||||
|
foreach ($fields as $field) {
|
||||||
|
$value = $this->getNestedValue($row, $field);
|
||||||
|
if (is_array($value) || is_object($value)) {
|
||||||
|
$value = json_encode($value, JSON_UNESCAPED_UNICODE);
|
||||||
|
}
|
||||||
|
$line[] = $value;
|
||||||
|
}
|
||||||
|
fputcsv($output, $line);
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose($output);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,6 @@ class Auditorder extends Backend
|
||||||
* @var \app\admin\model\Order
|
* @var \app\admin\model\Order
|
||||||
*/
|
*/
|
||||||
protected $model = null;
|
protected $model = null;
|
||||||
protected $noNeedRight = ['export'];
|
|
||||||
|
|
||||||
public function _initialize()
|
public function _initialize()
|
||||||
{
|
{
|
||||||
|
|
@ -49,21 +48,13 @@ class Auditorder extends Backend
|
||||||
/**
|
/**
|
||||||
* 查看
|
* 查看
|
||||||
*/
|
*/
|
||||||
public function index($getArray = false, $page = 0, $input_limit = 0)
|
public function index()
|
||||||
{
|
{
|
||||||
//当前是否为关联查询
|
//当前是否为关联查询
|
||||||
$this->relationSearch = true;
|
$this->relationSearch = true;
|
||||||
//设置过滤方法
|
//设置过滤方法
|
||||||
$this->request->filter(['strip_tags', 'trim']);
|
$this->request->filter(['strip_tags', 'trim']);
|
||||||
|
if ($this->request->isAjax()) {
|
||||||
|
|
||||||
if (false === $this->request->isAjax() && $getArray == false) {
|
|
||||||
$res = $this->getSource();
|
|
||||||
$this->view->assign("sources", $res);
|
|
||||||
return $this->view->fetch();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//如果发送的来源是Selectpage,则转发到Selectpage
|
//如果发送的来源是Selectpage,则转发到Selectpage
|
||||||
if ($this->request->request('keyField')) {
|
if ($this->request->request('keyField')) {
|
||||||
return $this->selectpage();
|
return $this->selectpage();
|
||||||
|
|
@ -71,13 +62,13 @@ class Auditorder extends Backend
|
||||||
list($where, $sort, $order, $offset, $limit) = $this->buildparams();
|
list($where, $sort, $order, $offset, $limit) = $this->buildparams();
|
||||||
|
|
||||||
|
|
||||||
$build = $this->model
|
$list = $this->model
|
||||||
->scope('tab', Order::TAB_AUDIT)
|
->scope('tab',Order::TAB_AUDIT)
|
||||||
->alias('order')
|
->alias('order')
|
||||||
->with([
|
->with([
|
||||||
'user' => function ($q) {
|
'user' => function ($q) {
|
||||||
$q->field('id,nickname');
|
$q->field('id,nickname');
|
||||||
}, 'workerman', 'auditadmin' => function ($q) {
|
},'workerman','auditadmin' => function ($q) {
|
||||||
$q->field('id,nickname');
|
$q->field('id,nickname');
|
||||||
}, 'source' => [
|
}, 'source' => [
|
||||||
'parent' => function ($q) {
|
'parent' => function ($q) {
|
||||||
|
|
@ -85,39 +76,26 @@ class Auditorder extends Backend
|
||||||
}
|
}
|
||||||
]])
|
]])
|
||||||
->where($where)
|
->where($where)
|
||||||
->order($sort, $order);
|
->order($sort, $order)
|
||||||
|
->paginate($limit);
|
||||||
$performance = 0;
|
|
||||||
if ($getArray) {
|
|
||||||
$list = $build->paginate([
|
|
||||||
'list_rows' => $input_limit,
|
|
||||||
'page' => $page
|
|
||||||
]);
|
|
||||||
} else {
|
|
||||||
$list = $build->paginate($limit);
|
|
||||||
|
|
||||||
// ✅ 新增:汇总总金额
|
|
||||||
$sum = $this->model
|
|
||||||
->where($where)
|
|
||||||
->field('SUM(performance) as performance')
|
|
||||||
->find();
|
|
||||||
$performance = $sum->performance ?? 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach ($list as $item) {
|
foreach ($list as $item) {
|
||||||
if (isset($item->getRelation('source')->parent->title)) {
|
if (isset($item->getRelation('source')->parent->title)){
|
||||||
$item->source_total_name = '【' . $item->getRelation('source')->parent->title . '】' . ($item->getRelation('source')->title ?? '');
|
$item->source_total_name = '【' . $item->getRelation('source')->parent->title . '】' . ($item->getRelation('source')->title??'');
|
||||||
} else {
|
}else{
|
||||||
$item->source_total_name = ($item->getRelation('source')->title ?? '');
|
$item->source_total_name = ($item->getRelation('source')->title??'');
|
||||||
}
|
}
|
||||||
unset($item->source);
|
unset($item->source);
|
||||||
}
|
}
|
||||||
$result = array("total" => $list->total(), "rows" => $list->items(),'sum' => $performance);
|
$result = array("total" => $list->total(), "rows" => $list->items());
|
||||||
|
|
||||||
return json($result);
|
return json($result);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
$res = $this->getSource();
|
||||||
|
$this->view->assign("sources", $res);
|
||||||
|
return $this->view->fetch();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -130,12 +108,12 @@ class Auditorder extends Backend
|
||||||
*/
|
*/
|
||||||
public function edit($ids = null)
|
public function edit($ids = null)
|
||||||
{
|
{
|
||||||
$row = $this->model->get($ids, ['dispatch']);
|
$row = $this->model->get($ids,['dispatch']);
|
||||||
if (!$row) {
|
if (!$row) {
|
||||||
$this->error(__('No Results were found'));
|
$this->error(__('No Results were found'));
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($row->status != Order::STATUS_AUDITING) {
|
if($row ->status != Order::STATUS_AUDITING){
|
||||||
$this->error('订单状态不可审核');
|
$this->error('订单状态不可审核');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -144,10 +122,10 @@ class Auditorder extends Backend
|
||||||
$this->error(__('You have no permission'));
|
$this->error(__('You have no permission'));
|
||||||
}
|
}
|
||||||
if (false === $this->request->isPost()) {
|
if (false === $this->request->isPost()) {
|
||||||
$order = Order::where('id', $ids)->find();
|
$order = Order::where('id',$ids)->find();
|
||||||
$this->view->assign('row', $row);
|
$this->view->assign('row', $row);
|
||||||
$worker = Worker::withTrashed()->where('id', $order->worker_id)->find();
|
$worker = Worker::withTrashed()->where('id', $order->worker_id)->find();
|
||||||
$this->view->assign('worker', $worker);
|
$this->view->assign('worker',$worker);
|
||||||
$this->view->assign('cdnurl', config('upload.cdnurl'));
|
$this->view->assign('cdnurl', config('upload.cdnurl'));
|
||||||
return $this->view->fetch();
|
return $this->view->fetch();
|
||||||
}
|
}
|
||||||
|
|
@ -170,9 +148,9 @@ class Auditorder extends Backend
|
||||||
}
|
}
|
||||||
|
|
||||||
$txt = '审核通过';
|
$txt = '审核通过';
|
||||||
if ($audit_status) {
|
if($audit_status){
|
||||||
$params['status'] = Order::STATUS_FINISHED;
|
$params['status'] = Order::STATUS_FINISHED;
|
||||||
} else {
|
}else{
|
||||||
$params['status'] = Order::STATUS_CHECKONCE;
|
$params['status'] = Order::STATUS_CHECKONCE;
|
||||||
$txt = '审核未通过';
|
$txt = '审核未通过';
|
||||||
}
|
}
|
||||||
|
|
@ -185,16 +163,16 @@ class Auditorder extends Backend
|
||||||
$hookParams['order'] = $row;
|
$hookParams['order'] = $row;
|
||||||
$hookParams['role'] = 1;
|
$hookParams['role'] = 1;
|
||||||
$hookParams['auth'] = $this->auth;
|
$hookParams['auth'] = $this->auth;
|
||||||
$hookParams['remark'] = $txt . ',审核备注:' . $params['audit_remark'];
|
$hookParams['remark'] = $txt.',审核备注:'.$params['audit_remark'];
|
||||||
Hook::listen('order_change', $hookParams);
|
Hook::listen('order_change',$hookParams);
|
||||||
|
|
||||||
if ($params['status'] == Order::STATUS_CHECKONCE) {
|
if($params['status'] == Order::STATUS_CHECKONCE){
|
||||||
//未通过审核,通知派单员,重新配置
|
//未通过审核,通知派单员,重新配置
|
||||||
Message::create([
|
Message::create([
|
||||||
'to_id' => $row->dispatch_admin_id,
|
'to_id' => $row->dispatch_admin_id,
|
||||||
'type' => 1,
|
'type' => 1,
|
||||||
'title' => '订单结算审核未通过',
|
'title' => '订单结算审核未通过',
|
||||||
'content' => '【订单结算未通过】订单编号:' . $row->order_no . ',审核备注:' . $params['audit_remark'] . ',审核人:' . $this->auth->nickname
|
'content' => '【订单结算未通过】订单编号:'.$row->order_no.',审核备注:'.$params['audit_remark'].',审核人:'.$this->auth->nickname
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -210,42 +188,4 @@ class Auditorder extends Backend
|
||||||
$this->success();
|
$this->success();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function export()
|
|
||||||
{
|
|
||||||
$columns = json_decode($this->request->get('columns', ''), true);
|
|
||||||
if (!$columns) {
|
|
||||||
$sample = $this->index(true, 1, 1)->getData();
|
|
||||||
|
|
||||||
if (!isset($sample['rows'][0])) {
|
|
||||||
return json(['code' => 0, 'msg' => '无数据可导出']);
|
|
||||||
}
|
|
||||||
$columns = [];
|
|
||||||
foreach ($sample['rows'][0] as $key => $value) {
|
|
||||||
$columns[] = ['field' => $key, 'title' => $key];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$generator = function () use ($columns) {
|
|
||||||
$limit = 1000;
|
|
||||||
$page = 1;
|
|
||||||
$order = new \app\admin\model\Order();
|
|
||||||
do {
|
|
||||||
$result = $this->index(true, $page, $limit);
|
|
||||||
$rows = $result->getData()['rows'] ?? [];
|
|
||||||
if (!$rows) break;
|
|
||||||
|
|
||||||
foreach ($rows as $item) {
|
|
||||||
$item->status = $order->getStatusList()[$item->status] ?? '';
|
|
||||||
$item->amount_images = $this->dealImages($item->amount_images);
|
|
||||||
$item->workerman->images = $this->dealImages($item->workerman->images);
|
|
||||||
yield $item->toArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
$page++;
|
|
||||||
} while (count($rows) === $limit);
|
|
||||||
};
|
|
||||||
|
|
||||||
$this->streamCsv($columns, $generator(), '订单导出_' . date('Ymd_His') . '.csv');
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -110,7 +110,6 @@ class Dispatch extends Backend
|
||||||
$formattedTree = $this->formatTree($tree);
|
$formattedTree = $this->formatTree($tree);
|
||||||
|
|
||||||
$area_name = model('area')->getNameByCode($order->area_id);
|
$area_name = model('area')->getNameByCode($order->area_id);
|
||||||
// dd($area_name);
|
|
||||||
$order->area_name = str_replace(',', '/', $area_name);
|
$order->area_name = str_replace(',', '/', $area_name);
|
||||||
$this->view->assign('items', $formattedTree);
|
$this->view->assign('items', $formattedTree);
|
||||||
$this->view->assign('row', $order);
|
$this->view->assign('row', $order);
|
||||||
|
|
|
||||||
|
|
@ -282,7 +282,7 @@ class Dispatch2 extends Backend
|
||||||
|
|
||||||
|
|
||||||
$params = $this->request->post('row/a');
|
$params = $this->request->post('row/a');
|
||||||
dd($params);
|
|
||||||
$orderParsms = $this->request->post('order/a');
|
$orderParsms = $this->request->post('order/a');
|
||||||
if (empty($params) || empty($orderParsms)) {
|
if (empty($params) || empty($orderParsms)) {
|
||||||
$this->error(__('Parameter %s can not be empty', ''));
|
$this->error(__('Parameter %s can not be empty', ''));
|
||||||
|
|
@ -329,7 +329,6 @@ class Dispatch2 extends Backend
|
||||||
'cost' => $orderParsms['cost'],
|
'cost' => $orderParsms['cost'],
|
||||||
'cost_rate' => $orderParsms['cost_rate'],
|
'cost_rate' => $orderParsms['cost_rate'],
|
||||||
'offline_amount_type'=> $row->offline_total_type,
|
'offline_amount_type'=> $row->offline_total_type,
|
||||||
'amount_images' => $params['image']??'',
|
|
||||||
];
|
];
|
||||||
|
|
||||||
if($row->type == 1){ //手动
|
if($row->type == 1){ //手动
|
||||||
|
|
|
||||||
|
|
@ -29,9 +29,6 @@ class Review extends Backend
|
||||||
{
|
{
|
||||||
parent::_initialize();
|
parent::_initialize();
|
||||||
$this->model = new \app\admin\model\OrderReview;
|
$this->model = new \app\admin\model\OrderReview;
|
||||||
$order = new Order();
|
|
||||||
$this->view->assign("statusList", $order->getStatusList());
|
|
||||||
$this->view->assign("offlineTotalTypeList", $order->getOfflineTotalTypeList());
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -131,24 +131,24 @@ class Dispatcher extends Backend
|
||||||
|
|
||||||
$orderValid = implode(',',$this->model->tabStatus(Order::TAB_VALID));
|
$orderValid = implode(',',$this->model->tabStatus(Order::TAB_VALID));
|
||||||
|
|
||||||
|
//"COUNT(CASE WHEN status IN (".$orderValid.") THEN 1 END) AS ing_num",
|
||||||
$fields = [
|
$fields = [
|
||||||
'dispatch_admin_id',
|
'dispatch_admin_id',
|
||||||
// 只要是 COUNT(...) 不用 IFNULL
|
// 使用 IFNULL 确保结果为 null 时返回 0
|
||||||
"COUNT(CASE WHEN status = 60 THEN 1 END) AS finish_num", // 完成数
|
"IFNULL(COUNT(CASE WHEN status = 60 THEN 1 END), 0) AS finish_num", //完成数
|
||||||
"COUNT(CASE WHEN status IN (".$orderValid.") THEN 1 END) AS count_num", // 总订单数(排除取消和草稿)
|
"IFNULL(COUNT(CASE WHEN status IN (".$orderValid.") THEN 1 END), 0) AS count_num", //总订单数 (排除取消 和草稿)
|
||||||
"COUNT(CASE WHEN status IN (".$orderValid.") AND is_overtime = 1 THEN 1 END) AS overtime_num", // 超时数
|
"IFNULL(COUNT(CASE WHEN status = 60 AND is_overtime = 1 THEN 1 END), 0) AS overtime_num", //超时数
|
||||||
|
|
||||||
// SUM 可能为 NULL,使用 IFNULL 保证 0
|
"IFNULL(SUM(CASE WHEN status = 60 THEN total END), 0) AS total", //成效额
|
||||||
"IFNULL(SUM(CASE WHEN status = 60 THEN total END), 0) AS total", // 成效额
|
"IFNULL(SUM(CASE WHEN status = 60 THEN performance END), 0) AS performance", //业绩
|
||||||
"IFNULL(SUM(CASE WHEN status = 60 THEN performance END), 0) AS performance", // 业绩
|
"IFNULL(SUM(CASE WHEN status = 60 THEN (cost + material_cost) END), 0) AS cost_total", //总成本
|
||||||
"IFNULL(SUM(CASE WHEN status = 60 THEN (cost + material_cost) END), 0) AS cost_total", // 总成本
|
//"IFNULL(SUM(CASE WHEN status = 60 THEN (refund_amount + worker_refund_amount) END), 0) AS refund_total", //退款总数
|
||||||
|
"SUM(
|
||||||
// refund_total 计算改成 IFNULL(SUM(...), 0)
|
CASE WHEN status = 60 THEN (refund_amount + worker_refund_amount) ELSE 0 END
|
||||||
"IFNULL(SUM(CASE WHEN status = 60 THEN (refund_amount + worker_refund_amount) ELSE 0 END), 0) AS refund_total",
|
) AS refund_total",
|
||||||
|
"IFNULL(COUNT(CASE WHEN status = 60 AND (refund_amount > 0 OR worker_refund_amount > 0) THEN 1 END), 0) AS refund_count", //退款订单数量
|
||||||
"COUNT(CASE WHEN status = 60 AND (refund_amount > 0 OR worker_refund_amount > 0) THEN 1 END) AS refund_count", // 退款订单数量
|
"IFNULL(AVG(CASE WHEN status = 60 THEN UNIX_TIMESTAMP(dispatch_time) - UNIX_TIMESTAMP(create_time) END), 0) AS avg_time_diff", //派单时效
|
||||||
|
// "SUM(CASE WHEN status = 60 THEN (field1 + field2) END) AS performance",
|
||||||
"IFNULL(AVG(CASE WHEN status = 60 THEN UNIX_TIMESTAMP(dispatch_time) - UNIX_TIMESTAMP(create_time) END), 0) AS avg_time_diff", // 派单时效
|
|
||||||
];
|
];
|
||||||
|
|
||||||
$builder = $this->model
|
$builder = $this->model
|
||||||
|
|
|
||||||
|
|
@ -96,7 +96,7 @@ class Item extends Backend
|
||||||
if (!empty($filter)){
|
if (!empty($filter)){
|
||||||
$arr = explode(' - ', $filter);
|
$arr = explode(' - ', $filter);
|
||||||
if (trim($arr[0])) {
|
if (trim($arr[0])) {
|
||||||
$start = trim($arr[0]). ' 00:00:00';
|
$start = trim($arr[0]);
|
||||||
}
|
}
|
||||||
if (trim($arr[1])) {
|
if (trim($arr[1])) {
|
||||||
$end_at = trim($arr[1]) . ' 23:29:59';
|
$end_at = trim($arr[1]) . ' 23:29:59';
|
||||||
|
|
@ -113,6 +113,10 @@ class Item extends Backend
|
||||||
if(!empty(request()->get('source',null))){
|
if(!empty(request()->get('source',null))){
|
||||||
$build->where('source',request()->get('source'));
|
$build->where('source',request()->get('source'));
|
||||||
}
|
}
|
||||||
|
//城市
|
||||||
|
/* if(!empty(request()->post('area_id',null))){
|
||||||
|
$build->where('area_id','LIKE',request()->post('source').'%');
|
||||||
|
}*/
|
||||||
|
|
||||||
if(!empty(request()->get('item_id',null))){
|
if(!empty(request()->get('item_id',null))){
|
||||||
$item_id =request()->get('item_id');
|
$item_id =request()->get('item_id');
|
||||||
|
|
@ -121,7 +125,7 @@ class Item extends Backend
|
||||||
$build->whereIn('item_id', $item_ids);
|
$build->whereIn('item_id', $item_ids);
|
||||||
}
|
}
|
||||||
|
|
||||||
$build->whereBetween('audit_time', [$start, $end_at])
|
$build->whereBetween('create_time', [$start, $end_at])
|
||||||
->field([
|
->field([
|
||||||
'item_title name', // 类型
|
'item_title name', // 类型
|
||||||
'sum(total) total', // 营业额
|
'sum(total) total', // 营业额
|
||||||
|
|
@ -137,14 +141,12 @@ class Item extends Backend
|
||||||
])->group('item_title')
|
])->group('item_title')
|
||||||
->order('count_num', 'desc');
|
->order('count_num', 'desc');
|
||||||
// dd($total);
|
// dd($total);
|
||||||
|
|
||||||
$res = $build->paginate($limit);
|
$res = $build->paginate($limit);
|
||||||
$total = $res->total();
|
$total = $res->total();
|
||||||
$ress = $res->items();
|
$ress = $res->items();
|
||||||
$data = [];
|
$data = [];
|
||||||
// dd($res);
|
// dd($res);
|
||||||
foreach ($ress as $re) {
|
foreach ($ress as $re) {
|
||||||
|
|
||||||
$re = $re->toArray();
|
$re = $re->toArray();
|
||||||
// dd($re);
|
// dd($re);
|
||||||
$cost_total = $re['cost'] + $re['material_cost'];
|
$cost_total = $re['cost'] + $re['material_cost'];
|
||||||
|
|
@ -157,6 +159,7 @@ class Item extends Backend
|
||||||
$re['performance_avg'] = $this->mydiv($re['performance'],$re['finish_num'],2,false);
|
$re['performance_avg'] = $this->mydiv($re['performance'],$re['finish_num'],2,false);
|
||||||
$re['avg_time_diff'] = $this->mydiv($re['avg_time_diff'],3600,2,false);
|
$re['avg_time_diff'] = $this->mydiv($re['avg_time_diff'],3600,2,false);
|
||||||
$re['cost_total'] = number_format($cost_total,2,'.','');
|
$re['cost_total'] = number_format($cost_total,2,'.','');
|
||||||
|
// $re['id'] = $re['item_id'];
|
||||||
$data [] = $re;
|
$data [] = $re;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -45,28 +45,33 @@ class Kpidispatcher extends Backend
|
||||||
$itemUnits[$item['attr']] = $item['unit'];
|
$itemUnits[$item['attr']] = $item['unit'];
|
||||||
}
|
}
|
||||||
|
|
||||||
$items = [
|
|
||||||
'ZHL' => ['name' => '转化率', 'unit' => '%'],
|
|
||||||
'LRL' => ['name' => '利润率'],
|
|
||||||
'PDSX' => ['name' => '派单时效'],
|
|
||||||
'PCCGL' => ['name' => '派出成功率'],
|
|
||||||
'GDJSL' => ['name' => '跟单及时率'],
|
|
||||||
'LRSFS' => ['name' => '录入师傅数'],
|
|
||||||
];
|
|
||||||
|
|
||||||
$item_title = [];
|
$item_title = [];
|
||||||
|
|
||||||
foreach ($items as $key => $info) {
|
$item_title['ZHL'] = [
|
||||||
$weight = !empty($itemRate[$key]) ? '(权重'.$itemRate[$key].'%)' : '';
|
'title' => '转化率'.(!empty($itemRate['ZHL'])?'(权重'.$itemRate['ZHL'].'%)':''),
|
||||||
$item_title[$key] = [
|
'isshow' => !empty($itemRate['ZHL']),
|
||||||
'title' => $info['name'] . $weight,
|
'unit' => '%'
|
||||||
'isshow' => !empty($itemRate[$key]),
|
];
|
||||||
|
$item_title['LRL'] = [
|
||||||
|
'title' => '利润率'.(!empty($itemRate['LRL'])?'(权重'.$itemRate['LRL'].'%)':''),
|
||||||
|
'isshow' =>!empty($itemRate['LRL']),
|
||||||
|
];
|
||||||
|
$item_title['PDSX'] = [
|
||||||
|
'title' => '派单时效'.(!empty($itemRate['PDSX'])?'(权重'.$itemRate['PDSX'].'%)':''),
|
||||||
|
'isshow' =>!empty($itemRate['PDSX']),
|
||||||
|
];
|
||||||
|
$item_title['PCCGL'] = [
|
||||||
|
'title' => '派出成功率'.(!empty($itemRate['PCCGL'])?'(权重'.$itemRate['PCCGL'].'%)':''),
|
||||||
|
'isshow' =>!empty($itemRate['PCCGL']),
|
||||||
|
];
|
||||||
|
$item_title['GDJSL'] = [
|
||||||
|
'title' => '跟单及时率'.(!empty($itemRate['GDJSL'])?'(权重'.$itemRate['GDJSL'].'%)':''),
|
||||||
|
'isshow' =>!empty($itemRate['GDJSL']),
|
||||||
|
];
|
||||||
|
$item_title['LRSFS'] = [
|
||||||
|
'title' => '录入师傅数'.(!empty($itemRate['LRSFS'])?'(权重'.$itemRate['LRSFS'].'%)':''),
|
||||||
|
'isshow' =>!empty($itemRate['LRSFS']),
|
||||||
];
|
];
|
||||||
if (isset($info['unit'])) {
|
|
||||||
$item_title[$key]['unit'] = $info['unit'];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*$item_title['LRL'] = '利润率'.(!empty($itemRate['LRL'])?$itemRate['LRL'].'%':'');
|
/*$item_title['LRL'] = '利润率'.(!empty($itemRate['LRL'])?$itemRate['LRL'].'%':'');
|
||||||
$item_title['PDSX'] = '派单时效'.(!empty($itemRate['PDSX'])?$itemRate['LRL'].'%':'');
|
$item_title['PDSX'] = '派单时效'.(!empty($itemRate['PDSX'])?$itemRate['LRL'].'%':'');
|
||||||
$item_title['PCCGL'] = '派出成功率'.(!empty($itemRate['PCCGL'])?$itemRate['LRL'].'%':'');
|
$item_title['PCCGL'] = '派出成功率'.(!empty($itemRate['PCCGL'])?$itemRate['LRL'].'%':'');
|
||||||
|
|
@ -179,26 +184,19 @@ class Kpidispatcher extends Backend
|
||||||
$orderValid = implode(',',$this->model->tabStatus(Order::TAB_VALID));
|
$orderValid = implode(',',$this->model->tabStatus(Order::TAB_VALID));
|
||||||
|
|
||||||
//"COUNT(CASE WHEN status IN (".$orderValid.") THEN 1 END) AS ing_num",
|
//"COUNT(CASE WHEN status IN (".$orderValid.") THEN 1 END) AS ing_num",
|
||||||
|
|
||||||
$fields = [
|
$fields = [
|
||||||
'dispatch_admin_id',
|
'dispatch_admin_id',
|
||||||
'worker_num',
|
'worker_num',
|
||||||
// 完成数
|
// 使用 IFNULL 确保结果为 null 时返回 0
|
||||||
"COUNT(CASE WHEN status = 60 THEN 1 END) AS finish_num",
|
"IFNULL(COUNT(CASE WHEN status = 60 THEN 1 END), 0) AS finish_num", //完成数
|
||||||
// 总订单数(排除取消和草稿)
|
"IFNULL(COUNT(CASE WHEN status IN (".$orderValid.") THEN 1 END), 0) AS count_num", //总订单数 (排除取消 和草稿)
|
||||||
"COUNT(CASE WHEN status IN (".$orderValid.") THEN 1 END) AS count_num",
|
"IFNULL(SUM(CASE WHEN status = 60 THEN total END), 0) AS total", //成效额
|
||||||
// 成效额
|
"IFNULL(SUM(CASE WHEN status = 60 THEN performance END), 0) AS performance", //业绩
|
||||||
"IFNULL(SUM(CASE WHEN status = 60 THEN total END), 0) AS total",
|
"IFNULL(SUM(CASE WHEN status = 60 THEN (cost + material_cost) END), 0) AS cost_total", //总成本
|
||||||
// 业绩
|
"IFNULL(SUM(CASE WHEN status = 60 THEN (refund_amount + worker_refund_amount) END), 0) AS refund_total", //退款总数
|
||||||
"IFNULL(SUM(CASE WHEN status = 60 THEN performance END), 0) AS performance",
|
"IFNULL(COUNT(CASE WHEN refund_amount > 0 OR worker_refund_amount > 0 THEN 1 END), 0) AS refund_count", //退款订单数量
|
||||||
// 总成本
|
"IFNULL(AVG(CASE WHEN status > 10 THEN UNIX_TIMESTAMP(dispatch_time) - UNIX_TIMESTAMP(create_time) END), 0) AS avg_time_diff", //派单时效
|
||||||
"IFNULL(SUM(CASE WHEN status = 60 THEN (cost + material_cost) END), 0) AS cost_total",
|
// "SUM(CASE WHEN status = 60 THEN (field1 + field2) END) AS performance",
|
||||||
// 退款总数
|
|
||||||
"IFNULL(SUM(CASE WHEN status = 60 THEN (refund_amount + worker_refund_amount) END), 0) AS refund_total",
|
|
||||||
// 退款订单数量
|
|
||||||
"COUNT(CASE WHEN refund_amount > 0 OR worker_refund_amount > 0 THEN 1 END) AS refund_count",
|
|
||||||
// 派单时效(过滤状态大于10)
|
|
||||||
"IFNULL(AVG(CASE WHEN status > 10 THEN UNIX_TIMESTAMP(dispatch_time) - UNIX_TIMESTAMP(create_time) END), 0) AS avg_time_diff",
|
|
||||||
];
|
];
|
||||||
|
|
||||||
$builder = $this->model
|
$builder = $this->model
|
||||||
|
|
@ -248,67 +246,92 @@ class Kpidispatcher extends Backend
|
||||||
$max_score = $template->max_score??100;
|
$max_score = $template->max_score??100;
|
||||||
|
|
||||||
if(!empty($data)){
|
if(!empty($data)){
|
||||||
|
foreach ($data as &$datum){
|
||||||
|
//利润率 = 总业绩/总成效额
|
||||||
|
$datum->performance_rate = $this->_calc($datum->performance,$datum->total,4,true);
|
||||||
|
//转化率 = 完单数 / 总订单数
|
||||||
|
$datum->trans_rate = $this->_calc($datum->finish_num,$datum->count_num,4,true);
|
||||||
|
//变现值 = 总业绩 / 总订单数
|
||||||
|
$datum->cash_value = $this->_calc($datum->performance,$datum->count_num,2);
|
||||||
|
//客单利润 = 总利润 / 完单数
|
||||||
|
$datum->performance_avg = $this->_calc($datum->performance,$datum->finish_num,2);
|
||||||
|
//客单价 = 总成效额 / 完单数
|
||||||
|
$datum->total_avg = $this->_calc($datum->total,$datum->finish_num,2);
|
||||||
|
|
||||||
foreach ($data as &$datum) {
|
if(!empty($datum->dispatch_admin_id)){
|
||||||
// 常规字段计算
|
$datum->admin_user = Admin::where('id',$datum->dispatch_admin_id)->value('nickname')??'系统';
|
||||||
$datum->performance_rate = $this->_calc($datum->performance, $datum->total, 4, true);
|
}else{
|
||||||
$datum->trans_rate = $this->_calc($datum->finish_num, $datum->count_num, 4, true);
|
$datum->admin_user = '系统';
|
||||||
$datum->cash_value = $this->_calc($datum->performance, $datum->count_num, 2);
|
}
|
||||||
$datum->performance_avg = $this->_calc($datum->performance, $datum->finish_num, 2);
|
$datum->avg_time_diff = $this->_calc($datum->avg_time_diff,3600,4);
|
||||||
$datum->total_avg = $this->_calc($datum->total, $datum->finish_num, 2);
|
|
||||||
$datum->avg_time_diff = $this->_calc($datum->avg_time_diff, 3600, 4);
|
|
||||||
|
|
||||||
// 管理员名称
|
|
||||||
//派单员数量不多,循环中查
|
|
||||||
$datum->admin_user = !empty($datum->dispatch_admin_id)
|
|
||||||
? Admin::where('id', $datum->dispatch_admin_id)->value('nickname') ?? '系统'
|
|
||||||
: '系统';
|
|
||||||
|
|
||||||
$datum->id = $datum->dispatch_admin_id;
|
$datum->id = $datum->dispatch_admin_id;
|
||||||
|
|
||||||
// 初始化 KPI 总分
|
|
||||||
$kpi_total = 0;
|
$kpi_total = 0;
|
||||||
|
//kpi
|
||||||
// 定义 KPI 计算配置
|
//转化率
|
||||||
$kpiMap = [
|
$datum->zhl_score = 0;
|
||||||
KpiItem::ATTR_ZHL => ['field' => 'trans_rate', 'score_field' => 'zhl_score', 'target_field' => 'zhl_target_value'],
|
$datum->zhl_target_value = $kpiItem[KpiItem::ATTR_ZHL]['target_value']??0;
|
||||||
KpiItem::ATTR_LRL => ['field' => 'performance_rate','score_field' => 'lrl_score', 'target_field' => 'lrl_target_value'],
|
$datum->unit = '';
|
||||||
KpiItem::ATTR_PDSX => ['field' => 'avg_time_diff', 'score_field' => 'pdsx_score', 'target_field' => 'pdsx_target_value', 'reverse' => true],
|
if(!empty($kpiItem[KpiItem::ATTR_ZHL])){
|
||||||
KpiItem::ATTR_PCCGL => ['field' => 'succ_rate', 'score_field' => 'pccgl_score', 'target_field' => 'pccgl_target_value'],
|
$datum->zhl_score = $this->_kpi_score($datum->trans_rate,$kpiItem[KpiItem::ATTR_ZHL]);
|
||||||
KpiItem::ATTR_LRSFS => ['field' => 'worker_num', 'score_field' => 'lrsfs_score', 'target_field' => 'lrsfs_target_value'],
|
$kpi_total += $datum->zhl_score;
|
||||||
];
|
//$datum->zhl_unit = $kpiItem[KpiItem::ATTR_ZHL]['unit'];
|
||||||
|
|
||||||
// 单独处理 success rate(派单成功率)
|
|
||||||
$datum->succ_rate = $this->_calc($datum->finish_num, $datum->count_num, 4, true);
|
|
||||||
$datum->worker_num = $datum->worker_num ?? 0;
|
|
||||||
|
|
||||||
// 批量处理 KPI 项
|
|
||||||
foreach ($kpiMap as $attr => $conf) {
|
|
||||||
$item = $kpiItem[$attr] ?? null;
|
|
||||||
$datum->{$conf['score_field']} = 0;
|
|
||||||
$datum->{$conf['target_field']} = $item['target_value'] ?? 0;
|
|
||||||
|
|
||||||
if ($item) {
|
|
||||||
$reverse = $conf['reverse'] ?? false;
|
|
||||||
$value = $datum->{$conf['field']};
|
|
||||||
$score = $this->_kpi_score($value, $item, $reverse);
|
|
||||||
$datum->{$conf['score_field']} = $score;
|
|
||||||
$kpi_total += $score;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// KPI 总分和比值
|
//利润率
|
||||||
$datum->kpi_total = bcadd($kpi_total, 0, 2);
|
$datum->lrl_score = 0;
|
||||||
$datum->kpi_value = $this->_calc($kpi_total, $template->score ?: 1, 2);
|
$datum->lrl_target_value = $kpiItem[KpiItem::ATTR_LRL]['target_value']??0;
|
||||||
|
if (!empty($kpiItem[KpiItem::ATTR_LRL])) {
|
||||||
|
$datum->lrl_score = $this->_kpi_score($datum->performance_rate, $kpiItem[KpiItem::ATTR_LRL]);
|
||||||
|
$kpi_total += $datum->lrl_score;
|
||||||
|
//$datum->lrl_unit = $kpiItem[KpiItem::ATTR_LRL]['unit'];
|
||||||
|
}
|
||||||
|
|
||||||
// KPI 奖金
|
//派单时效
|
||||||
if ($datum->kpi_value <= 0) {
|
$datum->pdsx_score = 0;
|
||||||
|
$datum->pdsx_target_value = $kpiItem[KpiItem::ATTR_PDSX]['target_value']??0; //秒
|
||||||
|
if (!empty($kpiItem[KpiItem::ATTR_PDSX])) {
|
||||||
|
$datum->pdsx_score = $this->_kpi_score($datum->avg_time_diff, $kpiItem[KpiItem::ATTR_PDSX],$fande=true);
|
||||||
|
$kpi_total += $datum->pdsx_score;
|
||||||
|
//$datum->pdsx_unit = $kpiItem[KpiItem::ATTR_PDSX]['unit'];
|
||||||
|
}
|
||||||
|
|
||||||
|
//派单成功率
|
||||||
|
$datum->succ_rate = $this->_calc($datum->finish_num,$datum->count_num,4,true);
|
||||||
|
$datum->pccgl_score = 0;
|
||||||
|
$datum->pccgl_target_value = $kpiItem[KpiItem::ATTR_PCCGL]['target_value']??0;
|
||||||
|
if (!empty($kpiItem[KpiItem::ATTR_PCCGL])) {
|
||||||
|
$datum->pccgl_score = $this->_kpi_score($datum->succ_rate, $kpiItem[KpiItem::ATTR_PCCGL]);
|
||||||
|
$kpi_total += $datum->pccgl_score;
|
||||||
|
//$datum->pccgl_unit = $kpiItem[KpiItem::ATTR_PCCGL]['unit'];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//录单师傅数
|
||||||
|
$datum->lrsfs_score = 0;
|
||||||
|
$datum->lrsfs_target_value = $kpiItem[KpiItem::ATTR_LRSFS]['target_value']??0;
|
||||||
|
$datum->worker_num = $datum->worker_num??0;
|
||||||
|
if (!empty($kpiItem[KpiItem::ATTR_LRSFS])) {
|
||||||
|
$datum->lrsfs_score = $this->_kpi_score($datum->worker_num, $kpiItem[KpiItem::ATTR_LRSFS]);
|
||||||
|
$kpi_total += $datum->lrsfs_score;
|
||||||
|
}
|
||||||
|
|
||||||
|
$datum->kpi_total = bcadd($kpi_total,0,2);
|
||||||
|
|
||||||
|
$datum->kpi_value = $this->_calc($kpi_total,$template->score ?: 1,2);
|
||||||
|
|
||||||
|
if($datum->kpi_value <= 0){
|
||||||
$datum->kpi_money = 0;
|
$datum->kpi_money = 0;
|
||||||
} else {
|
}else{
|
||||||
$money = bcmul($datum->performance, $datum->kpi_value, 4);
|
$datum->kpi_money = bcmul($datum->performance,$datum->kpi_value,4);
|
||||||
$datum->kpi_money = $money > 0 ? bcdiv($money, 100, 2) : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if($datum->kpi_money <= 0){
|
||||||
|
$datum->kpi_money = 0;
|
||||||
|
}else{
|
||||||
|
$datum->kpi_money = bcdiv($datum->kpi_money,100,2);
|
||||||
|
}
|
||||||
|
}
|
||||||
$newData[] = $datum->toArray();
|
$newData[] = $datum->toArray();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -342,32 +365,36 @@ class Kpidispatcher extends Backend
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private function _kpi_score($num, $item, $fande = false)
|
private function _kpi_score($num,$item,$fande=false)
|
||||||
{
|
{
|
||||||
$target = $item['target_value'] ?? 1;
|
//完成值/目标值*单个指标分*权重
|
||||||
$target = $target == 0 ? 1 : $target; // 避免除以0
|
|
||||||
|
|
||||||
// 计算得分比例
|
if($item['target_value'] == 0){
|
||||||
if ($fande) {
|
$item['target_value'] = 1;
|
||||||
$diff = bcsub($num, $target, 4);
|
}
|
||||||
$rate = bcdiv(abs($diff), $target, 4);
|
if($fande){
|
||||||
|
//哦哦 如果定的是10分钟,完成的为15分钟,则1-(15-10)/10
|
||||||
// 方向判断:小于目标加分,超过目标扣分
|
//这个还要区分是超过10还是小于10,超过10了就上面的,没超过就是1 + (10-完成值)/10
|
||||||
$rate = $num > $target
|
if($num > $item['target_value']){
|
||||||
? bcsub(1, $rate, 4)
|
$rate = bcdiv(($num-$item['target_value']),$item['target_value'],4);
|
||||||
: bcadd(1, $rate, 4);
|
$rate = bcsub(1,$rate,4);
|
||||||
} else {
|
}else{
|
||||||
$rate = bcdiv($num, $target, 4);
|
$rate = bcdiv(($item['target_value']-$num),$item['target_value'],4);
|
||||||
|
$rate = bcadd(1,$rate,4);
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
$rate = bcdiv($num,$item['target_value'],4);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 得分 = 比例 × 指标分数 × 权重
|
$score = bcmul($item['score'],$rate,4);
|
||||||
$score = bcmul($item['score'], $rate, 4);
|
$score = bcmul($score,$item['pivot']['rate']/100,2);
|
||||||
$weight = isset($item['pivot']['rate']) ? $item['pivot']['rate'] : 100;
|
|
||||||
$score = bcmul($score, bcdiv($weight, 100, 4), 2);
|
|
||||||
|
|
||||||
return max($score, 0); // 保证非负
|
if($score<= 0){
|
||||||
|
$score = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return $score;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -156,7 +156,7 @@ class Worker extends Backend
|
||||||
'fa_worker.*',
|
'fa_worker.*',
|
||||||
'IFNULL(a.dispatch_count, 0) AS dispatch_count',
|
'IFNULL(a.dispatch_count, 0) AS dispatch_count',
|
||||||
'IFNULL(a.get_js_count, 0) AS get_js_count',
|
'IFNULL(a.get_js_count, 0) AS get_js_count',
|
||||||
'IFNULL(b.get_count, 0) AS get_count',
|
'IFNULL(a.get_count, 0) AS get_count',
|
||||||
'IFNULL(a.refuse_count, 0) AS refuse_count',
|
'IFNULL(a.refuse_count, 0) AS refuse_count',
|
||||||
'IFNULL(a.arrive_count, 0) AS arrive_count',
|
'IFNULL(a.arrive_count, 0) AS arrive_count',
|
||||||
'IFNULL(a.avg_time_diff, 0) AS avg_time_diff',
|
'IFNULL(a.avg_time_diff, 0) AS avg_time_diff',
|
||||||
|
|
@ -256,18 +256,16 @@ class Worker extends Backend
|
||||||
$builder = new OrderDispatch();
|
$builder = new OrderDispatch();
|
||||||
$fields = [
|
$fields = [
|
||||||
'worker_id',
|
'worker_id',
|
||||||
// 分配数,COUNT(*) 不可能为 NULL
|
// 使用 IFNULL 确保结果为 null 时返回 0
|
||||||
"COUNT(*) AS dispatch_count",
|
"IFNULL(COUNT(*), 0) AS dispatch_count", //分配数
|
||||||
// 接单数,状态为 30 或 60
|
"IFNULL(COUNT(CASE WHEN status NOT IN (0,-30, -10) THEN 1 END), 0) AS get_count", //接单数
|
||||||
"COUNT(CASE WHEN status IN (30, 60) THEN 1 END) AS get_js_count",
|
|
||||||
// 拒绝数,状态为 -10
|
|
||||||
"COUNT(CASE WHEN status = -10 THEN 1 END) AS refuse_count",
|
|
||||||
// 上门数,统计非 NULL 的 arrive_time
|
|
||||||
"COUNT(arrive_time) AS arrive_count",
|
|
||||||
// 联系时效,平均时间差,保留 IFNULL 防止 NULL
|
|
||||||
"IFNULL(AVG(CASE WHEN status = 60 AND arrive_time IS NOT NULL THEN UNIX_TIMESTAMP(arrive_time) - UNIX_TIMESTAMP(create_time) END), 0) AS avg_time_diff",
|
|
||||||
];
|
|
||||||
|
|
||||||
|
"IFNULL(COUNT(CASE WHEN status IN (30, 60) THEN 1 END), 0) AS get_js_count", //接单数
|
||||||
|
//"COUNT(CASE WHEN status IN (60) THEN 1 END) AS finish_count", //完成数
|
||||||
|
"IFNULL(COUNT(CASE WHEN status IN (-10) THEN 1 END), 0) AS refuse_count", //拒绝数
|
||||||
|
"IFNULL(COUNT(arrive_time), 0) AS arrive_count", //上门数
|
||||||
|
"IFNULL(AVG(CASE WHEN status = 60 AND arrive_time IS NOT NULL THEN UNIX_TIMESTAMP(arrive_time) - UNIX_TIMESTAMP(create_time) END), 0) AS avg_time_diff", //联系时效
|
||||||
|
];
|
||||||
$builder->field($fields);
|
$builder->field($fields);
|
||||||
|
|
||||||
if(!empty($filter['start_time'])){
|
if(!empty($filter['start_time'])){
|
||||||
|
|
@ -301,22 +299,20 @@ class Worker extends Backend
|
||||||
//"COUNT(CASE WHEN status IN (".$orderValid.") THEN 1 END) AS ing_num",
|
//"COUNT(CASE WHEN status IN (".$orderValid.") THEN 1 END) AS ing_num",
|
||||||
$fields = [
|
$fields = [
|
||||||
'worker_id',
|
'worker_id',
|
||||||
// 接单数,状态 > 10
|
// 使用 IFNULL 确保结果为 null 时返回 0
|
||||||
"COUNT(CASE WHEN status > 10 THEN 1 END) AS get_count",
|
"IFNULL(COUNT(CASE WHEN status = 60 THEN 1 END), 0) AS finish_num", //完成数
|
||||||
// 完成数,状态 = 60
|
//"COUNT(CASE WHEN status IN (".$orderValid.") THEN 1 END) AS count_num", //总订单数 (排除取消 和草稿)
|
||||||
"COUNT(CASE WHEN status = 60 THEN 1 END) AS finish_num",
|
"IFNULL(SUM(CASE WHEN status = 60 THEN total END), 0) AS total", //成效额
|
||||||
// 成效额,状态 = 60,SUM可能为NULL,保留IFNULL
|
"IFNULL(SUM(CASE WHEN status = 60 THEN performance END), 0) AS performance", //业绩
|
||||||
"IFNULL(SUM(CASE WHEN status = 60 THEN total END), 0) AS total",
|
"IFNULL(SUM(CASE WHEN status = 60 THEN cost END), 0) AS cost", //成效额
|
||||||
// 业绩,状态 = 60
|
|
||||||
"IFNULL(SUM(CASE WHEN status = 60 THEN performance END), 0) AS performance",
|
|
||||||
// 成本,状态 = 60
|
|
||||||
"IFNULL(SUM(CASE WHEN status = 60 THEN cost END), 0) AS cost",
|
|
||||||
// 退款总数,状态 = 60
|
|
||||||
"IFNULL(SUM(CASE WHEN status = 60 THEN (refund_amount + worker_refund_amount) END), 0) AS refund_total",
|
|
||||||
// 退款订单数量
|
|
||||||
"COUNT(CASE WHEN refund_amount > 0 OR worker_refund_amount > 0 THEN 1 END) AS refund_count",
|
|
||||||
];
|
|
||||||
|
|
||||||
|
// "SUM(CASE WHEN status = 60 THEN (cost + material_cost) END) AS cost_total", //总成本
|
||||||
|
|
||||||
|
"IFNULL(SUM(CASE WHEN status = 60 THEN (refund_amount + worker_refund_amount) END), 0) AS refund_total", //退款总数
|
||||||
|
"IFNULL(COUNT(CASE WHEN refund_amount > 0 OR worker_refund_amount > 0 THEN 1 END), 0) AS refund_count", //退款订单数量
|
||||||
|
//"AVG(CASE WHEN status > 10 THEN UNIX_TIMESTAMP(dispatch_time) - UNIX_TIMESTAMP(create_time) END) AS avg_time_diff", //派单时效
|
||||||
|
// "SUM(CASE WHEN status = 60 THEN (field1 + field2) END) AS performance",
|
||||||
|
];
|
||||||
|
|
||||||
$builder = (new Order())->field($fields);
|
$builder = (new Order())->field($fields);
|
||||||
|
|
||||||
|
|
@ -394,8 +390,8 @@ class Worker extends Backend
|
||||||
$op = $this->request->get("op", '', 'trim');
|
$op = $this->request->get("op", '', 'trim');
|
||||||
$sort = $this->request->get("sort", !empty($this->model) && $this->model->getPk() ? $this->model->getPk() : 'id');
|
$sort = $this->request->get("sort", !empty($this->model) && $this->model->getPk() ? $this->model->getPk() : 'id');
|
||||||
|
|
||||||
$asortFields = ['dispatch_count','refuse_count','arrive_count'];
|
$asortFields = ['dispatch_count','get_count','refuse_count','arrive_count'];
|
||||||
$bsortFields = ['finish_num','total','performance','refund_total','refund_count','cost','get_count'];
|
$bsortFields = ['finish_num','total','performance','refund_total','refund_count','cost'];
|
||||||
$csortFields = ['good_count'];
|
$csortFields = ['good_count'];
|
||||||
|
|
||||||
if(!empty($sort) ){
|
if(!empty($sort) ){
|
||||||
|
|
|
||||||
|
|
@ -85,11 +85,10 @@ class Worker extends Backend
|
||||||
$this->request->filter(['strip_tags', 'trim']);
|
$this->request->filter(['strip_tags', 'trim']);
|
||||||
$items = $this->items;
|
$items = $this->items;
|
||||||
$filtered = array_filter($items, function ($item) {
|
$filtered = array_filter($items, function ($item) {
|
||||||
return $item['level'] == 2;
|
return $item['pid'] == 0;
|
||||||
});
|
});
|
||||||
|
|
||||||
$pid_map = array_column($filtered, null, 'id');
|
$pid_map = array_column($filtered, null, 'id');
|
||||||
|
|
||||||
if ($this->request->isAjax()) {
|
if ($this->request->isAjax()) {
|
||||||
//如果发送的来源是Selectpage,则转发到Selectpage
|
//如果发送的来源是Selectpage,则转发到Selectpage
|
||||||
if ($this->request->request('keyField')) {
|
if ($this->request->request('keyField')) {
|
||||||
|
|
@ -136,8 +135,7 @@ class Worker extends Backend
|
||||||
$worker_ids = [];
|
$worker_ids = [];
|
||||||
foreach ($list->items() as $item){
|
foreach ($list->items() as $item){
|
||||||
$dt = $item->toArray();
|
$dt = $item->toArray();
|
||||||
preg_match_all('/\d+/', $dt['tel'], $matches);;
|
$tel = $dt['tel'];
|
||||||
$tel = $matches[0][0] ?? '';
|
|
||||||
if (preg_match('/^\d{7,}$/', $tel)) {
|
if (preg_match('/^\d{7,}$/', $tel)) {
|
||||||
$dt['tel'] = mb_substr($tel, 0, 3, 'UTF-8') . '****' . mb_substr($tel, -4, null, 'UTF-8');
|
$dt['tel'] = mb_substr($tel, 0, 3, 'UTF-8') . '****' . mb_substr($tel, -4, null, 'UTF-8');
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -147,9 +145,8 @@ class Worker extends Backend
|
||||||
$data[] = $dt;
|
$data[] = $dt;
|
||||||
$worker_ids [] = $item['id'];
|
$worker_ids [] = $item['id'];
|
||||||
}
|
}
|
||||||
$worker_item = WorkerItem::whereIn('worker_id',$worker_ids)->where('item_path_id',2)
|
$worker_item = WorkerItem::whereIn('worker_id',$worker_ids)->where('item_path_id',1)
|
||||||
->field('worker_id,item_id')->select();
|
->field('worker_id,item_id')->select();
|
||||||
|
|
||||||
$worker_item_map = [];
|
$worker_item_map = [];
|
||||||
// dd($worker_item);
|
// dd($worker_item);
|
||||||
foreach ($worker_item as $item){
|
foreach ($worker_item as $item){
|
||||||
|
|
@ -159,14 +156,12 @@ class Worker extends Backend
|
||||||
// dd($worker_item_map);
|
// dd($worker_item_map);
|
||||||
if (key_exists($datum['id'],$worker_item_map)){
|
if (key_exists($datum['id'],$worker_item_map)){
|
||||||
foreach ($worker_item_map[$datum['id']] as $item){
|
foreach ($worker_item_map[$datum['id']] as $item){
|
||||||
if ($pid_map[$item] ?? false){
|
$datum ['worker_item'][] = trim($pid_map[$item]['title']);
|
||||||
$datum ['worker_item'][] = str_replace(" ",'',$pid_map[$item]['title']);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
$datum ['worker_item'] = [];
|
$datum ['worker_item'] = [];
|
||||||
}
|
}
|
||||||
$datum['worker_item'] = implode(',',$datum['worker_item'] ?? []);
|
$datum['worker_item'] = implode(',',$datum['worker_item']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,10 +7,5 @@ return [
|
||||||
'Worker_star' => '师傅评分',
|
'Worker_star' => '师傅评分',
|
||||||
'Remark' => '备注',
|
'Remark' => '备注',
|
||||||
'Admin_id' => '回访人',
|
'Admin_id' => '回访人',
|
||||||
'Admin_user' => '回访人',
|
'Admin_user' => '回访人'
|
||||||
'Coupons' => '优惠',
|
|
||||||
'Offline_amount_type' => '线下尾款类型',
|
|
||||||
'Offline_amount_type 0' => '无',
|
|
||||||
'Offline_amount_type 1' => '师傅收',
|
|
||||||
'Offline_amount_type 2' => '公司收',
|
|
||||||
];
|
];
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@ class Area extends Model
|
||||||
->where('level','<',3)
|
->where('level','<',3)
|
||||||
->select();
|
->select();
|
||||||
|
|
||||||
|
|
||||||
// dd($ruleList);
|
// dd($ruleList);
|
||||||
|
|
||||||
foreach ($res as &$v) {
|
foreach ($res as &$v) {
|
||||||
|
|
|
||||||
|
|
@ -98,6 +98,7 @@ class Item extends Model
|
||||||
foreach ($data as $item) {
|
foreach ($data as $item) {
|
||||||
$index[$item['pid']][] = $item;
|
$index[$item['pid']][] = $item;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 递归函数,闭包形式避免污染全局
|
// 递归函数,闭包形式避免污染全局
|
||||||
$collect = function($pid) use (&$collect, &$index) {
|
$collect = function($pid) use (&$collect, &$index) {
|
||||||
$ids = [];
|
$ids = [];
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,6 @@
|
||||||
<link rel="shortcut icon" href="__CDN__/assets/img/favicon.ico" />
|
<link rel="shortcut icon" href="__CDN__/assets/img/favicon.ico" />
|
||||||
<!-- Loading Bootstrap -->
|
<!-- Loading Bootstrap -->
|
||||||
<link href="__CDN__/assets/css/backend{$Think.config.app_debug?'':'.min'}.css?v={$Think.config.site.version|htmlentities}" rel="stylesheet">
|
<link href="__CDN__/assets/css/backend{$Think.config.app_debug?'':'.min'}.css?v={$Think.config.site.version|htmlentities}" rel="stylesheet">
|
||||||
<link href="__CDN__/assets/css/common.css?v={$Think.config.site.version|htmlentities}" rel="stylesheet">
|
|
||||||
|
|
||||||
{if $Think.config.fastadmin.adminskin}
|
{if $Think.config.fastadmin.adminskin}
|
||||||
<link href="__CDN__/assets/css/skins/{$Think.config.fastadmin.adminskin|htmlentities}.css?v={$Think.config.site.version|htmlentities}" rel="stylesheet">
|
<link href="__CDN__/assets/css/skins/{$Think.config.fastadmin.adminskin|htmlentities}.css?v={$Think.config.site.version|htmlentities}" rel="stylesheet">
|
||||||
|
|
|
||||||
|
|
@ -20,9 +20,6 @@
|
||||||
<div class="widget-body no-padding">
|
<div class="widget-body no-padding">
|
||||||
<div id="toolbar" class="toolbar">
|
<div id="toolbar" class="toolbar">
|
||||||
<a href="javascript:;" class="btn btn-primary btn-refresh" title="{:__('Refresh')}" ><i class="fa fa-refresh"></i> </a>
|
<a href="javascript:;" class="btn btn-primary btn-refresh" title="{:__('Refresh')}" ><i class="fa fa-refresh"></i> </a>
|
||||||
<a href="javascript:;" class="btn btn-success btn-export" id="btn-export">
|
|
||||||
<i class="fa fa-download"></i> 导出
|
|
||||||
</a>
|
|
||||||
<!-- <a href="javascript:;" class="btn btn-success btn-add {:$auth->check('orders/auditorder/add')?'':'hide'}" title="{:__('Add')}" ><i class="fa fa-plus"></i> {:__('Add')}</a>
|
<!-- <a href="javascript:;" class="btn btn-success btn-add {:$auth->check('orders/auditorder/add')?'':'hide'}" title="{:__('Add')}" ><i class="fa fa-plus"></i> {:__('Add')}</a>
|
||||||
<a href="javascript:;" class="btn btn-success btn-edit btn-disabled disabled {:$auth->check('orders/auditorder/edit')?'':'hide'}" title="{:__('Edit')}" ><i class="fa fa-pencil"></i> {:__('Edit')}</a>
|
<a href="javascript:;" class="btn btn-success btn-edit btn-disabled disabled {:$auth->check('orders/auditorder/edit')?'':'hide'}" title="{:__('Edit')}" ><i class="fa fa-pencil"></i> {:__('Edit')}</a>
|
||||||
<a href="javascript:;" class="btn btn-danger btn-del btn-disabled disabled {:$auth->check('orders/auditorder/del')?'':'hide'}" title="{:__('Delete')}" ><i class="fa fa-trash"></i> {:__('Delete')}</a>
|
<a href="javascript:;" class="btn btn-danger btn-del btn-disabled disabled {:$auth->check('orders/auditorder/del')?'':'hide'}" title="{:__('Delete')}" ><i class="fa fa-trash"></i> {:__('Delete')}</a>
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,12 @@
|
||||||
<form id="edit-form" class="form-horizontal" role="form" data-toggle="validator" method="POST" action="">
|
<form id="edit-form" class="form-horizontal" role="form" data-toggle="validator" method="POST" action="">
|
||||||
|
|
||||||
|
<!-- <div class="form-group">-->
|
||||||
|
<!-- <label class="control-label col-xs-12 col-sm-2">{:__('Order_id')}:</label>-->
|
||||||
|
<!-- <div class="col-xs-12 col-sm-8">-->
|
||||||
|
<!-- <input id="c-order_id" data-rule="required" data-field="order_no" data-source="order/index" class="form-control selectpage" name="row[order_id]" type="text" value="{$row.order_id|htmlentities}">-->
|
||||||
|
<!-- </div>-->
|
||||||
|
<!-- </div>-->
|
||||||
|
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="control-label col-xs-12 col-sm-2">{:__('订单编号')}:</label>
|
<label class="control-label col-xs-12 col-sm-2">{:__('订单编号')}:</label>
|
||||||
|
|
@ -8,6 +15,42 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- <div class="form-group">-->
|
||||||
|
<!-- <label class="control-label col-xs-12 col-sm-2">{:__('客户姓名')}:</label>-->
|
||||||
|
<!-- <div class="col-xs-12 col-sm-8">-->
|
||||||
|
<!-- <input id="c-customer" readonly class="form-control" type="text" value="{$order.customer|htmlentities}">-->
|
||||||
|
<!-- </div>-->
|
||||||
|
<!-- </div>-->
|
||||||
|
|
||||||
|
<!-- <div class="form-group">-->
|
||||||
|
<!-- <label class="control-label col-xs-12 col-sm-2">{:__('客户电话')}:</label>-->
|
||||||
|
<!-- <div class="col-xs-12 col-sm-8">-->
|
||||||
|
<!-- <input id="c-tel" readonly class="form-control" type="text" value="{$order.tel|htmlentities}">-->
|
||||||
|
<!-- </div>-->
|
||||||
|
<!-- </div>-->
|
||||||
|
|
||||||
|
<!-- <div class="form-group">-->
|
||||||
|
<!-- <label class="control-label col-xs-12 col-sm-2">{:__('客户地址')}:</label>-->
|
||||||
|
<!-- <div class="col-xs-12 col-sm-8">-->
|
||||||
|
<!-- <input id="c-address" readonly class="form-control" type="text" value="{$order.area.short_merge_name|htmlentities} {$order.address|htmlentities}">-->
|
||||||
|
<!-- </div>-->
|
||||||
|
<!-- </div>-->
|
||||||
|
|
||||||
|
<!-- <div class="form-group">-->
|
||||||
|
<!-- <label class="control-label col-xs-12 col-sm-2">{:__('服务类目')}:</label>-->
|
||||||
|
<!-- <div class="col-xs-12 col-sm-8">-->
|
||||||
|
<!-- <input id="c-item_title" readonly class="form-control" type="text" value="{$order.item_title|htmlentities}">-->
|
||||||
|
<!-- </div>-->
|
||||||
|
<!-- </div>-->
|
||||||
|
|
||||||
|
<!-- <div class="form-group">-->
|
||||||
|
<!-- <label class="control-label col-xs-12 col-sm-2">{:__('Order.detail')}:</label>-->
|
||||||
|
<!-- <div class="col-xs-12 col-sm-8">-->
|
||||||
|
<!-- <input id="c-detail" readonly class="form-control" type="text" value="{$order.detail|htmlentities}">-->
|
||||||
|
<!-- </div>-->
|
||||||
|
<!-- </div>-->
|
||||||
|
|
||||||
{notempty name ='action'}
|
{notempty name ='action'}
|
||||||
|
|
||||||
<input id="c-action" name="row[action]" type="hidden" value="{$action|htmlentities}">
|
<input id="c-action" name="row[action]" type="hidden" value="{$action|htmlentities}">
|
||||||
|
|
@ -35,26 +78,38 @@
|
||||||
<!-- <input readonly type="text" class="form-control" value="{$row.status_text|htmlentities}">-->
|
<!-- <input readonly type="text" class="form-control" value="{$row.status_text|htmlentities}">-->
|
||||||
<!-- </div>-->
|
<!-- </div>-->
|
||||||
<!-- </div>-->
|
<!-- </div>-->
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
{if $row['is_receipt']==0 }
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="control-label col-xs-12 col-sm-2">{:__('线上收款')}:</label>
|
<label class="control-label col-xs-12 col-sm-2">{:__('线上收款')}:</label>
|
||||||
<div class="col-xs-12 col-sm-8">
|
<div class="col-xs-12 col-sm-8">
|
||||||
<input id="order-online-amount" name="order[online_amount]" readonly type="text" class="form-control" value="{$order.online_amount|htmlentities}">
|
<input id="order-online-amount" name="order[online_amount]" type="text" class="form-control" value="{$order.online_amount|htmlentities}">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="control-label col-xs-12 col-sm-2">收款方式:</label>
|
<label class="control-label col-xs-12 col-sm-2">{:__('尾款收款')}:</label>
|
||||||
<div class="col-xs-12 col-sm-8">
|
<div class="col-xs-12 col-sm-8">
|
||||||
<select name="order[is_receipt]" id="receive_type" class="form-control selectpicker">
|
<input readonly class="form-control" type="text" value="无需收尾款">
|
||||||
<option {if 1 == $order.receive_type} selected {/if} value="1">没有尾款</option>
|
|
||||||
<option {if 0 == $order.receive_type} selected {/if} value="0">收尾款</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
{if $row['is_receipt']==1 }
|
||||||
|
|
||||||
<div id="other_info">
|
<div class="form-group">
|
||||||
|
<label class="control-label col-xs-12 col-sm-2">{:__('线上预付')}:</label>
|
||||||
|
<div class="col-xs-12 col-sm-8">
|
||||||
|
<input id="order-online-amount" name="order[online_amount]" type="text" class="form-control" value="{$order.online_amount|htmlentities}">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="control-label col-xs-12 col-sm-2">{:__('线上尾款')}:</label>
|
<label class="control-label col-xs-12 col-sm-2">{:__('线上尾款')}:</label>
|
||||||
|
|
@ -62,20 +117,25 @@
|
||||||
<input id="c-online_total" name="row[online_total]" data-rule="required" type="number" min="0" placeholder="请输入线上尾款金额" class="form-control" value="{$row.online_total|htmlentities}">
|
<input id="c-online_total" name="row[online_total]" data-rule="required" type="number" min="0" placeholder="请输入线上尾款金额" class="form-control" value="{$row.online_total|htmlentities}">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="control-label col-xs-12 col-sm-2">{:__('Offline_total_type')}:</label>
|
<label class="control-label col-xs-12 col-sm-2">{:__('Offline_total_type')}:</label>
|
||||||
<div class="col-xs-12 col-sm-8">
|
<div class="col-xs-12 col-sm-8">
|
||||||
|
|
||||||
|
|
||||||
{:build_select('row[offline_total_type]',$offlineTotalTypeList,$row['offline_total_type'],['class'=>'form-control selectpicker','data-rule'=>'required'])}
|
{:build_select('row[offline_total_type]',$offlineTotalTypeList,$row['offline_total_type'],['class'=>'form-control','data-rule'=>'required'])}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="control-label col-xs-12 col-sm-2">{:__('线下尾款')}:</label>
|
<label class="control-label col-xs-12 col-sm-2">{:__('线下尾款')}:</label>
|
||||||
<div class="col-xs-12 col-sm-8">
|
<div class="col-xs-12 col-sm-8">
|
||||||
<input id="c-total" data-rule="required" placeholder="请输入线下尾款金额" class="form-control" name="row[total]" type="number" min="0" value="{$row.total|htmlentities}">
|
<input id="c-total" data-rule="required" placeholder="请输入线下尾款金额" class="form-control" name="row[total]" type="number" min="0" value="{$row.total|htmlentities}">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="c-image" class="control-label col-xs-12 col-sm-2">{:__('收款凭据')}:</label>
|
<label for="c-image" class="control-label col-xs-12 col-sm-2">{:__('收款凭据')}:</label>
|
||||||
<div class="col-xs-12 col-sm-8">
|
<div class="col-xs-12 col-sm-8">
|
||||||
|
|
@ -90,7 +150,9 @@
|
||||||
<ul class="row list-inline faupload-preview" id="p-image"></ul>
|
<ul class="row list-inline faupload-preview" id="p-image"></ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
{/if}
|
||||||
|
|
||||||
<!--<div class="form-group">
|
<!--<div class="form-group">
|
||||||
<label class="control-label col-xs-12 col-sm-2">{:__('材料成本(¥)')}:</label>
|
<label class="control-label col-xs-12 col-sm-2">{:__('材料成本(¥)')}:</label>
|
||||||
<div class="col-xs-12 col-sm-8">
|
<div class="col-xs-12 col-sm-8">
|
||||||
|
|
|
||||||
|
|
@ -53,7 +53,7 @@
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="control-label col-xs-12 col-sm-2">{:__('线上尾款类型')}:</label>
|
<label class="control-label col-xs-12 col-sm-2">{:__('线上尾款类型')}:</label>
|
||||||
<div class="col-xs-12 col-sm-8">
|
<div class="col-xs-12 col-sm-8">
|
||||||
{:build_select('row[offline_amount_type]',$offlineTotalTypeList,$row['offline_amount_type'],['class'=>'form-control','readonly','data-rule'=>'required'])}
|
{:build_select('row[offline_amount_type]',$offlineTotalTypeList,$row['offline_amount_type'],['class'=>'form-control readonly','data-rule'=>'required'])}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -31,5 +31,4 @@ return [
|
||||||
'app\common\command\CheckTTSTaskCommand',
|
'app\common\command\CheckTTSTaskCommand',
|
||||||
'app\common\command\CheckTTSPlantCommand',
|
'app\common\command\CheckTTSPlantCommand',
|
||||||
'app\common\command\FixOrderOvertime',
|
'app\common\command\FixOrderOvertime',
|
||||||
'app\common\command\ImportArea',
|
|
||||||
];
|
];
|
||||||
|
|
|
||||||
|
|
@ -1,81 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace app\common\command;
|
|
||||||
|
|
||||||
use think\console\Command;
|
|
||||||
use think\console\Input;
|
|
||||||
use think\console\Output;
|
|
||||||
use think\Db;
|
|
||||||
|
|
||||||
class ImportArea extends Command
|
|
||||||
{
|
|
||||||
protected function configure()
|
|
||||||
{
|
|
||||||
$this->setName('import:area')
|
|
||||||
->setDescription('导入港澳台行政区域数据到 fa_area 表');
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function execute(Input $input, Output $output)
|
|
||||||
{
|
|
||||||
// 区域数据(来自你提供的 JSON)
|
|
||||||
$areaData = json_decode(file_get_contents(__DIR__ . '/area.json'), true);
|
|
||||||
|
|
||||||
Db::startTrans();
|
|
||||||
$out = [];
|
|
||||||
try {
|
|
||||||
foreach ($areaData as $parentCode => $children) {
|
|
||||||
foreach ($children as $code => $name) {
|
|
||||||
|
|
||||||
if (strlen(rtrim($parentCode, '0')) == 2) {
|
|
||||||
// 省 -> 市(Level 2)
|
|
||||||
$provinceCode = $parentCode;
|
|
||||||
$level = 2;
|
|
||||||
$shortMergeName = $name;
|
|
||||||
$data = [
|
|
||||||
'code' => rtrim($code, "0"),
|
|
||||||
'name' => $name,
|
|
||||||
'short_name' => $name,
|
|
||||||
'merge_name' => $name,
|
|
||||||
'short_merge_name' => $shortMergeName,
|
|
||||||
'level' => $level,
|
|
||||||
'province_code' => rtrim($provinceCode, "0"),
|
|
||||||
'city_code' => rtrim($code, "0"),
|
|
||||||
'area_code' => rtrim($code, "0"),
|
|
||||||
'pinyin' => '',
|
|
||||||
'abbr' => ''
|
|
||||||
];
|
|
||||||
$out[] = $data;
|
|
||||||
// dd($data);
|
|
||||||
} else {
|
|
||||||
// 市 -> 区(Level 3)
|
|
||||||
|
|
||||||
$data = [
|
|
||||||
'code' => rtrim($code, '0'),
|
|
||||||
'name' => $name,
|
|
||||||
'short_name' => $name,
|
|
||||||
'merge_name' => $areaData[substr($parentCode, 0,2) . '0000'][$parentCode] . '/' . $name,
|
|
||||||
'short_merge_name' => $name,
|
|
||||||
'level' => 3,
|
|
||||||
'province_code' => rtrim($parentCode, '0'),
|
|
||||||
'city_code' => rtrim($code, '0'),
|
|
||||||
'area_code' => rtrim($code, '0'),
|
|
||||||
'pinyin' => '',
|
|
||||||
'abbr' => ''
|
|
||||||
];
|
|
||||||
$out[] = $data;
|
|
||||||
// dd($data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Db::table('fa_areas')->insertAll($out);
|
|
||||||
Db::commit();
|
|
||||||
$output->writeln("<info>港澳台区域数据导入成功!</info>");
|
|
||||||
} catch (\Throwable $e) {
|
|
||||||
Db::rollback();
|
|
||||||
throw $e;
|
|
||||||
$output->writeln("<error>导入失败:" . $e->getMessage() . "</error>");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,454 +0,0 @@
|
||||||
{
|
|
||||||
"710100": {
|
|
||||||
"710101": "中正区",
|
|
||||||
"710102": "大同区",
|
|
||||||
"710103": "中山区",
|
|
||||||
"710104": "松山区",
|
|
||||||
"710105": "大安区",
|
|
||||||
"710106": "万华区",
|
|
||||||
"710107": "信义区",
|
|
||||||
"710108": "士林区",
|
|
||||||
"710109": "北投区",
|
|
||||||
"710110": "内湖区",
|
|
||||||
"710111": "南港区",
|
|
||||||
"710112": "文山区"
|
|
||||||
},
|
|
||||||
"710000": {
|
|
||||||
"710100": "台北市",
|
|
||||||
"710200": "高雄市",
|
|
||||||
"710300": "台南市",
|
|
||||||
"710400": "台中市",
|
|
||||||
"710600": "南投县",
|
|
||||||
"710700": "基隆市",
|
|
||||||
"710800": "新竹市",
|
|
||||||
"710900": "嘉义市",
|
|
||||||
"711100": "新北市",
|
|
||||||
"711200": "宜兰县",
|
|
||||||
"711300": "新竹县",
|
|
||||||
"711400": "桃园市",
|
|
||||||
"711500": "苗栗县",
|
|
||||||
"711700": "彰化县",
|
|
||||||
"711900": "嘉义县",
|
|
||||||
"712100": "云林县",
|
|
||||||
"712400": "屏东县",
|
|
||||||
"712500": "台东县",
|
|
||||||
"712600": "花莲县",
|
|
||||||
"712700": "澎湖县"
|
|
||||||
},
|
|
||||||
"710200": {
|
|
||||||
"710201": "新兴区",
|
|
||||||
"710202": "前金区",
|
|
||||||
"710203": "苓雅区",
|
|
||||||
"710204": "盐埕区",
|
|
||||||
"710205": "鼓山区",
|
|
||||||
"710206": "旗津区",
|
|
||||||
"710207": "前镇区",
|
|
||||||
"710208": "三民区",
|
|
||||||
"710209": "左营区",
|
|
||||||
"710210": "楠梓区",
|
|
||||||
"710211": "小港区",
|
|
||||||
"710242": "仁武区",
|
|
||||||
"710243": "大社区",
|
|
||||||
"710244": "冈山区",
|
|
||||||
"710245": "路竹区",
|
|
||||||
"710246": "阿莲区",
|
|
||||||
"710247": "田寮区",
|
|
||||||
"710248": "燕巢区",
|
|
||||||
"710249": "桥头区",
|
|
||||||
"710250": "梓官区",
|
|
||||||
"710251": "弥陀区",
|
|
||||||
"710252": "永安区",
|
|
||||||
"710253": "湖内区",
|
|
||||||
"710254": "凤山区",
|
|
||||||
"710255": "大寮区",
|
|
||||||
"710256": "林园区",
|
|
||||||
"710257": "鸟松区",
|
|
||||||
"710258": "大树区",
|
|
||||||
"710259": "旗山区",
|
|
||||||
"710260": "美浓区",
|
|
||||||
"710261": "六龟区",
|
|
||||||
"710262": "内门区",
|
|
||||||
"710263": "杉林区",
|
|
||||||
"710264": "甲仙区",
|
|
||||||
"710265": "桃源区",
|
|
||||||
"710266": "那玛夏区",
|
|
||||||
"710267": "茂林区",
|
|
||||||
"710268": "茄萣区"
|
|
||||||
},
|
|
||||||
"710300": {
|
|
||||||
"710301": "中西区",
|
|
||||||
"710302": "东区",
|
|
||||||
"710303": "南区",
|
|
||||||
"710304": "北区",
|
|
||||||
"710305": "安平区",
|
|
||||||
"710306": "安南区",
|
|
||||||
"710339": "永康区",
|
|
||||||
"710340": "归仁区",
|
|
||||||
"710341": "新化区",
|
|
||||||
"710342": "左镇区",
|
|
||||||
"710343": "玉井区",
|
|
||||||
"710344": "楠西区",
|
|
||||||
"710345": "南化区",
|
|
||||||
"710346": "仁德区",
|
|
||||||
"710347": "关庙区",
|
|
||||||
"710348": "龙崎区",
|
|
||||||
"710349": "官田区",
|
|
||||||
"710350": "麻豆区",
|
|
||||||
"710351": "佳里区",
|
|
||||||
"710352": "西港区",
|
|
||||||
"710353": "七股区",
|
|
||||||
"710354": "将军区",
|
|
||||||
"710355": "学甲区",
|
|
||||||
"710356": "北门区",
|
|
||||||
"710357": "新营区",
|
|
||||||
"710358": "后壁区",
|
|
||||||
"710359": "白河区",
|
|
||||||
"710360": "东山区",
|
|
||||||
"710361": "六甲区",
|
|
||||||
"710362": "下营区",
|
|
||||||
"710363": "柳营区",
|
|
||||||
"710364": "盐水区",
|
|
||||||
"710365": "善化区",
|
|
||||||
"710366": "大内区",
|
|
||||||
"710367": "山上区",
|
|
||||||
"710368": "新市区",
|
|
||||||
"710369": "安定区"
|
|
||||||
},
|
|
||||||
"710400": {
|
|
||||||
"710401": "中区",
|
|
||||||
"710402": "东区",
|
|
||||||
"710403": "南区",
|
|
||||||
"710404": "西区",
|
|
||||||
"710405": "北区",
|
|
||||||
"710406": "北屯区",
|
|
||||||
"710407": "西屯区",
|
|
||||||
"710408": "南屯区",
|
|
||||||
"710431": "太平区",
|
|
||||||
"710432": "大里区",
|
|
||||||
"710433": "雾峰区",
|
|
||||||
"710434": "乌日区",
|
|
||||||
"710435": "丰原区",
|
|
||||||
"710436": "后里区",
|
|
||||||
"710437": "石冈区",
|
|
||||||
"710438": "东势区",
|
|
||||||
"710439": "和平区",
|
|
||||||
"710440": "新社区",
|
|
||||||
"710441": "潭子区",
|
|
||||||
"710442": "大雅区",
|
|
||||||
"710443": "神冈区",
|
|
||||||
"710444": "大肚区",
|
|
||||||
"710445": "沙鹿区",
|
|
||||||
"710446": "龙井区",
|
|
||||||
"710447": "梧栖区",
|
|
||||||
"710448": "清水区",
|
|
||||||
"710449": "大甲区",
|
|
||||||
"710450": "外埔区",
|
|
||||||
"710451": "大安区"
|
|
||||||
},
|
|
||||||
"710600": {
|
|
||||||
"710614": "南投市",
|
|
||||||
"710615": "中寮乡",
|
|
||||||
"710616": "草屯镇",
|
|
||||||
"710617": "国姓乡",
|
|
||||||
"710618": "埔里镇",
|
|
||||||
"710619": "仁爱乡",
|
|
||||||
"710620": "名间乡",
|
|
||||||
"710621": "集集镇",
|
|
||||||
"710622": "水里乡",
|
|
||||||
"710623": "鱼池乡",
|
|
||||||
"710624": "信义乡",
|
|
||||||
"710625": "竹山镇",
|
|
||||||
"710626": "鹿谷乡"
|
|
||||||
},
|
|
||||||
"710700": {
|
|
||||||
"710701": "仁爱区",
|
|
||||||
"710702": "信义区",
|
|
||||||
"710703": "中正区",
|
|
||||||
"710704": "中山区",
|
|
||||||
"710705": "安乐区",
|
|
||||||
"710706": "暖暖区",
|
|
||||||
"710707": "七堵区"
|
|
||||||
},
|
|
||||||
"710800": {
|
|
||||||
"710801": "东区",
|
|
||||||
"710802": "北区",
|
|
||||||
"710803": "香山区"
|
|
||||||
},
|
|
||||||
"710900": {
|
|
||||||
"710901": "东区",
|
|
||||||
"710902": "西区"
|
|
||||||
},
|
|
||||||
"711100": {
|
|
||||||
"711130": "万里区",
|
|
||||||
"711131": "金山区",
|
|
||||||
"711132": "板桥区",
|
|
||||||
"711133": "汐止区",
|
|
||||||
"711134": "深坑区",
|
|
||||||
"711135": "石碇区",
|
|
||||||
"711136": "瑞芳区",
|
|
||||||
"711137": "平溪区",
|
|
||||||
"711138": "双溪区",
|
|
||||||
"711139": "贡寮区",
|
|
||||||
"711140": "新店区",
|
|
||||||
"711141": "坪林区",
|
|
||||||
"711142": "乌来区",
|
|
||||||
"711143": "永和区",
|
|
||||||
"711144": "中和区",
|
|
||||||
"711145": "土城区",
|
|
||||||
"711146": "三峡区",
|
|
||||||
"711147": "树林区",
|
|
||||||
"711148": "莺歌区",
|
|
||||||
"711149": "三重区",
|
|
||||||
"711150": "新庄区",
|
|
||||||
"711151": "泰山区",
|
|
||||||
"711152": "林口区",
|
|
||||||
"711153": "芦洲区",
|
|
||||||
"711154": "五股区",
|
|
||||||
"711155": "八里区",
|
|
||||||
"711156": "淡水区",
|
|
||||||
"711157": "三芝区",
|
|
||||||
"711158": "石门区"
|
|
||||||
},
|
|
||||||
"711200": {
|
|
||||||
"711214": "宜兰市",
|
|
||||||
"711215": "头城镇",
|
|
||||||
"711216": "礁溪乡",
|
|
||||||
"711217": "壮围乡",
|
|
||||||
"711218": "员山乡",
|
|
||||||
"711219": "罗东镇",
|
|
||||||
"711220": "三星乡",
|
|
||||||
"711221": "大同乡",
|
|
||||||
"711222": "五结乡",
|
|
||||||
"711223": "冬山乡",
|
|
||||||
"711224": "苏澳镇",
|
|
||||||
"711225": "南澳乡"
|
|
||||||
},
|
|
||||||
"711300": {
|
|
||||||
"711314": "竹北市",
|
|
||||||
"711315": "湖口乡",
|
|
||||||
"711316": "新丰乡",
|
|
||||||
"711317": "新埔镇",
|
|
||||||
"711318": "关西镇",
|
|
||||||
"711319": "芎林乡",
|
|
||||||
"711320": "宝山乡",
|
|
||||||
"711321": "竹东镇",
|
|
||||||
"711322": "五峰乡",
|
|
||||||
"711323": "横山乡",
|
|
||||||
"711324": "尖石乡",
|
|
||||||
"711325": "北埔乡",
|
|
||||||
"711326": "峨眉乡"
|
|
||||||
},
|
|
||||||
"711400": {
|
|
||||||
"711414": "中坜区",
|
|
||||||
"711415": "平镇区",
|
|
||||||
"711416": "龙潭区",
|
|
||||||
"711417": "杨梅区",
|
|
||||||
"711418": "新屋区",
|
|
||||||
"711419": "观音区",
|
|
||||||
"711420": "桃园区",
|
|
||||||
"711421": "龟山区",
|
|
||||||
"711422": "八德区",
|
|
||||||
"711423": "大溪区",
|
|
||||||
"711424": "复兴区",
|
|
||||||
"711425": "大园区",
|
|
||||||
"711426": "芦竹区"
|
|
||||||
},
|
|
||||||
"711500": {
|
|
||||||
"711519": "竹南镇",
|
|
||||||
"711520": "头份市",
|
|
||||||
"711521": "三湾乡",
|
|
||||||
"711522": "南庄乡",
|
|
||||||
"711523": "狮潭乡",
|
|
||||||
"711524": "后龙镇",
|
|
||||||
"711525": "通霄镇",
|
|
||||||
"711526": "苑里镇",
|
|
||||||
"711527": "苗栗市",
|
|
||||||
"711528": "造桥乡",
|
|
||||||
"711529": "头屋乡",
|
|
||||||
"711530": "公馆乡",
|
|
||||||
"711531": "大湖乡",
|
|
||||||
"711532": "泰安乡",
|
|
||||||
"711533": "铜锣乡",
|
|
||||||
"711534": "三义乡",
|
|
||||||
"711535": "西湖乡",
|
|
||||||
"711536": "卓兰镇"
|
|
||||||
},
|
|
||||||
"711700": {
|
|
||||||
"711727": "彰化市",
|
|
||||||
"711728": "芬园乡",
|
|
||||||
"711729": "花坛乡",
|
|
||||||
"711730": "秀水乡",
|
|
||||||
"711731": "鹿港镇",
|
|
||||||
"711732": "福兴乡",
|
|
||||||
"711733": "线西乡",
|
|
||||||
"711734": "和美镇",
|
|
||||||
"711735": "伸港乡",
|
|
||||||
"711736": "员林市",
|
|
||||||
"711737": "社头乡",
|
|
||||||
"711738": "永靖乡",
|
|
||||||
"711739": "埔心乡",
|
|
||||||
"711740": "溪湖镇",
|
|
||||||
"711741": "大村乡",
|
|
||||||
"711742": "埔盐乡",
|
|
||||||
"711743": "田中镇",
|
|
||||||
"711744": "北斗镇",
|
|
||||||
"711745": "田尾乡",
|
|
||||||
"711746": "埤头乡",
|
|
||||||
"711747": "溪州乡",
|
|
||||||
"711748": "竹塘乡",
|
|
||||||
"711749": "二林镇",
|
|
||||||
"711750": "大城乡",
|
|
||||||
"711751": "芳苑乡",
|
|
||||||
"711752": "二水乡"
|
|
||||||
},
|
|
||||||
"711900": {
|
|
||||||
"711919": "番路乡",
|
|
||||||
"711920": "梅山乡",
|
|
||||||
"711921": "竹崎乡",
|
|
||||||
"711922": "阿里山乡",
|
|
||||||
"711923": "中埔乡",
|
|
||||||
"711924": "大埔乡",
|
|
||||||
"711925": "水上乡",
|
|
||||||
"711926": "鹿草乡",
|
|
||||||
"711927": "太保市",
|
|
||||||
"711928": "朴子市",
|
|
||||||
"711929": "东石乡",
|
|
||||||
"711930": "六脚乡",
|
|
||||||
"711931": "新港乡",
|
|
||||||
"711932": "民雄乡",
|
|
||||||
"711933": "大林镇",
|
|
||||||
"711934": "溪口乡",
|
|
||||||
"711935": "义竹乡",
|
|
||||||
"711936": "布袋镇"
|
|
||||||
},
|
|
||||||
"712100": {
|
|
||||||
"712121": "斗南镇",
|
|
||||||
"712122": "大埤乡",
|
|
||||||
"712123": "虎尾镇",
|
|
||||||
"712124": "土库镇",
|
|
||||||
"712125": "褒忠乡",
|
|
||||||
"712126": "东势乡",
|
|
||||||
"712127": "台西乡",
|
|
||||||
"712128": "仑背乡",
|
|
||||||
"712129": "麦寮乡",
|
|
||||||
"712130": "斗六市",
|
|
||||||
"712131": "林内乡",
|
|
||||||
"712132": "古坑乡",
|
|
||||||
"712133": "莿桐乡",
|
|
||||||
"712134": "西螺镇",
|
|
||||||
"712135": "二仑乡",
|
|
||||||
"712136": "北港镇",
|
|
||||||
"712137": "水林乡",
|
|
||||||
"712138": "口湖乡",
|
|
||||||
"712139": "四湖乡",
|
|
||||||
"712140": "元长乡"
|
|
||||||
},
|
|
||||||
"712400": {
|
|
||||||
"712434": "屏东市",
|
|
||||||
"712435": "三地门乡",
|
|
||||||
"712436": "雾台乡",
|
|
||||||
"712437": "玛家乡",
|
|
||||||
"712438": "九如乡",
|
|
||||||
"712439": "里港乡",
|
|
||||||
"712440": "高树乡",
|
|
||||||
"712441": "盐埔乡",
|
|
||||||
"712442": "长治乡",
|
|
||||||
"712443": "麟洛乡",
|
|
||||||
"712444": "竹田乡",
|
|
||||||
"712445": "内埔乡",
|
|
||||||
"712446": "万丹乡",
|
|
||||||
"712447": "潮州镇",
|
|
||||||
"712448": "泰武乡",
|
|
||||||
"712449": "来义乡",
|
|
||||||
"712450": "万峦乡",
|
|
||||||
"712451": "崁顶乡",
|
|
||||||
"712452": "新埤乡",
|
|
||||||
"712453": "南州乡",
|
|
||||||
"712454": "林边乡",
|
|
||||||
"712455": "东港镇",
|
|
||||||
"712456": "琉球乡",
|
|
||||||
"712457": "佳冬乡",
|
|
||||||
"712458": "新园乡",
|
|
||||||
"712459": "枋寮乡",
|
|
||||||
"712460": "枋山乡",
|
|
||||||
"712461": "春日乡",
|
|
||||||
"712462": "狮子乡",
|
|
||||||
"712463": "车城乡",
|
|
||||||
"712464": "牡丹乡",
|
|
||||||
"712465": "恒春镇",
|
|
||||||
"712466": "满州乡"
|
|
||||||
},
|
|
||||||
"712500": {
|
|
||||||
"712517": "台东市",
|
|
||||||
"712518": "绿岛乡",
|
|
||||||
"712519": "兰屿乡",
|
|
||||||
"712520": "延平乡",
|
|
||||||
"712521": "卑南乡",
|
|
||||||
"712522": "鹿野乡",
|
|
||||||
"712523": "关山镇",
|
|
||||||
"712524": "海端乡",
|
|
||||||
"712525": "池上乡",
|
|
||||||
"712526": "东河乡",
|
|
||||||
"712527": "成功镇",
|
|
||||||
"712528": "长滨乡",
|
|
||||||
"712529": "金峰乡",
|
|
||||||
"712530": "大武乡",
|
|
||||||
"712531": "达仁乡",
|
|
||||||
"712532": "太麻里乡"
|
|
||||||
},
|
|
||||||
"712600": {
|
|
||||||
"712615": "花莲市",
|
|
||||||
"712616": "新城乡",
|
|
||||||
"712618": "秀林乡",
|
|
||||||
"712619": "吉安乡",
|
|
||||||
"712620": "寿丰乡",
|
|
||||||
"712621": "凤林镇",
|
|
||||||
"712622": "光复乡",
|
|
||||||
"712623": "丰滨乡",
|
|
||||||
"712624": "瑞穗乡",
|
|
||||||
"712625": "万荣乡",
|
|
||||||
"712626": "玉里镇",
|
|
||||||
"712627": "卓溪乡",
|
|
||||||
"712628": "富里乡"
|
|
||||||
},
|
|
||||||
"712700": {
|
|
||||||
"712707": "马公市",
|
|
||||||
"712708": "西屿乡",
|
|
||||||
"712709": "望安乡",
|
|
||||||
"712710": "七美乡",
|
|
||||||
"712711": "白沙乡",
|
|
||||||
"712712": "湖西乡"
|
|
||||||
},
|
|
||||||
"810000": {
|
|
||||||
"810100": "香港特别行政区"
|
|
||||||
},
|
|
||||||
"810100": {
|
|
||||||
"810101": "中西区",
|
|
||||||
"810102": "东区",
|
|
||||||
"810103": "九龙城区",
|
|
||||||
"810104": "观塘区",
|
|
||||||
"810105": "南区",
|
|
||||||
"810106": "深水埗区",
|
|
||||||
"810107": "湾仔区",
|
|
||||||
"810108": "黄大仙区",
|
|
||||||
"810109": "油尖旺区",
|
|
||||||
"810110": "离岛区",
|
|
||||||
"810111": "葵青区",
|
|
||||||
"810112": "北区",
|
|
||||||
"810113": "西贡区",
|
|
||||||
"810114": "沙田区",
|
|
||||||
"810115": "屯门区",
|
|
||||||
"810116": "大埔区",
|
|
||||||
"810117": "荃湾区",
|
|
||||||
"810118": "元朗区"
|
|
||||||
},
|
|
||||||
"820000": {
|
|
||||||
"820100": "澳门特别行政区"
|
|
||||||
},
|
|
||||||
"820100": {
|
|
||||||
"820101": "澳门半岛",
|
|
||||||
"820102": "凼仔",
|
|
||||||
"820103": "路凼城",
|
|
||||||
"820104": "路环"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -766,41 +766,75 @@ class Backend extends Controller
|
||||||
return $res;
|
return $res;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function streamCsv(array $columns, \Generator $rows, string $filename)
|
protected function exportCsvByStream(array $columns, callable $fetchData, string $filename = '导出.csv', int $limit = 1000)
|
||||||
{
|
{
|
||||||
|
$page = 1;
|
||||||
|
$rowIndex = 2;
|
||||||
|
|
||||||
|
ini_set('memory_limit', '512M');
|
||||||
set_time_limit(0);
|
set_time_limit(0);
|
||||||
ini_set('memory_limit', '-1');
|
|
||||||
ignore_user_abort(true);
|
ignore_user_abort(true);
|
||||||
|
ini_set('zlib.output_compression', 'Off');
|
||||||
|
|
||||||
|
// 创建 Spreadsheet 和 Sheet
|
||||||
|
$spreadsheet = new Spreadsheet();
|
||||||
|
$spreadsheet->removeSheetByIndex(0);
|
||||||
|
$sheet = new Worksheet($spreadsheet, 'Sheet1');
|
||||||
|
$spreadsheet->addSheet($sheet);
|
||||||
|
$spreadsheet->setActiveSheetIndex(0);
|
||||||
|
$sheet = $spreadsheet->getActiveSheet();
|
||||||
|
|
||||||
|
$writer = new Csv($spreadsheet);
|
||||||
|
$writer->setDelimiter(','); // 可改为 \t 导出为 TSV
|
||||||
|
$writer->setEnclosure('"');
|
||||||
|
$writer->setLineEnding("\r\n");
|
||||||
|
$writer->setSheetIndex(0);
|
||||||
|
|
||||||
|
// 获取字段映射
|
||||||
|
$titles = array_column($columns, 'title');
|
||||||
|
$fields = array_column($columns, 'field');
|
||||||
|
|
||||||
|
// 写入表头
|
||||||
|
$sheet->fromArray($titles, null, 'A1');
|
||||||
|
|
||||||
|
// 分页写入数据
|
||||||
|
do {
|
||||||
|
$rows = $fetchData($page, $limit);
|
||||||
|
$count = count($rows);
|
||||||
|
if ($count === 0) break;
|
||||||
|
|
||||||
|
foreach ($rows as $row) {
|
||||||
|
$dataRow = [];
|
||||||
|
foreach ($fields as $field) {
|
||||||
|
$value = $this->getNestedValue($row->toArray(), $field);
|
||||||
|
if (is_array($value) || is_object($value)) {
|
||||||
|
$value = json_encode($value, JSON_UNESCAPED_UNICODE);
|
||||||
|
}
|
||||||
|
$dataRow[] = $value;
|
||||||
|
}
|
||||||
|
$sheet->fromArray($dataRow, null, 'A' . $rowIndex);
|
||||||
|
$rowIndex++;
|
||||||
|
}
|
||||||
|
|
||||||
|
$page++;
|
||||||
|
} while ($count === $limit);
|
||||||
|
|
||||||
|
// 输出为 CSV 下载流
|
||||||
|
$filename = $filename ?: ('导出_' . date('Ymd_His') . '.csv');
|
||||||
|
|
||||||
header('Content-Type: text/csv; charset=UTF-8');
|
header('Content-Type: text/csv; charset=UTF-8');
|
||||||
header('Content-Disposition: attachment;filename="' . $filename . '"');
|
header('Content-Disposition: attachment;filename="' . $filename . '"');
|
||||||
header('Cache-Control: max-age=0');
|
header('Cache-Control: max-age=0');
|
||||||
|
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
|
||||||
|
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
|
||||||
header('Pragma: public');
|
header('Pragma: public');
|
||||||
|
|
||||||
// 防止 Excel 打开乱码
|
// 输出 UTF-8 BOM 防止 Excel 乱码
|
||||||
echo "\xEF\xBB\xBF";
|
echo "\xEF\xBB\xBF";
|
||||||
|
|
||||||
$output = fopen('php://output', 'w');
|
$writer->save('php://output');
|
||||||
|
$spreadsheet->disconnectWorksheets();
|
||||||
$fields = array_column($columns, 'field');
|
unset($spreadsheet);
|
||||||
$titles = array_column($columns, 'title');
|
|
||||||
// 写入表头
|
|
||||||
fputcsv($output, $titles);
|
|
||||||
|
|
||||||
// 逐行写入数据
|
|
||||||
foreach ($rows as $row) {
|
|
||||||
$line = [];
|
|
||||||
foreach ($fields as $field) {
|
|
||||||
$value = $this->getNestedValue($row, $field);
|
|
||||||
if (is_array($value) || is_object($value)) {
|
|
||||||
$value = json_encode($value, JSON_UNESCAPED_UNICODE);
|
|
||||||
}
|
|
||||||
$line[] = $value;
|
|
||||||
}
|
|
||||||
fputcsv($output, $line);
|
|
||||||
}
|
|
||||||
|
|
||||||
fclose($output);
|
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
protected function getNestedValue(array $data, string $path, $default = '')
|
protected function getNestedValue(array $data, string $path, $default = '')
|
||||||
|
|
@ -817,18 +851,4 @@ class Backend extends Controller
|
||||||
}
|
}
|
||||||
return $data;
|
return $data;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function dealImages($image_str)
|
|
||||||
{
|
|
||||||
if (empty($image_str)){
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
$images = explode(',', $image_str);
|
|
||||||
$url = '';
|
|
||||||
foreach ($images as $img) {
|
|
||||||
if (empty($img)) continue;
|
|
||||||
$url .= cdnurl($img) . ',';
|
|
||||||
}
|
|
||||||
return $url;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
1129
composer.lock
generated
1129
composer.lock
generated
File diff suppressed because it is too large
Load Diff
4994
public/api.html
4994
public/api.html
File diff suppressed because it is too large
Load Diff
|
|
@ -1,5 +0,0 @@
|
||||||
|
|
||||||
/* 固定分页条 */
|
|
||||||
.fixed-table-body{
|
|
||||||
max-height: calc(100vh - 240px) !important;
|
|
||||||
}
|
|
||||||
|
|
@ -90,7 +90,7 @@ ${data.receive_type == 1 ? '已收定金' : '已收全款'}
|
||||||
pk: 'id',
|
pk: 'id',
|
||||||
sortName: 'id',
|
sortName: 'id',
|
||||||
fixedRightNumber: 1,
|
fixedRightNumber: 1,
|
||||||
fixedNumber: 5,
|
fixedNumber: 4,
|
||||||
fixedColumns: true,
|
fixedColumns: true,
|
||||||
renderDefault: true,
|
renderDefault: true,
|
||||||
searchFormVisible: true,
|
searchFormVisible: true,
|
||||||
|
|
@ -125,12 +125,6 @@ ${data.receive_type == 1 ? '已收定金' : '已收全款'}
|
||||||
"10": "my_dispatch"
|
"10": "my_dispatch"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
|
||||||
field: 'order_remark',
|
|
||||||
title: '标记',
|
|
||||||
operate: 'like',
|
|
||||||
autocomplete: false
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
field: 'create_time',
|
field: 'create_time',
|
||||||
title: __('Create_time'),
|
title: __('Create_time'),
|
||||||
|
|
@ -387,45 +381,6 @@ ${data.receive_type == 1 ? '已收定金' : '已收全款'}
|
||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name: "order_remark",
|
|
||||||
text: "标记",
|
|
||||||
title: "标记",
|
|
||||||
classname: 'btn btn-xs btn-click',
|
|
||||||
icon: 'fa fa-comment',
|
|
||||||
click: function (e, row) {
|
|
||||||
Layer.open({
|
|
||||||
type: 1,
|
|
||||||
title: '请输入备注信息(可为空)',
|
|
||||||
area: ['400px', '250px'],
|
|
||||||
btn: ['确定', '取消'],
|
|
||||||
content: '<div style="padding:20px;">' +
|
|
||||||
'<textarea id="remark-input" style="width:100%;" rows="4" placeholder="留空表示清空备注">' +
|
|
||||||
(row.order_remark || '') + '</textarea>' +
|
|
||||||
'</div>',
|
|
||||||
yes: function (index, layero) {
|
|
||||||
var text = $('#remark-input').val();
|
|
||||||
Fast.api.ajax({
|
|
||||||
type: 'POST',
|
|
||||||
url: 'order/orderRemark/ids/' + row.id,
|
|
||||||
data: {id: row.id, remark: text},
|
|
||||||
}, function (data, ret) {
|
|
||||||
Layer.close(index);
|
|
||||||
Toastr.success("备注提交成功");
|
|
||||||
table.bootstrapTable('refresh');
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
dropdown: "更多",
|
|
||||||
visible: function (row) {
|
|
||||||
if (Config.permissions.reminder && row.status == 10) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
name: "copy_text",
|
name: "copy_text",
|
||||||
text: "复制信息",
|
text: "复制信息",
|
||||||
|
|
|
||||||
|
|
@ -34,30 +34,13 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
|
||||||
params.op = JSON.stringify(op);
|
params.op = JSON.stringify(op);
|
||||||
return params;
|
return params;
|
||||||
},
|
},
|
||||||
onLoadSuccess: function (data) {
|
|
||||||
var sum = data || {};
|
|
||||||
|
|
||||||
// 1) 把汇总放到表格上方(可改为 append 到其它元素)
|
|
||||||
$('#table-sum-area').remove(); // 先移除已有的,防止重复
|
|
||||||
var html = '<div id="table-sum-area" style="margin:8px 0;text-align:right;">' +
|
|
||||||
'筛选条件总计 — 总预计利润:<strong>' + (parseFloat(data.sum || 0).toFixed(2)) + '</strong>' +
|
|
||||||
',总数量:<strong>' + (parseInt(data.total || 0)) + '</strong>' +
|
|
||||||
'</div>';
|
|
||||||
// 把汇总放在表格容器前面(你也可以放到 table.closest('.bootstrap-table') 里)
|
|
||||||
table.closest('.bootstrap-table').before(html);
|
|
||||||
|
|
||||||
// 2) (可选)如果你想把汇总放到表格 footer 的某一列,用 footerFormatter 示例:
|
|
||||||
// 注意:footerFormatter 会在表格渲染 footer 时调用,这里只是演示
|
|
||||||
// 例如你有一列 field: 'real_amount',它的 footerFormatter 可以是:
|
|
||||||
// footerFormatter: function () { var s = table.data('sum') || {}; return (parseFloat(s.real_amount||0)).toFixed(2); }
|
|
||||||
},
|
|
||||||
url: $.fn.bootstrapTable.defaults.extend.index_url,
|
url: $.fn.bootstrapTable.defaults.extend.index_url,
|
||||||
pk: 'id',
|
pk: 'id',
|
||||||
sortName: 'update_time',
|
sortName: 'update_time',
|
||||||
sortOrder: 'desc',
|
sortOrder: 'desc',
|
||||||
fixedColumns: true,
|
fixedColumns: true,
|
||||||
fixedRightNumber: 1,
|
fixedRightNumber: 1,
|
||||||
showExport: false,
|
|
||||||
columns: [
|
columns: [
|
||||||
[
|
[
|
||||||
// {checkbox: true},
|
// {checkbox: true},
|
||||||
|
|
@ -148,33 +131,7 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
table.closest('.bootstrap-table').addClass('table-with-fixed-pagination');
|
|
||||||
|
|
||||||
$('#btn-export').on('click', function () {
|
|
||||||
var options = $("#table").bootstrapTable('getOptions');
|
|
||||||
|
|
||||||
// 提取列信息(不含 checkbox)
|
|
||||||
var columns = [];
|
|
||||||
$.each(options.columns[0], function (i, item) {
|
|
||||||
if (item.field && !item.checkbox && !item.visible === false) {
|
|
||||||
columns.push({
|
|
||||||
field: item.field,
|
|
||||||
title: item.title
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
var params = {
|
|
||||||
columns: JSON.stringify(columns),
|
|
||||||
filter: options.queryParams({}).filter || {},
|
|
||||||
op: options.queryParams({}).op || {},
|
|
||||||
sort: options.sortName,
|
|
||||||
order: options.sortOrder
|
|
||||||
};
|
|
||||||
// console.log($.param(params))
|
|
||||||
var url = '/admin/orders/auditorder/export?' + $.param(params);
|
|
||||||
window.open(url); // 发起文件下载
|
|
||||||
});
|
|
||||||
// 为表格绑定事件
|
// 为表格绑定事件
|
||||||
Table.api.bindevent(table);
|
Table.api.bindevent(table);
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -436,19 +436,6 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form','layer'], function ($,
|
||||||
// 判断 #c-action 是否存在且有值
|
// 判断 #c-action 是否存在且有值
|
||||||
const $action = $("#c-action");
|
const $action = $("#c-action");
|
||||||
if ($action.length && $action.val()) {
|
if ($action.length && $action.val()) {
|
||||||
|
|
||||||
/* ["c-online_total", "c-total", "order-cost", "order-material_cost"].forEach(function(id) {
|
|
||||||
$("#" + id).on("input", calculatePerformance);
|
|
||||||
});*/
|
|
||||||
|
|
||||||
$('#c-online_total, #c-total, #order-cost, #order-material_cost').on('input', function () {
|
|
||||||
//calcProfit();
|
|
||||||
calculatePerformance();
|
|
||||||
});
|
|
||||||
|
|
||||||
// 页面加载时先算一次
|
|
||||||
calculatePerformance();
|
|
||||||
}
|
|
||||||
function calculatePerformance() {
|
function calculatePerformance() {
|
||||||
//console.log("sb:计算利润...");
|
//console.log("sb:计算利润...");
|
||||||
const orderOnlineAmount = parseFloat($("#order-online-amount").val()) || 0;
|
const orderOnlineAmount = parseFloat($("#order-online-amount").val()) || 0;
|
||||||
|
|
@ -465,18 +452,19 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form','layer'], function ($,
|
||||||
|
|
||||||
$("#c-performance").val(performance.toFixed(2));
|
$("#c-performance").val(performance.toFixed(2));
|
||||||
}
|
}
|
||||||
function toggleReceiveFields() {
|
|
||||||
const type = $('#receive_type').val();
|
/* ["c-online_total", "c-total", "order-cost", "order-material_cost"].forEach(function(id) {
|
||||||
if (type === '0') {
|
$("#" + id).on("input", calculatePerformance);
|
||||||
$('#other_info').show();
|
});*/
|
||||||
} else {
|
|
||||||
$('#other_info').hide();
|
$('#c-online_total, #c-total, #order-cost, #order-material_cost').on('input', function () {
|
||||||
}
|
//calcProfit();
|
||||||
}
|
calculatePerformance();
|
||||||
toggleReceiveFields();
|
|
||||||
$('#receive_type').on('change', function () {
|
|
||||||
toggleReceiveFields();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 页面加载时先算一次
|
||||||
|
calculatePerformance();
|
||||||
|
}
|
||||||
},
|
},
|
||||||
addrecord: function () {
|
addrecord: function () {
|
||||||
Controller.api.bindevent();
|
Controller.api.bindevent();
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,7 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'echarts','echarts-th
|
||||||
searchFormVisible: true,
|
searchFormVisible: true,
|
||||||
columns: [
|
columns: [
|
||||||
[
|
[
|
||||||
{field: 'id', title: __('ID'),visible:true,operate: false},
|
// {field: 'id', title: __('ID'),visible:true,operate: false},
|
||||||
{field: 'name', title: '项目类型', operate: false},
|
{field: 'name', title: '项目类型', operate: false},
|
||||||
{field: 'total', title: __('成效额(¥)'), operate: false},
|
{field: 'total', title: __('成效额(¥)'), operate: false},
|
||||||
{field: 'performance', title: __('总业绩(¥)'), operate: false},
|
{field: 'performance', title: __('总业绩(¥)'), operate: false},
|
||||||
|
|
|
||||||
|
|
@ -59,12 +59,7 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'jstree','cascader'],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
field: 'worker_item',
|
field: 'worker_item',
|
||||||
width:500,
|
|
||||||
title: '工种',
|
title: '工种',
|
||||||
operate: false,
|
|
||||||
table: table,
|
|
||||||
class: 'autocontent',
|
|
||||||
formatter: Table.api.formatter.content
|
|
||||||
},
|
},
|
||||||
//{field: 'area_id', title: __('Area_id')},
|
//{field: 'area_id', title: __('Area_id')},
|
||||||
//{field: 'lng', title: __('Lng'), operate:'BETWEEN'},
|
//{field: 'lng', title: __('Lng'), operate:'BETWEEN'},
|
||||||
|
|
|
||||||
104
public/assets/js/require-backend.min.js
vendored
104
public/assets/js/require-backend.min.js
vendored
|
|
@ -7199,6 +7199,110 @@ define("bootstrap-table-lang", ["bootstrap-table"], (function (global) {
|
||||||
};
|
};
|
||||||
}(this)));
|
}(this)));
|
||||||
|
|
||||||
|
/*
|
||||||
|
tableExport.jquery.plugin
|
||||||
|
|
||||||
|
Version 1.10.26
|
||||||
|
|
||||||
|
Copyright (c) 2015-2021 hhurz, https://github.com/hhurz/tableExport.jquery.plugin
|
||||||
|
|
||||||
|
Based on https://github.com/kayalshri/tableExport.jquery.plugin
|
||||||
|
|
||||||
|
Licensed under the MIT License
|
||||||
|
*/
|
||||||
|
var $jscomp=$jscomp||{};$jscomp.scope={};$jscomp.findInternal=function(d,k,y){d instanceof String&&(d=String(d));for(var C=d.length,v=0;v<C;v++){var R=d[v];if(k.call(y,R,v,d))return{i:v,v:R}}return{i:-1,v:void 0}};$jscomp.ASSUME_ES5=!1;$jscomp.ASSUME_NO_NATIVE_MAP=!1;$jscomp.ASSUME_NO_NATIVE_SET=!1;$jscomp.defineProperty=$jscomp.ASSUME_ES5||"function"==typeof Object.defineProperties?Object.defineProperty:function(d,k,y){d!=Array.prototype&&d!=Object.prototype&&(d[k]=y.value)};
|
||||||
|
$jscomp.getGlobal=function(d){return"undefined"!=typeof window&&window===d?d:"undefined"!=typeof global&&null!=global?global:d};$jscomp.global=$jscomp.getGlobal(this);$jscomp.polyfill=function(d,k,y,C){if(k){y=$jscomp.global;d=d.split(".");for(C=0;C<d.length-1;C++){var v=d[C];v in y||(y[v]={});y=y[v]}d=d[d.length-1];C=y[d];k=k(C);k!=C&&null!=k&&$jscomp.defineProperty(y,d,{configurable:!0,writable:!0,value:k})}};
|
||||||
|
$jscomp.polyfill("Array.prototype.find",function(d){return d?d:function(d,y){return $jscomp.findInternal(this,d,y).v}},"es6","es3");
|
||||||
|
(function(d){d.fn.tableExport=function(k){function y(b){var c=[];v(b,"thead").each(function(){c.push.apply(c,v(d(this),a.theadSelector).toArray())});return c}function C(b){var c=[];v(b,"tbody").each(function(){c.push.apply(c,v(d(this),a.tbodySelector).toArray())});a.tfootSelector.length&&v(b,"tfoot").each(function(){c.push.apply(c,v(d(this),a.tfootSelector).toArray())});return c}function v(b,a){var c=b[0].tagName,q=b.parents(c).length;return b.find(a).filter(function(){return q===d(this).closest(c).parents(c).length})}
|
||||||
|
function R(b){var a=[],e=0,q=0,f=0;d(b).find("thead").first().find("th").each(function(b,c){b=void 0!==d(c).attr("data-field");"undefined"!==typeof c.parentNode.rowIndex&&q!==c.parentNode.rowIndex&&(q=c.parentNode.rowIndex,e=f=0);var h=J(c);for(e+=h?h:1;f<e;)a[f]=b?d(c).attr("data-field"):f.toString(),f++});return a}function I(b){var a="undefined"!==typeof b[0].rowIndex,e=!1===a&&"undefined"!==typeof b[0].cellIndex,q=e||a?Ja(b):b.is(":visible"),f=b.attr("data-tableexport-display");e&&"none"!==f&&
|
||||||
|
"always"!==f&&(b=d(b[0].parentNode),a="undefined"!==typeof b[0].rowIndex,f=b.attr("data-tableexport-display"));a&&"none"!==f&&"always"!==f&&(f=b.closest("table").attr("data-tableexport-display"));return"none"!==f&&(!0===q||"always"===f)}function Ja(b){var a=[];V&&(a=K.filter(function(){var a=!1;this.nodeType===b[0].nodeType&&("undefined"!==typeof this.rowIndex&&this.rowIndex===b[0].rowIndex?a=!0:"undefined"!==typeof this.cellIndex&&this.cellIndex===b[0].cellIndex&&"undefined"!==typeof this.parentNode.rowIndex&&
|
||||||
|
"undefined"!==typeof b[0].parentNode.rowIndex&&this.parentNode.rowIndex===b[0].parentNode.rowIndex&&(a=!0));return a}));return!1===V||0===a.length}function ta(b,c,e){var q=!1;I(b)?0<a.ignoreColumn.length&&(-1!==d.inArray(e,a.ignoreColumn)||-1!==d.inArray(e-c,a.ignoreColumn)||S.length>e&&"undefined"!==typeof S[e]&&-1!==d.inArray(S[e],a.ignoreColumn))&&(q=!0):q=!0;return q}function E(b,c,e,q,f){if("function"===typeof f){var h=!1;"function"===typeof a.onIgnoreRow&&(h=a.onIgnoreRow(d(b),e));if(!1===h&&
|
||||||
|
(0===a.ignoreRow.length||-1===d.inArray(e,a.ignoreRow)&&-1===d.inArray(e-q,a.ignoreRow))&&I(d(b))){b=v(d(b),c);var n=b.length,l=0,u=0;b.each(function(){var b=d(this),a=J(this),c=T(this),h;d.each(G,function(){if(e>this.s.r&&e<=this.e.r&&l>=this.s.c&&l<=this.e.c)for(h=0;h<=this.e.c-this.s.c;++h)n++,u++,f(null,e,l++)});if(c||a)a=a||1,G.push({s:{r:e,c:l},e:{r:e+(c||1)-1,c:l+a-1}});!1===ta(b,n,u++)&&f(this,e,l++);if(1<a)for(h=0;h<a-1;++h)u++,f(null,e,l++)});d.each(G,function(){if(e>=this.s.r&&e<=this.e.r&&
|
||||||
|
l>=this.s.c&&l<=this.e.c)for(ea=0;ea<=this.e.c-this.s.c;++ea)f(null,e,l++)})}}}function ua(b,a,e,d){if("undefined"!==typeof d.images&&(e=d.images[e],"undefined"!==typeof e)){a=a.getBoundingClientRect();var c=b.width/b.height,h=a.width/a.height,q=b.width,l=b.height,u=19.049976/25.4,g=0;h<=c?(l=Math.min(b.height,a.height),q=a.width*l/a.height):h>c&&(q=Math.min(b.width,a.width),l=a.height*q/a.width);q*=u;l*=u;l<b.height&&(g=(b.height-l)/2);try{d.doc.addImage(e.src,b.textPos.x,b.y+g,q,l)}catch(Pa){}b.textPos.x+=
|
||||||
|
q}}function va(b,c){if("string"===a.outputMode)return b.output();if("base64"===a.outputMode)return L(b.output());if("window"===a.outputMode)window.URL=window.URL||window.webkitURL,window.open(window.URL.createObjectURL(b.output("blob")));else try{var e=b.output("blob");saveAs(e,a.fileName+".pdf")}catch(q){ka(a.fileName+".pdf","data:application/pdf"+(c?"":";base64")+",",c?b.output("blob"):b.output())}}function wa(b,a,e){var c=0;"undefined"!==typeof e&&(c=e.colspan);if(0<=c){for(var f=b.width,d=b.textPos.x,
|
||||||
|
n=a.table.columns.indexOf(a.column),l=1;l<c;l++)f+=a.table.columns[n+l].width;1<c&&("right"===b.styles.halign?d=b.textPos.x+f-b.width:"center"===b.styles.halign&&(d=b.textPos.x+(f-b.width)/2));b.width=f;b.textPos.x=d;"undefined"!==typeof e&&1<e.rowspan&&(b.height*=e.rowspan);if("middle"===b.styles.valign||"bottom"===b.styles.valign)e=("string"===typeof b.text?b.text.split(/\r\n|\r|\n/g):b.text).length||1,2<e&&(b.textPos.y-=(2-1.15)/2*a.row.styles.fontSize*(e-2)/3);return!0}return!1}function xa(b,
|
||||||
|
a,e){"undefined"!==typeof b&&null!==b&&(b.hasAttribute("data-tableexport-canvas")?(a=(new Date).getTime(),d(b).attr("data-tableexport-canvas",a),e.images[a]={url:'[data-tableexport-canvas="'+a+'"]',src:null}):"undefined"!==a&&null!=a&&a.each(function(){if(d(this).is("img")){var a=ya(this.src);e.images[a]={url:this.src,src:this.src}}xa(b,d(this).children(),e)}))}function Ka(b,a){function c(b){if(b.url)if(b.src){var c=new Image;q=++f;c.crossOrigin="Anonymous";c.onerror=c.onload=function(){if(c.complete&&
|
||||||
|
(0===c.src.indexOf("data:image/")&&(c.width=b.width||c.width||0,c.height=b.height||c.height||0),c.width+c.height)){var e=document.createElement("canvas"),d=e.getContext("2d");e.width=c.width;e.height=c.height;d.drawImage(c,0,0);b.src=e.toDataURL("image/png")}--f||a(q)};c.src=b.url}else{var e=d(b.url);e.length&&(q=++f,html2canvas(e[0]).then(function(c){b.src=c.toDataURL("image/png");--f||a(q)}))}}var q=0,f=0;if("undefined"!==typeof b.images)for(var h in b.images)b.images.hasOwnProperty(h)&&c(b.images[h]);
|
||||||
|
(b=f)||(a(q),b=void 0);return b}function za(b,c,e){c.each(function(){if(d(this).is("div")){var c=fa(M(this,"background-color"),[255,255,255]),f=fa(M(this,"border-top-color"),[0,0,0]),h=ha(this,"border-top-width",a.jspdf.unit),n=this.getBoundingClientRect(),l=this.offsetLeft*e.wScaleFactor,u=this.offsetTop*e.hScaleFactor,g=n.width*e.wScaleFactor;n=n.height*e.hScaleFactor;e.doc.setDrawColor.apply(void 0,f);e.doc.setFillColor.apply(void 0,c);e.doc.setLineWidth(h);e.doc.rect(b.x+l,b.y+u,g,n,h?"FD":"F")}else d(this).is("img")&&
|
||||||
|
(c=ya(this.src),ua(b,this,c,e));za(b,d(this).children(),e)})}function Aa(b,c,e){if("function"===typeof e.onAutotableText)e.onAutotableText(e.doc,b,c);else{var q=b.textPos.x,f=b.textPos.y,h={halign:b.styles.halign,valign:b.styles.valign};if(c.length){for(c=c[0];c.previousSibling;)c=c.previousSibling;for(var n=!1,l=!1;c;){var u=c.innerText||c.textContent||"",g=u.length&&" "===u[0]?" ":"",k=1<u.length&&" "===u[u.length-1]?" ":"";!0!==a.preserve.leadingWS&&(u=g+la(u));!0!==a.preserve.trailingWS&&(u=ma(u)+
|
||||||
|
k);d(c).is("br")&&(q=b.textPos.x,f+=e.doc.internal.getFontSize());d(c).is("b")?n=!0:d(c).is("i")&&(l=!0);(n||l)&&e.doc.setFontType(n&&l?"bolditalic":n?"bold":"italic");if(g=e.doc.getStringUnitWidth(u)*e.doc.internal.getFontSize()){"linebreak"===b.styles.overflow&&q>b.textPos.x&&q+g>b.textPos.x+b.width&&(0<=".,!%*;:=-".indexOf(u.charAt(0))&&(k=u.charAt(0),g=e.doc.getStringUnitWidth(k)*e.doc.internal.getFontSize(),q+g<=b.textPos.x+b.width&&(e.doc.autoTableText(k,q,f,h),u=u.substring(1,u.length)),g=
|
||||||
|
e.doc.getStringUnitWidth(u)*e.doc.internal.getFontSize()),q=b.textPos.x,f+=e.doc.internal.getFontSize());if("visible"!==b.styles.overflow)for(;u.length&&q+g>b.textPos.x+b.width;)u=u.substring(0,u.length-1),g=e.doc.getStringUnitWidth(u)*e.doc.internal.getFontSize();e.doc.autoTableText(u,q,f,h);q+=g}if(n||l)d(c).is("b")?n=!1:d(c).is("i")&&(l=!1),e.doc.setFontType(n||l?n?"bold":"italic":"normal");c=c.nextSibling}b.textPos.x=q;b.textPos.y=f}else e.doc.autoTableText(b.text,b.textPos.x,b.textPos.y,h)}}
|
||||||
|
function W(b,a,e){return null==b?"":b.toString().replace(new RegExp(null==a?"":a.toString().replace(/([.*+?^=!:${}()|\[\]\/\\])/g,"\\$1"),"g"),e)}function la(b){return null==b?"":b.toString().replace(/^\s+/,"")}function ma(b){return null==b?"":b.toString().replace(/\s+$/,"")}function La(b){if(0===a.date.html.length)return!1;a.date.pattern.lastIndex=0;var c=a.date.pattern.exec(b);if(null==c)return!1;b=+c[a.date.match_y];if(0>b||8099<b)return!1;var e=1*c[a.date.match_m];c=1*c[a.date.match_d];if(!isFinite(c))return!1;
|
||||||
|
var d=new Date(b,e-1,c,0,0,0);return d.getFullYear()===b&&d.getMonth()===e-1&&d.getDate()===c?new Date(Date.UTC(b,e-1,c,0,0,0)):!1}function na(b){b=b||"0";""!==a.numbers.html.thousandsSeparator&&(b=W(b,a.numbers.html.thousandsSeparator,""));"."!==a.numbers.html.decimalMark&&(b=W(b,a.numbers.html.decimalMark,"."));return"number"===typeof b||!1!==jQuery.isNumeric(b)?b:!1}function Ma(b){-1<b.indexOf("%")?(b=na(b.replace(/%/g,"")),!1!==b&&(b/=100)):b=!1;return b}function D(b,c,e,q){var f="",h="text";
|
||||||
|
if(null!==b){var n=d(b);n.removeData("teUserDefText");if(n[0].hasAttribute("data-tableexport-canvas"))var l="";else if(n[0].hasAttribute("data-tableexport-value"))l=(l=n.attr("data-tableexport-value"))?l+"":"",n.data("teUserDefText",1);else if(l=n.html(),"function"===typeof a.onCellHtmlData)l=a.onCellHtmlData(n,c,e,l),n.data("teUserDefText",1);else if(""!==l){b=d.parseHTML(l);var g=0,k=0;l="";d.each(b,function(){if(d(this).is("input"))l+=n.find("input").eq(g++).val();else if(d(this).is("select"))l+=
|
||||||
|
n.find("select option:selected").eq(k++).text();else if(d(this).is("br"))l+="<br>";else{if("undefined"===typeof d(this).html())l+=d(this).text();else if(void 0===jQuery().bootstrapTable||!1===d(this).hasClass("fht-cell")&&!1===d(this).hasClass("filterControl")&&0===n.parents(".detail-view").length)l+=d(this).html();if(d(this).is("a")){var b=n.find("a").attr("href")||"";f="function"===typeof a.onCellHtmlHyperlink?f+a.onCellHtmlHyperlink(n,c,e,b,l):"href"===a.htmlHyperlink?f+b:f+l;l=""}}})}if(l&&""!==
|
||||||
|
l&&!0===a.htmlContent)f=d.trim(l);else if(l&&""!==l)if(""!==n.attr("data-tableexport-cellformat")){var m=l.replace(/\n/g,"\u2028").replace(/(<\s*br([^>]*)>)/gi,"\u2060"),p=d("<div/>").html(m).contents();b=!1;m="";d.each(p.text().split("\u2028"),function(b,c){0<b&&(m+=" ");!0!==a.preserve.leadingWS&&(c=la(c));m+=!0!==a.preserve.trailingWS?ma(c):c});d.each(m.split("\u2060"),function(b,c){0<b&&(f+="\n");!0!==a.preserve.leadingWS&&(c=la(c));!0!==a.preserve.trailingWS&&(c=ma(c));f+=c.replace(/\u00AD/g,
|
||||||
|
"")});f=f.replace(/\u00A0/g," ");if("json"===a.type||"excel"===a.type&&"xmlss"===a.mso.fileFormat||!1===a.numbers.output)b=na(f),!1!==b&&(h="number",f=Number(b));else if(a.numbers.html.decimalMark!==a.numbers.output.decimalMark||a.numbers.html.thousandsSeparator!==a.numbers.output.thousandsSeparator)if(b=na(f),!1!==b){p=(""+b.substr(0>b?1:0)).split(".");1===p.length&&(p[1]="");var t=3<p[0].length?p[0].length%3:0;h="number";f=(0>b?"-":"")+(a.numbers.output.thousandsSeparator?(t?p[0].substr(0,t)+a.numbers.output.thousandsSeparator:
|
||||||
|
"")+p[0].substr(t).replace(/(\d{3})(?=\d)/g,"$1"+a.numbers.output.thousandsSeparator):p[0])+(p[1].length?a.numbers.output.decimalMark+p[1]:"")}}else f=l;!0===a.escape&&(f=escape(f));"function"===typeof a.onCellData&&(f=a.onCellData(n,c,e,f,h),n.data("teUserDefText",1))}void 0!==q&&(q.type=h);return f}function Ba(b){return 0<b.length&&!0===a.preventInjection&&0<="=+-@".indexOf(b.charAt(0))?"'"+b:b}function Na(b,a,e){return a+"-"+e.toLowerCase()}function fa(b,a){(b=/^rgb\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3})\)$/.exec(b))&&
|
||||||
|
(a=[parseInt(b[1]),parseInt(b[2]),parseInt(b[3])]);return a}function Ca(b){var a=M(b,"text-align"),e=M(b,"font-weight"),d=M(b,"font-style"),f="";"start"===a&&(a="rtl"===M(b,"direction")?"right":"left");700<=e&&(f="bold");"italic"===d&&(f+=d);""===f&&(f="normal");a={style:{align:a,bcolor:fa(M(b,"background-color"),[255,255,255]),color:fa(M(b,"color"),[0,0,0]),fstyle:f},colspan:J(b),rowspan:T(b)};null!==b&&(b=b.getBoundingClientRect(),a.rect={width:b.width,height:b.height});return a}function J(b){var a=
|
||||||
|
d(b).attr("data-tableexport-colspan");"undefined"===typeof a&&d(b).is("[colspan]")&&(a=d(b).attr("colspan"));return parseInt(a)||0}function T(b){var a=d(b).attr("data-tableexport-rowspan");"undefined"===typeof a&&d(b).is("[rowspan]")&&(a=d(b).attr("rowspan"));return parseInt(a)||0}function M(a,c){try{return window.getComputedStyle?(c=c.replace(/([a-z])([A-Z])/,Na),window.getComputedStyle(a,null).getPropertyValue(c)):a.currentStyle?a.currentStyle[c]:a.style[c]}catch(e){}return""}function ha(a,c,e){c=
|
||||||
|
M(a,c).match(/\d+/);if(null!==c){c=c[0];a=a.parentElement;var b=document.createElement("div");b.style.overflow="hidden";b.style.visibility="hidden";a.appendChild(b);b.style.width=100+e;e=100/b.offsetWidth;a.removeChild(b);return c*e}return 0}function Oa(a){for(var b=new ArrayBuffer(a.length),e=new Uint8Array(b),d=0;d!==a.length;++d)e[d]=a.charCodeAt(d)&255;return b}function oa(a){var b=a.c,e="";for(++b;b;b=Math.floor((b-1)/26))e=String.fromCharCode((b-1)%26+65)+e;return e+(""+(a.r+1))}function pa(a,
|
||||||
|
c){if("undefined"===typeof c||"number"===typeof c)return pa(a.s,a.e);"string"!==typeof a&&(a=oa(a));"string"!==typeof c&&(c=oa(c));return a===c?a:a+":"+c}function Da(a,c){var b=Number(a);if(isFinite(b))return b;var d=1;""!==c.thousandsSeparator&&(a=a.replace(new RegExp("([\\d])"+c.thousandsSeparator+"([\\d])","g"),"$1$2"));"."!==c.decimalMark&&(a=a.replace(new RegExp("([\\d])"+c.decimalMark+"([\\d])","g"),"$1.$2"));a=a.replace(/[$]/g,"").replace(/[%]/g,function(){d*=100;return""});if(isFinite(b=Number(a)))return b/
|
||||||
|
d;a=a.replace(/[(](.*)[)]/,function(a,b){d=-d;return b});return isFinite(b=Number(a))?b/d:b}function ya(a){var b=0,d;if(0===a.length)return b;var q=0;for(d=a.length;q<d;q++){var f=a.charCodeAt(q);b=(b<<5)-b+f;b|=0}return b}function N(b,c,d,q,f,h){var e=!0;"function"===typeof a.onBeforeSaveToFile&&(e=a.onBeforeSaveToFile(b,c,d,q,f),"boolean"!==typeof e&&(e=!0));if(e)try{if(Ea=new Blob([b],{type:d+";charset="+q}),saveAs(Ea,c,!1===h),"function"===typeof a.onAfterSaveToFile)a.onAfterSaveToFile(b,c)}catch(l){ka(c,
|
||||||
|
"data:"+d+(q.length?";charset="+q:"")+(f.length?";"+f:"")+",",h?"\ufeff"+b:b)}}function ka(b,c,d){var e=window.navigator.userAgent;if(!1!==b&&window.navigator.msSaveOrOpenBlob)window.navigator.msSaveOrOpenBlob(new Blob([d]),b);else if(!1!==b&&(0<e.indexOf("MSIE ")||e.match(/Trident.*rv\:11\./))){if(c=document.createElement("iframe")){document.body.appendChild(c);c.setAttribute("style","display:none");c.contentDocument.open("txt/plain","replace");c.contentDocument.write(d);c.contentDocument.close();
|
||||||
|
c.contentWindow.focus();switch(b.substr(b.lastIndexOf(".")+1)){case "doc":case "json":case "png":case "pdf":case "xls":case "xlsx":b+=".txt"}c.contentDocument.execCommand("SaveAs",!0,b);document.body.removeChild(c)}}else{var f=document.createElement("a");if(f){var h=null;f.style.display="none";!1!==b?f.download=b:f.target="_blank";"object"===typeof d?(window.URL=window.URL||window.webkitURL,e=[],e.push(d),h=window.URL.createObjectURL(new Blob(e,{type:c})),f.href=h):0<=c.toLowerCase().indexOf("base64,")?
|
||||||
|
f.href=c+L(d):f.href=c+encodeURIComponent(d);document.body.appendChild(f);if(document.createEvent)null===ia&&(ia=document.createEvent("MouseEvents")),ia.initEvent("click",!0,!1),f.dispatchEvent(ia);else if(document.createEventObject)f.fireEvent("onclick");else if("function"===typeof f.onclick)f.onclick();setTimeout(function(){h&&window.URL.revokeObjectURL(h);document.body.removeChild(f);if("function"===typeof a.onAfterSaveToFile)a.onAfterSaveToFile(d,b)},100)}}}function L(a){var b,d="",q=0;if("string"===
|
||||||
|
typeof a){a=a.replace(/\x0d\x0a/g,"\n");var f="";for(b=0;b<a.length;b++){var h=a.charCodeAt(b);128>h?f+=String.fromCharCode(h):(127<h&&2048>h?f+=String.fromCharCode(h>>6|192):(f+=String.fromCharCode(h>>12|224),f+=String.fromCharCode(h>>6&63|128)),f+=String.fromCharCode(h&63|128))}a=f}for(;q<a.length;){var n=a.charCodeAt(q++);f=a.charCodeAt(q++);b=a.charCodeAt(q++);h=n>>2;n=(n&3)<<4|f>>4;var l=(f&15)<<2|b>>6;var g=b&63;isNaN(f)?l=g=64:isNaN(b)&&(g=64);d=d+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".charAt(h)+
|
||||||
|
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".charAt(n)+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".charAt(l)+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".charAt(g)}return d}var a={csvEnclosure:'"',csvSeparator:",",csvUseBOM:!0,date:{html:"dd/mm/yyyy"},displayTableName:!1,escape:!1,exportHiddenCells:!1,fileName:"tableExport",htmlContent:!1,htmlHyperlink:"content",ignoreColumn:[],ignoreRow:[],jsonScope:"all",jspdf:{orientation:"p",
|
||||||
|
unit:"pt",format:"a4",margins:{left:20,right:10,top:10,bottom:10},onDocCreated:null,autotable:{styles:{cellPadding:2,rowHeight:12,fontSize:8,fillColor:255,textColor:50,fontStyle:"normal",overflow:"ellipsize",halign:"inherit",valign:"middle"},headerStyles:{fillColor:[52,73,94],textColor:255,fontStyle:"bold",halign:"inherit",valign:"middle"},alternateRowStyles:{fillColor:245},tableExport:{doc:null,onAfterAutotable:null,onBeforeAutotable:null,onAutotableText:null,onTable:null,outputImages:!0}}},mso:{fileFormat:"xlshtml",
|
||||||
|
onMsoNumberFormat:null,pageFormat:"a4",pageOrientation:"portrait",rtl:!1,styles:[],worksheetName:"",xslx:{formatId:{date:14,numbers:2}}},numbers:{html:{decimalMark:".",thousandsSeparator:","},output:{decimalMark:".",thousandsSeparator:","}},onAfterSaveToFile:null,onBeforeSaveToFile:null,onCellData:null,onCellHtmlData:null,onCellHtmlHyperlink:null,onIgnoreRow:null,onTableExportBegin:null,onTableExportEnd:null,outputMode:"file",pdfmake:{enabled:!1,docDefinition:{pageSize:"A4",pageOrientation:"portrait",
|
||||||
|
styles:{header:{background:"#34495E",color:"#FFFFFF",bold:!0,alignment:"center",fillColor:"#34495E"},alternateRow:{fillColor:"#f5f5f5"}},defaultStyle:{color:"#000000",fontSize:8,font:"Roboto"}},fonts:{}},preserve:{leadingWS:!1,trailingWS:!1},preventInjection:!0,sql:{tableEnclosure:"`",columnEnclosure:"`"},tbodySelector:"tr",tfootSelector:"tr",theadSelector:"tr",tableName:"Table",type:"csv"},O={a0:[2383.94,3370.39],a1:[1683.78,2383.94],a2:[1190.55,1683.78],a3:[841.89,1190.55],a4:[595.28,841.89],a5:[419.53,
|
||||||
|
595.28],a6:[297.64,419.53],a7:[209.76,297.64],a8:[147.4,209.76],a9:[104.88,147.4],a10:[73.7,104.88],b0:[2834.65,4008.19],b1:[2004.09,2834.65],b2:[1417.32,2004.09],b3:[1000.63,1417.32],b4:[708.66,1000.63],b5:[498.9,708.66],b6:[354.33,498.9],b7:[249.45,354.33],b8:[175.75,249.45],b9:[124.72,175.75],b10:[87.87,124.72],c0:[2599.37,3676.54],c1:[1836.85,2599.37],c2:[1298.27,1836.85],c3:[918.43,1298.27],c4:[649.13,918.43],c5:[459.21,649.13],c6:[323.15,459.21],c7:[229.61,323.15],c8:[161.57,229.61],c9:[113.39,
|
||||||
|
161.57],c10:[79.37,113.39],dl:[311.81,623.62],letter:[612,792],"government-letter":[576,756],legal:[612,1008],"junior-legal":[576,360],ledger:[1224,792],tabloid:[792,1224],"credit-card":[153,243]},B=this,ia=null,r=[],w=[],p=0,t="",S=[],G=[],Ea,K=[],V=!1;d.extend(!0,a,k);"xlsx"===a.type&&(a.mso.fileFormat=a.type,a.type="excel");"undefined"!==typeof a.excelFileFormat&&"undefined"===a.mso.fileFormat&&(a.mso.fileFormat=a.excelFileFormat);"undefined"!==typeof a.excelPageFormat&&"undefined"===a.mso.pageFormat&&
|
||||||
|
(a.mso.pageFormat=a.excelPageFormat);"undefined"!==typeof a.excelPageOrientation&&"undefined"===a.mso.pageOrientation&&(a.mso.pageOrientation=a.excelPageOrientation);"undefined"!==typeof a.excelRTL&&"undefined"===a.mso.rtl&&(a.mso.rtl=a.excelRTL);"undefined"!==typeof a.excelstyles&&"undefined"===a.mso.styles&&(a.mso.styles=a.excelstyles);"undefined"!==typeof a.onMsoNumberFormat&&"undefined"===a.mso.onMsoNumberFormat&&(a.mso.onMsoNumberFormat=a.onMsoNumberFormat);"undefined"!==typeof a.worksheetName&&
|
||||||
|
"undefined"===a.mso.worksheetName&&(a.mso.worksheetName=a.worksheetName);a.mso.pageOrientation="l"===a.mso.pageOrientation.substr(0,1)?"landscape":"portrait";a.date.html=a.date.html||"";if(a.date.html.length){k=[];k.dd="(3[01]|[12][0-9]|0?[1-9])";k.mm="(1[012]|0?[1-9])";k.yyyy="((?:1[6-9]|2[0-2])\\d{2})";k.yy="(\\d{2})";var z=a.date.html.match(/[^a-zA-Z0-9]/)[0];z=a.date.html.toLowerCase().split(z);a.date.regex="^\\s*";a.date.regex+=k[z[0]];a.date.regex+="(.)";a.date.regex+=k[z[1]];a.date.regex+=
|
||||||
|
"\\2";a.date.regex+=k[z[2]];a.date.regex+="\\s*$";a.date.pattern=new RegExp(a.date.regex,"g");k=z.indexOf("dd")+1;a.date.match_d=k+(1<k?1:0);k=z.indexOf("mm")+1;a.date.match_m=k+(1<k?1:0);k=(0<=z.indexOf("yyyy")?z.indexOf("yyyy"):z.indexOf("yy"))+1;a.date.match_y=k+(1<k?1:0)}S=R(B);if("function"===typeof a.onTableExportBegin)a.onTableExportBegin();if("csv"===a.type||"tsv"===a.type||"txt"===a.type){var P="",Z=0;G=[];p=0;var qa=function(b,c,e){b.each(function(){t="";E(this,c,p,e+b.length,function(b,
|
||||||
|
c,d){var e=t,f="";if(null!==b)if(b=D(b,c,d),c=null===b||""===b?"":b.toString(),"tsv"===a.type)b instanceof Date&&b.toLocaleString(),f=W(c,"\t"," ");else if(b instanceof Date)f=a.csvEnclosure+b.toLocaleString()+a.csvEnclosure;else if(f=Ba(c),f=W(f,a.csvEnclosure,a.csvEnclosure+a.csvEnclosure),0<=f.indexOf(a.csvSeparator)||/[\r\n ]/g.test(f))f=a.csvEnclosure+f+a.csvEnclosure;t=e+(f+("tsv"===a.type?"\t":a.csvSeparator))});t=d.trim(t).substring(0,t.length-1);0<t.length&&(0<P.length&&(P+="\n"),P+=t);p++});
|
||||||
|
return b.length};Z+=qa(d(B).find("thead").first().find(a.theadSelector),"th,td",Z);v(d(B),"tbody").each(function(){Z+=qa(v(d(this),a.tbodySelector),"td,th",Z)});a.tfootSelector.length&&qa(d(B).find("tfoot").first().find(a.tfootSelector),"td,th",Z);P+="\n";if("string"===a.outputMode)return P;if("base64"===a.outputMode)return L(P);if("window"===a.outputMode){ka(!1,"data:text/"+("csv"===a.type?"csv":"plain")+";charset=utf-8,",P);return}N(P,a.fileName+"."+a.type,"text/"+("csv"===a.type?"csv":"plain"),
|
||||||
|
"utf-8","","csv"===a.type&&a.csvUseBOM)}else if("sql"===a.type){p=0;G=[];var A="INSERT INTO "+a.sql.tableEnclosure+a.tableName+a.sql.tableEnclosure+" (";r=y(d(B));d(r).each(function(){E(this,"th,td",p,r.length,function(b,c,d){b=D(b,c,d)||"";-1<b.indexOf(a.sql.columnEnclosure)&&(b=W(b.toString(),a.sql.columnEnclosure,a.sql.columnEnclosure+a.sql.columnEnclosure));A+=a.sql.columnEnclosure+b+a.sql.columnEnclosure+","});p++;A=d.trim(A).substring(0,A.length-1)});A+=") VALUES ";w=C(d(B));d(w).each(function(){t=
|
||||||
|
"";E(this,"td,th",p,r.length+w.length,function(a,c,d){a=D(a,c,d)||"";-1<a.indexOf("'")&&(a=W(a.toString(),"'","''"));t+="'"+a+"',"});3<t.length&&(A+="("+t,A=d.trim(A).substring(0,A.length-1),A+="),");p++});A=d.trim(A).substring(0,A.length-1);A+=";";if("string"===a.outputMode)return A;if("base64"===a.outputMode)return L(A);N(A,a.fileName+".sql","application/sql","utf-8","",!1)}else if("json"===a.type){var X=[];G=[];r=y(d(B));d(r).each(function(){var a=[];E(this,"th,td",p,r.length,function(b,d,g){a.push(D(b,
|
||||||
|
d,g))});X.push(a)});var ra=[];w=C(d(B));d(w).each(function(){var a={},c=0;E(this,"td,th",p,r.length+w.length,function(b,d,f){X.length?a[X[X.length-1][c]]=D(b,d,f):a[c]=D(b,d,f);c++});!1===d.isEmptyObject(a)&&ra.push(a);p++});k="head"===a.jsonScope?JSON.stringify(X):"data"===a.jsonScope?JSON.stringify(ra):JSON.stringify({header:X,data:ra});if("string"===a.outputMode)return k;if("base64"===a.outputMode)return L(k);N(k,a.fileName+".json","application/json","utf-8","base64",!1)}else if("xml"===a.type){p=
|
||||||
|
0;G=[];var Q='<?xml version="1.0" encoding="utf-8"?>';Q+="<tabledata><fields>";r=y(d(B));d(r).each(function(){E(this,"th,td",p,r.length,function(a,d,e){Q+="<field>"+D(a,d,e)+"</field>"});p++});Q+="</fields><data>";var Fa=1;w=C(d(B));d(w).each(function(){var a=1;t="";E(this,"td,th",p,r.length+w.length,function(b,d,g){t+="<column-"+a+">"+D(b,d,g)+"</column-"+a+">";a++});0<t.length&&"<column-1></column-1>"!==t&&(Q+='<row id="'+Fa+'">'+t+"</row>",Fa++);p++});Q+="</data></tabledata>";if("string"===a.outputMode)return Q;
|
||||||
|
if("base64"===a.outputMode)return L(Q);N(Q,a.fileName+".xml","application/xml","utf-8","base64",!1)}else if("excel"===a.type&&"xmlss"===a.mso.fileFormat){var sa=[],F=[];d(B).filter(function(){return I(d(this))}).each(function(){function b(a,b,c){var f=[];d(a).each(function(){var b=0,e=0;t="";E(this,"td,th",p,c+a.length,function(a,c,h){if(null!==a){var l="";c=D(a,c,h);h="String";if(!1!==jQuery.isNumeric(c))h="Number";else{var n=Ma(c);!1!==n&&(c=n,h="Number",l+=' ss:StyleID="pct1"')}"Number"!==h&&(c=
|
||||||
|
c.replace(/\n/g,"<br>"));n=J(a);a=T(a);d.each(f,function(){if(p>=this.s.r&&p<=this.e.r&&e>=this.s.c&&e<=this.e.c)for(var a=0;a<=this.e.c-this.s.c;++a)e++,b++});if(a||n)a=a||1,n=n||1,f.push({s:{r:p,c:e},e:{r:p+a-1,c:e+n-1}});1<n&&(l+=' ss:MergeAcross="'+(n-1)+'"',e+=n-1);1<a&&(l+=' ss:MergeDown="'+(a-1)+'" ss:StyleID="rsp1"');0<b&&(l+=' ss:Index="'+(e+1)+'"',b=0);t+="<Cell"+l+'><Data ss:Type="'+h+'">'+d("<div />").text(c).html()+"</Data></Cell>\r";e++}});0<t.length&&(H+='<Row ss:AutoFitHeight="0">\r'+
|
||||||
|
t+"</Row>\r");p++});return a.length}var c=d(this),e="";"string"===typeof a.mso.worksheetName&&a.mso.worksheetName.length?e=a.mso.worksheetName+" "+(F.length+1):"undefined"!==typeof a.mso.worksheetName[F.length]&&(e=a.mso.worksheetName[F.length]);e.length||(e=c.find("caption").text()||"");e.length||(e="Table "+(F.length+1));e=d.trim(e.replace(/[\\\/[\]*:?'"]/g,"").substring(0,31));F.push(d("<div />").text(e).html());!1===a.exportHiddenCells&&(K=c.find("tr, th, td").filter(":hidden"),V=0<K.length);
|
||||||
|
p=0;S=R(this);H="<Table>\r";e=b(y(c),"th,td",0);b(C(c),"td,th",e);H+="</Table>\r";sa.push(H)});k={};z={};for(var m,aa,Y=0,ea=F.length;Y<ea;Y++)m=F[Y],aa=k[m],aa=k[m]=null==aa?1:aa+1,2===aa&&(F[z[m]]=F[z[m]].substring(0,29)+"-1"),1<k[m]?F[Y]=F[Y].substring(0,29)+"-"+k[m]:z[m]=Y;k='<?xml version="1.0" encoding="UTF-8"?>\r<?mso-application progid="Excel.Sheet"?>\r<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet"\r xmlns:o="urn:schemas-microsoft-com:office:office"\r xmlns:x="urn:schemas-microsoft-com:office:excel"\r xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"\r xmlns:html="http://www.w3.org/TR/REC-html40">\r<DocumentProperties xmlns="urn:schemas-microsoft-com:office:office">\r <Created>'+
|
||||||
|
(new Date).toISOString()+'</Created>\r</DocumentProperties>\r<OfficeDocumentSettings xmlns="urn:schemas-microsoft-com:office:office">\r <AllowPNG/>\r</OfficeDocumentSettings>\r<ExcelWorkbook xmlns="urn:schemas-microsoft-com:office:excel">\r <WindowHeight>9000</WindowHeight>\r <WindowWidth>13860</WindowWidth>\r <WindowTopX>0</WindowTopX>\r <WindowTopY>0</WindowTopY>\r <ProtectStructure>False</ProtectStructure>\r <ProtectWindows>False</ProtectWindows>\r</ExcelWorkbook>\r<Styles>\r <Style ss:ID="Default" ss:Name="Normal">\r <Alignment ss:Vertical="Bottom"/>\r <Borders/>\r <Font/>\r <Interior/>\r <NumberFormat/>\r <Protection/>\r </Style>\r <Style ss:ID="rsp1">\r <Alignment ss:Vertical="Center"/>\r </Style>\r <Style ss:ID="pct1">\r <NumberFormat ss:Format="Percent"/>\r </Style>\r</Styles>\r';
|
||||||
|
for(z=0;z<sa.length;z++)k+='<Worksheet ss:Name="'+F[z]+'" ss:RightToLeft="'+(a.mso.rtl?"1":"0")+'">\r'+sa[z],k=a.mso.rtl?k+'<WorksheetOptions xmlns="urn:schemas-microsoft-com:office:excel">\r<DisplayRightToLeft/>\r</WorksheetOptions>\r':k+'<WorksheetOptions xmlns="urn:schemas-microsoft-com:office:excel"/>\r',k+="</Worksheet>\r";k+="</Workbook>\r";if("string"===a.outputMode)return k;if("base64"===a.outputMode)return L(k);N(k,a.fileName+".xml","application/xml","utf-8","base64",!1)}else if("excel"===
|
||||||
|
a.type&&"xlsx"===a.mso.fileFormat){var ba=[],Ga=XLSX.utils.book_new();d(B).filter(function(){return I(d(this))}).each(function(){for(var b=d(this),c={},e=this.getElementsByTagName("tr"),g={s:{r:0,c:0},e:{r:0,c:0}},f=[],h,n=[],l=0,u=0,k,m,p,t,r,w=XLSX.SSF.get_table();l<e.length&&1E7>u;++l)if(k=e[l],m=!1,"function"===typeof a.onIgnoreRow&&(m=a.onIgnoreRow(d(k),l)),!0!==m&&(0===a.ignoreRow.length||-1===d.inArray(l,a.ignoreRow)&&-1===d.inArray(l-e.length,a.ignoreRow))&&!1!==I(d(k))){var y=k.children,
|
||||||
|
B=0;for(k=0;k<y.length;++k)r=y[k],t=+J(r)||1,B+=t;var z=0;for(k=m=0;k<y.length;++k)if(r=y[k],t=+J(r)||1,h=k+z,!ta(d(r),B,h+(h<m?m-h:0))){z+=t-1;for(h=0;h<f.length;++h){var v=f[h];v.s.c==m&&v.s.r<=u&&u<=v.e.r&&(m=v.e.c+1,h=-1)}(0<(p=+T(r))||1<t)&&f.push({s:{r:u,c:m},e:{r:u+(p||1)-1,c:m+t-1}});var C={type:""};h=D(r,l,k+z,C);v={t:"s",v:h};var A="";if(""!==(d(r).attr("data-tableexport-cellformat")||"")){var x=parseInt(d(r).attr("data-tableexport-xlsxformatid")||0);0===x&&"function"===typeof a.mso.xslx.formatId.numbers&&
|
||||||
|
(x=a.mso.xslx.formatId.numbers(d(r),l,k+z));0===x&&"function"===typeof a.mso.xslx.formatId.date&&(x=a.mso.xslx.formatId.date(d(r),l,k+z));if(49===x||"@"===x)A="s";else if("number"===C.type||0<x&&14>x||36<x&&41>x||48===x)A="n";else if("date"===C.type||13<x&&37>x||44<x&&48>x||56===x)A="d"}else A="s";if(null!=h)if(0===h.length)v.t="z";else if(0!==h.trim().length)if("s"===A)d(r).find("a").length&&(h="href"!==a.htmlHyperlink?h:"",v={f:'=HYPERLINK("'+d(r).find("a").attr("href")+(h.length?'","'+h:"")+'")'});
|
||||||
|
else if("function"===C.type)v={f:h};else if("TRUE"===h)v={t:"b",v:!0};else if("FALSE"===h)v={t:"b",v:!1};else if("n"===A||isFinite(Da(h,a.numbers.output))){if(r=Da(h,a.numbers.output),0===x&&"function"!==typeof a.mso.xslx.formatId.numbers&&(x=a.mso.xslx.formatId.numbers),isFinite(r)||isFinite(h))v={t:"n",v:isFinite(r)?r:h,z:"string"===typeof x?x:x in w?w[x]:"0.00"}}else if(!1!==(r=La(h))||"d"===A)0===x&&"function"!==typeof a.mso.xslx.formatId.date&&(x=a.mso.xslx.formatId.date),v={t:"d",v:!1!==r?r:
|
||||||
|
h,z:"string"===typeof x?x:x in w?w[x]:"m/d/yy"};c[oa({c:m,r:u})]=v;g.e.c<m&&(g.e.c=m);m+=t}++u}f.length&&(c["!merges"]=f);n.length&&(c["!rows"]=n);g.e.r=u-1;c["!ref"]=pa(g);1E7<=u&&(c["!fullref"]=pa((g.e.r=e.length-l+u-1,g)));e="";"string"===typeof a.mso.worksheetName&&a.mso.worksheetName.length?e=a.mso.worksheetName+" "+(ba.length+1):"undefined"!==typeof a.mso.worksheetName[ba.length]&&(e=a.mso.worksheetName[ba.length]);e.length||(e=b.find("caption").text()||"");e.length||(e="Table "+(ba.length+
|
||||||
|
1));e=d.trim(e.replace(/[\\\/[\]*:?'"]/g,"").substring(0,31));ba.push(e);XLSX.utils.book_append_sheet(Ga,c,e)});k=XLSX.write(Ga,{type:"binary",bookType:a.mso.fileFormat,bookSST:!1});N(Oa(k),a.fileName+"."+a.mso.fileFormat,"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet","UTF-8","",!1)}else if("excel"===a.type||"xls"===a.type||"word"===a.type||"doc"===a.type){k="excel"===a.type||"xls"===a.type?"excel":"word";z="excel"===k?"xls":"doc";m='xmlns:x="urn:schemas-microsoft-com:office:'+
|
||||||
|
k+'"';var H="",ca="";d(B).filter(function(){return I(d(this))}).each(function(){var b=d(this);""===ca&&(ca=a.mso.worksheetName||b.find("caption").text()||"Table",ca=d.trim(ca.replace(/[\\\/[\]*:?'"]/g,"").substring(0,31)));!1===a.exportHiddenCells&&(K=b.find("tr, th, td").filter(":hidden"),V=0<K.length);p=0;G=[];S=R(this);H+="<table><thead>";r=y(b);d(r).each(function(){var b=d(this);t="";E(this,"th,td",p,r.length,function(d,c,f){if(null!==d){var e="";t+="<th";if(a.mso.styles.length){var n=document.defaultView.getComputedStyle(d,
|
||||||
|
null),l=document.defaultView.getComputedStyle(b[0],null),g;for(g in a.mso.styles){var k=n[a.mso.styles[g]];""===k&&(k=l[a.mso.styles[g]]);""!==k&&"0px none rgb(0, 0, 0)"!==k&&"rgba(0, 0, 0, 0)"!==k&&(e+=""===e?'style="':";",e+=a.mso.styles[g]+":"+k)}}""!==e&&(t+=" "+e+'"');e=J(d);0<e&&(t+=' colspan="'+e+'"');e=T(d);0<e&&(t+=' rowspan="'+e+'"');t+=">"+D(d,c,f)+"</th>"}});0<t.length&&(H+="<tr>"+t+"</tr>");p++});H+="</thead><tbody>";w=C(b);d(w).each(function(){var b=d(this);t="";E(this,"td,th",p,r.length+
|
||||||
|
w.length,function(c,g,f){if(null!==c){var e=D(c,g,f),n="",l=d(c).attr("data-tableexport-msonumberformat");"undefined"===typeof l&&"function"===typeof a.mso.onMsoNumberFormat&&(l=a.mso.onMsoNumberFormat(c,g,f));"undefined"!==typeof l&&""!==l&&(n="style=\"mso-number-format:'"+l+"'");if(a.mso.styles.length){g=document.defaultView.getComputedStyle(c,null);f=document.defaultView.getComputedStyle(b[0],null);for(var k in a.mso.styles)l=g[a.mso.styles[k]],""===l&&(l=f[a.mso.styles[k]]),""!==l&&"0px none rgb(0, 0, 0)"!==
|
||||||
|
l&&"rgba(0, 0, 0, 0)"!==l&&(n+=""===n?'style="':";",n+=a.mso.styles[k]+":"+l)}t+="<td";""!==n&&(t+=" "+n+'"');n=J(c);0<n&&(t+=' colspan="'+n+'"');c=T(c);0<c&&(t+=' rowspan="'+c+'"');"string"===typeof e&&""!==e&&(e=Ba(e),e=e.replace(/\n/g,"<br>"));t+=">"+e+"</td>"}});0<t.length&&(H+="<tr>"+t+"</tr>");p++});a.displayTableName&&(H+="<tr><td></td></tr><tr><td></td></tr><tr><td>"+D(d("<p>"+a.tableName+"</p>"))+"</td></tr>");H+="</tbody></table>"});m='<html xmlns:o="urn:schemas-microsoft-com:office:office" '+
|
||||||
|
m+' xmlns="http://www.w3.org/TR/REC-html40">'+('<meta http-equiv="content-type" content="application/vnd.ms-'+k+'; charset=UTF-8">')+"<head>";"excel"===k&&(m+="\x3c!--[if gte mso 9]>",m+="<xml>",m+="<x:ExcelWorkbook>",m+="<x:ExcelWorksheets>",m+="<x:ExcelWorksheet>",m+="<x:Name>",m+=ca,m+="</x:Name>",m+="<x:WorksheetOptions>",m+="<x:DisplayGridlines/>",a.mso.rtl&&(m+="<x:DisplayRightToLeft/>"),m+="</x:WorksheetOptions>",m+="</x:ExcelWorksheet>",m+="</x:ExcelWorksheets>",m+="</x:ExcelWorkbook>",m+=
|
||||||
|
"</xml>",m+="<![endif]--\x3e");m+="<style>";m+="@page { size:"+a.mso.pageOrientation+"; mso-page-orientation:"+a.mso.pageOrientation+"; }";m+="@page Section1 {size:"+O[a.mso.pageFormat][0]+"pt "+O[a.mso.pageFormat][1]+"pt";m+="; margin:1.0in 1.25in 1.0in 1.25in;mso-header-margin:.5in;mso-footer-margin:.5in;mso-paper-source:0;}";m+="div.Section1 {page:Section1;}";m+="@page Section2 {size:"+O[a.mso.pageFormat][1]+"pt "+O[a.mso.pageFormat][0]+"pt";m+=";mso-page-orientation:"+a.mso.pageOrientation+";margin:1.25in 1.0in 1.25in 1.0in;mso-header-margin:.5in;mso-footer-margin:.5in;mso-paper-source:0;}";
|
||||||
|
m+="div.Section2 {page:Section2;}";m+="br {mso-data-placement:same-cell;}";m+="</style>";m+="</head>";m+="<body>";m+='<div class="Section'+("landscape"===a.mso.pageOrientation?"2":"1")+'">';m+=H;m+="</div>";m+="</body>";m+="</html>";if("string"===a.outputMode)return m;if("base64"===a.outputMode)return L(m);N(m,a.fileName+"."+z,"application/vnd.ms-"+k,"","base64",!1)}else if("png"===a.type)html2canvas(d(B)[0]).then(function(b){b=b.toDataURL();for(var c=atob(b.substring(22)),d=new ArrayBuffer(c.length),
|
||||||
|
g=new Uint8Array(d),f=0;f<c.length;f++)g[f]=c.charCodeAt(f);if("string"===a.outputMode)return c;if("base64"===a.outputMode)return L(b);"window"===a.outputMode?window.open(b):N(d,a.fileName+".png","image/png","","",!1)});else if("pdf"===a.type)if(!0===a.pdfmake.enabled){var U={content:[]};d.extend(!0,U,a.pdfmake.docDefinition);G=[];d(B).filter(function(){return I(d(this))}).each(function(){var b=d(this),c=[],e=[];p=0;var g=function(a,b,c){var f=0;d(a).each(function(){var a=[];E(this,b,p,c,function(c,
|
||||||
|
d,f){if("undefined"!==typeof c&&null!==c){var e=J(c),h=T(c);c={text:D(c,d,f)||" "};if(1<e||1<h)c.colSpan=e||1,c.rowSpan=h||1}else c={text:" "};0<=b.indexOf("th")&&(c.style="header");a.push(c)});a.length&&e.push(a);f<a.length&&(f=a.length);p++});return f};r=y(b);for(var f=g(r,"th,td",r.length),h=c.length;h<f;h++)c.push("*");w=C(b);f=g(w,"td",r.length+w.length);for(h=c.length;h<f;h++)c.push("*");U.content.push({table:{headerRows:r.length?r.length:null,widths:c,body:e},layout:{layout:"noBorders",hLineStyle:function(a,
|
||||||
|
b){return 0},vLineWidth:function(a,b){return 0},hLineColor:function(b,c){return b<c.table.headerRows?a.pdfmake.docDefinition.styles.header.background:a.pdfmake.docDefinition.styles.alternateRow.fillColor},vLineColor:function(b,c){return b<c.table.headerRows?a.pdfmake.docDefinition.styles.header.background:a.pdfmake.docDefinition.styles.alternateRow.fillColor},fillColor:function(b,c,d){return 0===b%2?a.pdfmake.docDefinition.styles.alternateRow.fillColor:null}},pageBreak:U.content.length?"before":void 0})});
|
||||||
|
"undefined"!==typeof pdfMake&&"undefined"!==typeof pdfMake.createPdf&&(pdfMake.fonts={Roboto:{normal:"Roboto-Regular.ttf",bold:"Roboto-Medium.ttf",italics:"Roboto-Italic.ttf",bolditalics:"Roboto-MediumItalic.ttf"}},pdfMake.vfs.hasOwnProperty("Mirza-Regular.ttf")?(U.defaultStyle.font="Mirza",d.extend(!0,pdfMake.fonts,{Mirza:{normal:"Mirza-Regular.ttf",bold:"Mirza-Bold.ttf",italics:"Mirza-Medium.ttf",bolditalics:"Mirza-SemiBold.ttf"}})):pdfMake.vfs.hasOwnProperty("gbsn00lp.ttf")?(U.defaultStyle.font=
|
||||||
|
"gbsn00lp",d.extend(!0,pdfMake.fonts,{gbsn00lp:{normal:"gbsn00lp.ttf",bold:"gbsn00lp.ttf",italics:"gbsn00lp.ttf",bolditalics:"gbsn00lp.ttf"}})):pdfMake.vfs.hasOwnProperty("ZCOOLXiaoWei-Regular.ttf")&&(U.defaultStyle.font="ZCOOLXiaoWei",d.extend(!0,pdfMake.fonts,{ZCOOLXiaoWei:{normal:"ZCOOLXiaoWei-Regular.ttf",bold:"ZCOOLXiaoWei-Regular.ttf",italics:"ZCOOLXiaoWei-Regular.ttf",bolditalics:"ZCOOLXiaoWei-Regular.ttf"}})),d.extend(!0,pdfMake.fonts,a.pdfmake.fonts),pdfMake.createPdf(U).getBuffer(function(b){N(b,
|
||||||
|
a.fileName+".pdf","application/pdf","","",!1)}))}else if(!1===a.jspdf.autotable){k={dim:{w:ha(d(B).first().get(0),"width","mm"),h:ha(d(B).first().get(0),"height","mm")},pagesplit:!1};var Ha=new jsPDF(a.jspdf.orientation,a.jspdf.unit,a.jspdf.format);Ha.addHTML(d(B).first(),a.jspdf.margins.left,a.jspdf.margins.top,k,function(){va(Ha,!1)})}else{var g=a.jspdf.autotable.tableExport;if("string"===typeof a.jspdf.format&&"bestfit"===a.jspdf.format.toLowerCase()){var ja="",da="",Ia=0;d(B).each(function(){if(I(d(this))){var a=
|
||||||
|
ha(d(this).get(0),"width","pt");if(a>Ia){a>O.a0[0]&&(ja="a0",da="l");for(var c in O)O.hasOwnProperty(c)&&O[c][1]>a&&(ja=c,da="l",O[c][0]>a&&(da="p"));Ia=a}}});a.jspdf.format=""===ja?"a4":ja;a.jspdf.orientation=""===da?"w":da}if(null==g.doc&&(g.doc=new jsPDF(a.jspdf.orientation,a.jspdf.unit,a.jspdf.format),g.wScaleFactor=1,g.hScaleFactor=1,"function"===typeof a.jspdf.onDocCreated))a.jspdf.onDocCreated(g.doc);!0===g.outputImages&&(g.images={});"undefined"!==typeof g.images&&(d(B).filter(function(){return I(d(this))}).each(function(){var b=
|
||||||
|
0;G=[];!1===a.exportHiddenCells&&(K=d(this).find("tr, th, td").filter(":hidden"),V=0<K.length);r=y(d(this));w=C(d(this));d(w).each(function(){E(this,"td,th",r.length+b,r.length+w.length,function(a){xa(a,d(a).children(),g)});b++})}),r=[],w=[]);Ka(g,function(){d(B).filter(function(){return I(d(this))}).each(function(){var b;p=0;G=[];!1===a.exportHiddenCells&&(K=d(this).find("tr, th, td").filter(":hidden"),V=0<K.length);S=R(this);g.columns=[];g.rows=[];g.teCells={};if("function"===typeof g.onTable&&
|
||||||
|
!1===g.onTable(d(this),a))return!0;a.jspdf.autotable.tableExport=null;var c=d.extend(!0,{},a.jspdf.autotable);a.jspdf.autotable.tableExport=g;c.margin={};d.extend(!0,c.margin,a.jspdf.margins);c.tableExport=g;"function"!==typeof c.beforePageContent&&(c.beforePageContent=function(a){if(1===a.pageCount){var b=a.table.rows.concat(a.table.headerRow);d.each(b,function(){0<this.height&&(this.height+=(2-1.15)/2*this.styles.fontSize,a.table.height+=(2-1.15)/2*this.styles.fontSize)})}});"function"!==typeof c.createdHeaderCell&&
|
||||||
|
(c.createdHeaderCell=function(a,b){a.styles=d.extend({},b.row.styles);if("undefined"!==typeof g.columns[b.column.dataKey]){var e=g.columns[b.column.dataKey];if("undefined"!==typeof e.rect){a.contentWidth=e.rect.width;if("undefined"===typeof g.heightRatio||0===g.heightRatio){var f=b.row.raw[b.column.dataKey].rowspan?b.row.raw[b.column.dataKey].rect.height/b.row.raw[b.column.dataKey].rowspan:b.row.raw[b.column.dataKey].rect.height;g.heightRatio=a.styles.rowHeight/f}f=b.row.raw[b.column.dataKey].rect.height*
|
||||||
|
g.heightRatio;f>a.styles.rowHeight&&(a.styles.rowHeight=f)}a.styles.halign="inherit"===c.headerStyles.halign?"center":c.headerStyles.halign;a.styles.valign=c.headerStyles.valign;"undefined"!==typeof e.style&&!0!==e.style.hidden&&("inherit"===c.headerStyles.halign&&(a.styles.halign=e.style.align),"inherit"===c.styles.fillColor&&(a.styles.fillColor=e.style.bcolor),"inherit"===c.styles.textColor&&(a.styles.textColor=e.style.color),"inherit"===c.styles.fontStyle&&(a.styles.fontStyle=e.style.fstyle))}});
|
||||||
|
"function"!==typeof c.createdCell&&(c.createdCell=function(a,b){b=g.teCells[b.row.index+":"+b.column.dataKey];a.styles.halign="inherit"===c.styles.halign?"center":c.styles.halign;a.styles.valign=c.styles.valign;"undefined"!==typeof b&&"undefined"!==typeof b.style&&!0!==b.style.hidden&&("inherit"===c.styles.halign&&(a.styles.halign=b.style.align),"inherit"===c.styles.fillColor&&(a.styles.fillColor=b.style.bcolor),"inherit"===c.styles.textColor&&(a.styles.textColor=b.style.color),"inherit"===c.styles.fontStyle&&
|
||||||
|
(a.styles.fontStyle=b.style.fstyle))});"function"!==typeof c.drawHeaderCell&&(c.drawHeaderCell=function(a,b){var c=g.columns[b.column.dataKey];return(!0!==c.style.hasOwnProperty("hidden")||!0!==c.style.hidden)&&0<=c.rowIndex?wa(a,b,c):!1});"function"!==typeof c.drawCell&&(c.drawCell=function(a,b){var c=g.teCells[b.row.index+":"+b.column.dataKey];if(!0!==("undefined"!==typeof c&&c.isCanvas))wa(a,b,c)&&(g.doc.rect(a.x,a.y,a.width,a.height,a.styles.fillStyle),"undefined"===typeof c||"undefined"!==typeof c.hasUserDefText&&
|
||||||
|
!0===c.hasUserDefText||"undefined"===typeof c.elements||!c.elements.length?Aa(a,{},g):(b=a.height/c.rect.height,b>g.hScaleFactor&&(g.hScaleFactor=b),g.wScaleFactor=a.width/c.rect.width,b=a.textPos.y,za(a,c.elements,g),a.textPos.y=b,Aa(a,c.elements,g)));else{c=c.elements[0];var e=d(c).attr("data-tableexport-canvas"),f=c.getBoundingClientRect();a.width=f.width*g.wScaleFactor;a.height=f.height*g.hScaleFactor;b.row.height=a.height;ua(a,c,e,g)}return!1});g.headerrows=[];r=y(d(this));d(r).each(function(){b=
|
||||||
|
0;g.headerrows[p]=[];E(this,"th,td",p,r.length,function(a,c,d){var e=Ca(a);e.title=D(a,c,d);e.key=b++;e.rowIndex=p;g.headerrows[p].push(e)});p++});if(0<p)for(var e=p-1;0<=e;)d.each(g.headerrows[e],function(){var a=this;0<e&&null===this.rect&&(a=g.headerrows[e-1][this.key]);null!==a&&0<=a.rowIndex&&(!0!==a.style.hasOwnProperty("hidden")||!0!==a.style.hidden)&&g.columns.push(a)}),e=0<g.columns.length?-1:e-1;var k=0;w=[];w=C(d(this));d(w).each(function(){var a=[];b=0;E(this,"td,th",p,r.length+w.length,
|
||||||
|
function(c,e,f){if("undefined"===typeof g.columns[b]){var h={title:"",key:b,style:{hidden:!0}};g.columns.push(h)}a.push(D(c,e,f));"undefined"!==typeof c&&null!==c?(h=Ca(c),h.isCanvas=c.hasAttribute("data-tableexport-canvas"),h.elements=h.isCanvas?d(c):d(c).children(),"undefined"!==typeof d(c).data("teUserDefText")&&(h.hasUserDefText=!0)):(h=d.extend(!0,{},g.teCells[k+":"+(b-1)]),h.colspan=-1);g.teCells[k+":"+b++]=h});a.length&&(g.rows.push(a),k++);p++});if("function"===typeof g.onBeforeAutotable)g.onBeforeAutotable(d(this),
|
||||||
|
g.columns,g.rows,c);g.doc.autoTable(g.columns,g.rows,c);if("function"===typeof g.onAfterAutotable)g.onAfterAutotable(d(this),c);a.jspdf.autotable.startY=g.doc.autoTableEndPosY()+c.margin.top});va(g.doc,"undefined"!==typeof g.images&&!1===jQuery.isEmptyObject(g.images));"undefined"!==typeof g.headerrows&&(g.headerrows.length=0);"undefined"!==typeof g.columns&&(g.columns.length=0);"undefined"!==typeof g.rows&&(g.rows.length=0);delete g.doc;g.doc=null})}if("function"===typeof a.onTableExportEnd)a.onTableExportEnd();
|
||||||
|
return this}})(jQuery);
|
||||||
|
|
||||||
|
define("tableexport", ["jquery"], (function (global) {
|
||||||
|
return function () {
|
||||||
|
var ret, fn;
|
||||||
|
return ret || global.$.fn.extend;
|
||||||
|
};
|
||||||
|
}(this)));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* bootstrap-table - v1.11.12 - 2024-03-28
|
* bootstrap-table - v1.11.12 - 2024-03-28
|
||||||
https://github.com/wenzhixin/bootstrap-table
|
https://github.com/wenzhixin/bootstrap-table
|
||||||
|
|
|
||||||
|
|
@ -35,8 +35,9 @@
|
||||||
top: 50%;
|
top: 50%;
|
||||||
right: 24px;
|
right: 24px;
|
||||||
width: 10px;
|
width: 10px;
|
||||||
margin-top: -13px;
|
margin-top: -12px;
|
||||||
font-size: 20px;
|
font-size: 20px;
|
||||||
|
height: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.city-picker-span.focus,
|
.city-picker-span.focus,
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,7 @@
|
||||||
if (value !== undefined && value !== "" && !isNaN(Number(value))) this.$element.val($.fn.citypicker.getAddressbyCodeId(value))
|
if (value !== undefined && value !== "" && !isNaN(Number(value))) this.$element.val($.fn.citypicker.getAddressbyCodeId(value))
|
||||||
}, render: function () {
|
}, render: function () {
|
||||||
var p = this.getPosition(), placeholder = this.$element.attr("placeholder") || this.options.placeholder,
|
var p = this.getPosition(), placeholder = this.$element.attr("placeholder") || this.options.placeholder,
|
||||||
textspan = '<span class="city-picker-span" style="' + this.getWidthStyle('100%') + "height:" + p.height + "px;line-height:" + (p.height - 1) + 'px;">' + (placeholder ? '<span class="placeholder">' + placeholder + "</span>" : "") + '<span class="title"></span><div class="arrow"></div><div class="close">×</div>' + "</span>",
|
textspan = '<span class="city-picker-span" style="' + this.getWidthStyle('100%') + "height:" + p.height + "px;line-height:" + (p.height - 1) + 'px;">' + (placeholder ? '<span class="placeholder">' + placeholder + "</span>" : "") + '<span class="title"></span><div class="arrow"></div>' + "</span>",
|
||||||
dropdown = '<div class="city-picker-dropdown" style="left:0px;top:100%;' + this.getWidthStyle(p.width, true) + '">' + '<div class="city-select-wrap">' + '<div class="city-select-tab">' + '<a class="active" data-count="province">省份</a>' + (this.includeDem("city") ? '<a data-count="city">城市</a>' : "") + (this.includeDem("district") ? '<a data-count="district">区县</a>' : "") + "</div>" + '<div class="city-select-content">' + '<div class="city-select province" data-count="province"></div>' + (this.includeDem("city") ? '<div class="city-select city" data-count="city"></div>' : "") + (this.includeDem("district") ? '<div class="city-select district" data-count="district"></div>' : "") + "</div></div>";
|
dropdown = '<div class="city-picker-dropdown" style="left:0px;top:100%;' + this.getWidthStyle(p.width, true) + '">' + '<div class="city-select-wrap">' + '<div class="city-select-tab">' + '<a class="active" data-count="province">省份</a>' + (this.includeDem("city") ? '<a data-count="city">城市</a>' : "") + (this.includeDem("district") ? '<a data-count="district">区县</a>' : "") + "</div>" + '<div class="city-select-content">' + '<div class="city-select province" data-count="province"></div>' + (this.includeDem("city") ? '<div class="city-select city" data-count="city"></div>' : "") + (this.includeDem("district") ? '<div class="city-select district" data-count="district"></div>' : "") + "</div></div>";
|
||||||
this.$element.addClass("city-picker-input");
|
this.$element.addClass("city-picker-input");
|
||||||
this.$textspan = $(textspan).insertAfter(this.$element);
|
this.$textspan = $(textspan).insertAfter(this.$element);
|
||||||
|
|
@ -161,16 +161,13 @@
|
||||||
this.close(true)
|
this.close(true)
|
||||||
}
|
}
|
||||||
}, this));
|
}, this));
|
||||||
|
|
||||||
this.$textspan.on("click", function (e) {
|
this.$textspan.on("click", function (e) {
|
||||||
var $target = $(e.target), type;
|
var $target = $(e.target), type;
|
||||||
$this.needBlur = false;
|
$this.needBlur = false;
|
||||||
if ($target.is(".select-item")) {
|
if ($target.is(".select-item")) {
|
||||||
type = $target.data("count");
|
type = $target.data("count");
|
||||||
$this.open(type)
|
$this.open(type)
|
||||||
} else if($target.is(".close")){
|
} else {
|
||||||
$this.reset()
|
|
||||||
}else {
|
|
||||||
if ($this.$dropdown.is(":visible")) {
|
if ($this.$dropdown.is(":visible")) {
|
||||||
$this.close()
|
$this.close()
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -369,7 +366,7 @@
|
||||||
$tab.addClass("active")
|
$tab.addClass("active")
|
||||||
}
|
}
|
||||||
}, reset: function () {
|
}, reset: function () {
|
||||||
this.$element.val(null).trigger("change").trigger("cp:updated")
|
this.$element.val(null).trigger("change")
|
||||||
}, destroy: function () {
|
}, destroy: function () {
|
||||||
this.unbind();
|
this.unbind();
|
||||||
this.$element.removeData(NAMESPACE).removeClass("city-picker-input");
|
this.$element.removeData(NAMESPACE).removeClass("city-picker-input");
|
||||||
|
|
|
||||||
34
sql/sync.sh
34
sql/sync.sh
|
|
@ -1,34 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# 配置参数
|
|
||||||
HOST="rm-bp1769w7k3om452lvzo.mysql.rds.aliyuncs.com"
|
|
||||||
USER="wanyu"
|
|
||||||
SOURCE_DB="wanyu"
|
|
||||||
TARGET_DB="wanyu_test"
|
|
||||||
|
|
||||||
# 输入密码(不回显)
|
|
||||||
read -s -p "请输入数据库用户 $USER 的密码: " DBPASS
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
# 检查目标库是否存在,不存在就创建
|
|
||||||
echo "🧩 检查目标数据库 $TARGET_DB 是否存在..."
|
|
||||||
mysql -h $HOST -u $USER -p"$DBPASS" -e "CREATE DATABASE IF NOT EXISTS \`$TARGET_DB\` CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;" || {
|
|
||||||
echo "❌ 无法连接或创建目标数据库 $TARGET_DB"
|
|
||||||
exit 1
|
|
||||||
}
|
|
||||||
|
|
||||||
# 开始导出并导入
|
|
||||||
echo "📦 正在从 $SOURCE_DB 导出并导入到 $TARGET_DB,请稍候..."
|
|
||||||
|
|
||||||
mysqldump -h $HOST -u $USER -p"$DBPASS" \
|
|
||||||
--single-transaction \
|
|
||||||
--set-gtid-purged=OFF \
|
|
||||||
--routines --triggers --events \
|
|
||||||
"$SOURCE_DB" | mysql -h $HOST -u $USER -p"$DBPASS" "$TARGET_DB"
|
|
||||||
|
|
||||||
# 检查导入结果
|
|
||||||
if [ $? -eq 0 ]; then
|
|
||||||
echo "✅ 数据库复制完成:$SOURCE_DB → $TARGET_DB"
|
|
||||||
else
|
|
||||||
echo "❌ 数据库复制失败,请检查日志或权限设置"
|
|
||||||
fi
|
|
||||||
Loading…
Reference in New Issue
Block a user