gdoo/app/Gdoo/Model/Form.php

2866 lines
109 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace Gdoo\Model;
use XMLReader;
use DB;
use Request;
use Validator;
use URL;
use View;
use Auth;
use App\Support\AES;
use App\Support\Hook;
use App\Support\License;
use Gdoo\Model\Models\Bill;
use Gdoo\Model\Models\Model;
use Gdoo\Model\Models\Field;
use Gdoo\Model\Models\Permission;
use Gdoo\Model\Models\Template;
use Gdoo\Model\Models\Step;
use Gdoo\Model\Models\StepLog;
use Gdoo\Index\Models\Attachment;
use Gdoo\Index\Models\Access;
use Gdoo\Index\Services\AttachmentService;
use Gdoo\User\Models\User;
use Gdoo\User\Models\UserAsset;
use Gdoo\Model\Models\Run;
use Gdoo\Model\Models\RunStep;
use Gdoo\Model\Models\RunLog;
use Gdoo\Model\Services\FieldService;
use Gdoo\Model\Services\ModuleService;
use Gdoo\Index\Services\NotificationService;
use Gdoo\Model\Services\StepService;
use Gdoo\User\Services\UserAssetService;
use Gdoo\User\Services\UserService;
use Illuminate\Support\Arr;
class Form
{
/**
* 关联字段处理
*/
public static function fieldRelated($table, &$field, &$join, &$select, &$links)
{
if ($field['data_type']) {
$data_type = $field['data_type'];
$data_field = $field['data_field'];
$data_link = $field['data_link'];
$_table = $data_link.'_'.$data_type;
if ($field['type']) {
$join[$_table] = [$data_type.' as '.$_table, $_table.'.id', '=', $table.'.'.$data_link, $table, 1];
}
$links[$data_link][$data_link] = 'id';
if ($field['field'] == $data_link) {
$column = $field['field'].'_'.$data_field;
} else {
$column = $field['field'];
}
$field_count = mb_substr_count($data_field, ':');
if ($field_count > 0) {
$var1 = explode(':', $data_field);
list($_v1, $_v2) = explode('.', $var1[0]);
list($_t1, $_t2) = explode('.', $var1[1]);
if ($field['type']) {
$_table = $data_link.'_'.$_t1;
} else {
$_table = $field['field'].'_'.$_t1;
}
$join[$_table] = [$_t1.' as '.$_table, $_table.'.id', '=', $data_link.'_'.$data_type.'.'.$_v2, $data_link.'_'.$data_type, 1];
$index = $_table.'.'.$_t2;
if ($field['field'] == $data_link) {
$column = $field['field'].'_'.$_v1;
// 这里本地字段和右表字段一样时,直接取右表名称
$links[$data_link][$column] = $_v1;
} else {
// $_v2 右表关联字段,$_t2 右表映射字段
if ($field['type']) {
$links[$data_link][$column] = $_v2;
// 右表 id_name
$links[$data_link][$column.'_'.$_t2] = $_v2.'_'.$_t2;
$field['dest_column'] = $column.'_'.$_t2;
$column = $column.'_'.$_t2;
} else {
$links[$data_link][$column] = $_v2.'_'.$_t2;
}
}
} else {
if ($field['type']) {
if ($field['field'] == $data_link) {
$index = $data_link.'_'.$data_type.'.'.$data_field;
} else {
$index = $table.'.'.$field['field'];
}
} else {
$index = $data_link.'_'.$data_type.'.'.$data_field;
}
$links[$data_link][$column] = $data_field;
}
$field['_column'] = $column;
$select[] = $index. ' as '.$column;
}
}
public static function make($options)
{
$assets = UserAssetService::getNowRoleAssets();
// 权限查询类型
$code = $options['code'];
$bill = Bill::where('code', $code)->first();
// 表数据
$flow = DB::table('model')
->where('id', $bill['model_id'])
->first();
// 主表字段
$fields = DB::table('model_field')
->where('model_id', $bill['model_id'])
->orderBy('sort', 'asc')
->get()->keyBy('field');
$table = $flow['table'];
// 查询主表数据
$join = $select = $links = [];
$select[] = $table.'.*';
foreach($fields as $field) {
static::fieldRelated($table, $field, $join, $select, $links);
}
$join = Grid::sortJoin($join);
$q = DB::table($table)
->where($table.'.id', (int)$options['id']);
foreach($join as $j) {
$q->leftJoin($j[0], $j[1], $j[2], $j[3]);
}
$row = $q->select($select)->first();
$auth = auth()->user();
$action = $options['action'];
if ($action == 'show') {
$tpl = 'show';
$type_sql = '(' . join(' or ', [db_instr('type', $tpl)]) . ')';
} else {
$tpl = $row['id'] > 0 ? 'edit' : 'create';
$type_sql = '(' . join(' or ', [db_instr('type', $tpl)]) . ')';
}
if ($action == 'print') {
$type_sql = '(' . join(' or ', [db_instr('type', 'print')]) . ')';
}
$key = AES::encrypt($bill['id'].'.'.(int)$row['id'], config('app.key'));
$run_id = 0;
$step_id = 0;
$run_log_id = 0;
$run_step_id = 0;
$recall_log_id = 0;
$recall_btn = $audit_btn = $abort_btn = $read_btn = false;
if ($bill['audit_type'] == 1) {
$run = DB::table('model_run')
->where('bill_id', $bill['id'])
->where('data_id', $row['id'])
->first();
// 流程是新建的
if (empty($run)) {
$step = DB::table('model_step')
->where('bill_id', $bill['id'])
->where('type', 'start')
->first();
$step_id = $step['id'];
} else {
$step = DB::table('model_run_log')
->leftJoin('model_run_step', 'model_run_step.id', '=', 'model_run_log.run_step_id')
->where('model_run_log.run_id', $run['id'])
->where('model_run_log.user_id', $auth['id'])
->where('model_run_log.status', 0)
->orderBy('model_run_log.id', 'asc')
->first([
'model_run_log.*',
'model_run_step.type as step_type',
'model_run_step.step_id',
'model_run_step.permission_id'
]);
$run_id = $run['id'];
$step_id = $step['step_id'];
$run_step_id = $step['run_step_id'];
$run_log_id = $step['id'];
$option = $step['option'];
// 判断是有审核权限
$audit_status = $step['user_id'] == auth()->id();
if ($option == 1) {
$audit_btn = $audit_status;
} else {
$read_btn = $audit_status;
}
}
if ($row['status'] == '0') {
$audit_btn = 1;
}
if ($row['status'] == '1') {
$abort_btn = 1;
}
// 获取表单操作权限
$_permission = DB::table('model_permission')
->permission('receive_id')
->where('id', $step['permission_id'])
->first();
// 获取最后已转交节点
$passed = DB::table('model_run_log')
->where('run_id', $run['id'])
->where('user_id', $auth['id'])
->where('status', '>', 0)
->orderBy('id', 'desc')
->first();
if ($passed) {
$recall_log_id = $passed['id'];
$nodes = DB::table('model_run_log')
->where('parent_id', $passed['id'])
->get();
$node_count = $nodes->count();
$todo_count = $nodes->where('status', 0)->count();
// 全部未办理才能撤回
if ($node_count > 0) {
if ($node_count == $todo_count) {
$recall_btn = true;
}
}
}
/*
if ($audit_btn == true && $run_id > 0) {
// 更新待办接收时间
if ($step['received_id'] == 0) {
DB::table('model_run_log')->where('id', $step['id'])->update([
'updated_id' => 0,
'updated_by' => '',
'updated_at' => 0,
'received_id' => $auth['id'],
'received_by' => $auth['name'],
'received_at' => time(),
]);
}
}
*/
} else {
$_permission = DB::table('model_permission')
->permission('receive_id')
->whereRaw($type_sql)
->where('bill_id', $bill['id'])
->first();
}
$permission = json_decode($_permission['data'], true);
$model = DB::table('model_template')
->permission('receive_id', null, false, false)
->whereRaw($type_sql)
->where('bill_id', $bill['id']);
if ($options['template_id'] > 0) {
$model->where('id', $options['template_id']);
}
$template = $model->first();
if (empty($template)) {
$model = DB::table('model_template')
->where('receive_id', 'all')
->whereRaw($type_sql)
->where('bill_id', $bill['id']);
if ($options['template_id'] > 0) {
$model->where('id', $options['template_id']);
}
$template = $model->first();
}
$prints_btn = '';
if (isset($assets['print']) && $row['id'] > 0) {
// 获取打印模板
$prints = DB::table('model_template')
->permission('receive_id')
->where('type', 'print')
->where('bill_id', $bill['id'])
->orderBy('sort', 'asc')
->get();
if ($prints) {
$prints_btn .= '<div class="btn-group" role="group">
<button type="button" class="btn btn-sm btn-default dropdown-toggle" data-toggle="dropdown">
<span class="fa fa-print"></span> 打印
<span class="caret"></span>
</button>
<ul class="dropdown-menu" role="menu">';
foreach($prints as $print) {
$prints_btn .= '<li><a href="'.url('print', ['id' => $row['id'], 'template_id' => $print['id']]).'" target="_blank"> '.$print['name'].'</a></li>';
}
$prints_btn .= '</ul></div> ';
}
}
$views = json_decode($template['tpl'], true);
$js = '<script type="text/javascript">formGridList.' . $flow['table'] . ' = [];';
$js .= '$(function() {';
$html = '';
$sublist_status = false;
$tabs = [];
$_master_data = Hook::fire($table . '.onBeforeForm', ['options' => $options, 'permission' => $permission, 'model' => $flow, 'fields' => $fields, 'views' => $views, 'row' => $row]);
extract($_master_data);
$tpls = [];
$sublist = [];
$print_row = [];
foreach ($views as $group) {
$_replace = [];
$tpl = '';
$_sub_view = [];
$col = 0;
if ($group['border'] == '') {
$group['border'] = 1;
}
foreach ($group['fields'] as $view) {
if ($view['role_id']) {
$role_ids = explode(',', $view['role_id']);
if (in_array($auth->role_id, $role_ids)) {
continue;
}
}
// 显示流程记录
if ($view['field'] == '{flowlog}') {
if ($action == 'print') {
$tpl = StepService::getFlowLogTpl($run_id, $row, $flow, $tpl);
} else {
$flowlog = StepService::getFlowLogTpl($run_id, $row, $flow, $flowlog);
}
continue;
}
// 处理流程意见字段
list($view_type, $view_step_id) = explode('.', $view['field']);
if ($view_type == 'flow_step') {
$view_step = StepService::getFlowField($run_id, $row, $flow, $steps, $step, $view, $view_step_id, $action, $permission);
if ($view_step) {
$view['title'] = $steps[$view_step_id]['name'].'意见';
$_replace['{' . $view['field'] . '}'] = $view_step;
} else {
continue;
}
}
$field = $fields[$view['field']];
// 是多行子表
if ($view['type'] == 0) {
if ($view['hidden']) {
$tpl .= '<div style="display:none;">{' . $view['field'] . '}</div>';
} else {
if ($col == 0) {
if ($action == 'print') {
$tpl .= '<div class="row '.($group['border'] == 0 ? 'no-border' : '').'">';
} else {
$tpl .= $action == 'show' ? '<div class="row">' : '<div class="form-group">';
}
}
// 补全错位
if ($col > 0 && $view['col'] == 12) {
$line = 12 - $col;
if ($action == 'print') {
$tpl .= '</div><div class="row">';
} else {
$tpl .= '<div class="col-xs-8 col-sm-' . ($line) . ' control-text"></div>';
$tpl .= ($action == 'show' || $action == 'print') ? '</div><div class="row">' : '</div><div class="form-group">';
}
$col = 0;
}
if ($col + $view['col'] > 12) {
$line = $col + $view['col'] - 12;
if ($action == 'print') {
$tpl .= '</div><div class="row '.($group['border'] == 0 ? 'no-border' : '').'">';
} else {
$tpl .= '<div class="col-xs-8 col-sm-' . ($line) . ' control-text"></div>';
$tpl .= ($action == 'show' || $action == 'print') ? '</div><div class="row">' : '</div><div class="form-group">';
}
$col = 0;
}
$col += $view['col'];
$field['name'] = empty($view['title']) ? $field['name'] : $view['title'];
$label = '{' . $field['name'] . '}';
if ($view['hide_title'] == 1) {
$label = '';
}
if ($view['type'] == 1) {
$right_col = $view['col'];
} else {
$right_col = $view['col'] - 1;
}
if ($action == 'print') {
$right_col += 1;
} else {
if ($label) {
$tpl .= '<div class="col-xs-4 col-sm-1 control-label">' . $label . '</div>';
} else {
$right_col += 1;
}
}
if ($action == 'print') {
if ($view['custom'] == 1) {
$tpl .= '<div id="'.$view['field'].'" class="col-sm-' . $right_col . ' control-text">' . ($label == '' ? '' : $label . ': ') . $view['content'] . '</div>';
} else {
$tpl .= '<div id="'.$view['field'].'" class="col-sm-' . $right_col . ' control-text">' . ($label == '' ? '' : $label . ': ').'{' . $view['field'] . '}</div>';
}
} else {
if ($view['custom'] == 1) {
$tpl .= '<div id="'.$view['field'].'" class="col-xs-8 col-sm-' . $right_col . ' control-text" '.($action == 'show' ? '' : 'style="padding-top:10px;"' ).'>' . $view['content'] . '</div>';
} else {
$tpl .= '<div id="'.$view['field'].'" class="col-xs-8 col-sm-' . $right_col . ' control-text">{' . $view['field'] . '}</div>';
}
}
if ($col == 12) {
$col = 0;
$tpl .= '</div>';
}
}
$field['model'] = $flow;
$attribute = [];
$permission_table = $permission[$flow['table']];
$p = $permission_table[$field['field']];
$field['is_print'] = $action == 'print';
$field['is_write'] = $p['w'] == 1 ? 1 : 0;
$field['is_read'] = $p['w'] == 1 ? 0 : 1;
$field['is_auto'] = $p['m'] == 1 ? 1 : 0;
$field['is_hide'] = $p['s'] == 1 ? 1 : $field['is_hide'];
if ($action == 'show' || $action == 'print') {
$field['is_show'] = 1;
$field['is_write'] = 0;
}
$validate = (array) $p['v'];
if ($action == 'print') {
} else {
$required = '';
if (in_array('required', $validate)) {
$required = '<span class="red">*</span> ';
if ($field['is_write']) {
$attribute['required'] = 'required';
if ($field['is_auto'] == 0) {
$attribute['class'][] = 'input-required';
} else {
$attribute['class'][] = 'input-auto';
}
}
}
}
$field['verify'] = $validate;
$field['attribute'] = $attribute;
$field['table'] = $table;
$tooltip = $field['tips'] ? ' <a class="hinted" href="javascript:;" title="' . $field['tips'] . '"><i class="fa fa-question-circle"></i></a>' : '';
if ($action == 'show' || $action == 'print') {
$tooltip = '';
$required = '';
}
$_replace['{' . $field['name'] . '}'] = $required . $field['name'] . $tooltip;
$data_type = $field['data_type'];
$data_field = $field['data_field'];
$data_link = $field['data_link'];
if ($data_type) {
$related = [];
if (strpos($data_field, ':')) {
list($var1, $var2) = explode(':', $data_field);
list($_v1, $_v2) = explode('.', $var1);
list($_t1, $_t2) = explode('.', $var2);
if ($field['type']) {
$related['table'] = $table;
$related['field'] = $field['field'];
} else {
$related['table'] = $_t1;
$related['field'] = $_v2;
}
} else {
if ($field['type']) {
$related['table'] = $table;
$related['field'] = $field['field'];
} else {
$related['table'] = $data_type;
$related['field'] = $data_field;
}
}
$field['related'] = $related;
}
$value = $row[$field['field']];
if ($field['form_type']) {
$field['view'] = $view;
$field['bill'] = $bill->toArray();
$vv = FieldService::{'content_' . $field['form_type']}($field, $value, $row, $permission_table);
$print_row[$field['field']] = $vv;
$_replace['{'.$field['field'].'}'] = $vv;
}
} else {
$sublist[] = $view;
$_sub_view = $view;
}
}
$_field_data = Hook::fire($table.'.onFormFieldFilter', ['table' => $table, 'tpl' => $tpl, 'master' => $master, 'field' => $field, '_replace' => $_replace]);
extract($_field_data);
$tpls[] = ['title' => $group['title'], 'tpl' => strtr($tpl, $_replace)];
// 插入子表位置
if ($action == 'print') {
if ($_sub_view) {
$tpls[] = ['title' => '', 'table' => 1, 'tpl' => '{'.$_sub_view['field'].'}'];
}
} else {
if ($sublist && $sublist_status == false) {
$tpls[] = ['title' => '', 'tpl' => '{__sublist__}'];
$sublist_status = true;
}
}
}
$tabs = static::sublist(['select' => $options['select'], 'sublist' => $sublist, 'permission' => $permission, 'action' => $action, 'table' => $table, 'row' => $row, 'bill' => $bill]);
if ($flowlog) {
$tabs[] = [
'tpl' => '<div class="b-a">'.$flowlog.'</div>',
'id' => 'flowlog',
'tool' => '',
'name' => '审核记录',
];
}
if ($action == 'print') {
$prints = [[
'name' => 'master',
'fields' => $fields->toArray(),
'data' => [$print_row],
]];
$_prints['master'] = [$print_row];
$_prints['flowlog'] = $flowlog;
foreach($tpls as $index => $tpl) {
foreach($tabs as $tab) {
if ('{'.$tab['id'].'}' == $tpl['tpl']) {
$tpls[$index]['table'] = true;
$tpls[$index]['tpl'] = $tab['print'];
$prints[] = [
'name' => $tab['id'],
'fields' => $tab['fields'],
'data' => $tab['rows'],
];
$_prints[$tab['id']] = $tab['rows'];
}
}
}
} else {
if ($tabs) {
$_tabs = '
<div class="panel-heading tabs-box">
<ul class="nav nav-tabs">';
foreach($tabs as $tab_index => $tab):
$js .= $tab['js'];
$active = $tab_index == 0 ? 'active' : '';
$_tabs .= '<li class="'.$active.'">
<a data-toggle="tab" class="text-sm" href="#'.$tab['id'].'">'.$tab['name'].'</a>
</li>';
endforeach;
$_tabs .= '</ul>
</div>
<div id="tab-content-'.$table.'" class="tab-content">';
foreach($tabs as $tab_index => $tab):
$active = $tab_index == 0 ? ' in active ' : '';
$tool = $tab['tool'];
if ($tool) {
$tool .= ' <span id="'.$tab['id'].'_tool"></span> ';
}
if (isset($row['id'])) {
$tool .= ' <a href="javascript:;" onclick="flow.exportDataAsExcel(\''.$tab['id'].'\');" class="btn btn-sm btn-default">导出</a> ';
}
// 操作按钮
if (isset($assets['closeRow'])) {
$tool .= ' <a href="javascript:;" onclick="flow.closeRow(\''.$tab['id'].'\');" class="btn btn-sm btn-default">关闭行(恢复)</a> ';
}
if (isset($assets['closeAllRow'])) {
$tool .= ' <a href="javascript:;" onclick="flow.closeAllRow(\''.$tab['id'].'\');" class="btn btn-sm btn-default">关闭所有行(恢复)</a> ';
}
$tool = $tool == '' ? $tool : '<div class="system_btn m-b-sm">'.$tool.'</div>';
// 审核记录不显示工具栏
if ($tab['id'] == 'flowlog') {
$tool = '';
}
$_tabs .= '<div class="tab-pane fade '.$active.'" id="'.$tab['id'].'">
<div class="wrapper-sm">
<div class="grid-tool" id="'.$table.'-tool">
'.$tool.'
</div>
'.$tab['tpl'].'
</div>
</div>';
endforeach;
$_tabs .= '</div>';
}
}
// 重新构建
$_tpls = [];
foreach($tpls as $index => $tpl) {
if ($tpl['tpl']) {
if ($tpl['tpl'] == '{__sublist__}') {
$tpl['tpl'] = $_tabs;
}
$_tpls[] = $tpl;
}
}
$tpls = $_tpls;
$_master_data = Hook::fire($table . '.onAfterForm', ['options' => $options, 'tpls' => $tpls, 'model' => $flow, 'row' => $row]);
extract($_master_data);
$html = '';
$tpls_count = count($tpls) - 1;
$a = 0;
foreach($tpls as $index => $tpl) {
if(empty($tpl['tpl'])) {
continue;
}
$end = ($tpls_count == $index) ? ' m-b-none' : '';
$heading = $tpl['title'] == '' ? '' : '<div class="panel-heading"><i class="fa fa-clone"></i> '.$tpl['title'].'</div>';
if ($action == 'print') {
if ($tpl['table']) {
$html .= '<div id="print_'.$index.'" class="print">'.$tpl['tpl'].'</div>';
$a = 1;
} else {
if ($a == 1) {
$html .= '<div id="print_'.$index.'" class="print">'.$tpl['tpl'].'</div>';
$a = 0;
} else {
$html .= '<div id="print_'.$index.'" class="print">'.$tpl['tpl'].'</div>';
}
}
} else {
$html .= '<div class="panel no-border'.$end.'">'.$heading.''.$tpl['tpl'].'</div>';
}
}
if ($action == 'print') {
} else {
if ($row['id']) {
$html .= '<input type="hidden" name="' . $table . '[id]" id="' . $table . '_id" value="' . $row['id'] . '">';
}
// 子表关联逻辑
foreach($tabs as $tab) {
$html .= $tab['buttons'];
}
$html .= '<input type="hidden" name="_token" value="' . csrf_token() . '">';
$html .= '<input type="hidden" name="master[key]" id="master_key" value="'.$key.'">';
$html .= '<input type="hidden" name="master[uri]" id="master_uri" value="' . Request::module() . '/' . Request::controller() . '">';
$html .= '<input type="hidden" name="master[permission_id]" value="' . $_permission['id'] . '">';
$html .= '<input type="hidden" name="master[model_id]" value="' . $flow['id'] . '">';
$html .= '<input type="hidden" name="master[bill_id]" value="' . $bill['id'] . '">';
$html .= '<input type="hidden" name="master[created_id]" value="' . $row['created_id'] . '">';
$html .= '<input type="hidden" name="master[id]" value="' . $row['id'] . '">';
if (!is_weixin()) {
$page = static::getPage([
'table' => $table,
'id' => $row['id'],
'region' => $options['region'],
'authorise' => $options['authorise'],
]);
$btn = '<div class="btn-group hidden-xs"><a class="btn btn-sm btn-default" href="'.url('show', ['id' => $page['start']]).'">首张</a> ';
if ($row['id'] > 0) {
if ($page['prev'] > 0) {
$btn .= '<a class="btn btn-sm btn-default" href="'.url('show', ['id' => $page['prev']]).'">上一张</a> ';
} else {
$btn .= '<a class="btn btn-sm btn-default disabled" href="javascript:;">上一张</a> ';
}
if ($page['next'] > 0) {
$btn .= '<a class="btn btn-sm btn-default" href="'.url('show', ['id' => $page['next']]).'">下一张</a> ';
} else {
$btn .= '<a class="btn btn-sm btn-default disabled" href="javascript:;">下一张</a> ';
}
}
$btn .= '<a class="btn btn-sm btn-default" href="'.url('show', ['id' => $page['end']]).'">末张</a> ';
$btn .= ' <a class="btn btn-sm btn-default" href="javascript:location.reload();">刷新</a> ';
$btn .= '</div> ';
}
// 流程审核
if ($bill['audit_type'] == 1) {
$html .= '<input type="hidden" name="master[run_id]" id="master_run_id" value="' . $run_id . '">';
$html .= '<input type="hidden" name="master[step_id]" id="master_step_id" value="' . $step_id . '">';
$html .= '<input type="hidden" name="master[run_step_id]" id="master_run_step_id" value="' . $run_step_id . '">';
$html .= '<input type="hidden" name="master[run_log_id]" id="master_run_log_id" value="' . $run_log_id . '">';
$html .= '<input type="hidden" name="master[recall_log_id]" id="master_recall_log_id" value="' . $recall_log_id . '">';
if (isset($assets['create'])) {
$btn .= ' <a class="btn btn-sm btn-default" href="'.url('create').'">添加</a> ';
}
// 流程单据删除
if (isset($assets['delete']) && $row['id'] > 0) {
// 已经审核的单据不能删除
if ($row['status'] <= 0) {
$btn .= '<a class="btn btn-sm btn-default" href="javascript:;" onclick="flow.remove(\''.url('delete', ['id' => $row['id']]).'\');"><i class="fa fa-times"></i> 删除</a> ';
} else {
$btn .= '<a class="btn btn-sm btn-default disabled"><i class="fa fa-times"></i> 删除</a> ';
}
}
$op_btn = '';
if (isset($assets['abort']) && $abort_btn == true) {
$op_btn .= '<a class="btn btn-sm btn-default" href="javascript:;" onclick="flow.abort(\''.$table.'\');"><i class="fa fa-ban"></i> 弃审</a> ';
}
if (isset($assets['recall']) && $recall_btn == true) {
$op_btn .= '<a class="btn btn-sm btn-default" href="javascript:;" onclick="flow.recall(\''.$table.'\');"><i class="fa fa-reply"></i> 撤回</a> ';
}
if ($action == 'show') {
if (isset($assets['audit']) && $audit_btn == true) {
$btn .= '<a class="btn btn-sm btn-default" href="'.url('audit', ['id' => $row['id']]).'"><i class="fa fa-pencil"></i> 修改</a> ';
if (intval($bill['form_type']) == 0) {
if (intval($row['status']) == 0) {
$btn .= '<a class="btn btn-sm btn-default" href="javascript:;" onclick="flow.audit(\''.$table.'\');"><i class="fa fa-check"></i> 提交</a> ';
} else {
$btn .= '<a class="btn btn-sm btn-default" href="javascript:;" onclick="flow.audit(\''.$table.'\');"><i class="fa fa-check"></i> 审核</a> ';
}
}
}
if ($read_btn == true) {
$op_btn .= '<a class="btn btn-sm btn-default" href="javascript:;" onclick="flow.read(\''.$table.'\', \''.$run_log_id.'\');"><i class="fa fa-eye"></i> 已阅</a> ';
}
} else {
$btn .= '<a class="btn btn-sm btn-default" href="javascript:;" onclick="flow.draft(\''.$table.'\');"><i class="icon icon-coffee-cup"></i> 保存</a> ';
if (isset($assets['audit']) && $audit_btn == true && intval($bill['form_type']) == 1) {
if (intval($row['status']) == 0) {
$btn .= '<a class="btn btn-sm btn-default" href="javascript:;" onclick="flow.audit(\''.$table.'\');"><i class="fa fa-check"></i> 提交</a> ';
} else {
$btn .= '<a class="btn btn-sm btn-default" href="javascript:;" onclick="flow.audit(\''.$table.'\');"><i class="fa fa-check"></i> 审核</a> ';
}
}
}
if ($op_btn) {
$btn .= '<div class="btn-group">'.$op_btn.'</div> ';
}
if ($run_id > 0) {
$btn .= '<a class="btn btn-sm btn-default" href="javascript:;" onclick="flow.auditLog(\''.$key.'\');"><i class="fa fa-file-text-o"></i> 审核记录</a> ';
}
if ($run_id > 0 && $auth['id'] == 1) {
$btn .= '<div class="btn-group" role="group">
<button type="button" class="btn btn-sm btn-default dropdown-toggle" data-toggle="dropdown" aria-expanded="false">
<span class="fa fa-wrench"></span> 工具
<span class="caret"></span>
</button>
<ul class="dropdown-menu" role="menu">
<!--<li><a href="javascript:;" onclick="flow.revise(\''.$key.'\');">流程修正</a></li>-->
<li><a href="javascript:;" onclick="flow.reset(\''.$table.'\');">流程重置</a></li>
</ul>
</div>';
}
// 普通审核
} else if($bill['audit_type'] == 3) {
if ($action == 'show') {
if (isset($assets['create'])) {
$btn .= ' <a class="btn btn-sm btn-default" href="'.url('create').'">添加</a> ';
}
// 审核单据删除
if (isset($assets['delete']) && $row['id'] > 0) {
// 已经审核的单据不能删除
if ($row['status'] == 1) {
$btn .= '<a class="btn btn-sm btn-default disabled"><i class="fa fa-times"></i> 删除</a> ';
} else {
$btn .= '<a class="btn btn-sm btn-default" href="javascript:;" onclick="flow.remove(\''.url('delete', ['id' => $row['id']]).'\');"><i class="fa fa-times"></i> 删除</a> ';
}
}
$btn .= '<div class="btn-group">';
if ($row['status'] == 1) {
if (isset($assets['abort'])) {
$btn .= '<a class="btn btn-sm btn-default" href="javascript:;" onclick="flow.abort2(\''.$table.'\');"><i class="fa fa-ban"></i> 弃审</a> ';
}
} else {
if (isset($assets['audit'])) {
$btn .= '<a class="btn btn-sm btn-default" href="javascript:;" onclick="flow.audit2(\''.$table.'\');"><i class="fa fa-check"></i> 审核</a> ';
}
if (isset($assets['edit'])) {
$btn .= '<a class="btn btn-sm btn-default" href="'.url('edit', ['id' => $row['id']]).'"><i class="fa fa-pencil"></i> 编辑</a> ';
}
}
$btn .= '</div> ';
} else {
$btn .= '<a class="btn btn-sm btn-default" href="javascript:;" onclick="flow.store(\''.$table.'\');"><i class="fa fa-check"></i> 保存</a> ';
}
} else {
if ($action == 'show') {
if (isset($assets['create'])) {
$btn .= ' <a class="btn btn-sm btn-default" href="'.url('create').'">添加</a> ';
}
// 普通单据删除
if (isset($assets['delete']) && $row['id'] > 0) {
$btn .= '<a class="btn btn-sm btn-default" href="javascript:;" onclick="flow.remove(\''.url('delete', ['id' => $row['id']]).'\');"><i class="fa fa-times"></i> 删除</a> ';
}
$btn .= '<div class="btn-group">';
if (isset($assets['edit'])) {
$btn .= '<a class="btn btn-sm btn-default" href="'.url('edit', ['id' => $row['id']]).'"><i class="fa fa-pencil"></i> 修改</a> ';
}
$btn .= '</div> ';
} else {
$btn .= '<a class="btn btn-sm btn-default" href="javascript:;" onclick="flow.store(\''.$table.'\');"><i class="fa fa-check"></i> 保存</a> ';
}
}
if (!is_weixin()) {
$btn .= ' <a class="btn btn-sm btn-default" data-toggle="closetab" data-id="'.Request::module().'_'.Request::controller().'_show"><i class="fa fa-sign-out"></i> 退出</a> ';
}
if (isset($assets['print']) && $row['id'] > 0 && $prints_btn) {
$btn .= $prints_btn;
}
if (!is_weixin()) {
$joint = $options['joint'];
if ($joint) {
$btn .= '<div class="btn-group">
<button type="button" class="btn btn-default btn-sm dropdown-toggle" data-toggle="dropdown" aria-expanded="false">
联查 <span class="caret"></span>
<span class="sr-only">Toggle Dropdown</span>
</button>
<ul class="dropdown-menu text-xs" role="menu">';
foreach($joint as $v) {
$btn .= '<li><a data-toggle="joint" data-action="'.$v['action'].'" data-id="'.$row[$v['field']].'" href="javascript:;">'.$v['name'].'</a></li>';
}
$btn .= '</ul></div>';
}
}
$js .= '
$.each(select2List, function(k, v) {
select2List[k].el = $("#" + k).select2Field(v.options);
});';
$js .= '});
flow.bill_url = "' . Request::module() . '/' . Request::controller() . '";</script>';
$html .= $js;
}
View::share([
'model_view' => 1,
]);
return [
'table' => $table,
'model_id' => $flow['id'],
'run_id' => $run_id,
'row' => $row,
'action' => $action,
'actions' => $permission['actions'],
'permission' => $permission,
'btn' => $btn,
'key' => $key,
'tpl' => $html,
'tabs' => $tabs,
'access' => $assets,
'template' => $template,
'prints' => $prints,
'print_data' => $_prints,
'print_type' => $template['print_type'],
'width' => $template['width'],
'bill_code' => $options['code'],
];
}
/**
* 多行子表构建
*/
public static function sublist($options)
{
$sublist = $options['sublist'];
$permission = $options['permission'];
$action = $options['action'];
$table = $options['table'];
$row = $options['row'];
$bill = $options['bill'];
$auth = auth()->user();
$tabs = [];
$buttons = '';
foreach ($sublist as $_view) {
$model = DB::table('model')->where('table', $_view['field'])->first();
$fields = Field::where('model_id', $model['id'])
->orderBy('sort', 'asc')
->get()->toArray();
$fields = array_by($fields, 'field');
$columns = [
['field' => "id", 'hide' => true],
['field' => $model['relation'], 'hide' => true],
['field' => 'bill_id', 'hide' => true],
['field' => 'bill_data_id', 'hide' => true],
];
$permission_table = $permission[$model['table']];
$permission_option = $permission_table['@option'];
$tool = '';
$tool .= '<span style="display:none;"><div id="'.$_view['field'].'_quick_filter_text" class="wrapper-xs"><input placeholder="请输入过滤关键字" class="form-control input-sm"></div></span><a href="javascript:;" onclick="flow.quickFilter(\''.$_view['field'].'\');" class="btn btn-sm btn-default"> <i class="fa fa-filter"></i/> 过滤 </a> ';
if ($action == 'show') {
$permission_option['w'] = false;
} else {
if ($permission_option['w']) {
$tool .= ' <a href="javascript:;" onclick="flow.createRow(\''.$_view['field'].'\');" class="btn btn-sm btn-default">新增</a> ';
}
if ($permission_option['d']) {
$tool .= ' <a href="javascript:;" onclick="flow.deleteRow(\''.$_view['field'].'\');" class="btn btn-sm btn-default">删除</a> ';
}
if ($permission_option['w']) {
$columns[] = [
'suppressSizeToFit' => true,
'headerName' => '',
'cellRenderer' => 'optionCellRenderer',
'width' => 60,
'sortable' => false,
'cellClass' => 'text-center',
'suppressNavigable' => true,
];
}
}
$columns[] = [
'suppressSizeToFit' => true,
'headerName' => '序号',
'type' => 'sn',
'width' => 60,
'sortable' => false,
'cellClass' => 'text-center',
'suppressNavigable' => true,
];
// 查询子表数据
$q = DB::table($model['table'])->where($model['table'].'.'.$model['relation'], $row['id']);
$views = $_view['fields'];
$_data = Hook::fire($model['table'] . '.onBeforeForm', ['q' => $q, 'model' => $model, 'fields' => $fields, 'views' => $views]);
extract($_data);
$join = [];
$select = [$model['table'].'.id', $model['table'].'.'.$model['relation']];
$links = [];
$buttons .= '<input type="hidden" name="models[' . $model['table'] . '][type]" value="' . $model['type'] . '">';
$buttons .= '<input type="hidden" name="models[' . $model['table'] . '][relation]" value="' . $model['relation'] . '">';
$tabContent .= '<table class="table"><tbody>';
$tabContent .= '<tr><td align="center">序号</td>';
$__views = [];
foreach ($views as $view) {
if ($view['role_id']) {
$role_ids = explode(',', $view['role_id']);
if (in_array($auth->role_id, $role_ids)) {
if ($action == 'print') {
continue;
} else {
$view['hidden'] = true;
}
}
}
$field = $fields[$view['field']];
$field['raw_field'] = $field['field'];
if ($field['type']) {
$select[] = $model['table'].'.'.$field['field'];
}
static::fieldRelated($model['table'], $field, $join, $select, $links);
$column = [];
if ($field['data_format']) {
// 数据类型格式化
switch ($field['data_format']) {
case 'number':
case 'money':
list($_, $len) = explode(',', $field['length']);
$len = $len > 0 ? $len : 2;
$column['type'] = 'number';
$column['numberOptions'] = [
'separator' => '.',
'thousands' => ',',
'places' => (int)$len,
'default' => number_format(0, $len),
];
break;
}
} else {
// 数据类型格式化
switch ($field['type']) {
case 'DECIMAL':
list($_, $len) = explode(',', $field['length']);
$column['type'] = 'number';
$column['numberOptions'] = [
'separator' => '.',
'thousands' => ',',
'places' => (int)$len,
'default' => number_format(0, $len),
];
break;
}
}
if (is_string($field['setting'])) {
$setting = json_decode($field['setting'], true);
}
$view['align'] = $setting['align'] ? $setting['align'] : 'left';
$__views[$view['field']] = $view;
if ($setting['align']) {
$column['cellClass'] = 'text-'.$setting['align'];
}
// 行计事件
if ($setting['row_count']) {
$column['calcRow'] = $setting['row_count'];
}
// 列计事件
if ($setting['cell_count']) {
$column['calcFooter'] = $setting['cell_count'];
}
$permission_field = $permission_table[$field['field']];
$validates = $permission_field['v'];
$required = false;
if ($validates) {
$rules = [];
foreach ($validates as $validate) {
// 设置验证规则
$rules[$validate] = 1;
}
// 整形规则格式化
if ($rules['integer']) {
$column['formatter'] = 'integer';
}
// 如果规则有必填和整形设置大于0
if ($rules['required'] && $rules['integer']) {
$rules['minValue'] = 1;
}
$column['rules'] = $rules;
$required = isset($rules['required']) ? true : false;
// $column['headerClass'] .= isset($rules['required']) ? 'cell-required' : '';
// $required = isset($rules['required']) ? '<span class="red">*</span> ' : '';
}
if ($action == 'show') {
$required = false;
$rules = [];
}
if ($required) {
$column['headerClass'] = 'cell-required';
}
$column['headerName'] = $field['name'];
if($field['is_sort'] == 1) {
$column['sortable'] = true;
}
if ($field['form_type'] == 'label') {
$column['_editable'] = false;
} else {
$column['_editable'] = $permission_field['w'] == 1 ? true : false;
}
if ($action == 'show') {
$column['editable'] = false;
}
if ($column['_editable']) {
$column['suppressNavigable'] = false;
}
// 是否隐藏
$column['hide'] = $permission_field['s'] == 1 ? true : (bool) $view['hidden'];
// 字段宽度
if ($view['width']) {
$column['width'] = $view['width'];
} else {
if ($setting['width']) {
if ($setting['width'] == 'auto') {
$column['minWidth'] = 260;
} else {
$column['width'] = $setting['width'];
}
}
}
$column['width'] = (int)$column['width'];
if ($field['form_type'] == 'date') {
$column['cellEditorParams'] = [
'form_type' => $field['form_type'],
'type' => $setting['type'],
'field' => $field['field'],
];
$column['cellEditor'] = 'dateCellEditor';
}
if ($field['form_type'] == 'checkbox') {
$_checkbox = explode("\n", $setting['content']);
$values = [];
foreach ($_checkbox as $t) {
$n = $v;
list($n, $v) = explode('|', $t);
$v = is_null($v) ? trim($n) : trim($v);
$values[$v] = $n;
}
$column['cellEditorParams'] = [
'values' => $values,
];
$column['cellRenderer'] = 'checkboxCellRenderer';
$column['cellEditor'] = 'checkboxCellEditor';
}
if ($field['form_type'] == 'select') {
$a1 = true;
if ($field['data_type']) {
$query = [];
if ($setting['query']) {
list($k, $v) = explode('=', $setting['query']);
if (strpos($v, '$') === 0) {
$v = substr($v, 1);
$query[$k] = $row[$v];
} else {
$query[$k] = explode(',', $v);
}
}
$_model = DB::table($field['data_type'])->where('status', 1);
foreach ($query as $k => $v) {
if (is_array($v)) {
$_model->whereIn($k, $v);
} else {
$_model->where($k, $v);
}
}
$values = $_model->orderBy('sort', 'asc')->get([$field['data_field'], 'id'])->toArray();
} else {
$_select = explode("\n", $setting['content']);
$values = [];
foreach ($_select as $t) {
$n = $v;
list($n, $v) = explode('|', $t);
if (is_null($v)) {
$a1 = false;
}
$v = is_null($v) ? trim($n) : trim($v);
$values[] = ['id' => $v, 'name' => $n];
}
}
if ($a1 == true) {
$columns[] = ['name' => $field['field'], 'hide' => true];
$field['field'] = $field['field'].'_name';
}
$column['cellEditorParams'] = [
'values' => $values,
'select_key' => $field['raw_field'],
];
$column['cellEditor'] = 'selectCellEditor';
$field['select_values'] = $values;
}
if ($field['form_type'] == 'option') {
$values = option($setting['type']);
$column['cellEditorParams'] = [
'values' => $values,
'select_key' => $field['raw_field'],
];
$column['cellEditor'] = 'selectCellEditor';
$columns[] = ['field' => $field['field'], 'hide' => true];
$field['field'] = $field['_column'];
}
if ($field['form_type'] == 'dialog') {
if ($field['data_type']) {
$type = $field['data_type'];
} else {
$type = $setting['type'];
}
$dialog = ModuleService::dialogs($type);
if ($field['_column']) {
$columns[] = ['name' => $field['field'], 'hide' => true];
$field['field'] = $field['_column'];
}
// 没有关联字段时显示自己
$data_link = $field['data_link'] == '' ? $field['field'] : $field['data_link'];
$query = [
'form_id' => $model['table'],
'id' => $data_link,
'name' => $field['field'],
];
if ($setting['query']) {
list($k, $v) = explode('=', $setting['query']);
if (strpos($v, '$') === 0) {
$v = substr($v, 1);
$query[$k] = $row[$v];
} else {
$query[$k] = $v;
}
}
$cellEditorParams = [
'form_type' => $field['form_type'],
'title' => $dialog['name'],
'type' => $setting['type'],
'field' => $field['field'],
'url' => $dialog['url'],
'query' => $query,
];
$column['cellEditorParams'] = $cellEditorParams;
$column['cellEditor'] = 'dialogCellEditor';
}
if ($field['form_type'] == 'text') {
if ($field['dest_column']) {
$columns[] = ['name' => $field['field'], 'hide' => true];
$field['field'] = $field['dest_column'];
}
}
if ($view['hidden'] == 0) {
$tabContent .= '<td align="center">'.$view['name'].'</td>';
}
$field['setting'] = $setting;
$column['field'] = $field['field'];
$fields[$field['raw_field']] = $field;
$columns[] = $column;
}
$tabContent .= '</tr>';
foreach($join as $j) {
$q->leftJoin($j[0], $j[1], $j[2], $j[3]);
}
$_data = Hook::fire($model['table'] . '.onQueryForm', ['q' => $q, 'model' => $model, 'fields' => $fields, 'views' => $views]);
extract($_data);
$q->select($select);
if ($options['select']) {
$q->addSelect(DB::raw($options['select']));
}
// 子表查询
$rows = $q->get();
$rows->transform(function($row) use ($fields) {
foreach($fields as $column) {
$field = $column['field'];
$raw_field = $column['raw_field'];
$value = $row[$field];
$raw_value = $row[$raw_field];
if ($column['form_type'] == 'text') {
if ($column['type'] == 'DECIMAL') {
$value = floatval($value) == '0' ? '' : $value;
}
if ($column['type'] == 'INT' || $column['type'] == 'TINYINT') {
$value = floatval($value) == '0' ? '' : $value;
}
}
if ($column['type'] == 'DATE') {
$value = $value == '1900-01-01' ? '' : $value;
}
if ($column['form_type'] == 'select') {
if ($column['select_values']) {
foreach($column['select_values'] as $_values) {
if ($raw_value == $_values['id']) {
$value = $_values['name'];
}
}
}
}
$row[$field] = $value;
}
return $row;
});
$_data = Hook::fire($model['table'] . '.onAfterForm', ['rows' => $rows, 'gets' => $gets, 'fields' => $fields, 'id' => $id]);
extract($_data);
if ($action == 'print') {
// 打印渲染
$footers = [];
$_rows = [];
foreach ($rows as $i => $_row) {
$tabContent .= '<tr><td align="center">'.($i + 1).'</td>';
foreach ($__views as $k => $v) {
if ($v['hidden'] == 0) {
$field = $fields[$k];
$setting = $field['setting'];
if ($setting['cell_count'] == 'sum') {
$footers[$k] += (float)$_row[$field['field']];
}
$field['is_show'] = 1;
$field['is_print'] = 1;
$field['is_sub'] = 1;
$vv = FieldService::{'content_'.$field['form_type']}($field, $_row[$field['raw_field']], $_row);
$_rows[$i][$field['field']] = $vv;
$tabContent .= '<td align="'.$v['align'].'">'.$vv.'</td>';
}
}
$tabContent .= '</tr>';
}
if (count($footers) > 0) {
$tabContent .= '<tr><td align="center">合计</td>';
foreach ($__views as $k => $v) {
if ($v['hidden'] == 0) {
$field = $fields[$k];
$value = $footers[$k];
if (isset($value)) {
if ($field['form_type'] == 'text') {
if ($field['type'] == 'DECIMAL') {
list($_, $len) = explode(',', $field['length']);
$value = number_format($value, $len > 0 ? $len : 2);
}
if ($column['type'] == 'INT' || $column['type'] == 'TINYINT') {
$value = number_format($value);
}
}
$tabContent .= '<td align="'.$v['align'].'">'.$value.'</td>';
} else {
$tabContent .= '<td></td>';
}
}
}
$tabContent .= '</tr>';
}
$tabContent .= '</tbody></table>';
}
// 保存时数据不能为空
$saveDataNotEmpty = in_array('required', (array)$permission_option['v']);
$_options = [
'columns' => $columns,
'data' => $rows,
'links' => $links,
'table' => $model['table'],
'title' => $model['name'],
'saveDataNotEmpty' => $saveDataNotEmpty,
];
$js = 'gdoo.forms["'.$model['table'].'"] = gridForms("' . $table . '","' . $model['table'] . '", ' . json_encode($_options, JSON_UNESCAPED_UNICODE) . ');';
$tab = '<div id="grid-editor-container" class="form-grid"><div id="grid_' . $model['table'] . '" style="width:100%;" class="ag-theme-balham"></div></div>';
$tabs[] = ['tpl' => $tab, 'tool' => $tool, 'buttons' => $buttons, 'rows' => $_rows, 'fields' => $fields, 'print' => $tabContent, 'id' => $model['table'], 'name' => $model['name'], 'js' => $js];
}
return $tabs;
}
public static function make2($options)
{
$assets = UserAssetService::getNowRoleAssets();
// 权限查询类型
$table = $options['table'];
$row = $options['row'];
$auth = auth()->user();
// 表数据
$flow = DB::table('model')
->where('table', $table)
->first();
$fields = DB::table('model_field')
->where('model_id', $flow['id'])
->orderBy('sort', 'asc')
->get()->keyBy('field');
$file = $options['file'];
$views = $options['views'];
$js = '<script type="text/javascript">formGridList.' . $flow['table'] . ' = [];';
$js .= '$(function() {';
$html = '';
$col = 0;
$sublist_status = false;
$tabs = [];
$permission = [];
$_master_data = Hook::fire($table . '.onBeforeForm', ['options' => $options, 'permission' => $permission, 'model' => $flow, 'fields' => $fields, 'views' => $views, 'row' => $row]);
extract($_master_data);
$tpls = [];
$sublist = [];
$tpl = '';
libxml_disable_entity_loader(false);
$xml = new XMLReader();
$xml->open($options['file']);
while ($xml->read()) {
$depth = $xml->depth;
if ($xml->nodeType == XMLReader::ELEMENT) {
$nodeName = $xml->name;
$attr = [];
$attrs = [];
if ($xml->hasAttributes) {
while($xml->moveToNextAttribute()) {
$attr[$xml->name] = $xml->value;
$attrs[] = $xml->name.'="'.$xml->value.'"';
}
}
switch($nodeName) {
case 'style':
$tpl .= '<style type="text/css">';
break;
case 'script':
$tpl .= '<script type="text/javascript">';
break;
case 'form':
$tpl .= '<form '.join(' ', $attrs).'>';
break;
case 'div':
$tpl .= '<div '.join(' ', $attrs).'>';
break;
case 'group':
$tpl .= '<div class="form-group">';
break;
case 'field':
$field = $fields[$attr['name']];
$input = static::getField($flow, $table, $action, $row, $attr, $field);
if ($attr['hidden'] == 1) {
$tpl .= $input;
} else {
if ($attr['label']) {
$col = $attr['col_type'].'-'.$attr['col_label'];
$tpl .= '<div class="col-'.$col.' control-label">' . $field['name'] . '</div>';
}
$col = $attr['col_type'].'-'.$attr['col_name'];
$tpl .= '<div class="col-'.$col.' control-text">' . $input . '</div>';
}
break;
}
}
if ($xml->nodeType == XMLReader::TEXT) {
$tpl .= $xml->value;
}
if ($xml->nodeType == XMLReader::END_ELEMENT)
{
$nodeName = $xml->name;
switch($nodeName) {
case 'group':
case 'div':
$tpl .= '</div>';
break;
case 'form':
$tpl .= '</form>';
break;
case 'style':
$tpl .= '</style>';
break;
case 'script':
$tpl .= '</script>';
break;
}
}
}
return $tpl;
}
public static function getField($flow, $table, $action, $row, $attr, $field) {
$field['model'] = $flow;
$attribute = [];
if ($action == 'show') {
$field['is_show'] = true;
}
$p = [];
$p['w'] = $attr['read'] == 1 ? 0 : 1;
$p['s'] = $attr['hidden'] == 1 ? 1 : 0;
$field['is_print'] = $action == 'print';
$field['is_write'] = $p['w'] == 1 ? 1 : 0;
$field['is_read'] = $p['w'] == 1 ? 0 : 1;
$field['is_auto'] = $p['m'] == 1 ? 1 : 0;
$field['is_hide'] = $p['s'] == 1 ? 1 : $field['is_hide'];
$validate = (array) $p['v'];
if ($action == 'print') {
$field['is_show'] = true;
}
if ($action == 'print') {
} else {
$required = '';
if (in_array('required', $validate)) {
$required = '<span class="red">*</span> ';
if ($field['is_write']) {
$attribute['required'] = 'required';
if ($field['is_auto'] == 0) {
$attribute['class'][] = 'input-required';
} else {
$attribute['class'][] = 'input-auto';
}
}
}
}
$field['verify'] = $validate;
$field['attribute'] = $attribute;
$field['table'] = $table;
$tooltip = $field['tips'] ? ' <a class="hinted" href="javascript:;" title="' . $field['tips'] . '"><i class="fa fa-question-circle"></i></a>' : '';
if ($action == 'show' || $action == 'print') {
$tooltip = '';
$required = '';
}
$_replace['{' . $field['name'] . '}'] = $required . $field['name'] . $tooltip;
$data_type = $field['data_type'];
$data_field = $field['data_field'];
$data_link = $field['data_link'];
if ($data_type) {
$related = [];
if (strpos($data_field, ':')) {
list($var1, $var2) = explode(':', $data_field);
list($_v1, $_v2) = explode('.', $var1);
list($_t1, $_t2) = explode('.', $var2);
if ($field['type']) {
$related['table'] = $table;
$related['field'] = $field['field'];
} else {
$related['table'] = $_t1;
$related['field'] = $_v2;
}
} else {
if ($field['type']) {
$related['table'] = $table;
$related['field'] = $field['field'];
} else {
$related['table'] = $data_type;
$related['field'] = $data_field;
}
}
$field['related'] = $related;
}
$value = $row[$field['field']];
$field['view'] = $attr;
if ($field['form_type']) {
return FieldService::{'content_' . $field['form_type']}($field, $value, $row, $permission = []);
} else {
return FieldService::{'content_text'}($field, $value, $row, $permission = []);
}
}
public static function flowRules($models, $gets)
{
$master = $gets['master'];
$rules = $messages = $attributes = [];
$_permission = DB::table('model_permission')
->find($master['permission_id']);
$permissions = json_decode($_permission['data'], true);
foreach ($models as $model) {
$table = $model->table;
$fields = $model->fields->keyBy('field');
foreach ((array)$permissions[$table] as $key => $row) {
$field = $fields[$key];
$_rules = (array)$row['v'];
if ($_rules) {
$field_name = $fields[$key]['name'];
if ($model['type'] == 1) {
if ($key == '@option') {
$t = $table . '.rows';
$field_name = $model->name;
} else {
$t = $table . '.rows.*.' . $key;
}
} else {
$t = $table . '.' . $key;
}
$data_type = $field['data_type'];
$data_field = $field['data_field'];
$data_link = $field['data_link'];
$data_status = 0;
if ($data_type) {
if (empty($field['type'])) {
$data_status = 1;
$t = $model['type'] == 1 ? $data_type . '.rows.*.' . $data_field : $data_type . '.' . $data_field;
}
}
foreach($_rules as &$_rule) {
// 处理唯一判断
if ($_rule == 'unique') {
if ($data_status == 1) {
$_rule = 'unique:'.$data_type.','.$data_field.','.$gets[$data_type][$data_link].','.$data_link;
} else {
$_rule = 'unique:'.$table.','.$key.','.$gets[$table]['id'].',id';
}
}
}
$rules[$t] = join('|', $_rules);
$attributes[$t] = $field_name;
}
}
}
// 获取表单上的审核意见
if ($master['run_id'] && $gets['step_remark']) {
$run_steps = DB::table('model_run_step')
->where('run_id', $master['run_id'])
->get()->keyBy('step_id');
$steps = $permissions['flow_step'];
foreach((array)$steps as $step_id => $step) {
$v = (array)$step['v'];
if ($v) {
$rules['step_remark.'.$step_id] = join('|', $step['v']);
$attributes['step_remark.'.$step_id] = $run_steps[$step_id]['name'].'审核意见';
}
}
}
return ['rules' => $rules, 'messages' => $messages, 'attributes' => $attributes];
}
/**
* 数据导入
*/
public static function import($params)
{
// 上传文件
$table = $params['table'];
$keys = $params['keys'];
$file = Request::file('file');
if (empty($file)) {
return response_json('文件必须选择');
}
if ($file->isValid()) {
set_time_limit(0);
$datas = readExcel($file->getPathName());
$flow = DB::table('model')
->where('table', $table)
->first();
$fields = DB::table('model_field')
->where('model_id', $flow['id'])
->get();
$options = [];
$names = [];
$links = [];
// 记录提醒的字段的名称
$tips = [];
foreach ($fields as $field) {
$setting = json_decode($field['setting'], true);
$field['setting'] = $setting;
if ($field['form_type'] == 'option') {
$options[$field['field']] = option($field['setting']['type'])->pluck('id', 'name');
}
if ($field['data_type']) {
$data_type = $field['data_type'];
$data_field = $field['data_field'];
$data_link = $field['data_link'];
$key = $data_type.'_'.$data_link;
$_link = $links[$key];
$_link['table'] = $data_type;
$_link['link'] = $data_link;
if (strpos($data_field, ':')) {
list($var1, $var2) = explode(':', $data_field);
list($_t, $_f) = explode('.', $var2);
$_link['join'][$_t] = [$_t, $_t.'.id', '=', $data_type.'.'.$var1];
$_link['key'] = $var2;
$_link['field'] = $_f;
$_link['value'] = $data_type.'.id';
} else {
$_link['key'] = $data_field;
$_link['field'] = $data_field;
$_link['value'] = 'id';
}
$_link['base'] = $field['type'] == '' ? 0 : 1;
$links[$key] = $_link;
$tips[$data_link] = $field['name'];
} else {
$tips[$field['field']] = $field['name'];
}
$names[trim($field['name'])] = $field;
}
// 获取数据的第一行记录
$header = Arr::pull($datas, 1);
$fields = [];
foreach ($header as $i => $col) {
$col = trim($col);
if ($names[$col]) {
$fields[$i] = $names[$col];
}
}
$types = [];
$rows = [];
$i = 0;
foreach ($datas as $data) {
$row = [];
foreach ($data as $j => $col) {
$field = $fields[$j];
$col = trim($col);
if ($field['type']) {
if ($field['form_type'] == 'option') {
$row[$table][$field['field']] = $options[$field['field']][$col];
}
if ($field['form_type'] == 'dialog') {
$row[$table][$field['field']] = (int)$col;
}
if ($field['form_type'] == 'text') {
$row[$table][$field['field']] = $col;
}
if ($field['type'] == 'INT') {
$types[$table][$field['field']] = 'int';
}
}
if ($field['data_type']) {
$data_type = $field['data_type'];
$data_field = $field['data_field'];
$data_link = $field['data_link'];
if ($col) {
$link = $links[$data_type.'_'.$data_link];
$row[$data_type][$link['field']] = $col;
//if ($link['base'] == 0) {
$row[$table][$field['data_link']] = $col;
//}
$links[$data_type.'_'.$data_link]['in'][$col] = $col;
}
}
}
$rows[$i] = $row;
$i++;
}
$options = [];
foreach ($links as $i => $row) {
$model = DB::table($row['table']);
if ($row['join']) {
foreach ($row['join'] as $join) {
$model->leftJoin($join[0], $join[1], $join[2], $join[3]);
}
}
if ($row['in']) {
$items = $model->whereIn($row['key'], $row['in'])
->pluck($row['value'], $row['key'])->toArray();
$options[$row['link']] = $items;
}
}
$items = [];
foreach ($rows as $i => $data) {
$row = $data[$table];
foreach ($row as $field => $col) {
if (isset($options[$field])) {
$row[$field] = $options[$field][$col];
}
$type = $types[$table][$field];
if (isset($type)) {
if ($type == 'int') {
$row[$field] = (int)$row[$field];
}
}
}
$items[$i] = $row;
}
DB::beginTransaction();
try {
$start = microtime(true);
$update = $insert = 0;
foreach ($items as $i => $item) {
$model = DB::table($table);
foreach ($keys as $key) {
if (empty($item[$key])) {
abort_error('表格第'.($i + 1).'行['.$tips[$key].']数据不存在。');
}
$model->where($key, $item[$key]);
}
$ret = $model->first();
$_hook = Hook::fire($table.'.onBeforeImport', ['table' => $table, 'item' => $item, 'ret' => $ret]);
extract($_hook);
if ($ret['id']) {
$update++;
DB::table($table)->where('id', $ret['id'])->update($item);
} else {
$insert++;
$item['id'] = DB::table($table)->insertGetId($item);
}
$_hook['item'] = $item;
Hook::fire($table.'.onAfterImport', $_hook);
}
DB::commit();
$end = microtime(true) - $start;
return response_json('导入成功,耗时: '.number_format($end, 2).'秒,新建:'.$insert.',更新:'.$update, true);
} catch(\Exception $e) {
DB::rollBack();
abort_error($e->getMessage());
}
} else {
return response_json($file->getError());
}
}
/**
* 检查CSRF
*/
public static function tokensMatch()
{
$req = request();
$sessionToken = $req->session()->token();
$token = $req->input('_token') ?: $req->header('X-CSRF-TOKEN');
if (!$token && $header = $req->header('X-XSRF-TOKEN')) {
$token = decrypt($header);
}
if (! is_string($sessionToken) || ! is_string($token)) {
abort_error('Token Mismatch');
return false;
}
return hash_equals($sessionToken, $token);
}
public static function dataFilter($table, $fields, $permissions, $master, $values, &$dataFiles)
{
$_permissions = $permissions[$table];
foreach ($fields as $field) {
$key = $field['field'];
$setting = $field['setting'];
$value = $values[$key];
$permission = $_permissions[$key];
// 权限可写
if ($permission['w'] == 1) {
// 自定义过滤器
$_field_data = Hook::fire($table.'.onFieldFilter', ['table' => $table, 'master' => $master, 'field' => $field, 'values' => $values]);
extract($_field_data);
if ($field['data_format']) {
switch ($field['data_format']) {
case 'number':
case 'money':
list($_, $len) = explode(',', $field['length']);
$len = $len > 0 ? $len : 2;
$value = round(floatval($value), $len);
break;
}
} else {
switch ($field['type']) {
case 'DECIMAL':
list($_, $len) = explode(',', $field['length']);
$value = round(floatval($value), $len);
break;
}
}
switch ($field['form_type']) {
case 'autocomplete':
$value = str_replace('draft_', '', $value);
break;
case 'address':
$value = join("\n", (array)$value);
break;
case 'files':
$value = (array)$value;
$dataFiles = array_merge($dataFiles, $value);
$value = join(",", $value);
break;
case 'images':
$value = join(",", (array)$value);
break;
case 'date':
if ($setting['save'] == 'u') {
$value = empty($value) ? '' : strtotime($value);
}
break;
case 'checkbox':
if (is_array($value)) {
$value = join(",", (array)$value);
} else {
$value = intval($value);
}
break;
}
$values[$key] = $value;
}
}
return $values;
}
/**
* 保存数据
*/
public static function store($bill, $models, $gets, $id, $store_type = 'store')
{
$model = $models[0];
// 判断演示模式
License::demoCheck();
// 当前用户
$auth = Auth::user();
// 检查表单Token
static::tokensMatch();
// 主表名
$table = $model->table;
$master = $gets['master'];
$run_id = $master['run_id'];
$step_id = $master['step_id'];
$run_step_id = $master['run_step_id'];
$run_log_id = $master['run_log_id'];
$permission_id = $master['permission_id'];
$dataFiles = [];
$permission = DB::table('model_permission')->find($permission_id);
$permissions = json_decode($permission['data'], true);
$datas = $deleteds = [];
foreach ($models as $m) {
$t = $m->table;
$fields = $m->fields->keyBy('field');
// 获取setting内容
foreach ($fields as $key => $field) {
$setting = json_decode($field['setting'], true);
$field['setting'] = $setting;
$fields[$key] = $field;
}
// 获取多行子表数据
if ($m->parent_id > 0) {
$deleteds[$m->table] = $gets[$m->table]['deleteds'];
$rows = (array)$gets[$m->table]['rows'];
// 格式化子表数据格式
foreach ($rows as $i => $row) {
$rows[$i] = static::dataFilter($table, $fields, $permissions, $master, $row, $dataFiles);
}
$datas[] = [
'table' => $m->table,
'type' => $m->type,
'relation' => $m->relation,
'data' => $rows,
'deleteds' => (array)$gets[$m->table]['deleteds']
];
} else {
// 处理主表的字段格式
$gets[$t] = static::dataFilter($table, $fields, $permissions, $master, $gets[$t], $dataFiles);
}
}
// 主表数据
$master = $gets[$table];
DB::beginTransaction();
try {
// 是否自动处理表单写入相关,有时候我们希望自己处理相关写入功能
$terminate = true;
$_data = Hook::fire($table.'.onBeforeStore', ['table' => $table, 'gets' => $gets, 'master' => $master, 'datas' => $datas, 'terminate' => $terminate]);
extract($_data);
if ($terminate == true) {
// 更新主表
if ($id) {
DB::table($table)->where('id', $id)->update($master);
} else {
if ($bill['sn_length'] > 0) {
$make_sn = make_sn([
'table' => $table,
'data' => $master['sn'],
'bill_id' => $bill['id'],
'prefix' => $bill['sn_prefix'],
'rule' => $bill['sn_rule'],
'length' => $bill['sn_length'],
], true);
// 更新单据编码
$master['sn'] = $make_sn['new_value'];
}
$id = DB::table($table)->insertGetId($master);
}
foreach ($datas as $data) {
$rows = $data['data'];
// 多行子表
if ($data['type'] == 1) {
foreach ($rows as $row) {
// 子表关联ID
$row[$data['relation']] = $id;
// 事件过滤数据
$_event = Hook::fire($data['table'].'.onBeforeStore', ['table' => $table, 'master' => $master, 'row' => $row]);
$row = $_event['row'];
if ($row['id']) {
DB::table($data['table'])->where('id', $row['id'])->update($row);
} else {
$row['id'] = DB::table($data['table'])->insertGetId($row);
}
$_event['row'] = $row;
Hook::fire($data['table'].'.onAfterStore', $_event);
}
} else {
// 附表暂时未实现
}
}
// 删除列表数据
if (count($deleteds)) {
foreach($deleteds as $_deleted_table => $_deleteds) {
$_ids = [];
foreach((array)$_deleteds as $_deleted) {
if ($_deleted['id'] > 0) {
$_ids[] = $_deleted['id'];
}
}
if (count($_ids) > 0) {
DB::table($_deleted_table)->whereIn('id', $_ids)->delete();
}
}
}
// 附件发布
AttachmentService::publish($dataFiles);
// 重新赋值表主键id
$master['id'] = $id;
}
$_data = Hook::fire($table.'.onAfterStore', ['master' => $master, 'datas' => $datas, 'gets' => $gets]);
extract($_data);
// 单据和流程一起转交
$gets[$table] = $master;
if ($store_type == 'audit') {
static::storeFlowStep($bill, $models, $gets, $id);
} else {
// 更新表单的流程意见
static::storeStepRemark($gets, $run_id, $auth);
}
// 提交事务
DB::commit();
} catch (\App\Exceptions\AbortException $e) {
DB::rollback();
system_log('bill.store', '保存:'.$bill['name'], $e->getMessage(), 'error');
abort_error($bill['name']."<br>".$e->getMessage());
} catch (\Exception $e) {
DB::rollback();
system_log('bill.store', '保存:'.$bill['name'], $e->getMessage(), 'error');
abort_error($bill['name']."<br>".str_replace(base_path().DIRECTORY_SEPARATOR,'',$e->getFile()).'('.$e->getLine().")<br>".$e->getMessage());
}
return $master['id'];
}
/**
* 审核单据
*/
public static function audit($bill, $models, $gets, $id)
{
DB::beginTransaction();
try {
$master_id = static::storeFlowStep($bill, $models, $gets, $id);
// 提交事务
DB::commit();
return $master_id;
} catch (\App\Exceptions\AbortException $e) {
DB::rollback();
abort_error($bill['name']."<br>".$e->getMessage());
} catch (\Exception $e) {
DB::rollback();
abort_error($bill['name']."<br>".str_replace(base_path().DIRECTORY_SEPARATOR,'',$e->getFile()).'('.$e->getLine().")<br>".$e->getMessage());
}
}
/**
* 审核单据
*/
public static function storeFlowStep($bill, $models, $gets, $id)
{
$model = $models[0];
// 判断演示模式
License::demoCheck();
// 当前用户
$auth = Auth::user();
// 主表名
$table = $model->table;
$master = $gets['master'];
$run_id = $master['run_id'];
$step_id = $master['step_id'];
$run_step_id = $master['run_step_id'];
$run_log_id = $master['run_log_id'];
// 定义提醒方式
$messages = [
'audit' => [],
'notify' => [],
'uri' => $master['uri'].'/show'
];
// 主表数据
$master = $gets[$table];
/*
back 退回
draft 草稿
next 执行中
active 生效
recall 撤回
abort 弃审
*/
if ($bill['audit_type'] == 1) {
$run = DB::table('model_run')
->where('bill_id', $bill['id'])
->where('data_id', $id)
->first();
$run_index = $run['index'] + 1;
// 草稿审核
if (empty($run)) {
$flow_run = [
'bill_id' => $bill['id'],
'data_id' => $id,
'name' => $bill['name'],
'sn' => $master['sn'],
];
// 写入流程运行信息
$run_id = DB::table('model_run')->insertGetId($flow_run);
// 复制流程节点到运行节点
$_steps = DB::table('model_step')->where('bill_id', $bill['id'])->get();
foreach ($_steps as $_step) {
$_step['run_id'] = $run_id;
$_step['step_id'] = $_step['id'];
$_step['id'] = 0;
DB::table('model_run_step')->insert($_step);
}
// 读取第一步流程
$run_step = DB::table('model_run_step')
->where('bill_id', $bill['id'])
->where('run_id', $run_id)
->where('type', 'start')
->first();
$log = [
'bill_id' => $bill['id'],
'parent_id' => 0,
'user_id' => $auth['id'],
'role_id' => $auth['role_id'],
'run_id' => $run_id,
'run_step_id' => $run_step['id'],
'run_name' => $run_step['name'],
'run_status' => $gets['step_next_type'],
'updated_id' => $auth['id'],
'updated_at' => time(),
'run_index' => 0,
'status' => 1,
];
// 更新审核意见到节点
DB::table('model_run_step')
->where('id', $run_step['id'])
->update([
'run_remark' => $gets['remark'],
'run_updated_id' => $auth['id'],
'run_updated_by' => $auth['name'],
'run_updated_at' => time(),
]);
// 写入第一步办理节点
$run_log_id = DB::table('model_run_log')->insertGetId($log);
} else {
$run_id = $run['id'];
}
$run_mode = $gets['run_mode'];
// 当前办理日志
$run_log = DB::table('model_run_log')
->where('run_id', $run_id)
->where('id', $run_log_id)
->where('status', 0)
->first();
// 当前办理日志的父节点
$parent_run_log = DB::table('model_run_log')
->where('run_id', $run_id)
->where('id', $run_log['parent_id'])
->first();
// 读取上一步的所有未办理记录不包含自己
if ($run_log['parent_id'] > 0) {
$run_logs = DB::table('model_run_log')
->where('run_id', $run_id)
->where('parent_id', $run_log['parent_id'])
->whereNotIn('id', [$run_log['id']])
->where('status', 0)
->get();
// 其他人待办数量
$run_logs_count = $run_logs->count();
} else {
$run_logs = [];
// 其他人待办数量
$run_logs_count = 0;
}
// 写入下一步待办
$next_step_write = false;
// 更新其他人待办
$next_step_other = false;
// 1:单人执行2:多人执行3:全体执行4:竞争执行
switch ($run_mode)
{
case 1: // 单人执行
$next_step_write = true;
$next_step_other = true;
break;
case 2: // 多人执行
if ($run_logs_count > 0) {
$next_step_write = false;
} else {
$next_step_write = true;
}
$next_step_other = false;
break;
case 3: // 全体执行
if ($run_logs_count > 0) {
$next_step_write = false;
} else {
$next_step_write = true;
}
$next_step_other = false;
break;
case 4: // 竞争执行
$next_step_write = true;
$next_step_other = true;
break;
}
if ($gets['step_next_type']) {
// 设置流程主表状态
switch ($gets['step_next_type']) {
case 'next':
$master['status'] = '2';
break;
case 'back':
$master['status'] = '-2';
break;
case 'end':
$master['status'] = '1';
break;
}
}
// 结束节点时执行
if ($gets['step_next_type'] == 'end') {
// 结束流程时最后一个办理(针对多人执行)
if ($next_step_write) {
// 设置生效数据
$_run['actived_id'] = $auth['id'];
$_run['actived_by'] = $auth['name'];
$_run['actived_at'] = time();
// 生效时执行事件
$_data = Hook::fire($table.'.onBeforeAudit', ['table' => $table, 'master' => $master, 'id' => $master['id']]);
extract($_data);
} else {
// 结束节点不结束流程
$master['status'] = '2';
}
}
// 更新自己已办日志
DB::table('model_run_log')
->where('run_id', $run_id)
->where('id', $run_log['id'])
->update([
'status' => 1,
'run_status' => $gets['step_next_type'],
'remark' => $gets['remark'],
]);
// 更新其他人待办
if ($next_step_other == true) {
foreach ($run_logs as $log) {
// 更新已办日志
DB::table('model_run_log')
->where('run_id', $run_id)
->where('option', 1)
->where('id', $log['id'])
->update([
'status' => 1,
'run_status' => $gets['step_next_type'],
'remark' => $gets['remark'],
]);
}
}
// 获取审核人和抄送人
$user_all_ids = array_merge($gets['step_user_ids'], $gets['notify_user_ids']);
// 获取审核人和抄送人角色id
$role_ids = DB::table('user')->whereIn('id', $user_all_ids)->pluck('role_id', 'id');
// 写入下一步骤审核日志
if ($next_step_write == true) {
$run_log_id = $gets['step_next_type'] == 'back' ? $parent_run_log['parent_id'] : $run_log_id;
$step_next = DB::table('model_run_step')
->where('bill_id', $bill['id'])
->where('run_id', $run_id)
->where('step_id', $gets['step_next_id'])
->first();
// 结束流程直接跳过
if ($step_next['type'] == 'end') {
} else {
// 如果退回流程到开始
if ($gets['step_next_type'] == 'back' && $step_next['type'] == 'start') {
$master['status'] = 0;
}
$user_ids = (array)$gets['step_user_ids'];
foreach ($user_ids as $user_id) {
$messages['audit'][] = $user_id;
DB::table('model_run_log')->insert([
'bill_id' => $bill['id'],
'parent_id' => $run_log_id,
'run_id' => $run_id,
'user_id' => $user_id,
'role_id' => $role_ids[$user_id],
'run_step_id' => $step_next['id'],
'run_name' => $step_next['name'],
'run_status' => 'draft',
'run_index' => $run_index,
'status' => 0,
]);
}
}
}
// 写入知会节点
if ($gets['step_next_type'] == 'next' || $gets['step_next_type'] == 'end') {
$step_inform_ids = $gets['step_next_inform'];
if ($step_inform_ids) {
// 查询知会节点
$notify_step_ids = array_keys($step_inform_ids);
$notify_steps = DB::table('model_run_step')
->where('bill_id', $bill['id'])
->where('run_id', $run_id)
->whereIn('step_id', $notify_step_ids)
->where('option', 0)
->get()->keyBy('step_id');
foreach($step_inform_ids as $step_inform_id => $notify_user_ids) {
$user_ids = explode(',', $notify_user_ids);
foreach($user_ids as $user_id) {
if ($user_id) {
$notify = $notify_steps[$step_inform_id];
$messages['notify'][] = $user_id;
DB::table('model_run_log')->insert([
'bill_id' => $bill['id'],
'parent_id' => $run_log_id,
'run_id' => $run_id,
'user_id' => $user_id,
'role_id' => $role_ids[$user_id],
'run_step_id' => $notify['id'],
'run_name' => $notify['name'],
'run_status' => 'draft',
'run_index' => $run_index,
'option' => 0,
'status' => 0,
]);
}
}
}
}
} else if($gets['step_next_type'] == 'back') {
// 退回流程删除知会记录
$step_back_inform = array_values((array)$gets['step_back_inform']);
DB::table('model_run_log')->whereIn('id', $step_back_inform)->delete();
}
// 更新表单的流程意见
static::storeStepRemark($gets, $run_id, $auth);
// 更新办理序号
$_run['index'] = $run_index;
// 写入往来单位
if ($master['customer_id'] > 0) {
$_run['partner_id'] = $master['customer_id'];
$_run['partner_type'] = 'customer';
}
if ($master['supplier_id'] > 0) {
$_run['partner_id'] = $master['supplier_id'];
$_run['partner_type'] = 'supplier';
}
DB::table('model_run')
->where('id', $run_id)
->update($_run);
}
// 更新数据主表
DB::table($table)->where('id', $master['id'])->update($master);
$messages['master'] = $master;
$messages['table'] = $table;
static::notification($bill, $messages);
return $master['id'];
}
/**
* 保存流程审核意见
*/
public static function storeStepRemark($gets, $run_id, $auth)
{
// 更新表单的流程意见
$step_remark = $gets['step_remark'];
if (not_empty($step_remark)) {
foreach ($step_remark as $step_id => $remark) {
// 审核操作无审核意见
if ($remark == '') {
$remark = $gets['step_next_type'] == 'back' ? '退回' : '同意';
}
RunStep::where('run_id', $run_id)->where('step_id', $step_id)->update([
'run_remark' => $remark,
'run_updated_id' => $auth['id'],
'run_updated_by' => $auth['name'],
'run_updated_at' => time(),
]);
}
}
}
/**
* 流程办理通知相关
*/
public static function notification($bill, $params)
{
$gets = $params['gets'];
$master = $params['master'];
$auth = $params['auth'];
$data = DB::table($params['table'])->where('id', $master['id'])->first();
// 往来单位
if ($data['customer_id']) {
$partner = DB::table('customer')->where('id', $data['customer_id'])->first();
}
if ($data['supplier_id']) {
$partner = DB::table('supplier')->where('id', $data['supplier_id'])->first();
}
$step_inform_sms = $gets['step_inform_sms'];
$step_inform_text = $gets['step_inform_text'];
if (empty($step_inform_text)) {
$step_inform_text = '请您及时办理由'.$auth['name'].'转交的'.$bill['name'].'('.$data['sn'].')。';
}
// h5通知(微信公众号)
$url = env('WAP_BASE_URL').'/#/pages/webview?title='.$bill['name'].'&url='.encodeURIComponent($params['uri'].'?id='.$data['id']);
if (app()->environment() == 'development') {
$template_id = 'gL6qSaU4xiUC7Bk26R1WZvHugqheyZ6SQc0W09LF9RY';
} else {
$template_id = '1LkZcva0fba8el6tbGC7eoCg9D1u4TZ_o6Qqhd1CJAI';
}
$msg = [
'template_id' => $template_id,
'url' => $url,
'data' => [
'first' => $bill['name'],
'keyword1' => $partner['name'],
'keyword2' => $data['sn'],
'remark' => '待处理',
],
];
// 暂时不启用短信提醒
$step_inform_sms = 0;
// 审核
if ($params['audit']) {
NotificationService::wechatTemplate($params['audit'], $msg);
// 短信通知
if ($step_inform_sms) {
// 查询通知人手机号码
$phones = DB::table('user')->whereIn('id', $params['audit'])->whereRaw("isnull(phone,'') <> ''")->pluck('phone');
if ($phones->count()) {
NotificationService::sms($phones->toArray(), $step_inform_text);
}
}
}
// 知会
if ($params['notify']) {
NotificationService::wechatTemplate($params['notify'], $msg);
// 短信通知
if ($step_inform_sms) {
// 查询通知人手机号码
$phones = DB::table('user')->whereIn('id', $params['notify'])->whereRaw("isnull(phone,'') <> ''")->pluck('phone');
if ($phones->count()) {
NotificationService::sms($phones->toArray(), $step_inform_text);
}
}
}
}
// 删除表单数据
public static function remove($params)
{
$code = $params['code'];
$ids = array_filter((array)$params['ids']);
if (empty($ids)) {
return response_json('最少选择一行记录。');
}
// 获取应用
$bill = DB::table('model_bill')->where('code', $code)->first();
// 主模型字段
$flow = DB::table('model')->where('id', $bill['model_id'])->first();
// 查询子表
$models = DB::table('model')->where('parent_id', $flow['id'])->get();
DB::beginTransaction();
try {
// 数据主表
$masters = DB::table($flow['table'])->whereIn('id', $ids)->get();
// 数据子表
$datas = [];
if ($models->count()) {
foreach ($models as $model) {
$data['table'] = $model['table'];
$data['data'] = DB::table($model['table'])->whereIn($model['relation'], $ids)->get()->toArray();
$datas[] = $data;
}
}
// 删除使用过的关联表
Hook::fire($flow['table'].'.onBeforeDelete', ['table' => $flow['table'], 'masters' => $masters, 'datas' => $datas, 'ids' => $ids]);
// 删除主表数据
DB::table($flow['table'])->whereIn('id', $ids)->delete();
// 删除子表数据
foreach ($models as $model) {
DB::table($model['table'])->whereIn($model['relation'], $ids)->delete();
}
if ($bill['audit_type'] == 1) {
$run_ids = DB::table('model_run')
->where('bill_id', $bill['id'])
->whereIn('data_id', $masters->pluck('id'))
->pluck('id');
DB::table('model_run_step')
->whereIn('run_id', $run_ids)
->delete();
DB::table('model_run_log')
->whereIn('run_id', $run_ids)
->delete();
DB::table('model_run')
->whereIn('id', $run_ids)
->delete();
}
// 删除使用过的关联表
Hook::fire($flow['table'].'.onAfterDelete', ['table' => $flow['table'], 'masters' => $masters, 'datas' => $datas, 'ids' => $ids]);
// 最后清理附件和流程记录(未实现)
DB::commit();
return response_json('删除'.$flow['name'].'成功。', true);
} catch(\Exception $e) {
DB::rollBack();
abort_error('删除'.$flow['name'].'失败:'.$e->getMessage());
}
}
// 获取相关权限
public static function getAuthorise($options) {
$table = $options['table'];
$authorise = $options['authorise'];
$access = UserService::authoriseAccess($authorise['action']);
$region = $options['region'];
$m = DB::table($table);
if ($region) {
$_region = regionCustomer('customer');
if ($_region['authorise']) {
$model = DB::table('customer');
foreach ($_region['whereIn'] as $k => $v) {
$ids = $model->whereIn($k, $v)->pluck('id');
}
$m->whereIn($table.'.'.$region['field'], $ids);
} else {
if ($authorise) {
if ($access) {
$m->whereIn($table.'.'.$authorise['field'], $access);
}
}
}
} else {
if ($authorise) {
if ($access) {
$m->whereIn($table.'.'.$authorise['field'], $access);
}
}
}
return $m;
}
public static function getPage($options) {
$table = $options['table'];
$q = static::getAuthorise($options);
Hook::fire($table.'.onBeforePage', ['q' => $q, 'options' => $options['table']]);
$start = clone $q;
$end = clone $q;
$prev = clone $q;
$next = clone $q;
$id = $table.'.id';
$page['start'] = $start->orderBy($id, 'asc')
->limit(1)->value($id);
$page['end'] = $end->orderBy($id, 'desc')
->limit(1)->value($id);
if ($options['id'] > 0) {
$page['prev'] = $prev->where($id, '<', $options['id'])
->orderBy($id, 'desc')
->limit(1)->value($id);
$page['next'] = $next->where($id, '>', $options['id'])
->orderBy($id, 'asc')
->limit(1)->value($id);
}
return $page;
}
}