前言 泛微OA使用的Laravel
这是其对接数据库的文档
https://laravelacademy.org/post/22012
位置 项目位置
D:\e-office_server_11.0\www
外部脚本位置
D:\e-office_server_11.0\www\eoffice\server\ext
假如我的模块的位置
D:\e-office_server_11.0\www\eoffice\server\ext\ruku\add_product.php
则访问的地址为
http://60.205.244.163:8010/eoffice/server/ext/ruku/add_product.php
外发地址可以配置为
/eoffice/server/ext/ruku/add_product.php
测试
add_product.php
日志 1 2 3 4 5 6 7 $logDir = base_path ('/storage/' ) . 'logs/' ;if (empty ($data )) { file_put_contents ($logDir ."ruku_log.txt" ,"数据错误,外发失败。" ,FILE_APPEND); exit (); }
打印请求参数到日志 为了方便我们知道参数,我们在log中打印所有的参数
1 2 3 4 5 6 7 8 9 10 11 12 <?php require __DIR__ . '/../../bootstrap/app.php' ;use Illuminate \Support \Facades \DB ;header ("Content-Type:text/html;charset=gb2312" );$data = (isset ($_REQUEST ) && !empty ($_REQUEST )) ? $_REQUEST : [];$logDir = base_path ('/storage/' ) . 'logs/' ;file_put_contents ($logDir ."ruku_paras_log.txt" ,json_encode ($data ));echo "参数保存成功" ;?>
注意
设置请求头编码为utf8,并且转换一下输出的编码。
文件本身编码不要修改为utf8。
输出中文乱码 注意以下两种方式都可以,但是切记不要修改文件本身编码为UTF-8。
1 2 header ("Content-Type:text/html;charset=utf8" );echo iconv ("GB2312" ,"UTF-8" ,"参数保存成功" );
或者
1 2 header ("Content-Type:text/html;charset=gb2312" );echo "参数保存成功" ;
可取参数 JSON解析 流程中的无论表单提交,还是后续节点,外发的时候数据都会包含表单的所有值。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 { "data_id" : "9" , "creator" : "admin" , "DATA_6" : "6" , "DATA_6_TEXT" : "管城区市政基础能力提升工程项目-A包" , "DATA_1" : "5" , "DATA_1_TEXT" : "方圆项目" , "DATA_3" : { "data_id" : [ "11" , "12" ] , "id" : [ "11" , "12" ] , "form_data_id" : [ "9" , "9" ] , "parent_data_id" : [ "9" , "9" ] , "DATA_4" : [ "4" , "5" ] , "DATA_4_TEXT" : [ "金士顿U盘-128G" , "金士顿U盘-256G" ] , "DATA_5" : [ "" , "" ] , "DATA_7" : [ "10" , "20" ] , "DATA_8" : [ "10" , "20" ] , "DATA_9" : [ "" , "" ] } , "flow_id" : "100" , "run_id" : "511" , "form_id" : "570" , "outsend_id" : "214" , "run_name" : "入库单" , "node_id" : "387" , "process_name" : "发起人" , "userInfo" : { "user_id" : "admin" , "user_name" : "管理员" , "user_accounts" : "admin" , "dept_name" : "其他" , "dept_id" : "62" , "role_name" : "[\"OA\\u7ba1\\u7406\\u5458\",\"OA\\u7ba1\\u7406\\u5458\\u6d41\\u7a0b\\u8bbe\\u7f6e\\u7279\\u6743\"]" , "role_id" : "[1,68]" } }
其中
run_id 流程id 对应的表是 flow_run
node_id 流程当前节点
form_id 表单ID 那么对应的表就是 form_data_570 子表是 form_data_570_data_3
data_id 表的主键ID
DATA_6是下拉菜单,就会产生两个值 DATA_6和DATA_6_TEXT
DATA_3是明细布局 会产生子表 明细的数据都会以数组呈现
子表form_data_570_data_3的格式类似于
代码示例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 <?php require __DIR__ . '/../../bootstrap/app.php' ;use Illuminate \Support \Facades \DB ;$data = (isset ($_REQUEST ) && !empty ($_REQUEST )) ? $_REQUEST : [];$logDir = base_path ('/storage/' ) . 'logs/' ;if (empty ($data )) { file_put_contents ($logDir ."ruku_log.txt" ,"数据错误,外发失败。" ,FILE_APPEND); exit (); } $run_id = isset ($data ["run_id" ]) ? $data ["run_id" ] : "" ;$node_id = isset ($data ["node_id" ]) ? $data ["node_id" ] : "" ;?>
表通用字段 主键
data_id
时间字段
其中deleted_at为null的时候是可用的,泛微没有单独标记删除的字段。
SQL操作 1 2 3 4 5 6 7 <?php require __DIR__ . '/../../bootstrap/app.php' ; use Illuminate \Support \Facades \DB ; header ('Content-type: application/json' );$list = DB::table ('log_customer' )->limit (10 )->get ();echo json_encode ($list );?>
日期 1 2 use Carbon \Carbon ;Carbon ::now ()
SQL基本查询 运行 Select 查询
运行一个最基本的查询,可以使用 DB 门面的 select 方法:
1 $users = DB::select ('select * from users where active = ?' , [1 ]);
除了使用 ? 占位符来代表参数绑定外,还可以使用命名绑定来执行查询:
1 $results = DB::select ('select * from users where id = :id' , ['id' => 1 ]);
运行插入语句
使用 DB 门面的 insert 方法执行插入语句。和 select 一样,该方法将原生 SQL 语句作为第一个参数,将参数绑定作为第二个参数:
1 DB::insert ('insert into users (id, name) values (?, ?)' , [1 , '学院君' ]);
运行更新语句
update 方法用于更新数据库中已存在的记录,该方法返回受更新语句影响的行数:
1 $affected = DB::update ('update users set votes = 100 where name = ?' , ['学院君' ]);
运行删除语句
delete 方法用于删除数据库中已存在的记录,和 update 一样,该语句返回被删除的行数:
1 $deleted = DB::delete ('delete from users' );
使用 delete 和 update 语句时,需要非常小心,因为条件设置不慎,导致的后果有可能是无法挽回的,比如不带条件的 delete 语句删除的将是数据表的所有记录!这些都是有血淋淋的教训的。
运行一个通用语句
有些数据库语句不返回任何值,比如新增表,修改表,删除表等,对于这种类型的操作,可以使用 DB 门面的 statement 方法:
1 DB::statement ('drop table users' );
SQL查询构建器 单条数据 1 2 $user = DB::table ('users' )->where ('name' , '学院君' )->first ();echo $user ->name;
多个Where
1 2 3 4 $users = DB::table ('users' ) ->where ('name' , '=' , 'John' ) ->where ('age' , '>' , 18 ) ->first ();
查询列表 1 $users = DB::table ('users' )->select ('name' , 'email as user_email' )->get ();
distinct 方法允许你强制查询返回不重复的结果集:
1 $users = DB::table ('users' )->distinct ()->get ();
原生表达式 有时候你希望在查询中使用原生表达式,这些表达式将会以字符串的形式注入到查询中,所以要格外小心避免 SQL 注入。想要创建一个原生表达式,可以使用 DB::raw 方法:
1 2 3 4 5 $users = DB::table ('users' ) ->select (DB::raw ('count(*) as user_count, status' )) ->where ('status' , '<>' , 1 ) ->groupBy ('status' ) ->get ();
左连接/右连接 1 2 3 4 5 6 7 $users = DB::table ('users' ) ->leftJoin ('posts' , 'users.id' , '=' , 'posts.user_id' ) ->get (); $users = DB::table ('users' ) ->rightJoin ('posts' , 'users.id' , '=' , 'posts.user_id' ) ->get ();
Where 子句 whereBetween/orWhereBetween
whereBetween 方法验证列值是否在给定值之间:
1 2 3 $users = DB::table('users') ->whereBetween('votes', [1, 100]) ->get();
whereNotBetween/orWhereNotBetween
whereNotBetween 方法验证列值不在给定值之间:
1 2 3 $users = DB::table ('users' ) ->whereNotBetween ('votes' , [1 , 100 ]) ->get ();
whereIn/whereNotIn/orWhereIn/orWhereNotIn
whereIn 方法验证给定列的值是否在给定数组中:
1 2 3 $users = DB::table ('users' ) ->whereIn ('id' , [1 , 2 , 3 ]) ->get ();
whereNotIn 方法验证给定列的值不在给定数组中:
1 2 3 $users = DB::table ('users' ) ->whereNotIn ('id' , [1 , 2 , 3 ]) ->get ();
注:如果要添加非常大的整型数组绑定到查询,可以使用 whereIntegerInRaw 或 whereIntegerNotInRaw 方法来降低内存开销。
whereNull/whereNotNull/orWhereNull/orWhereNotNull
whereNull 方法验证给定列的值为 NULL:
1 2 3 $users = DB::table ('users' ) ->whereNull ('updated_at' ) ->get ();
whereNotNull 方法验证给定列的值不是 NULL:
1 2 3 $users = DB::table ('users' ) ->whereNotNull ('updated_at' ) ->get ();
whereDate/whereMonth/whereDay/whereYear/whereTime
whereDate 方法用于比较字段值和日期:
1 2 3 $users = DB::table ('users' ) ->whereDate ('created_at' , '2019-12-31' ) ->get ();
whereMonth 方法用于比较字段值和一年中的指定月份:
1 2 3 $users = DB::table ('users' ) ->whereMonth ('created_at' , '12' ) ->get ();
whereDay 方法用于比较字段值和一月中的指定日期:
1 2 3 $users = DB::table ('users' ) ->whereDay ('created_at' , '31' ) ->get ();
whereYear 方法用于比较字段值和指定年:
1 2 3 $users = DB::table ('users' ) ->whereYear ('created_at' , '2019' ) ->get ();
whereTime 方法用于比较字段值和指定时间:
1 2 3 $users = DB::table ('users' ) ->whereTime ('created_at' , '=' , '11:20:45' ) ->get ();
whereColumn/orWhereColumn
whereColumn 方法用于验证两个字段是否相等:
1 2 3 $users = DB::table ('users' ) ->whereColumn ('first_name' , 'last_name' ) ->get ();
还可以传递一个比较运算符到该方法:
1 2 3 $users = DB::table ('users' ) ->whereColumn ('updated_at' , '>' , 'created_at' ) ->get ();
还可以传递多条件数组到 whereColumn 方法,这些条件通过 and 操作符进行连接:
1 2 3 4 5 $users = DB::table ('users' ) ->whereColumn ([ ['first_name' , '=' , 'last_name' ], ['updated_at' , '>' , 'created_at' ] ])->get ();
插入(Insert) 查询构建器还提供了 insert 方法用于插入记录到数据表。insert 方法接收数组形式的字段名和字段值进行插入操作:
1 2 3 DB::table ('users' )->insert ( ['email' => 'john@example.com' , 'votes' => 0 ] );
你甚至可以一次性通过传入多个数组来插入多条记录,每个数组代表要插入数据表的记录:
1 2 3 4 DB::table ('users' )->insert ([ ['email' => 'taylor@example.com' , 'votes' => 0 ], ['email' => 'dayle@example.com' , 'votes' => 0 ] ]);
insertOrIgnore 方法会在插入记录到数据库时忽略重复记录错误:
1 2 3 4 DB::table ('users' )->insertOrIgnore ([ ['id' => 1 , 'email' => 'taylor@example.com' ], ['id' => 2 , 'email' => 'dayle@example.com' ] ]);
自增 ID
如果数据表有自增 ID,使用 insertGetId 方法来插入记录并返回ID值:
1 2 3 $id = DB::table('users')->insertGetId( ['email' => 'john@example.com', 'votes' => 0] );
注:当使用 PostgresSQL 时 insertGetId 方法默认自增列被命名为 id,如果你想要从其他“序列”获取ID,可以将序列名作为第二个参数传递到 insertGetId 方法。
更新(Update) 当然,除了插入记录到数据库,查询构建器还可以通过使用 update 方法更新已有记录。update 方法和 insert 方法一样,接收字段名和字段值的键值对数组,对应字段名就是要更新的列,你可以通过 where 子句来对 update 查询进行约束:
1 2 3 DB::table ('users' ) ->where ('id' , 1 ) ->update (['votes' => 1 ]);
更新或插入 有时候你可能想要更新数据库中已存在的某条记录,如果对应记录不存在的话,则插入这条记录。在这种场景下,可以使用 updateOrInsert 方法。
该方法接收两个参数:用于查询记录的条件数组和用于更新的列值对数组。
updateOrInsert 方法首先会尝试使用第一个参数的列值对匹配对应的数据库记录,
如果记录存在,则通过第二个参数来更新它。
如果记录不存在,则会合并这两个参数数组然后通过合并后的数组插入一条新纪录:
1 2 3 4 5 DB::table ('users' ) ->updateOrInsert ( ['email' => 'john@example.com' , 'name' => 'John' ], ['votes' => '2' ] );
SQL技巧 null置0
1 select IFNULL((select DATA_5 from form_data_568_data_3 where data_id= 10086 limit 1 ),0 ) as num;
打印SQL 一般使用链式操作来对数据库进行相关的增删改查。那么如何查看我们执行的sql 呢? 对于查询语句来说; 我们可以在链式操作后面加上->toSql();来打印执行的sql 语句。
但是,对于其他的就不适用了。所以可以采用以下的办法:
1 2 3 4 5 6 7 8 9 DB::enableQueryLog (); DB::table ('form_data_568_data_3' ) ->updateOrInsert ( ['DATA_4' => $DATA_4 [$i ], 'parent_data_id' => $DATA_6 ], ['DATA_5' => $DATA_8 [$i ],'created_at' => ] ); file_put_contents ($logDir . "ruku_log.txt" , json_encode (DB::getQueryLog ()), FILE_APPEND);
开启日志
运行SQL后查看日志
1 json_encode (DB::getQueryLog ())
实战 我这里form_data_568_data_3
1 select ifnull((select IFNULL(DATA_5,0 ) from form_data_568_data_3 where DATA_4 = '#DATA_4#' and parent_data_id = '#DATA_6#' ),0 );
仓库 form_data_568_data_3
DATA_4 产品ID
DATA_5 数量
parent_data_id 仓库ID
入库单form_data_570
入库单子表 form_data_570_data3
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 <?php require __DIR__ . '/../../bootstrap/app.php' ;use Illuminate \Support \Facades \DB ;use Carbon \Carbon ;$data = (isset ($_REQUEST ) && !empty ($_REQUEST )) ? $_REQUEST : [];$logDir = base_path ('/storage/' ) . 'logs/' ;if (empty ($data )) { file_put_contents ($logDir . "ruku_log.txt" , "数据错误,外发失败。" , FILE_APPEND); exit (); } $data_id = isset ($data ["data_id" ]) ? $data ["data_id" ] : "" ;$node_id = isset ($data ["node_id" ]) ? $data ["node_id" ] : "" ;$DATA_6 = isset ($data ["DATA_6" ]) ? $data ["DATA_6" ] : "" ;$DATA_4 = $data ["DATA_3" ]["DATA_4" ];$DATA_4_TEXT = $data ["DATA_3" ]["DATA_4_TEXT" ];$DATA_8 = $data ["DATA_3" ]["DATA_8" ];$num = count ($DATA_4 ); DB::enableQueryLog (); for ($i = 0 ; $i < $num ; ++$i ) { DB::table ('form_data_568_data_3' ) ->updateOrInsert ( ['DATA_4' => $DATA_4 [$i ], 'parent_data_id' => $DATA_6 ], ['form_data_id' => $DATA_6 , 'DATA_4_TEXT' => $DATA_4_TEXT [$i ], 'DATA_5' => $DATA_8 [$i ], 'created_at' => Carbon ::now (), 'updated_at' => Carbon ::now ()] ); file_put_contents ($logDir . "ruku_log.txt" , json_encode (DB::getQueryLog ()), FILE_APPEND); } ?>
但是这样的话创建时间 在更新的时候也会被更新,所以不满足我们的要求
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 <?php require __DIR__ . '/../../bootstrap/app.php' ;use Illuminate \Support \Facades \DB ;use Carbon \Carbon ;$data = (isset ($_REQUEST ) && !empty ($_REQUEST )) ? $_REQUEST : [];$logDir = base_path ('/storage/' ) . 'logs/' ;if (empty ($data )) { file_put_contents ($logDir . "ruku_log.txt" , "数据错误,外发失败" . PHP_EOL, FILE_APPEND); exit (); } $data_id = isset ($data ["data_id" ]) ? $data ["data_id" ] : "" ;$node_id = isset ($data ["node_id" ]) ? $data ["node_id" ] : "" ;$DATA_6 = isset ($data ["DATA_6" ]) ? $data ["DATA_6" ] : "" ;$DATA_4 = $data ["DATA_3" ]["DATA_4" ];$DATA_4_TEXT = $data ["DATA_3" ]["DATA_4_TEXT" ];$DATA_8 = $data ["DATA_3" ]["DATA_8" ];$num = count ($DATA_4 ); DB::enableQueryLog (); for ($i = 0 ; $i < $num ; ++$i ) { $rukuDetail = DB::table ('form_data_568_data_3' ) ->where ('DATA_4' , '=' , $DATA_4 [$i ]) ->where ('parent_data_id' , '=' , $DATA_6 ) ->first (); file_put_contents ($logDir . "ruku_log.txt" , json_encode (DB::getQueryLog ()) . PHP_EOL, FILE_APPEND); if ($rukuDetail == NULL ) { DB::table ('form_data_568_data_3' )->insert ( [ 'DATA_4' => $DATA_4 [$i ], 'parent_data_id' => $DATA_6 , 'form_data_id' => $DATA_6 , 'DATA_4_TEXT' => $DATA_4_TEXT [$i ], 'DATA_5' => $DATA_8 [$i ], 'created_at' => Carbon ::now (), 'updated_at' => Carbon ::now () ] ); } else { DB::table ('form_data_568_data_3' ) ->where ('DATA_4' , '=' , $DATA_4 [$i ]) ->where ('parent_data_id' , '=' , $DATA_6 ) ->update ([ 'DATA_4_TEXT' => $DATA_4_TEXT [$i ], 'DATA_5' => $DATA_8 [$i ], 'updated_at' => Carbon ::now () ]); } file_put_contents ($logDir . "ruku_log.txt" , json_encode (DB::getQueryLog ()) . PHP_EOL, FILE_APPEND); } ?>
字符串转数字 泛微表单的输入框就算类型是数字,返回的依旧是字符串,所以我们要字符串转数字。
使用3个具体类型的转换函数,intval();floatval();strval()
自定义选择器 数据源
1 2 3 4 select data_id,concat( DATA_1,'-' ,guige) as name,DATA_1,guige from form_data_566 where deleted_at is null < search > and DATA_1 like '%@value%' < / search > < id> and data_id in (@value )< / id>
定义参数
其中@DATA_6@为参数
1 2 3 select DATA_4 as id,DATA_4_TEXT as name from form_data_568_data_3 where deleted_at is null and form_data_id= '@DATA_6@' < search > and DATA_4_TEXT like '%@value%' < / search > < id> and DATA_4 in (@value )< / id>