前言 泛微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 >