diff --git a/imgnod1.png b/imgnod1.png
deleted file mode 100644
index 9d6b429..0000000
Binary files a/imgnod1.png and /dev/null differ
diff --git a/serve/.env b/serve/.env
new file mode 100644
index 0000000..629865d
--- /dev/null
+++ b/serve/.env
@@ -0,0 +1,2 @@
+APP_DEBUG = FALSE
+APP_TRACE = FALSE
\ No newline at end of file
diff --git a/serve/.htaccess b/serve/.htaccess
new file mode 100644
index 0000000..69a7f04
--- /dev/null
+++ b/serve/.htaccess
@@ -0,0 +1,7 @@
+
+ Options +FollowSymlinks -Multiviews
+ RewriteEngine On
+ RewriteCond %{REQUEST_FILENAME} !-d
+ RewriteCond %{REQUEST_FILENAME} !-f
+ RewriteRule ^(.*)$ index.php?/$1 [QSA,PT,L]
+
diff --git a/serve/.travis.yml b/serve/.travis.yml
new file mode 100644
index 0000000..36f7b6f
--- /dev/null
+++ b/serve/.travis.yml
@@ -0,0 +1,42 @@
+sudo: false
+
+language: php
+
+branches:
+ only:
+ - stable
+
+cache:
+ directories:
+ - $HOME/.composer/cache
+
+before_install:
+ - composer self-update
+
+install:
+ - composer install --no-dev --no-interaction --ignore-platform-reqs
+ - zip -r --exclude='*.git*' --exclude='*.zip' --exclude='*.travis.yml' ThinkPHP_Core.zip .
+ - composer require --update-no-dev --no-interaction "topthink/think-image:^1.0"
+ - composer require --update-no-dev --no-interaction "topthink/think-migration:^1.0"
+ - composer require --update-no-dev --no-interaction "topthink/think-captcha:^1.0"
+ - composer require --update-no-dev --no-interaction "topthink/think-mongo:^1.0"
+ - composer require --update-no-dev --no-interaction "topthink/think-worker:^1.0"
+ - composer require --update-no-dev --no-interaction "topthink/think-helper:^1.0"
+ - composer require --update-no-dev --no-interaction "topthink/think-queue:^1.0"
+ - composer require --update-no-dev --no-interaction "topthink/think-angular:^1.0"
+ - composer require --dev --update-no-dev --no-interaction "topthink/think-testing:^1.0"
+ - zip -r --exclude='*.git*' --exclude='*.zip' --exclude='*.travis.yml' ThinkPHP_Full.zip .
+
+script:
+ - php think unit
+
+deploy:
+ provider: releases
+ api_key:
+ secure: TSF6bnl2JYN72UQOORAJYL+CqIryP2gHVKt6grfveQ7d9rleAEoxlq6PWxbvTI4jZ5nrPpUcBUpWIJHNgVcs+bzLFtyh5THaLqm39uCgBbrW7M8rI26L8sBh/6nsdtGgdeQrO/cLu31QoTzbwuz1WfAVoCdCkOSZeXyT/CclH99qV6RYyQYqaD2wpRjrhA5O4fSsEkiPVuk0GaOogFlrQHx+C+lHnf6pa1KxEoN1A0UxxVfGX6K4y5g4WQDO5zT4bLeubkWOXK0G51XSvACDOZVIyLdjApaOFTwamPcD3S1tfvuxRWWvsCD5ljFvb2kSmx5BIBNwN80MzuBmrGIC27XLGOxyMerwKxB6DskNUO9PflKHDPI61DRq0FTy1fv70SFMSiAtUv9aJRT41NQh9iJJ0vC8dl+xcxrWIjU1GG6+l/ZcRqVx9V1VuGQsLKndGhja7SQ+X1slHl76fRq223sMOql7MFCd0vvvxVQ2V39CcFKao/LB1aPH3VhODDEyxwx6aXoTznvC/QPepgWsHOWQzKj9ftsgDbsNiyFlXL4cu8DWUty6rQy8zT2b4O8b1xjcwSUCsy+auEjBamzQkMJFNlZAIUrukL/NbUhQU37TAbwsFyz7X0E/u/VMle/nBCNAzgkMwAUjiHM6FqrKKBRWFbPrSIixjfjkCnrMEPw=
+ file:
+ - ThinkPHP_Core.zip
+ - ThinkPHP_Full.zip
+ skip_cleanup: true
+ on:
+ tags: true
diff --git a/serve/app/.htaccess.txt.txt.txt b/serve/app/.htaccess.txt.txt.txt
new file mode 100644
index 0000000..3418e55
--- /dev/null
+++ b/serve/app/.htaccess.txt.txt.txt
@@ -0,0 +1 @@
+deny from all
\ No newline at end of file
diff --git a/serve/app/BaseController.php b/serve/app/BaseController.php
new file mode 100644
index 0000000..b3bd7d3
--- /dev/null
+++ b/serve/app/BaseController.php
@@ -0,0 +1,94 @@
+app = $app;
+ $this->request = $this->app->request;
+
+ // 控制器初始化
+ $this->initialize();
+ }
+
+ // 初始化
+ protected function initialize()
+ {}
+
+ /**
+ * 验证数据
+ * @access protected
+ * @param array $data 数据
+ * @param string|array $validate 验证器名或者验证规则数组
+ * @param array $message 提示信息
+ * @param bool $batch 是否批量验证
+ * @return array|string|true
+ * @throws ValidateException
+ */
+ protected function validate(array $data, $validate, array $message = [], bool $batch = false)
+ {
+ if (is_array($validate)) {
+ $v = new Validate();
+ $v->rule($validate);
+ } else {
+ if (strpos($validate, '.')) {
+ // 支持场景
+ list($validate, $scene) = explode('.', $validate);
+ }
+ $class = false !== strpos($validate, '\\') ? $validate : $this->app->parseClass('validate', $validate);
+ $v = new $class();
+ if (!empty($scene)) {
+ $v->scene($scene);
+ }
+ }
+
+ $v->message($message);
+
+ // 是否批量验证
+ if ($batch || $this->batchValidate) {
+ $v->batch(true);
+ }
+
+ return $v->failException(true)->check($data);
+ }
+
+}
diff --git a/serve/app/ExceptionHandle.php b/serve/app/ExceptionHandle.php
new file mode 100644
index 0000000..453d126
--- /dev/null
+++ b/serve/app/ExceptionHandle.php
@@ -0,0 +1,58 @@
+header('token');
+ $parm=input('get.token');
+ if(empty($header) && empty($parm)){
+ $token='';
+ }else if(!empty($header)){
+ $token=$header;
+ }else{
+ $token=$parm;
+ }
+ return $token;
+}
+//获取登陆状态
+function checkLogin() {
+ $token=getToken();
+ $cache=cache($token);
+ if($cache==null){
+ return false;
+ }else{
+ //重置缓存有效期
+ cacheReset($token);
+ return true;
+ }
+}
+//重置缓存有效期
+function cacheReset($key){
+ $config=config();
+ if($config['cache']['default']=='file'){
+ //文件缓存
+ $file=cache()->getCacheKey($key);
+ touch($file);
+
+ }
+ return true;
+}
+//获取当前用户ID
+function getUserID(){
+ $cache=cache(getToken());
+ if(empty($cache)){
+ die('[ ERROR ] 获取用户失败!');
+ }else{
+ return $cache['user'];
+ }
+}
+//判断字段存在且不为空
+function existFull($arr,$keys){
+ $state=true;
+ foreach ($keys as $key) {
+ if(!isset($arr[$key]) || empty($arr[$key]) || $arr[$key] === 'null'){
+ $state=false;
+ break;
+ }
+ }
+ return $state;
+}
+//扩展数据验证
+function verify($data,$rule,$info=false){
+ $validate = \think\facade\Validate::rule($rule);
+ if($validate->check($data)){
+ return true;
+ }else{
+ return $info?$validate->getError():false;
+ }
+}
+//汉字转拼音
+//$type[head:首字母|all:全拼音]
+function zhToPy($text,$type='head'){
+ $nod=new \org\ZhToPy();
+ $result=$nod::encode($text,$type);
+ return strtolower($result);//返回结果转小写
+}
+//寻找数组多层键名
+//$source:键名数组 OR "键名1|键名2"
+//如查找过程键名不存在返回空
+function arraySeek($array,$source){
+ $recode=$array;
+ is_array($source)||($source=explode('|',$source));
+ foreach ($source as $sourceVo) {
+ if(is_array($recode) && isset($recode[$sourceVo])){
+ $recode=$recode[$sourceVo];
+ }else{
+ $recode='';
+ break;
+ }
+ }
+ return $recode;
+}
+//数组搜索
+function search($arr){
+ $search=new \org\Search($arr);
+ return $search;
+}
+//判断是否JSON数据
+function isJson($string) {
+ json_decode($string);
+ return(json_last_error()==JSON_ERROR_NONE);
+}
+//返回数据子元素递归数据
+function findSubData($arr,$id){
+ $data=[];
+ $search=search($arr,[['pid','=',$id]])->select();
+ foreach ($search as $searchVo) {
+ $subSearch=search($arr,[['pid','=',$searchVo['id']]])->select();
+ $data[]=$searchVo;
+ if(!empty($subSearch)){
+ $data=array_merge($data,findSubData($arr,$searchVo['id']));//合并数据
+ }
+ }
+ return $data;
+}
+//过滤XSS
+function htmlpurifier($html) {
+ $config = HTMLPurifier_Config::createDefault();
+ $config->set('CSS.AllowTricky', true);
+ $purifier = new \HTMLPurifier($config);
+ $clean_html = $purifier->purify($html);
+ return $clean_html;
+}
+//获取xlsx文件数据
+function getXlsx($file){
+ $reader = \PhpOffice\PhpSpreadsheet\IOFactory::createReader('Xlsx')->setReadDataOnly(TRUE)->load($file)->getSheet(0)->toArray (null,false,false,true);
+ //NULL转空白字符|拦截XSS
+ array_walk_recursive($reader,function(&$vo){$vo=$vo===null?'':htmlpurifier($vo);});
+ return $reader;
+}
+//路径转换
+//$path='skin.upload.xlsx'
+function pathChange($path=false){
+ return $path==false?root_path():root_path().str_replace(".",DIRECTORY_SEPARATOR,$path).DIRECTORY_SEPARATOR;
+}
+//删除过期文件
+//$path='skin.upload.xlsx'
+//默认过期时间30秒
+function delOverdueFile($path,$time=30){
+ clearstatcache();//清除文件状态缓存
+ $path=pathChange($path);//路径转换
+ $files=scandir($path);//获取文件目录
+ $nowTime=time();//当前时间
+ foreach ($files as $key=>$vo){
+ if(substr($vo,0,1)!='.'){
+ $filePath=$path.$vo;//文件路径
+ if ($nowTime-filectime($filePath)>$time){
+ @unlink($filePath);
+ }
+ }
+ }
+}
+//删除目录|递归删除
+function delDir($path){
+ $path=pathChange($path);
+ if(file_exists($path)){
+ $list=listFile($path);
+ //删除过期缓存
+ foreach ($list['files'] as $file) {
+ @unlink($file);
+ }
+ //删除空目录
+ foreach ($list['dirs'] as $dir) {
+ @rmdir($dir);
+ }
+ }
+
+}
+//删除目录|递归删除
+function delCache(){
+ $cache=pathChange('runtime.cache');
+ if(file_exists($cache)){
+ $list=listFile($cache);
+ //删除过期缓存
+ foreach ($list['files'] as $file) {
+ $content = @file_get_contents($file);
+ if($content!==false){
+ $expire = (int)substr($content, 8, 12);
+ if ($expire!=0 && time() - $expire > filemtime($file)){
+ @unlink($file);
+ }
+ }
+ }
+ //删除空目录
+ foreach ($list['dirs'] as $dir) {
+ @rmdir($dir);
+ }
+ }
+}
+
+//计算多维数组最多数组数量
+function calArrMaxCount($arr,$max=0){
+ //对多维数组进行循环
+ foreach ($arr as $vo) {
+ if(is_array($vo)){
+ $count=count($vo);
+ //判断是否多维数组
+ if ($count==count($vo,1)) {
+ $count > $max&&($max=$count);
+ }else{
+ $max=CalArrMaxCount($vo,$max);
+ }
+ }
+ }
+ return $max;
+}
+//生成EXCEL
+function buildExcel($fileName,$data,$down=true){
+ $spreadsheet = new \PhpOffice\PhpSpreadsheet\Spreadsheet();
+ $cellName=['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','AA','AB','AC','AD','AE','AF','AG','AH','AI','AJ','AK','AL','AM','AN','AO','AP','AQ','AR','AS','AT','AU','AV','AW','AX','AY','AZ'];//列标识
+ $shell=$spreadsheet->getActiveSheet(0);//工作簿
+ $shell->setTitle('NODCLOUD.COM');//工作簿名称
+ $shell->getDefaultColumnDimension()->setWidth(20);//设置默认行宽
+ $shell->getDefaultRowDimension()->setRowHeight(16);//设置默认行高
+ //循环加入数据
+ $rowNums=1;//初始化行数
+ $maxCell=calArrMaxCount($data);//获取多维数组最多数组数量
+ //循环增加数据
+ foreach ($data as $dataVo) {
+ //判断数据类型
+ if($dataVo['type']=='title'){
+ //标题行
+ $cellNums=0;//初始化列数
+ $shell->mergeCells($cellName[$cellNums].$rowNums.':'.$cellName[$maxCell-1].$rowNums);//合并单元格
+ $shell->setCellValue($cellName[$cellNums].$rowNums,$dataVo['info'])->getStyle ($cellName[$cellNums].$rowNums)->applyFromArray ([
+ 'font'=>['bold'=>true,'size'=>12],
+ 'alignment'=>['horizontal'=>\PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER]
+ ]);//设置内容|居中|粗体|12号
+ $shell->getRowDimension($rowNums)->setRowHeight(26);//设置行高
+ $rowNums++;//自增行数
+ }elseif($dataVo['type']=='node'){
+ //节点行
+ $cellNums=0;//初始化列数
+ $shell->getStyle($cellName[$cellNums].$rowNums.':'.$cellName[$maxCell-1].$rowNums)->getFill()->setFillType(\PhpOffice\PhpSpreadsheet\Style\Fill::FILL_SOLID)->getStartColor()->setRGB('e7e6e6');//设置背景颜色
+ foreach ($dataVo['info'] as $data_info) {
+ $shell->setCellValue ($cellName[$cellNums].$rowNums,$data_info);
+ $cellNums++;//自增列数
+ }
+ $shell->getRowDimension($rowNums)->setRowHeight(16);//设置行高
+ $rowNums++;//自增行数
+ }elseif($dataVo['type']=='table'){
+ //表格数据
+ //处理表头数据
+ $cellNums=0;//初始化列数
+ foreach ($dataVo['info']['thead'] as $theadVo) {
+ $shell->setCellValue($cellName[$cellNums].$rowNums,$theadVo)->getStyle($cellName[$cellNums].$rowNums)->applyFromArray ([
+ 'font'=>['bold'=>true],
+ 'alignment'=>['horizontal'=>\PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER]
+ ]);//设置内容|居中|粗体;
+ $cellNums++;//自增列数
+ }
+ $shell->getRowDimension($rowNums)->setRowHeight(16);//设置标题行高
+ $rowNums++;//自增行数
+ //处理表格数据
+ foreach ($dataVo['info']['tbody'] as $tbodyVo) {
+ $cellNums=0;//初始化列数
+ $RowHeight=16;
+ foreach ($tbodyVo as $tbodyVal) {
+ if(is_array($tbodyVal)){
+ if($tbodyVal['type']=='img'){
+ //图像
+ $drawing=new \PhpOffice\PhpSpreadsheet\Worksheet\Drawing();
+ $drawing->setPath($tbodyVal['info']);//设置图像路径
+ $drawing->setOffsetX(22);//设置X偏移距离
+ $drawing->setOffsetY(3);//设置Y偏移距离
+ $drawing->setWidth(100);//设置图像宽度
+ $drawing->setCoordinates($cellName[$cellNums].$rowNums)->setWorksheet($shell);//设置内容
+ $imgInfo=getimagesize($tbodyVal['info']);//读取图像信息
+ $ImgHeight=($imgInfo[1]/($imgInfo[0]/100))*0.75;//计算行高|按照宽度缩放比例缩放
+ $RowHeight=$ImgHeight+4.5;//增加Y偏移1.5倍关系
+ }
+ }else{
+ $shell->setCellValueExplicit($cellName[$cellNums].$rowNums,$tbodyVal,\PhpOffice\PhpSpreadsheet\Cell\DataType::TYPE_STRING);//设置内容并指定文本格式
+ $shell->getStyle($cellName[$cellNums].$rowNums)->getAlignment()->setWrapText(true);//设置多行文本
+ }
+ $cellNums++;//自增列数
+ }
+ $shell->getRowDimension($rowNums)->setRowHeight($RowHeight);//设置数据行高
+ $rowNums++;//自增行数
+ }
+ }
+ }
+ //设置边框
+ $shell->getStyle('A1:'.$cellName[$maxCell-1].($rowNums-1))->applyFromArray (['borders'=>['allBorders'=>['borderStyle'=>\PhpOffice\PhpSpreadsheet\Style\Border::BORDER_THIN]],'alignment'=>['vertical'=>\PhpOffice\PhpSpreadsheet\Style\Alignment::VERTICAL_CENTER]]);
+ //输出文件
+ ob_get_contents()&&(ob_end_clean());//清除缓冲区,避免乱码
+ $writer=\PhpOffice\PhpSpreadsheet\IOFactory::createWriter($spreadsheet,'Xlsx');
+ if($down){
+ header('Content-type:application/vnd.ms-excel');
+ header("Content-Disposition:attachment;filename=$fileName.xlsx");
+ $writer->save('php://output');
+ exit;
+ }else{
+ delOverdueFile('static.file.xlsx');//删除过期文件
+ $filePath=pathChange('static.file.xlsx').$fileName.'.xlsx';
+ $writer->save($filePath);
+ return $filePath;
+ }
+}
+//生成压缩文件
+function buildZip($fileName,$files,$down=true){
+ delOverdueFile('static.file.zip');//删除过期文件
+ empty($files)&&(die('[ 文件数据为空 ]'));//空数据检验
+ $filePath=pathChange('static.file.zip').$fileName.'.zip';
+ $zip=new ZipArchive();
+ if ($zip->open($filePath,ZIPARCHIVE::CREATE)!==TRUE) {
+ exit('创建压缩文件失败!');
+ }
+ foreach ($files as $file) {
+ $zip->addFile($file,basename($file));
+ }
+ $zip->close();
+ if($down){
+ header("Cache-Control: max-age=0");
+ header("Content-Description: File Transfer");
+ header('Content-disposition: attachment; filename='.basename($filePath)); //文件名
+ header("Content-Type: application/zip"); //zip格式的
+ header("Content-Transfer-Encoding: binary"); //告诉浏览器,这是二进制文件
+ header('Content-Length: '.filesize($filePath)); //告诉浏览器,文件大小
+ @readfile($filePath);//输出文件;
+ exit;
+ }else{
+ return $filePath;
+ }
+}
+//curl请求
+function curl($url,$header,$data,$method='POST'){
+ $ch=curl_init();
+ if($method == 'GET'){
+ $url = $url.'?'.http_build_query($data);
+ }
+ if($method == 'POST'){
+ curl_setopt($ch, CURLOPT_POST,TRUE);
+ curl_setopt($ch, CURLOPT_POSTFIELDS,$data);
+ }
+ curl_setopt($ch, CURLOPT_URL,$url);
+ curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,FALSE);
+ curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,FALSE);
+ curl_setopt($ch,CURLOPT_HEADER,FALSE);
+ if($header!=false){
+ curl_setopt($ch,CURLOPT_HTTPHEADER,$header);
+ }
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER,TRUE);
+ $result=curl_exec($ch);
+ curl_close($ch);
+ return $result;
+}
+//获取文件夹大小
+function getDirSize($dir){
+ static $sizeResult = 0;
+ $handle = opendir($dir);
+ while (false!==($FolderOrFile = readdir($handle))) {
+ if($FolderOrFile != "." && $FolderOrFile != "..") {
+ if(is_dir("$dir/$FolderOrFile")){
+ $sizeResult += getDirSize("$dir/$FolderOrFile");
+ }else{
+ $sizeResult += filesize("$dir/$FolderOrFile");
+ }
+ }
+ }
+ closedir($handle);
+ return round(($sizeResult/1048576),2);
+}
+//获取数据库大小
+function getMysqlSize(){
+ $dbInfo=config('database.connections.mysql');
+ $tabs = think\facade\Db::query("SHOW TABLE STATUS FROM `".$dbInfo['database']."`");
+ $size = 0;
+ foreach($tabs as $vo) {
+ $size += $vo["Data_length"] + $vo["Index_length"];
+ }
+ //转换为M
+ return round(($size/1048576),2);
+}
+
+//生成条形码
+//$type[true:直接输出|false:保存文件]
+function txm($text,$type=true){
+ delOverdueFile('static.code.txm');//删除过期文件
+ $font = new BarcodeBakery\Common\BCGFontFile(pathChange('static.code.font').'Arial.ttf', 18);
+ $colorFront = new BarcodeBakery\Common\BCGColor(0, 0, 0);
+ $colorBack = new BarcodeBakery\Common\BCGColor(255, 255, 255);
+ $code = new BarcodeBakery\Barcode\BCGcode128();
+ $code->setScale(2);
+ $code->setThickness(30);
+ $code->setForegroundColor($colorFront);
+ $code->setBackgroundColor($colorBack);
+ $code->setFont($font);
+ $code->setStart(null);
+ $code->setTilde(true);
+ $code->parse($text);
+ if ($type){
+ header('Content-Type: image/png');
+ $drawing = new BarcodeBakery\Common\BCGDrawing('',$colorBack);
+ $drawing->setBarcode($code);
+ $drawing->draw();
+ $drawing->finish(BarcodeBakery\Common\BCGDrawing::IMG_FORMAT_PNG);
+ exit;
+ }else {
+ $filePath=pathChange('static.code.txm').uniqid().'.png';
+ $drawing = new BarcodeBakery\Common\BCGDrawing($filePath, $colorBack);
+ $drawing->setBarcode($code);
+ $drawing->draw();
+ $drawing->finish(BarcodeBakery\Common\BCGDrawing::IMG_FORMAT_PNG);
+ return $filePath;
+ }
+}
+//生成二维码
+//$type[true:直接输出|false:返回文件地址]
+function ewm($text,$type=true){
+ delOverdueFile('static.code.ewm');//删除过期文件
+ $qrCode = new Endroid\QrCode\QrCode($text);
+ if($type){
+ header('Content-Type: '.$qrCode->getContentType());
+ echo $qrCode->writeString();
+ exit;
+ }else{
+ $filePath=pathChange('static.code.ewm').uniqid().'.png';
+ $qrCode->writeFile($filePath);
+ return $filePath;
+ }
+}
+
+//高精度运算
+function math($digit=6){
+ $math=new \org\Math($digit);
+ return $math;
+}
+//数组求和
+function mathArraySum($arr){
+ $sum=0;
+ foreach ($arr as $vo) {
+ $sum=math()->chain($sum)->add($vo)->done();
+ }
+ return $sum;
+}
+//四舍五入处理位数
+function roundFloat($number,$digit){
+ return floatval(round($number,$digit));
+}
+
+//MD5|16位
+function md5_16($str){
+ return substr(md5($str),8,16);
+}
+//计算分页
+function PageCalc($page,$limit,$type='array'){
+ $state=$limit*($page-1);
+ $end=$limit;
+ return $type=='array'?[$state,$end]:$state.','.$end;
+}
+//二维数组指定字段去重
+function assoc_unique($arr,$key){
+ $record=[];
+ foreach($arr as $k => $v) {
+ if(in_array($v[$key],$record)){
+ unset($arr[$k]);
+ }else{
+ $record[]=$v[$key];
+ }
+ }
+ sort($arr);
+ return $arr;
+}
+//数据排序
+function arraySort(&$arr,$field,$sort=SORT_ASC){
+ $fields = [];
+ foreach ($arr as $vo) {
+ $fields[] = $vo[$field];
+ }
+ array_multisort($fields,$sort,$arr);
+}
+//数组包含数组
+function arrayInArray($arr1,$arr2){
+ foreach ($arr1 as $vo) {
+ if(!in_array($vo,$arr2)){
+ return false;
+ }
+ }
+ return true;
+}
+//多重提取数组列
+function arrayColumns($arr,$fields){
+ foreach ($fields as $field) {
+ $arr=array_column($arr,$field);
+ }
+ return $arr;
+}
+//获取路径的文件夹和文件
+function listFile($path,$state=true){
+ static $record=['dirs'=>[],'files'=>[]];
+ $state&&$record=['dirs'=>[],'files'=>[]];
+ foreach (new \FilesystemIterator($path) as $item) {
+ if ($item->isDir() && !$item->isLink()) {
+ $record['dirs'][]=$item->getPathname();
+ listFile($item->getPathname(),false);
+ } else {
+ $record['files'][]=$item->getPathname();
+ }
+ }
+ return $record;
+}
+//判断数组中指定键是否为数组
+function is_arrays($arr,$fields){
+ foreach ($fields as $field) {
+ if(!isset($arr[$field]) || !is_array($arr[$field])){
+ return false;
+ }
+ }
+ return true;
+}
+//获取指定天数
+function getOldDay($day=7){
+ $time=strtotime(date('Y-m-d',time()));//获取今天开始时间戳
+ $tmp_time_arr=[];
+ for ($i = 0; $i < $day; $i++) {
+ array_push($tmp_time_arr,date('Y-m-d',$time-($i*86400)));
+ }
+ return array_reverse($tmp_time_arr);//返回反转的数组
+}
+function uuid($prefix=''){
+ $chars = md5(uniqid(mt_rand(), true));
+ $uuid = substr($chars,0,8) . '-';
+ $uuid .= substr($chars,8,4) . '-';
+ $uuid .= substr($chars,12,4) . '-';
+ $uuid .= substr($chars,16,4) . '-';
+ $uuid .= substr($chars,20,12);
+ return $prefix . $uuid;
+}
+//[---------- 数据相关函数 ----------]
+//DB助手函数
+function db($model){
+ return think\facade\Db::name($model);
+}
+//获取系统配置
+//传入数组分类返回|传入字符返回内容
+function getSys($name = []) {
+ if(empty($name)){
+ $sql=[];
+ }else{
+ $sql=is_array($name)?[['name','in',$name]]:[['name','=',$name]];
+ }
+ $sys = db('sys')->where($sql)->field(['name','info'])->select()->toArray();
+ //数据二次处理|JSON对象转换
+ foreach ($sys as $sysKey => $sysVo) {
+ isJson($sysVo['info']) && ($sys[$sysKey]['info'] = json_decode($sysVo['info'],true));
+ }
+ if (empty($sys)) {
+ $result = false;
+ } else {
+ if(is_array($name)){
+ //分类返回
+ $result = [];
+ foreach ($sys as $sysVo) {
+ $result[$sysVo['name']] = $sysVo['info'];
+ }
+ }else{
+ //返回内容
+ $result = $sys[0]['info'];
+ }
+ }
+ return $result;
+}
+//写入日志
+function pushLog($info,$user=false) {
+ db('log')->insert([
+ 'time' => time(),
+ 'user' => empty($user)?getUserID():$user,
+ 'info' => $info
+ ]);
+}
+//获取结账日期
+function getPeriod(){
+ $row=db('period')->order(['id'=>'desc'])->find();
+ return empty($row)?0:$row['date'];
+}
+
+//快捷获取SQL
+//$arr:数组数据|$config:配置项
+//['field','Eq']|[['field','a|b|c'],'eq']
+//eq:等同查询|fullEq:不为空等于数据|noNullEq:不为NULL等同数据|fullDec1:不为空内容减1|fullTime:不为空转时间戳
+//md5:MD5加密|like:包含查询|fullLike:不为空包含查询
+//fullIn:不为空包含查询(传入数组)|fullDivisionIn:不为空分割集合包含查询
+//startTime和endTime:扩展时间字段查询
+function fastSql($arr,$config) {
+ $sql = [];
+ foreach ($config as $item){
+ $key=is_array($item[0])?key($item[0]):$item[0];
+ $field=is_array($item[0])?$item[0][key($item[0])]:$item[0];
+ if(array_key_exists($key,$arr)){
+ $val=$arr[$key];
+ $val==='null'&&($val=null);
+ $condition=$item[1];
+ //判断条件
+ if ($condition == 'eq') {
+ //等同查询
+ $sql[] = [$field,'=',$val];
+ } elseif ($condition == 'fullEq') {
+ //不为空等于数据
+ empty($val) || ($sql[] = [$field,'=',$val]);
+ } elseif ($condition == 'noNullEq') {
+ //不为NULL等于数据
+ $val===null || ($sql[] = [$field,'=',$val]);
+ } elseif ($condition == 'fullDec1') {
+ //不为空内容减1
+ empty($val) || ($sql[] = [$field,'=',$val-1]);
+ } else if ($condition == 'md5') {
+ //md5加密
+ $sql[] = [$field,'=',md5($val)];
+ } elseif ($condition == 'like') {
+ //包含查询
+ $sql[] = [$field,'like','%'.$val.'%'];
+ } elseif ($condition == 'fullLike') {
+ //不为空包含查询
+ empty($val) || ($sql[] = [$field,'like','%'.$val.'%']);
+ }elseif ($condition == 'fullTime') {
+ //不为空转时间戳
+ empty($val) || ($sql[] = [$field,'=',strtotime($val)]);
+ }elseif ($condition == 'fullIn') {
+ //不为空包含查询
+ empty($val) || ($sql[] = [$field,'in',$val]);
+ } elseif ($condition == 'fullDivisionIn') {
+ //不为空分割集合查询
+ empty($val) || ($sql[] = [$field,'in',explode(",",$val)]);
+ } elseif ($condition == 'startTime') {
+ //开始时间
+ $start=strtotime($val);
+ empty($start)||($sql[] = [$field,'>=',$start]);
+ } elseif ($condition == 'endTime') {
+ //结束时间
+ $end=strtotime($val);
+ empty($end)||($sql[] = [$field,'<=',$end+86399]);
+ }else{
+ die('[ ERROR ]未匹配条件!');
+ }
+ }
+ }
+ return array_unique($sql,SORT_REGULAR);
+}
+//递归获取指定ID树状数组结构
+function findTreeArr($mode,$data,$field = false) {
+ $tree = [];
+ //判断是否初次执行
+ if (!is_array($data)) {
+ $first = db($mode)->where([['id','=',$data]])->find();
+ //查询首次数据
+ $tree[] = $first;
+ //加入首次数据
+ $data = [$first];
+ //修正数据数组类型
+ }
+ $gather = array_column($data,'id');
+ //获取集合数据
+ $arr = db($mode)->where([['pid','in',$gather]])->select()->toArray();
+ //查询子数据
+ if (!empty($arr)) {
+ $tree = array_merge($tree,$arr,findTreeArr($mode,$arr));
+ //合并数据
+ }
+ return $field == false?$tree:array_column($tree,$field);
+}
+//多表多条件find查询
+//$arr[['table'=>'plug','where'=>[['only','=',1]]]]
+function moreTableFind($arr) {
+ $result = false;
+ //默认未找到
+ foreach ($arr as $vo) {
+ $find = db($vo['table'])->where($vo['where'])->find();
+ if (!empty($find)) {
+ $result = true;
+ //找到数据
+ break;
+ }
+ }
+ return $result;
+}
+//SQL条件转换|数组条件转索引数组
+function parmToIndex($parm){
+ $sql=[];
+ foreach ($parm as $parmKey=>$parmVo) {
+ $sql[]=[$parmKey,'=',$parmVo];
+ }
+ return $sql;
+}
+//多单位分析|转换基数
+function unitRadix($unit,$data){
+ $radix=1;
+ $state=false;
+ array_unshift($data,['name'=>$data[0]['source'],'nums'=>1]);
+ $data=array_reverse($data);
+ foreach ($data as $dataVo) {
+ if($state || $dataVo['name']==$unit){
+ $state=true;
+ $radix=math()->chain($radix)->mul($dataVo['nums'])->done();
+ }
+ }
+ if($state){
+ return $radix;
+ }else{
+ return false;
+ }
+}
+//多单位分析|单位转换
+function unitSwitch($nums,$data){
+ //1 构造数据
+ $record=[];
+ foreach ($data as $dataVo) {
+ if(abs($nums)<$dataVo['nums']){
+ //1.1 小于归零
+ $record[]=['name'=>$dataVo['source'],'nums'=>$nums];
+ $nums=0;
+ }else{
+ //1.2 取余
+ $mod=math()->chain($nums)->mod($dataVo['nums'])->done();
+ $record[]=['name'=>$dataVo['source'],'nums'=>abs($mod)];
+ //1.3 递减数量
+ $nums=math()->chain($nums)->sub($mod)->div($dataVo['nums'])->done();
+ }
+ }
+ //2 追加数据
+ $end=end($data);
+ $record[]=['name'=>$end['name'],'nums'=>$nums];
+ //3 结构数据
+ $text='';
+ foreach (array_reverse($record) as $recordVo) {
+ if(!empty($recordVo['nums'])){
+ $text.=$recordVo['nums'].$recordVo['name'];
+ }
+ }
+ $text==''&&$text=0;
+ return $text;
+}
+//获取用户信息
+function userInfo($id,$field = false) {
+ $user = db('user')->where([['id','=',$id]])->find();
+ return $field == false?$user:$user[$field];
+}
+//获取授权数据范围
+function getUserAuth($type){
+ $user=userInfo(getUserID());
+ if($user['role']==0){
+ $result='all';
+ }else{
+ $role=db('role')->where([['id','=',$user['role']]])->find();
+ $auth=json_decode($role['auth'],true);
+ if($type=='frame'){
+ if(count($auth['frame'])==1 && $auth['frame'][0]==-2){
+ $result='all';
+ }else if(count($auth['frame'])==1 && $auth['frame'][0]==-1){
+ $result=[$user['frame']];
+ }else{
+ $result=$auth['frame'];
+ }
+ }elseif($type=='customer'){
+ if($auth['customer']=='all'){
+ $result='all';
+ }else if($auth['customer']=='userId'){
+ $user=getUserAuth('user');
+ if($user=='all'){
+ $result='all';
+ }else{
+ $result=array_column(db('customer')->where([['user','in',$user]])->field(['id'])->select()->toArray(),'id');
+ }
+ }else{
+ $frame=getUserAuth('frame');
+ if($frame=='all'){
+ $result='all';
+ }else{
+ $result=array_column(db('customer')->where([['frame','in',$frame]])->field(['id'])->select()->toArray(),'id');
+ }
+ }
+ }elseif($type=='supplier'){
+ if($auth['supplier']=='all'){
+ $result='all';
+ }else if($auth['supplier']=='userId'){
+ $user=getUserAuth('user');
+ if($user=='all'){
+ $result='all';
+ }else{
+ $result=array_column(db('supplier')->where([['user','in',$user]])->field(['id'])->select()->toArray(),'id');
+ }
+ }else{
+ $frame=getUserAuth('frame');
+ if($frame=='all'){
+ $result='all';
+ }else{
+ $result=array_column(db('supplier')->where([['frame','in',$frame]])->field(['id'])->select()->toArray(),'id');
+ }
+ }
+ }elseif($type=='warehouse'){
+ if($auth['warehouse']=='all'){
+ $result='all';
+ }else if($auth['warehouse']=='userFrame'){
+ $result=[$user['frame']];
+ }else{
+ $frame=getUserAuth('frame');
+ if($frame=='all'){
+ $result='all';
+ }else{
+ $result=array_column(db('warehouse')->where([['frame','in',$frame]])->field(['id'])->select()->toArray(),'id');
+ }
+ }
+ }elseif($type=='account'){
+ if($auth['account']=='all'){
+ $result='all';
+ }else if($auth['account']=='userFrame'){
+ $result=[$user['frame']];
+ }else{
+ $frame=getUserAuth('frame');
+ if($frame=='all'){
+ $result='all';
+ }else{
+ $result=array_column(db('account')->where([['frame','in',$frame]])->field(['id'])->select()->toArray(),'id');
+ }
+ }
+ }elseif($type=='user'){
+ if($auth['user']=='all'){
+ $result='all';
+ }else if($auth['user']=='userId'){
+ $result=[getUserID()];
+ }else{
+ $frame=getUserAuth('frame');
+ if($frame=='all'){
+ $result='all';
+ }else{
+ $result=array_column(db('user')->where([['frame','in',$frame]])->field(['id'])->select()->toArray(),'id');
+ }
+ }
+ }elseif($type=='people'){
+ if($auth['people']=='all'){
+ $result='all';
+ }else if($auth['people']=='userFrame'){
+ $result=[$user['frame']];
+ }else{
+ $frame=getUserAuth('frame');
+ if($frame=='all'){
+ $result='all';
+ }else{
+ $result=array_column(db('people')->where([['frame','in',$frame]])->field(['id'])->select()->toArray(),'id');
+ }
+ }
+ }else{
+ $result = false;
+ }
+ }
+ return $result;
+}
+//组织数据范围
+function frameScope($sql,$field='frame'){
+ $cache=cache(getToken());
+ if(empty($cache['frame'])){
+ $frame=getUserAuth('frame');
+ if($frame!='all'){
+ $sql[]=[$field,'in',$frame];
+ }
+ }else{
+ $sql[]=[$field,'in',$cache['frame']];
+ }
+ return $sql;
+}
+//SQL数据鉴权
+function sqlAuth($model,$sql=[]){
+ $tab=[
+ 'user'=>['id'=>'user','frame'=>'frame'],
+ 'log'=>['user'=>'user'],
+ 'customer'=>['id'=>'customer','frame'=>'frame','user'=>'user'],
+ 'supplier'=>['id'=>'supplier','frame'=>'frame','user'=>'user'],
+ 'warehouse'=>['id'=>'warehouse','frame'=>'frame'],
+ 'account'=>['id'=>'account','frame'=>'frame'],
+ 'people'=>['frame'=>'frame'],
+ 'bor'=>['frame'=>'frame','supplier'=>'supplier','people'=>'people','user'=>'user'],
+ 'buy'=>['frame'=>'frame','supplier'=>'supplier','people'=>'people','user'=>'user'],
+ 'bre'=>['frame'=>'frame','supplier'=>'supplier','people'=>'people','user'=>'user'],
+ 'sor'=>['frame'=>'frame','customer'=>'customer','people'=>'people','user'=>'user'],
+ 'sell'=>['frame'=>'frame','customer'=>'customer','people'=>'people','user'=>'user'],
+ 'sre'=>['frame'=>'frame','customer'=>'customer','people'=>'people','user'=>'user'],
+ 'swap'=>['frame'=>'frame','people'=>'people','user'=>'user'],
+ 'entry'=>['frame'=>'frame','people'=>'people','user'=>'user'],
+ 'extry'=>['frame'=>'frame','people'=>'people','user'=>'user'],
+ 'imy'=>['frame'=>'frame','customer'=>'customer','people'=>'people','user'=>'user'],
+ 'omy'=>['frame'=>'frame','supplier'=>'supplier','people'=>'people','user'=>'user'],
+ 'bill'=>['frame'=>'frame','people'=>'people','user'=>'user'],
+ 'allot'=>['frame'=>'frame','people'=>'people','user'=>'user'],
+ 'ice'=>['frame'=>'frame','customer'=>'customer','people'=>'people','user'=>'user'],
+ 'oce'=>['frame'=>'frame','supplier'=>'supplier','people'=>'people','user'=>'user'],
+ 'summary'=>['warehouse'=>'warehouse'],
+ 'room'=>['warehouse'=>'warehouse'],
+ 'batch'=>['warehouse'=>'warehouse'],
+ 'period'=>['user'=>'user']
+ ];
+ //扩展数据
+ $extend=[
+ 'entry'=>['customer'=>[0]],
+ 'extry'=>['supplier'=>[0]],
+ 'ice'=>['customer'=>[0]],
+ 'oce'=>['supplier'=>[0]]
+ ];
+ $user = userInfo(getUserID());
+ //排除管理员
+ if($user['role']!=0){
+ $role=db('role')->where([['id','=',$user['role']]])->find();
+ $auth=json_decode($role['auth'],true);
+ foreach ($tab[$model] as $tabKey => $tabVo) {
+ //排除存在SQL键名
+ if(!in_array($tabKey,array_column($sql,0))){
+ $auth=getUserAuth($tabVo);
+ if($auth!='all'){
+ //填入扩展
+ isset($extend[$model][$tabKey])&&$auth=array_merge($auth,$extend[$model][$tabKey]);
+ //赋值语句
+ $sql[] = [$tabKey,'in',$auth];
+ }
+ }
+ }
+ }
+ return $sql;
+}
+//获取扩展字段配置
+function getFields() {
+ $data=[];
+ $field = db('field')->select()->toArray();
+ foreach ($field as $fieldVo) {
+ $data[$fieldVo['key']] = json_decode($fieldVo['fields'],true);
+ }
+ return $data;
+}
+//获取用户权限数据
+function getUserRoot() {
+ $user=userInfo(getUserID());
+ if ($user['role'] == 0) {
+ return 'all';
+ } else {
+ $role = db('role')->where([['id','=',$user['role']]])->find();
+ $root = json_decode($role['root'],true);
+ //初始化权限数据
+ foreach ($root as $rootVo) {
+ $data[$rootVo['module']] = $rootVo['data'];
+ }
+ return $data;
+ }
+}
+//获取组织零售单配置
+function getFrameDeploy(){
+ $userFrame=userInfo(getUserID(),'frame');
+ $frame=db('frame')->where([['id','=',$userFrame]])->find();
+ $deploy=db('deploy')->where([['frame','=',$frame['id']]])->find();
+ while ($frame['pid']!=-1 && empty($deploy)){
+ $frame=db('frame')->where([['id','=',$frame['pid']]])->find();
+ $deploy=db('deploy')->where([['frame','=',$frame['id']]])->find();
+ }
+ return empty($deploy)?null:json_decode($deploy['source'],true);
+}
+
+//获用户权限菜单数据
+function getRootMemu() {
+ $root = getUserRoot();
+ if ($root == 'all') {
+ $menu= db('menu')->order('sort asc')->select()->toArray();
+ } else {
+ $menu = db('menu')->where([['root','<>','admin'],['id','>',0]])->order('sort asc')->select()->toArray();
+ //1.做数据标识
+ foreach ($menu as $menuKey=>$menuVo) {
+ $voRoot=explode('|',$menuVo['root']);
+ //[权限为空|常规上级菜单|权限存在且为真]
+ $menu[$menuKey]['check']=(empty($menuVo['root']) || $menuVo['resource']=='#group' || (isset($root[$voRoot[0]][count($voRoot)==1?'see':$voRoot[1]])&&$root[$voRoot[0]][count($voRoot)==1?'see':$voRoot[1]]=='true'))?1:0;
+ }
+ //2.处理附属菜单
+ foreach (search($menu)->where([['type','=',1],['check','=',1]])->select() as $menuVo) {
+ $pidData=search($menu)->where([['id','=',$menuVo['pid']],['check','=',false]],true)->find();
+ empty($pidData)||$menu[$pidData['rowKey']]['check']=-1;
+ }
+ //3.保留可访问菜单数据
+ $menu=search($menu)->where([['check','in',[1,-1]]])->select();
+ //4.处理空集菜单
+ $group=search($menu)->where([['resource','=','#group']],true)->select();
+ foreach ($group as $menuVo) {
+ $tree = new \org\Tree();
+ $v=$tree::vTree($menu,$menuVo['id']);
+ if(empty($v)){
+ unset($menu[$menuVo['rowKey']]);
+ }else{
+ $find=search($v)->where([['resource','<>','#group']])->find();
+ if(empty($find)){
+ unset($menu[$menuVo['rowKey']]);
+ }
+ }
+ }
+ }
+ return $menu;
+}
\ No newline at end of file
diff --git a/serve/app/controller/Account.php b/serve/app/controller/Account.php
new file mode 100644
index 0000000..f331752
--- /dev/null
+++ b/serve/app/controller/Account.php
@@ -0,0 +1,118 @@
+count();//获取总条数
+ $info = Accounts::with(['frameData'])->where($sql)->append(['extension'])->page($input['page'],$input['limit'])->order(['id'=>'desc'])->select();//查询分页数据
+ $result=[
+ 'state'=>'success',
+ 'count'=>$count,
+ 'info'=>$info
+ ];//返回数据
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //新增|更新
+ public function save(){
+ $input=input('post.');
+ if(isset($input['id'])){
+ //构造|验证
+ try {
+ //排除balance字段|防止更新账户余额
+ unset($input['balance']);
+ empty($input['id'])?$this->validate($input,'app\validate\Account'):$this->validate($input,'app\validate\Account.update');
+ } catch (ValidateException $e) {
+ return json(['state'=>'error','info'=>$e->getError()]);
+ exit;
+ }
+
+ //处理数据
+ Db::startTrans();
+ try {
+ if(empty($input['id'])){
+ //创建数据
+ Accounts::create($input);
+ pushLog('新增资金账户[ '.$input['name'].' ]');//日志
+ }else{
+ //更新数据
+ Accounts::update($input);
+ pushLog('更新资金账户[ '.$input['name'].' ]');//日志
+ }
+
+ Db::commit();
+ $result=['state'=>'success'];
+ } catch (\Exception $e) {
+ Db::rollback();
+ $result=['state'=>'error','info'=>'内部错误,操作已撤销!'];
+ }
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //获取
+ public function get(){
+ $input=input('post.');
+ if(existFull($input,['id'])){
+ $info=Accounts::where([['id','=',$input['id']]])->find();
+ $result=['state'=>'success','info'=>$info];
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //删除
+ public function del(){
+ $input=input('post.');
+ if(existFull($input,['id'])){
+ //关联判断
+ $exist=moreTableFind([
+ ['table'=>'sell','where'=>[['account','=',$input['id']]]],
+ ['table'=>'sre','where'=>[['account','=',$input['id']]]],
+ ['table'=>'buy','where'=>[['account','=',$input['id']]]],
+ ['table'=>'bre','where'=>[['account','=',$input['id']]]],
+ ['table'=>'ice','where'=>[['account','=',$input['id']]]],
+ ['table'=>'oce','where'=>[['account','=',$input['id']]]],
+ ['table'=>'allot_info','where'=>[['account|tat','=',$input['id']]]],
+ ['table'=>'deploy','where'=>[['source','like','%"account":'.$input['id'].'%']]]
+ ]);
+ if(empty($exist)){
+ //逻辑处理
+ $find=Db::name('account')->where([['id','=',$input['id']]])->find();
+ Db::startTrans();
+ try {
+ Db::name('account')->where([['id','=',$input['id']]])->delete();
+ Db::name('account_info')->where([['pid','=',$input['id']]])->delete();
+ pushLog('删除资金账户[ '.$find['name'].' ]');//日志
+
+ Db::commit();
+ $result=['state'=>'success'];
+ } catch (\Exception $e) {
+ Db::rollback();
+ $result=['state'=>'error','info'=>'内部错误,操作已撤销!'];
+ }
+ }else{
+ $result=['state'=>'error','info'=>'存在数据关联,删除失败!'];
+ }
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+}
\ No newline at end of file
diff --git a/serve/app/controller/Acl.php b/serve/app/controller/Acl.php
new file mode 100644
index 0000000..8e3116d
--- /dev/null
+++ b/serve/app/controller/Acl.php
@@ -0,0 +1,11 @@
+'error','info'=>'访问由于凭证无效被拒绝!'],401)->send());
+ }
+ }
+}
\ No newline at end of file
diff --git a/serve/app/controller/Ali.php b/serve/app/controller/Ali.php
new file mode 100644
index 0000000..dca4570
--- /dev/null
+++ b/serve/app/controller/Ali.php
@@ -0,0 +1,129 @@
+protocol = 'https';
+ $config->gatewayHost = 'openapi.alipay.com';
+ $config->appId = $deploy['ali']['appid'];
+ $config->signType = 'RSA2';
+ $config->alipayPublicKey = $deploy['ali']['public'];
+ $config->merchantPrivateKey = $deploy['ali']['private'];
+ Factory::setOptions($config);
+ //单据数据
+ $result = Factory::payment()->faceToFace()->pay($deploy['ali']['title'],$input['number'],$input['money'],$input['code']);
+ if($result->code=='10000'){
+ //支付成功
+ $result=['state'=>'success','info'=>$result->tradeNo];
+ }else{
+ //支付失败
+ if(in_array($result->code,['10003','20000'])){
+ //返回等待信息
+ $result=['state'=>'wait','info'=>'等待操作...'];
+ }else{
+ //确认失败,返回错误信息
+ $result=['state'=>'wrong','info'=>$result->subMsg];
+ }
+ }
+ }else{
+ $result=['state'=>'error','info'=>'支付参数不完整!'];
+ }
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //查询单据
+ public function query(){
+ $input=input('post.');
+ if(existFull($input,['number'])){
+ //读取配置
+ $deploy=getFrameDeploy();
+ if(!empty($deploy)){
+ //配置数据
+ $config=new Config;
+ $config->protocol = 'https';
+ $config->gatewayHost = 'openapi.alipay.com';
+ $config->appId = $deploy['ali']['appid'];
+ $config->signType = 'RSA2';
+ $config->alipayPublicKey = $deploy['ali']['public'];
+ $config->merchantPrivateKey = $deploy['ali']['private'];
+ Factory::setOptions($config);
+ //单据数据
+ $result = Factory::payment()->common()->query($input['number']);
+ //调用结果
+ if($result->code=='10000'){
+ if(in_array($result->tradeStatus,['TRADE_SUCCESS','TRADE_FINISHED'])){
+ //支付成功
+ $result=['state'=>'success','info'=>$result->tradeNo];
+ }elseif($result->tradeStatus=='WAIT_BUYER_PAY'){
+ //返回等待信息
+ $result=['state'=>'wait','info'=>'等待操作...'];
+ }else{
+ $result=['state'=>'wrong','info'=>'未付款|支付超时|已撤销|已退款'];
+ }
+ }else{
+ //确认失败,返回错误信息
+ $result=['state'=>'wrong','info'=>$result->subMsg];
+ }
+ }else{
+ $result=['state'=>'error','info'=>'支付参数不完整!'];
+ }
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //撤销单据
+ //支付成功退款|未支付关闭单据
+ public function cancel(){
+ $input=input('post.');
+ if(existFull($input,['number'])){
+ //读取配置
+ $deploy=getFrameDeploy();
+ if(!empty($deploy)){
+ //配置数据
+ $config=new Config;
+ $config->protocol = 'https';
+ $config->gatewayHost = 'openapi.alipay.com';
+ $config->appId = $deploy['ali']['appid'];
+ $config->signType = 'RSA2';
+ $config->alipayPublicKey = $deploy['ali']['public'];
+ $config->merchantPrivateKey = $deploy['ali']['private'];
+ Factory::setOptions($config);
+ //单据数据
+ $result = Factory::payment()->common()->cancel($input['number']);
+ //调用结果
+ if($result->code=='10000'){
+ if(in_array($result->action,['close','refund'])){
+ //撤销成功
+ $result=['state'=>'success','info'=>'撤销单据成功!'];
+ }else{
+ $result=['state'=>'wrong','info'=>'撤销单据失败,请人工处理!'];
+ }
+ }else{
+ //确认失败,返回错误信息
+ $result=['state'=>'wrong','info'=>$result->subMsg];
+ }
+ }else{
+ $result=['state'=>'error','info'=>'支付参数不完整!'];
+ }
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+}
\ No newline at end of file
diff --git a/serve/app/controller/Allot.php b/serve/app/controller/Allot.php
new file mode 100644
index 0000000..64d5292
--- /dev/null
+++ b/serve/app/controller/Allot.php
@@ -0,0 +1,462 @@
+'time'],'startTime'],
+ [['endTime'=>'time'],'endTime'],
+ ['user','fullEq'],
+ ['examine','fullDec1'],
+ ['people','fullEq'],
+ ['data','fullLike']
+ ]);//构造SQL
+ //转账字段扩展查询
+ if(existFull($input,['account'])){
+ $sql[]=['id','in',array_column(Db::name('allot_info')->where([['account|tat','=',$input['account']]])->select()->toArray(),'pid')];
+ }
+ $sql=frameScope($sql);//组织数据
+ $sql=sqlAuth('allot',$sql);//数据鉴权
+ $count = Allots::where($sql)->count();//获取总条数
+ $info = Allots::with(['frameData','peopleData','userData','recordData'])->where($sql)->append(['extension'])->page($input['page'],$input['limit'])->order(['id'=>'desc'])->select()->toArray();//查询分页数据
+ $result=[
+ 'state'=>'success',
+ 'count'=>$count,
+ 'info'=>$info
+ ];//返回数据
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //新增|更新
+ public function save(){
+ $input=input('post.');
+ if(existFull($input,['class','info']) && isset($input['class']['id'])){
+ //构造|验证CLASS
+ try {
+ $class=$input['class'];
+ $class['frame']=userInfo(getUserID(),'frame');
+ $class['user']=getUserID();
+ $class['examine']=0;
+ empty($class['id'])?$this->validate($class,'app\validate\Allot'):$this->validate($class,'app\validate\Allot.update');
+ $period=getPeriod();
+ if(strtotime($class['time'])<=$period){
+ throw new ValidateException('单据日期与结账日期冲突!');
+ }
+ } catch (ValidateException $e) {
+ return json(['state'=>'error','info'=>$e->getError()]);
+ exit;
+ }
+
+ //验证INFO
+ foreach ($input['info'] as $infoKey=>$infoVo) {
+ try {
+ $this->validate($infoVo,'app\validate\AllotInfo');
+ } catch (ValidateException $e) {
+ return json(['state'=>'error','info'=>'数据表格第'.($infoKey+1).'条'.$e->getError()]);
+ exit;
+ }
+ }
+
+ //处理数据
+ Db::startTrans();
+ try {
+ //CLASS数据
+ if(empty($class['id'])){
+ //创建数据
+ $createInfo=Allots::create($class);
+ $class['id']=$createInfo['id'];//转存主键
+ Db::name('record')->insert(['type'=>'allot','source'=>$class['id'],'time'=>time(),'user'=>getUserID(),'info'=>'新增单据']);
+ pushLog('新增转账单[ '.$class['number'].' ]');//日志
+ }else{
+ //更新数据
+ $updateInfo=Allots::update($class);
+ Db::name('record')->insert(['type'=>'allot','source'=>$class['id'],'time'=>time(),'user'=>getUserID(),'info'=>'更新单据']);
+ pushLog('更新转账单[ '.$class['number'].' ]');//日志
+ }
+
+ //INFO数据
+ AllotInfo::where([['pid','=',$class['id']]])->delete();
+ foreach ($input['info'] as $infoKey=>$infoVo) {
+ $input['info'][$infoKey]['pid']=$class['id'];
+ }
+ $model = new AllotInfo;
+ $model->saveAll($input['info']);
+
+ Db::commit();
+ $result=['state'=>'success','info'=>$class['id']];
+ } catch (\Exception $e) {
+ Db::rollback();
+ $result=['state'=>'error','info'=>'内部错误,操作已撤销!'];
+ }
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //获取
+ public function get(){
+ $input=input('post.');
+ if(existFull($input,['parm'])){
+ $class=Allots::where([['id','=',$input['parm']]])->find();
+ $info=AllotInfo::with(['accountData','tatData'])->where([['pid','=',$input['parm']]])->order(['id'=>'asc'])->select();
+ $result=['state'=>'success','info'=>[
+ 'class'=>$class,
+ 'info'=>$info,
+ ]];
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //删除
+ public function del(){
+ $input=input('post.');
+ if(existFull($input,['parm']) && is_array($input['parm'])){
+ $data=Db::name('allot')->where([['id','in',$input['parm']]])->order(['id'=>'desc'])->select()->toArray();
+ $search=search($data)->where([['examine','=','1']])->find();
+ if(empty($search)){
+ Db::startTrans();
+ try {
+ Db::name('allot')->where([['id','in',$input['parm']]])->delete();
+ Db::name('allot_info')->where([['pid','in',$input['parm']]])->delete();
+ Db::name('record')->where([['type','=','allot'],['source','in',$input['parm']]])->delete();
+ Db::name('log')->insert(['time'=>time(),'user'=>getUserID(),'info'=>'删除转账单[ '.implode(' | ',array_column($data,'number')).' ]']);
+
+ Db::commit();
+ $result=['state'=>'success'];
+ } catch (\Exception $e) {
+ Db::rollback();
+ $result=['state'=>'error','info'=>'内部错误,操作已撤销!'];
+ }
+ }else{
+ $result=['state'=>'error','info'=>'单据['.$search['number'].']已审核,不可删除!'];
+ }
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //审核|反审核
+ public function examine(){
+ $input=input('post.');
+ if(existFull($input,['parm']) && is_array($input['parm'])){
+ //1 基础数据
+ $period=getPeriod();
+ $classList=Db::name('allot')->where([['id','in',$input['parm']]])->order(['id'=>'desc'])->select()->toArray();
+ $infoList=Db::name('allot_info')->where([['pid','in',$input['parm']]])->order(['id'=>'asc'])->select()->toArray();
+ //2 综合处理
+ foreach ($input['parm'] as $parmVo) {
+ //1 匹配数据
+ $class=search($classList)->where([['id','=',$parmVo]])->find();
+ $info=search($infoList)->where([['pid','=',$parmVo]])->select();
+ //2 CLASS验证
+ if($class['time']<=$period){
+ return json(['state'=>'error','info'=>'操作单据[ '.$class['number'].' ]失败,原因:单据日期与结账日期冲突!']);
+ exit;
+ }
+ //3 数据处理
+ Db::startTrans();
+ try {
+ //场景验证
+ if(empty($class['examine'])){
+ //审核
+ //1 构造数据
+ $outStore=['account'=>[],'accountInfo'=>[]];
+ $enterStore=['account'=>[],'accountInfo'=>[]];
+ foreach ($info as $infoKey=>$infoVo){
+ //1 转出账户
+ $outStore['account'][]=['id'=>$infoVo['account'],'balance'=>$infoVo['money']];
+ //2 转出账户详情
+ $outStore['accountInfo'][]=['pid'=>$infoVo['account'],'type'=>'allotOut','class'=>$class['id'],'time'=>$class['time'],'direction'=>0,'money'=>$infoVo['money']];
+ //3 转入账户
+ $enterStore['account'][]=['id'=>$infoVo['tat'],'balance'=>$infoVo['money']];
+ //4 转入账户详情
+ $enterStore['accountInfo'][]=['pid'=>$infoVo['tat'],'type'=>'allotEnter','class'=>$class['id'],'time'=>$class['time'],'direction'=>1,'money'=>$infoVo['money']];
+ }
+ //2 转出账户
+ Db::name('account')->duplicate(['balance'=>Db::raw('balance - VALUES(`balance`)')])->insertAll($outStore['account']);
+ //3 转出账户详情
+ Db::name('account_info')->insertAll($outStore['accountInfo']);
+ //4 转入账户
+ Db::name('account')->duplicate(['balance'=>Db::raw('balance + VALUES(`balance`)')])->insertAll($enterStore['account']);
+ //5 转入账户详情
+ Db::name('account_info')->insertAll($enterStore['accountInfo']);
+ //6 更新单据
+ Db::name('allot')->where([['id','=',$class['id']]])->update(['examine'=>1]);
+ //7 单据记录
+ Db::name('record')->insert(['type'=>'allot','source'=>$class['id'],'time'=>time(),'user'=>getUserID(),'info'=>'审核单据']);
+ //8 记录操作
+ pushLog('审核转账单[ '.$class['number'].' ]');//单据日志
+ }else{
+ //反审核
+
+ //--- 转出数据 ---
+
+ //1 匹配数据
+ $accountInfoList=Db::name('account_info')->where([['type','=','allotOut'],['class','=',$class['id']]])->select()->toArray();
+ //2 资金账户
+ $accountDuplicate=[];
+ foreach ($accountInfoList as $accountInfoVo) {
+ $accountDuplicate[]=['id'=>$accountInfoVo['pid'],'balance'=>$accountInfoVo['money']];
+ }
+ //2.1 更新资金
+ Db::name('account')->duplicate(['balance'=>Db::raw('balance + VALUES(`balance`)')])->insertAll($accountDuplicate);
+ //2.2 删除资金详情
+ Db::name('account_info')->where([['id','in',array_column($accountInfoList,'id')]])->delete();
+
+ //--- 转入数据 ---
+
+ //3 匹配数据
+ $accountInfoList=Db::name('account_info')->where([['type','=','allotEnter'],['class','=',$class['id']]])->select()->toArray();
+ //4 资金账户
+ $accountDuplicate=[];
+ foreach ($accountInfoList as $accountInfoVo) {
+ $accountDuplicate[]=['id'=>$accountInfoVo['pid'],'balance'=>$accountInfoVo['money']];
+ }
+ //5.1 更新资金
+ Db::name('account')->duplicate(['balance'=>Db::raw('balance - VALUES(`balance`)')])->insertAll($accountDuplicate);
+ //5.2 删除资金详情
+ Db::name('account_info')->where([['id','in',array_column($accountInfoList,'id')]])->delete();
+
+ //6 更新单据
+ Db::name('allot')->where([['id','=',$class['id']]])->update(['examine'=>0]);
+ //7 单据记录
+ Db::name('record')->insert(['type'=>'allot','source'=>$class['id'],'time'=>time(),'user'=>getUserID(),'info'=>'反审核单据']);
+ //8 记录操作
+ pushLog('反审核转账单[ '.$class['number'].' ]');//单据日志
+ }
+
+ Db::commit();
+ } catch (\Exception $e) {
+ Db::rollback();
+ return json(['state'=>'error','info'=>'内部错误,操作已撤销!']);
+ exit;
+ }
+ }
+ $result=['state'=>'success'];
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //上传
+ public function upload(){
+ $file = request()->file('file');
+ //获取上传文件
+ if (empty($file)) {
+ $result = ['state' => 'error','info' => '传入数据不完整!'];
+ } else {
+ //文件限制5MB
+ try{
+ validate(['file'=>['fileSize'=>5*1024*1024,'fileExt'=>'png,gif,jpg,jpeg,txt,doc,docx,rtf,xls,xlsx,ppt,pptx,pdf,zip,rar']])->check(['file'=>$file]);
+ $fileInfo=Filesystem::disk('upload')->putFile('allot', $file, 'uniqid');
+ $filePath=request()->domain().'/static/upload/'.$fileInfo;
+ $result=['state'=>'success','info'=>$filePath];
+ }catch(ValidateException $e) {
+ $result = ['state' => 'error','info' => $e->getMessage()];
+ }
+ }
+ return json($result);
+ }
+ //导入
+ public function import(){
+ delOverdueFile('static.upload.xlsx');//删除过期文件
+ $file=request()->file('file');//获取上传文件
+ if(empty($file)){
+ $result=['state'=>'error','info'=>'传入数据不完整!'];
+ }else{
+ $fun=getSys('fun');
+ try{
+ validate(['file'=>['fileSize'=>2*1024*1024,'fileExt'=>'xlsx']])->check(['file'=>$file]);
+ $fileInfo = Filesystem::disk('upload')->putFile('xlsx', $file, 'uniqid');
+ $filePath = pathChange('static.upload').$fileInfo;
+ $data=getXlsx($filePath);
+ unset($data[1]);//删除标题行
+ unset($data[2]);//删除列名行
+ //初始化CLASS
+ //关联人员匹配
+ if(empty($data[3]['D'])){
+ $people=['id'=>0];
+ }else{
+ $people=Db::name('people')->where([['name','=',$data[3]['D']]])->find();
+ if(empty($people)){
+ throw new ValidateException('关联人员[ '.$data[3]['D'].' ]未匹配!');
+ }
+ }
+ $class=[
+ 'frame'=>userInfo(getUserID(),'frame'),
+ 'time'=>$data[3]['A'],
+ 'number'=>$data[3]['B'],
+ 'total'=>0,
+ 'people'=>$people['id'],
+ 'file'=>[],
+ 'data'=>$data[3]['E'],
+ 'more'=>[],
+ 'examine'=>0,
+ 'user'=>getUserID()
+ ];
+ $this->validate($class,'app\validate\Allot');//数据合法性验证
+ //初始化INFO
+ $info=[];
+ $account=Db::name('account')->where([['name','in',array_column($data,'F')]])->select()->toArray();
+ $tat=Db::name('account')->where([['name','in',array_column($data,'G')]])->select()->toArray();
+ foreach ($data as $dataKey=>$dataVo) {
+ $record=[
+ 'account'=>$dataVo['F'],
+ 'tat'=>$dataVo['G'],
+ 'money'=>$dataVo['H'],
+ 'settle'=>$dataVo['I'],
+ 'data'=>$dataVo['J']
+ ];
+ //转出账户匹配
+ $accountFind=search($account)->where([['name','=',$record['account']]])->find();
+ if(empty($accountFind)){
+ throw new ValidateException('模板文件第'.$dataKey.'行转出账户[ '.$record['account'].' ]未匹配!');
+ }else{
+ $record['account']=$accountFind['id'];
+ }
+ //转入账户匹配
+ $tatFind=search($tat)->where([['name','=',$record['tat']]])->find();
+ if(empty($tatFind)){
+ throw new ValidateException('模板文件第'.$dataKey.'行转入账户[ '.$record['tat'].' ]未匹配!');
+ }else{
+ $record['tat']=$tatFind['id'];
+ }
+ //结算金额匹配
+ if(!preg_match("/^\d+(\.\d{0,".$fun['digit']['money']."})?$/",$record['money'])){
+ throw new ValidateException('模板文件第'.$dataKey.'行结算金额不正确!');
+ }
+ try{
+ $this->validate($record,'app\validate\AllotInfo');//数据合法性验证
+ //转存数据
+ $class['total']=math()->chain($class['total'])->add($record['money'])->done();//累加单据金额
+ $info[]=$record;
+ } catch (ValidateException $e) {
+ return json(['state'=>'error','info'=>'模板文件第'.$dataKey.'行'.$e->getMessage()]);//返回错误信息
+ exit;
+ }
+ }
+ Db::startTrans();
+ try {
+ //新增CLASS
+ $classData=Allots::create($class);
+ //新增INFO
+ foreach ($info as $infoKey=>$infoVo) {
+ $info[$infoKey]['pid']=$classData['id'];
+ }
+ $model = new AllotInfo;
+ $model->saveAll($info);
+ Db::name('record')->insert(['type'=>'allot','source'=>$classData['id'],'time'=>time(),'user'=>getUserID(),'info'=>'导入单据']);
+ pushLog('导入转账单[ '.$classData['number'].' ]');//日志
+
+ Db::commit();
+ $result=['state'=>'success'];
+ } catch (\Exception $e) {
+ Db::rollback();
+ $result=['state'=>'error','info'=>'内部错误,操作已撤销!'];
+ }
+ }catch(ValidateException $e) {
+ $result=['state'=>'error','info'=>$e->getMessage()];//返回错误信息
+ }
+ }
+ return json($result);
+ }
+ //导出
+ public function exports(){
+ $input=input('get.');
+ if(existFull($input,['scene','parm']) && is_array($input['parm'])){
+ pushLog('导出转账单列表');//日志
+ $source=Allots::with(['frameData','peopleData','userData'])->where([['id','in',$input['parm']]])->append(['extension'])->order(['id'=>'desc'])->select()->toArray();//查询CLASS数据
+ if($input['scene']=='simple'){
+ //简易报表
+ //开始构造导出数据
+ $excel=[];//初始化导出数据
+ //标题数据
+ $excel[]=['type'=>'title','info'=>'转账单列表'];
+ //表格数据
+ $field=[
+ 'frameData|name'=>'所属组织',
+ 'time'=>'单据时间',
+ 'number'=>'单据编号',
+ 'total'=>'单据金额',
+ 'peopleData|name'=>'关联人员',
+ 'extension|examine'=>'审核状态',
+ 'userData|name'=>'制单人',
+ 'data'=>'备注信息'
+ ];
+ $thead=array_values($field);//表格标题
+ $tbody=[];//表格内容
+ //构造表内数据
+ foreach ($source as $sourceVo) {
+ $rowData=[];
+ foreach (array_keys($field) as $fieldVo) {
+ $rowData[]=arraySeek($sourceVo,$fieldVo);//多键名数据赋值
+ }
+ $tbody[]=$rowData;//加入行数据
+ }
+ $excel[]=['type'=>'table','info'=>['thead'=>$thead,'tbody'=>$tbody]];//表格数据
+ //统计数据
+ $excel[]=['type'=>'node','info'=>[
+ '总数:'.count($source),
+ '总单据金额:'.mathArraySum(array_column($source,'total'))
+ ]];
+ //导出execl
+ buildExcel('转账单列表',$excel);
+ }else{
+ //详细报表
+ $files=[];//初始化文件列表
+ foreach ($source as $sourceVo) {
+ //开始构造导出数据
+ $excel=[];//初始化导出数据
+ //标题数据
+ $excel[]=['type'=>'title','info'=>'转账单'];
+ //节点数据
+ $excel[]=['type'=>'node','info'=>[
+ '单据日期:'.$sourceVo['time'],
+ '单据编号:'.$sourceVo['number']]
+ ];
+ //表格数据
+ $field=[
+ 'accountData|name'=>'转出账户',
+ 'tatData|name'=>'转入账户',
+ 'money'=>'结算金额',
+ 'settle'=>'结算号',
+ 'data'=>'备注信息'
+ ];
+ //构造表内数据
+ $info=AllotInfo::with(['accountData','tatData'])->where([['pid','=',$sourceVo['id']]])->order(['id'=>'asc'])->select()->toArray();
+ $thead=array_values($field);//表格标题
+ $tbody=[];//表格内容
+ foreach ($info as $infoVo) {
+ $rowData=[];
+ foreach (array_keys($field) as $fieldVo) {
+ $rowData[]=arraySeek($infoVo,$fieldVo);//多键名数据赋值
+ }
+ $tbody[]=$rowData;//加入行数据
+ }
+ $excel[]=['type'=>'table','info'=>['thead'=>$thead,'tbody'=>$tbody]];//表格数据
+ //节点数据
+ $excel[]=['type'=>'node','info'=>[
+ '单据金额:'.$sourceVo['total'],
+ '关联人员:'.arraySeek($sourceVo,'peopleData|name'),
+ '备注信息:'.$sourceVo['data']]
+ ];
+ //生成execl
+ $files[]=buildExcel($sourceVo['number'],$excel,false);
+ }
+ buildZip('转账单_'.time(),$files);
+ }
+ }else{
+ return json(['state'=>'error','info'=>'传入数据不完整!']);
+ }
+ }
+}
\ No newline at end of file
diff --git a/serve/app/controller/Api.php b/serve/app/controller/Api.php
new file mode 100644
index 0000000..a14a398
--- /dev/null
+++ b/serve/app/controller/Api.php
@@ -0,0 +1,49 @@
+'user|tel'],'eq'],
+ ['pwd','md5']
+ ]);
+ $user=User::where($sql)->field(['id','name','tel','frame','user','img'])->find();
+ if(empty($user)){
+ $result=['state'=>'error','info'=>'账号|手机号或密码不正确!'];
+ }else{
+ $token=token();
+ cache($token,['user'=>$user['id'],'frame'=>[]]);
+ cache($input['uuid'],null);
+ pushLog('登录成功',$user['id']);
+ $result=['state'=>'success','info'=>$user,'token'=>$token];
+ }
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //获取验证
+ public function captcha(){
+ $uuid=uuid();
+ $captcha=new \org\Captcha();
+ $info=$captcha->entry();
+ cache($uuid,$info['code']);
+ return json(['state'=>'success','info'=>['uuid'=>$uuid,'data'=>$info['data']]]);
+ }
+ //运行数据
+ public function runData(){
+ return json([
+ 'state'=>'success',
+ 'info'=>[
+ 'login'=>checkLogin(),
+ 'sys'=>getSys(['name','company','icp','notice']),
+ 'ver'=>config('soft.version')
+ ]
+ ]);
+ }
+}
\ No newline at end of file
diff --git a/serve/app/controller/Attribute.php b/serve/app/controller/Attribute.php
new file mode 100644
index 0000000..5b4284d
--- /dev/null
+++ b/serve/app/controller/Attribute.php
@@ -0,0 +1,149 @@
+count();//获取总条数
+ $info = Attributes::where($sql)->page($input['page'],$input['limit'])->order(['sort'=>'asc'])->select();//查询分页数据
+ $result=[
+ 'state'=>'success',
+ 'count'=>$count,
+ 'info'=>$info
+ ];//返回数据
+ return json($result);
+ }
+ //新增|更新
+ public function save(){
+ $input=input('post.');
+ if(isset($input['id'])){
+ //验证数据
+ try {
+ empty($input['id'])?$this->validate($input,'app\validate\Attribute'):$this->validate($input,'app\validate\Attribute.update');
+ //关联判断
+ if(!empty($input['id'])){
+ $column=[array_column($input['info'],'name'),array_column(Db::name('attribute_info')->where([['pid','=',$input['id']]])->select()->toArray(),'name')];
+ $diff=array_diff($column[1],$column[0]);
+ if(!empty($diff)){
+ $whereOr=[];
+ foreach($diff as $v){$whereOr[]=['name','like','%'.$v.'%'];}
+ $attr=Db::name('attr')->whereOr($whereOr)->select()->toArray();
+ if(!empty($attr)){
+ $column[]=array_column($attr,'name');
+ $columns=[];
+ foreach($column[2] as $v){$columns=array_merge($columns,explode("|",$v));}
+ foreach($column[2] as $v){
+ if(in_array($v,$columns)){throw new ValidateException('[ '.$v.' ] 存在数据关联,操作已撤销!');}
+ }
+ }
+ }
+ }
+ } catch (ValidateException $e) {
+ return json(['state'=>'error','info'=>$e->getError()]);
+ exit;
+ }
+
+ //处理数据
+ Db::startTrans();
+ try {
+ if(empty($input['id'])){
+ //创建数据
+ $createInfo=Attributes::create($input);
+ $input['id']=$createInfo['id'];//转存主键
+ pushLog('新增辅助属性[ '.$input['name'].' ]');//日志
+ }else{
+ //更新数据
+ Attributes::update($input);
+ pushLog('更新辅助属性[ '.$input['name'].' ]');//日志
+ }
+
+ //INFO数据
+ Db::name('attribute_info')->where([['pid','=',$input['id']]])->delete();
+ foreach ($input['info'] as $k=>$v) {
+ $input['info'][$k]['pid']=$input['id'];
+ }
+ Db::name('attribute_info')->insertAll($input['info']);
+
+ Db::commit();
+ $result=['state'=>'success'];
+ } catch (\Exception $e) {
+ Db::rollback();
+ $result=['state'=>'error','info'=>'内部错误,操作已撤销!'];
+ }
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //获取
+ public function get(){
+ $input=input('post.');
+ if(existFull($input,['id'])){
+ $result=[
+ 'state'=>'success',
+ 'info'=>Attributes::with(['info'])->where([['id','=',$input['id']]])->find()
+ ];
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //删除
+ public function del(){
+ $input=input('post.');
+ if(existFull($input,['id'])){
+ $find=Db::name('attribute')->where([['id','=',$input['id']]])->find();
+ $info=Db::name('attribute_info')->where([['pid','=',$input['id']]])->select()->toArray();
+
+ //关联判断
+ $list=array_column($info,'name');
+ $whereOr=[];
+ foreach($list as $v){
+ $whereOr[]=['name','like','%'.$v.'%'];
+ }
+ $attr=Db::name('attr')->whereOr($whereOr)->select()->toArray();
+ if(!empty($attr)){
+ $column=array_column($attr,'name');
+ $columns=[];
+ foreach($column as $v){
+ $columns=array_merge($columns,explode("|",$v));
+ }
+ foreach($list as $v){
+ if(in_array($v,$columns)){
+ return json(['state'=>'error','info'=>'存在数据关联,删除失败!']);
+ }
+ }
+ }
+
+ Db::startTrans();
+ try {
+ Db::name('attribute')->where([['id','=',$input['id']]])->delete();
+ Db::name('attribute_info')->where([['pid','=',$input['id']]])->delete();
+ pushLog('删除辅助属性[ '.$find['name'].' ]');//日志
+
+ Db::commit();
+ $result=['state'=>'success'];
+ } catch (\Exception $e) {
+ Db::rollback();
+ $result=['state'=>'error','info'=>'内部错误,操作已撤销!'];
+ }
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //全部
+ public function select(){
+ $info = Attributes::with('info')->order(['sort'=>'asc'])->select();
+ $result=['state'=>'success','info'=>$info];
+ return json($result);
+ }
+}
\ No newline at end of file
diff --git a/serve/app/controller/Backup.php b/serve/app/controller/Backup.php
new file mode 100644
index 0000000..8fccfa1
--- /dev/null
+++ b/serve/app/controller/Backup.php
@@ -0,0 +1,74 @@
+get_filelist();
+ //排除配置文件
+ foreach ($list as $listKey=>$listVo){
+ if(substr($listVo['name'],0,1)=='.'){
+ unset($list[$listKey]);
+ }
+ }
+ $count = count($list);//获取总条数
+ $info =array_slice($list,$input['limit']*($input['page']-1),$input['limit']);//匹配分页数据
+ $result=[
+ 'state'=>'success',
+ 'count'=>$count,
+ 'info'=>$info
+ ];//返回数据
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //备份
+ public function backup(){
+ $dbInfo=config('database.connections.mysql');
+ $backup=new \org\BakSql($dbInfo['hostname'],$dbInfo['username'],$dbInfo['password'],$dbInfo['database']);
+ $backup->backup();
+ pushLog('备份数据');
+ return json (['state'=>'success']);
+ }
+ //恢复
+ public function restore(){
+ $input=input('post.');
+ if(existFull($input,['name'])){
+ //恢复指定数据
+ $dbInfo=config('database.connections.mysql');
+ $backup=new \org\BakSql($dbInfo['hostname'],$dbInfo['username'],$dbInfo['password'],$dbInfo['database']);
+ $backup->restore($input['name']);
+ pushLog('恢复数据备份[ '.$input['name'].' ]');//日志信息
+ $result=['state'=>'success'];
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //删除
+ public function del(){
+ $input=input('post.');
+ if(existFull($input,['parm']) && is_array($input['parm'])){
+ $path=pathChange('static.backup');
+ foreach ($input['parm'] as $infoVo) {
+ //防止恶意请求
+ if(strpos($infoVo,DIRECTORY_SEPARATOR)===false && strpos($infoVo,'..')===false){
+ @unlink($path.$infoVo);
+ pushLog('删除数据备份[ '.$infoVo.' ]');//日志信息
+ }else{
+ return json(['state'=>'error','info'=>'传入参数错误!']);
+ }
+ }
+ $result=['state'=>'success'];
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+}
\ No newline at end of file
diff --git a/serve/app/controller/Batch.php b/serve/app/controller/Batch.php
new file mode 100644
index 0000000..533c437
--- /dev/null
+++ b/serve/app/controller/Batch.php
@@ -0,0 +1,687 @@
+where(empty($input['warehouse'])?sqlAuth('warehouse',[]):[['id','in',$input['warehouse']]])->order(['id'=>'desc'])->select()->toArray();
+ //构造表头|集合
+ $column=[];
+ foreach ($warehouse as $warehouseVo) {
+ $column[]=['id'=>$warehouseVo['id'],'key'=>'stock_'.$warehouseVo['id'],'name'=>$warehouseVo['name']];
+ }
+ //匹配商品
+ $sql=fastSql($input,[
+ [['name'=>'name|py'],'fullLike'],
+ ['number','fullLike'],
+ ['spec','fullLike'],
+ ['brand','fullEq'],
+ ['code','fullLike']
+ ]);//构造SQL
+ //商品类型
+ $sql[]=['type','=',0];
+ //辅助属性扩展查询
+ $sqlOr=existFull($input,['code'])?[['id','in',array_column(Db::name('attr')->where([['code','=',$input['code']]])->select()->toArray(),'pid')]]:[];
+ //商品分类树结构查询
+ existFull($input,['category'])&&$sql[]=['category','in',findTreeArr('category',$input['category'],'id')];
+ //批次查询
+ $batchSql=fastSql($input,[
+ [['batch'=>'number'],'fullLike'],
+ ['time','fullTime']
+ ]);//构造SQL
+ $batchSql[]=['warehouse','in',array_column($warehouse,'id')];
+ //查询操作-批次类型
+ if(empty($input['state'])){
+ $batch=Db::name('batch')->where($batchSql)->select()->toArray();
+ }else{
+ $batchSql[]=['time','<>',0];
+ $batch=Db::name('batch')->alias('a')->join('goods b','a.goods = b.id')->where($batchSql)->whereRaw('a.time + (b.validity * 86400) >= :time - (b.threshold * 86400)',['time'=>strtotime(date('Y-m-d',time()))])->field('a.*')->select()->toArray();
+ }
+ //查询商品
+ $sql[]=['id','in',array_column($batch,'goods')];
+ //获取总条数
+ $count = Goods::where($sql)->whereOr($sqlOr)->count();
+ //查询分页数据
+ $info = Goods::with(['categoryData','attr'])->where($sql)->whereOr($sqlOr)->order(['id'=>'desc'])->page($input['page'],$input['limit'])->append(['extension'])->select()->toArray();
+ //唯一标识|属性处理
+ foreach ($info as $infoKey=>$infoVo) {
+ $info[$infoKey]['key']=$infoVo['id'];
+ foreach ($infoVo['attr'] as $attrKey=>$attrVo) {
+ $info[$infoKey]['attr'][$attrKey]['key']=$infoVo['id'].'.'.$attrVo['id'];
+ //属性处理
+ if(existFull($input,['code']) && !in_array($input['code'],[$infoVo['code'],$attrVo['code']])){
+ unset($info[$infoKey]['attr'][$attrKey]);
+ }
+ }
+ //重建索引
+ $info[$infoKey]['attr']=array_values($info[$infoKey]['attr']);
+ }
+ //库存集合[w:仓库|g:商品|a:属性|b:批次|t:生产日期]
+ $gather=['g'=>[],'wg'=>[],'ga'=>[],'wga'=>[],'gb'=>[],'wgb'=>[],'gbt'=>[],'wgbt'=>[],'gab'=>[],'wgab'=>[],'gabt'=>[],'wgabt'=>[]];
+ //查询库存数据-仓储
+ $room=Db::name('room')->where([['warehouse','in',array_column($warehouse,'id')],['goods','in',array_column($info,'id')]])->select()->toArray();
+ //构造库存数据
+ foreach ($room as $roomVo) {
+ //商品
+ $g=md5_16($roomVo['goods']);
+ $gather['g'][$g]=math()->chain($gather['g'][$g]??0)->add($roomVo['nums'])->done();
+ //仓库|商品
+ $wg=md5_16($roomVo['warehouse'].'&'.$roomVo['goods']);
+ $gather['wg'][$wg]=math()->chain($gather['wg'][$wg]??0)->add($roomVo['nums'])->done();
+ //判断属性
+ if(!empty($roomVo['attr'])){
+ //商品|属性
+ $ga=md5_16($roomVo['goods'].'&'.$roomVo['attr']);
+ $gather['ga'][$ga]=math()->chain($gather['ga'][$ga]??0)->add($roomVo['nums'])->done();
+ //仓库|商品|属性
+ $wga=md5_16($roomVo['warehouse'].'&'.$roomVo['goods'].'&'.$roomVo['attr']);
+ $gather['wga'][$wga]=math()->chain($gather['wga'][$wga]??0)->add($roomVo['nums'])->done();
+ }
+ }
+
+ //构造库存数据-批次
+ foreach ($batch as $batchKey=>$batchVo) {
+ //商品|批次
+ $gb=md5_16($batchVo['goods'].'&'.$batchVo['number']);
+ $gather['gb'][$gb]=math()->chain($gather['gb'][$gb]??0)->add($batchVo['nums'])->done();
+ //仓库|商品|批次
+ $wgb=md5_16($batchVo['warehouse'].'&'.$batchVo['goods'].'&'.$batchVo['number']);
+ $gather['wgb'][$wgb]=math()->chain($gather['wgb'][$wgb]??0)->add($batchVo['nums'])->done();
+
+ //匹配辅助属性
+ $find=search($room)->where([['id','=',$batchVo['room']]])->find();
+ if(empty($find['attr'])){
+ //转存数据
+ $batch[$batchKey]['attr']=null;
+ //生产日期
+ if(!empty($batchVo['time'])){
+ //商品|批次|生产日期
+ $gbt=md5_16($batchVo['goods'].'&'.$batchVo['id'].'&'.$batchVo['time']);
+ $gather['gbt'][$gbt]=math()->chain($gather['gbt'][$gbt]??0)->add($batchVo['nums'])->done();
+ //仓库|商品|批次|生产日期
+ $wgbt=md5_16($batchVo['warehouse'].'&'.$batchVo['goods'].'&'.$batchVo['id'].'&'.$batchVo['time']);
+ $gather['wgbt'][$wgbt]=math()->chain($gather['wgbt'][$wgbt]??0)->add($batchVo['nums'])->done();
+ }
+ }else{
+ //转存数据
+ $batch[$batchKey]['attr']=$find['attr'];
+ //商品|属性|批次
+ $gab=md5_16($batchVo['goods'].'&'.$find['attr'].'&'.$batchVo['number']);
+ $gather['gab'][$gab]=math()->chain($gather['gab'][$gab]??0)->add($batchVo['nums'])->done();
+ //仓库|商品|属性|批次
+ $wgab=md5_16($batchVo['warehouse'].'&'.$batchVo['goods'].'&'.$find['attr'].'&'.$batchVo['number']);
+ $gather['wgab'][$wgab]=math()->chain($gather['wgab'][$wgab]??0)->add($batchVo['nums'])->done();
+ //生产日期
+ if(!empty($batchVo['time'])){
+ //商品|属性|批次|生产日期
+ $gabt=md5_16($batchVo['goods'].'&'.$find['attr'].'&'.$batchVo['id'].'&'.$batchVo['time']);
+ $gather['gabt'][$gabt]=math()->chain($gather['gabt'][$gabt]??0)->add($batchVo['nums'])->done();
+ //仓库|商品|属性|批次|生产日期
+ $wgabt=md5_16($batchVo['warehouse'].'&'.$batchVo['goods'].'&'.$find['attr'].'&'.$batchVo['id'].'&'.$batchVo['time']);
+ $gather['wgabt'][$wgabt]=math()->chain($gather['wgabt'][$wgabt]??0)->add($batchVo['nums'])->done();
+ }
+ }
+ }
+ //数量匹配|库存处理
+ foreach ($info as $infoKey=>$infoVo) {
+ //商品
+ $g=md5_16($infoVo['id']);
+ $info[$infoKey]['summary']=isset($gather['g'][$g])?($infoVo['unit']=='-1'?unitSwitch($gather['g'][$g],$infoVo['units']):$gather['g'][$g]):0;
+ //仓库|商品
+ foreach ($column as $columnVo) {
+ $wg=md5_16($columnVo['id'].'&'.$infoVo['id']);
+ $info[$infoKey]['stock_'.$columnVo['id']]=isset($gather['wg'][$wg])?($infoVo['unit']=='-1'?unitSwitch($gather['wg'][$wg],$infoVo['units']):$gather['wg'][$wg]):0;
+ }
+ //匹配辅助属性
+ foreach ($infoVo['attr'] as $attrKey=>$attrVo) {
+ //商品|属性
+ $ga=md5_16($infoVo['id'].'&'.$attrVo['name']);
+ $info[$infoKey]['attr'][$attrKey]['summary']=isset($gather['ga'][$ga])?($infoVo['unit']=='-1'?unitSwitch($gather['ga'][$ga],$infoVo['units']):$gather['ga'][$ga]):0;
+ //仓库|商品|属性
+ foreach ($column as $columnVo) {
+ $wga=md5_16($columnVo['id'].'&'.$infoVo['id'].'&'.$attrVo['name']);
+ $info[$infoKey]['attr'][$attrKey]['stock_'.$columnVo['id']]=isset($gather['wga'][$wga])?($infoVo['unit']=='-1'?unitSwitch($gather['wga'][$wga],$infoVo['units']):$gather['wga'][$wga]):0;
+ }
+ }
+ //重建索引
+ $info[$infoKey]['attr']=array_values($info[$infoKey]['attr']);
+ }
+ //数量匹配|批次处理
+ foreach ($info as $infoKey=>$infoVo) {
+ //数组改造
+ if(empty($infoVo['attr'])){
+ $list=search($batch)->where([['goods','=',$infoVo['id']],['attr','=',null]])->select();
+ //去重匹配
+ foreach (assoc_unique($list,'number') as $listVo) {
+ $row=[
+ 'name'=>$listVo['number']
+ ];
+ //商品|批次
+ $gb=md5_16($infoVo['id'].'&'.$listVo['number']);
+ $row['summary']=isset($gather['gb'][$gb])?($infoVo['unit']=='-1'?unitSwitch($gather['gb'][$gb],$infoVo['units']):$gather['gb'][$gb]):0;
+ //仓库|商品|批次
+ foreach ($column as $columnVo) {
+ $wgb=md5_16($columnVo['id'].'&'.$infoVo['id'].'&'.$listVo['number']);
+ $row['stock_'.$columnVo['id']]=isset($gather['wgb'][$wgb])?($infoVo['unit']=='-1'?unitSwitch($gather['wgb'][$wgb],$infoVo['units']):$gather['wgb'][$wgb]):0;
+ }
+ //生产日期处理
+ if(empty($listVo['time'])){
+ $row['batch']=$listVo['id'];
+ }else{
+ $sub=search($list)->where([['number','=',$listVo['number']]])->select();
+ foreach ($sub as $subVo) {
+ $tag=[
+ 'batch'=>$subVo['id'],
+ 'name'=>'-',
+ 'protect'=>$infoVo['protect'],
+ 'startTime'=>date('Y-m-d',$subVo['time']),
+ 'endTime'=>date('Y-m-d',$subVo['time']+($infoVo['protect']*86400))
+ ];
+ //商品|批次|生产日期
+ $gbt=md5_16($infoVo['id'].'&'.$subVo['id'].'&'.$subVo['time']);
+ $tag['summary']=isset($gather['gbt'][$gbt])?($infoVo['unit']=='-1'?unitSwitch($gather['gbt'][$gbt],$infoVo['units']):$gather['gbt'][$gbt]):0;
+ //仓库|商品|批次|生产日期
+ foreach ($column as $columnVo) {
+ $wgbt=md5_16($columnVo['id'].'&'.$infoVo['id'].'&'.$subVo['id'].'&'.$subVo['time']);
+ $tag['stock_'.$columnVo['id']]=isset($gather['wgbt'][$wgbt])?($infoVo['unit']=='-1'?unitSwitch($gather['wgbt'][$wgbt],$infoVo['units']):$gather['wgbt'][$wgbt]):0;
+ }
+ $tag['key']=$gbt;
+ $row['attr'][]=$tag;
+ }
+ }
+ $row['key']=$gb;
+ $info[$infoKey]['attr'][]=$row;
+ }
+ }else{
+ //匹配数据
+ $list=search($batch)->where([['goods','=',$infoVo['id']],['attr','<>',null]])->select();
+ //循环属性
+ foreach ($infoVo['attr'] as $attrKey=>$attrVo) {
+ $select=search($list)->where([['attr','=',$attrVo['name']]])->select();
+ //去重匹配
+ foreach (assoc_unique($select,'number') as $selectVo) {
+ $row=[
+ 'name'=>$selectVo['number']
+ ];
+ //商品|属性|批次
+ $gab=md5_16($infoVo['id'].'&'.$selectVo['attr'].'&'.$selectVo['number']);
+ $row['summary']=isset($gather['gab'][$gab])?($infoVo['unit']=='-1'?unitSwitch($gather['gab'][$gab],$infoVo['units']):$gather['gab'][$gab]):0;
+ //仓库|商品|属性|批次
+ foreach ($column as $columnVo) {
+ $wgab=md5_16($columnVo['id'].'&'.$infoVo['id'].$selectVo['attr'].'&'.$selectVo['number']);
+ $row['stock_'.$columnVo['id']]=isset($gather['wgab'][$wgab])?($infoVo['unit']=='-1'?unitSwitch($gather['wgab'][$wgab],$infoVo['units']):$gather['wgab'][$wgab]):0;
+ }
+ //生产日期处理
+ if(empty($selectVo['time'])){
+ $row['batch']=$selectVo['id'];
+ }else{
+ $sub=search($list)->where([['number','=',$selectVo['number']]])->select();
+ foreach ($sub as $subVo) {
+ $tag=[
+ 'batch'=>$subVo['id'],
+ 'name'=>'-',
+ 'protect'=>$infoVo['protect'],
+ 'startTime'=>date('Y-m-d',$subVo['time']),
+ 'endTime'=>date('Y-m-d',$subVo['time']+($infoVo['protect']*86400))
+ ];
+ //商品|属性|批次|生产日期
+ $gabt=md5_16($infoVo['id'].'&'.$selectVo['attr'].'&'.$subVo['id'].'&'.$subVo['time']);
+ $tag['summary']=isset($gather['gabt'][$gabt])?($infoVo['unit']=='-1'?unitSwitch($gather['gabt'][$gabt],$infoVo['units']):$gather['gabt'][$gabt]):0;
+ //仓库|商品|属性|批次|生产日期
+ foreach ($column as $columnVo) {
+ $wgabt=md5_16($columnVo['id'].'&'.$infoVo['id'].'&'.$selectVo['attr'].'&'.$subVo['id'].'&'.$subVo['time']);
+ $tag['stock_'.$columnVo['id']]=isset($gather['wgabt'][$wgabt])?($infoVo['unit']=='-1'?unitSwitch($gather['wgabt'][$wgabt],$infoVo['units']):$gather['wgabt'][$wgabt]):0;
+ }
+ $tag['key']=$gabt;
+ $row['attr'][]=$tag;
+ }
+ }
+ $row['key']=$gab;
+ $info[$infoKey]['attr'][$attrKey]['attr'][]=$row;
+ }
+ if(empty($select))unset($info[$infoKey]['attr'][$attrKey]);
+ }
+ $info[$infoKey]['attr']=array_values($info[$infoKey]['attr']);
+ }
+ }
+ $result=[
+ 'state'=>'success',
+ 'count'=>$count,
+ 'info'=>$info,
+ 'column'=>$column
+ ];//返回数据
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //导出
+ public function exports(){
+ $input=input('get.');
+ existFull($input,['warehouse'])||$input['warehouse']=[];
+ if(isset($input['warehouse']) && is_array($input['warehouse']) && isset($input['state']) && in_array($input['state'],[0,1])){
+ pushLog('导出批次列表');//日志
+ //匹配仓库
+ $warehouse = Db::name('warehouse')->where(empty($input['warehouse'])?sqlAuth('warehouse',[]):[['id','in',explode(',',$input['warehouse'])]])->order(['id'=>'desc'])->select()->toArray();
+ //构造表头
+ $column=[];
+ foreach ($warehouse as $warehouseVo) {
+ $column['stock_'.$warehouseVo['id']]=$warehouseVo['name'];
+ }
+ //匹配商品
+ $sql=fastSql($input,[
+ [['name'=>'name|py'],'fullLike'],
+ ['number','fullLike'],
+ ['spec','fullLike'],
+ ['brand','fullEq'],
+ ['code','fullLike']
+ ]);//构造SQL
+ //商品类型
+ $sql[]=['type','=',0];
+ //辅助属性扩展查询
+ $sqlOr=existFull($input,['code'])?[['id','in',array_column(Db::name('attr')->where([['code','=',$input['code']]])->select()->toArray(),'pid')]]:[];
+ //商品分类树结构查询
+ existFull($input,['category'])&&$sql[]=['category','in',findTreeArr('category',$input['category'],'id')];
+ //批次查询
+ $batchSql=fastSql($input,[
+ [['batch'=>'number'],'fullLike'],
+ ['time','fullTime']
+ ]);//构造SQL
+ $batchSql[]=['warehouse','in',array_column($warehouse,'id')];
+ //查询操作-批次类型
+ if(empty($input['state'])){
+ $batch=Db::name('batch')->where($batchSql)->select()->toArray();
+ }else{
+ $batchSql[]=['time','<>',0];
+ $batch=Db::name('batch')->alias('a')->join('goods b','a.goods = b.id')->where($batchSql)->whereRaw('a.time + (b.threshold * 86400) < :time',['time'=>strtotime(date('Y-m-d',time()))])->field('a.*')->select()->toArray();
+ }
+ //查询商品
+ $sql[]=['id','in',array_column($batch,'goods')];
+ //查询分页数据
+ $info = Goods::with(['categoryData','attr'])->where($sql)->whereOr($sqlOr)->order(['id'=>'desc'])->append(['extension'])->select()->toArray();
+ //属性处理
+ foreach ($info as $infoKey=>$infoVo) {
+ foreach ($infoVo['attr'] as $attrKey=>$attrVo) {
+ //属性处理
+ if(existFull($input,['code']) && !in_array($input['code'],[$infoVo['code'],$attrVo['code']])){
+ unset($info[$infoKey]['attr'][$attrKey]);
+ }
+ }
+ //重建索引
+ $info[$infoKey]['attr']=array_values($info[$infoKey]['attr']);
+ }
+
+ //库存集合[w:仓库|g:商品|a:属性|b:批次|t:生产日期]
+ $gather=['g'=>[],'wg'=>[],'ga'=>[],'wga'=>[],'gb'=>[],'wgb'=>[],'gbt'=>[],'wgbt'=>[],'gab'=>[],'wgab'=>[],'gabt'=>[],'wgabt'=>[]];
+ //查询库存数据-仓储
+ $room=Db::name('room')->where([['warehouse','in',array_column($warehouse,'id')],['goods','in',array_column($info,'id')]])->select()->toArray();
+ //构造库存数据
+ foreach ($room as $roomVo) {
+ //商品
+ $g=md5_16($roomVo['goods']);
+ $gather['g'][$g]=math()->chain($gather['g'][$g]??0)->add($roomVo['nums'])->done();
+ //仓库|商品
+ $wg=md5_16($roomVo['warehouse'].'&'.$roomVo['goods']);
+ $gather['wg'][$wg]=math()->chain($gather['wg'][$wg]??0)->add($roomVo['nums'])->done();
+ //判断属性
+ if(!empty($roomVo['attr'])){
+ //商品|属性
+ $ga=md5_16($roomVo['goods'].'&'.$roomVo['attr']);
+ $gather['ga'][$ga]=math()->chain($gather['ga'][$ga]??0)->add($roomVo['nums'])->done();
+ //仓库|商品|属性
+ $wga=md5_16($roomVo['warehouse'].'&'.$roomVo['goods'].'&'.$roomVo['attr']);
+ $gather['wga'][$wga]=math()->chain($gather['wga'][$wga]??0)->add($roomVo['nums'])->done();
+ }
+ }
+
+ //构造库存数据-批次
+ foreach ($batch as $batchKey=>$batchVo) {
+ //商品|批次
+ $gb=md5_16($batchVo['goods'].'&'.$batchVo['number']);
+ $gather['gb'][$gb]=math()->chain($gather['gb'][$gb]??0)->add($batchVo['nums'])->done();
+ //仓库|商品|批次
+ $wgb=md5_16($batchVo['warehouse'].'&'.$batchVo['goods'].'&'.$batchVo['number']);
+ $gather['wgb'][$wgb]=math()->chain($gather['wgb'][$wgb]??0)->add($batchVo['nums'])->done();
+
+ //匹配辅助属性
+ $find=search($room)->where([['id','=',$batchVo['room']]])->find();
+ if(empty($find['attr'])){
+ //转存数据
+ $batch[$batchKey]['attr']=null;
+ //生产日期
+ if(!empty($batchVo['time'])){
+ //商品|批次|生产日期
+ $gbt=md5_16($batchVo['goods'].'&'.$batchVo['id'].'&'.$batchVo['time']);
+ $gather['gbt'][$gbt]=math()->chain($gather['gbt'][$gbt]??0)->add($batchVo['nums'])->done();
+ //仓库|商品|批次|生产日期
+ $wgbt=md5_16($batchVo['warehouse'].'&'.$batchVo['goods'].'&'.$batchVo['id'].'&'.$batchVo['time']);
+ $gather['wgbt'][$wgbt]=math()->chain($gather['wgbt'][$wgbt]??0)->add($batchVo['nums'])->done();
+ }
+ }else{
+ //转存数据
+ $batch[$batchKey]['attr']=$find['attr'];
+ //商品|属性|批次
+ $gab=md5_16($batchVo['goods'].'&'.$find['attr'].'&'.$batchVo['number']);
+ $gather['gab'][$gab]=math()->chain($gather['gab'][$gab]??0)->add($batchVo['nums'])->done();
+ //仓库|商品|属性|批次
+ $wgab=md5_16($batchVo['warehouse'].'&'.$batchVo['goods'].'&'.$find['attr'].'&'.$batchVo['number']);
+ $gather['wgab'][$wgab]=math()->chain($gather['wgab'][$wgab]??0)->add($batchVo['nums'])->done();
+ //生产日期
+ if(!empty($batchVo['time'])){
+ //商品|属性|批次|生产日期
+ $gabt=md5_16($batchVo['goods'].'&'.$find['attr'].'&'.$batchVo['id'].'&'.$batchVo['time']);
+ $gather['gabt'][$gabt]=math()->chain($gather['gabt'][$gabt]??0)->add($batchVo['nums'])->done();
+ //仓库|商品|属性|批次|生产日期
+ $wgabt=md5_16($batchVo['warehouse'].'&'.$batchVo['goods'].'&'.$find['attr'].'&'.$batchVo['id'].'&'.$batchVo['time']);
+ $gather['wgabt'][$wgabt]=math()->chain($gather['wgabt'][$wgabt]??0)->add($batchVo['nums'])->done();
+ }
+ }
+ }
+ //数量匹配|库存处理
+ foreach ($info as $infoKey=>$infoVo) {
+ //商品
+ $g=md5_16($infoVo['id']);
+ $info[$infoKey]['summary']=isset($gather['g'][$g])?($infoVo['unit']=='-1'?unitSwitch($gather['g'][$g],$infoVo['units']):$gather['g'][$g]):0;
+ //仓库|商品
+ foreach ($warehouse as $warehouseVo) {
+ $wg=md5_16($warehouseVo['id'].'&'.$infoVo['id']);
+ $info[$infoKey]['stock_'.$warehouseVo['id']]=isset($gather['wg'][$wg])?($infoVo['unit']=='-1'?unitSwitch($gather['wg'][$wg],$infoVo['units']):$gather['wg'][$wg]):0;
+ }
+ //匹配辅助属性
+ foreach ($infoVo['attr'] as $attrKey=>$attrVo) {
+ //商品|属性
+ $ga=md5_16($infoVo['id'].'&'.$attrVo['name']);
+ $info[$infoKey]['attr'][$attrKey]['summary']=isset($gather['ga'][$ga])?($infoVo['unit']=='-1'?unitSwitch($gather['ga'][$ga],$infoVo['units']):$gather['ga'][$ga]):0;
+ //仓库|商品|属性
+ foreach ($warehouse as $warehouseVo) {
+ $wga=md5_16($warehouseVo['id'].'&'.$infoVo['id'].'&'.$attrVo['name']);
+ $info[$infoKey]['attr'][$attrKey]['stock_'.$warehouseVo['id']]=isset($gather['wga'][$wga])?($infoVo['unit']=='-1'?unitSwitch($gather['wga'][$wga],$infoVo['units']):$gather['wga'][$wga]):0;
+ }
+ }
+ //重建索引
+ $info[$infoKey]['attr']=array_values($info[$infoKey]['attr']);
+ }
+ //数量匹配|批次处理
+ foreach ($info as $infoKey=>$infoVo) {
+ //数组改造
+ if(empty($infoVo['attr'])){
+ $list=search($batch)->where([['goods','=',$infoVo['id']],['attr','=',null]])->select();
+ //去重匹配
+ foreach (assoc_unique($list,'number') as $listVo) {
+ $row=[
+ 'name'=>$listVo['number']
+ ];
+ //商品|批次
+ $gb=md5_16($infoVo['id'].'&'.$listVo['number']);
+ $row['summary']=isset($gather['gb'][$gb])?($infoVo['unit']=='-1'?unitSwitch($gather['gb'][$gb],$infoVo['units']):$gather['gb'][$gb]):0;
+ //仓库|商品|批次
+ foreach ($warehouse as $columnVo) {
+ $wgb=md5_16($warehouseVo['id'].'&'.$infoVo['id'].'&'.$listVo['number']);
+ $row['stock_'.$warehouseVo['id']]=isset($gather['wgb'][$wgb])?($infoVo['unit']=='-1'?unitSwitch($gather['wgb'][$wgb],$infoVo['units']):$gather['wgb'][$wgb]):0;
+ }
+ //生产日期处理
+ if(!empty($listVo['time'])){
+ $sub=search($list)->where([['number','=',$listVo['number']]])->select();
+ foreach ($sub as $subVo) {
+ $tag=[
+ 'name'=>'-',
+ 'protect'=>$infoVo['protect'],
+ 'startTime'=>date('Y-m-d',$subVo['time']),
+ 'endTime'=>date('Y-m-d',$subVo['time']+($infoVo['protect']*86400))
+ ];
+ //商品|批次|生产日期
+ $gbt=md5_16($infoVo['id'].'&'.$subVo['id'].'&'.$subVo['time']);
+ $tag['summary']=isset($gather['gbt'][$gbt])?($infoVo['unit']=='-1'?unitSwitch($gather['gbt'][$gbt],$infoVo['units']):$gather['gbt'][$gbt]):0;
+ //仓库|商品|批次|生产日期
+ foreach ($warehouse as $warehouseVo) {
+ $wgbt=md5_16($warehouseVo['id'].'&'.$infoVo['id'].'&'.$subVo['id'].'&'.$subVo['time']);
+ $tag['stock_'.$warehouseVo['id']]=isset($gather['wgbt'][$wgbt])?($infoVo['unit']=='-1'?unitSwitch($gather['wgbt'][$wgbt],$infoVo['units']):$gather['wgbt'][$wgbt]):0;
+ }
+ $tag['key']=$gbt;
+ $row['attr'][]=$tag;
+ }
+ }
+ $row['key']=$gb;
+ $info[$infoKey]['attr'][]=$row;
+ }
+ }else{
+ //匹配数据
+ $list=search($batch)->where([['goods','=',$infoVo['id']],['attr','<>',null]])->select();
+ //循环属性
+ foreach ($infoVo['attr'] as $attrKey=>$attrVo) {
+ $select=search($list)->where([['attr','=',$attrVo['name']]])->select();
+ //去重匹配
+ foreach (assoc_unique($select,'number') as $selectVo) {
+ $row=[
+ 'name'=>$selectVo['number']
+ ];
+ //商品|属性|批次
+ $gab=md5_16($infoVo['id'].'&'.$selectVo['attr'].'&'.$selectVo['number']);
+ $row['summary']=isset($gather['gab'][$gab])?($infoVo['unit']=='-1'?unitSwitch($gather['gab'][$gab],$infoVo['units']):$gather['gab'][$gab]):0;
+ //仓库|商品|属性|批次
+ foreach ($warehouse as $warehouseVo) {
+ $wgab=md5_16($warehouseVo['id'].'&'.$infoVo['id'].$selectVo['attr'].'&'.$selectVo['number']);
+ $row['stock_'.$warehouseVo['id']]=isset($gather['wgab'][$wgab])?($infoVo['unit']=='-1'?unitSwitch($gather['wgab'][$wgab],$infoVo['units']):$gather['wgab'][$wgab]):0;
+ }
+ //生产日期处理
+ if(!empty($selectVo['time'])){
+ $sub=search($list)->where([['number','=',$selectVo['number']]])->select();
+ foreach ($sub as $subVo) {
+ $tag=[
+ 'name'=>'-',
+ 'protect'=>$infoVo['protect'],
+ 'startTime'=>date('Y-m-d',$subVo['time']),
+ 'endTime'=>date('Y-m-d',$subVo['time']+($infoVo['protect']*86400))
+ ];
+ //商品|属性|批次|生产日期
+ $gabt=md5_16($infoVo['id'].'&'.$selectVo['attr'].'&'.$subVo['id'].'&'.$subVo['time']);
+ $tag['summary']=isset($gather['gabt'][$gabt])?($infoVo['unit']=='-1'?unitSwitch($gather['gabt'][$gabt],$infoVo['units']):$gather['gabt'][$gabt]):0;
+ //仓库|商品|属性|批次|生产日期
+ foreach ($warehouse as $warehouseVo) {
+ $wgabt=md5_16($warehouseVo['id'].'&'.$infoVo['id'].'&'.$selectVo['attr'].'&'.$subVo['id'].'&'.$subVo['time']);
+ $tag['stock_'.$warehouseVo['id']]=isset($gather['wgabt'][$wgabt])?($infoVo['unit']=='-1'?unitSwitch($gather['wgabt'][$wgabt],$infoVo['units']):$gather['wgabt'][$wgabt]):0;
+ }
+ $tag['key']=$gabt;
+ $row['attr'][]=$tag;
+ }
+ }
+ $row['key']=$gab;
+ $info[$infoKey]['attr'][$attrKey]['attr'][]=$row;
+ }
+ if(empty($select))unset($info[$infoKey]['attr'][$attrKey]);
+ }
+ $info[$infoKey]['attr']=array_values($info[$infoKey]['attr']);
+ }
+ }
+ //结构重组
+ $source=[];
+ foreach ($info as $infoVo) {
+ $source[]=$infoVo;
+ if(!empty($infoVo['attr'])){
+ foreach ($infoVo['attr'] as $attrVo) {
+ $attrVo['name']='|- '.$attrVo['name'];
+ $source[]=$attrVo;
+ if(existFull($attrVo,['attr'])){
+ foreach ($attrVo['attr'] as $subVo) {
+ $subVo['name']='|-- '.$subVo['name'];
+ $source[]=$subVo;
+ }
+ }
+ }
+ }
+ }
+ //开始构造导出数据
+ $excel=[];//初始化导出数据
+ //标题数据
+ $excel[]=['type'=>'title','info'=>'批次列表'];
+ //表格数据
+ $field=array_merge(['name'=>'商品名称','summary'=>'库存数量'],$column,['protect'=>'保质期(天)','startTime'=>'生产日期','endTime'=>'过期日期','number'=>'商品编号','spec'=>'规格型号','categoryData|name'=>'商品分类','brand'=>'商品品牌','extension|unit'=>'商品单位','code'=>'商品条码','data'=>'商品备注']);
+ $thead=array_values($field);//表格标题
+ $tbody=[];//表格内容
+ //构造表内数据
+ foreach ($source as $sourceVo) {
+ $rowData=[];
+ foreach (array_keys($field) as $fieldVo) {
+ $rowData[]=arraySeek($sourceVo,$fieldVo);//多键名数据赋值
+ }
+ $tbody[]=$rowData;//加入行数据
+ }
+ $excel[]=['type'=>'table','info'=>['thead'=>$thead,'tbody'=>$tbody]];//表格数据
+ //导出execl
+ buildExcel('批次列表',$excel);
+ }else{
+ return json(['state'=>'error','info'=>'传入数据不完整!']);
+ }
+ }
+ //详情列表
+ public function detailRecord(){
+ $input=input('post.');
+ $sheet=['buy','bre','sell','sre','swapOut','swapEnter','entry','extry'];
+ existFull($input,['type'])||$input['type']=$sheet;
+ if(existFull($input,['page','limit','batch','warehouse']) && is_arrays($input,['batch','warehouse','type']) && arrayInArray($input['type'],$sheet)){
+ //构造SQL|batch
+ $sql=fastSql($input,[
+ [['batch'=>'id'],'fullIn'],
+ ['warehouse','fullIn']
+ ]);
+ //查询批次数据
+ $batch=Db::name('batch')->where($sql)->field(['id','goods'])->select()->toArray();
+ if(empty($batch)){
+ $count=0;
+ $info=[];
+ }else{
+ //构造SQL|BATCHINFO
+ $infoSql=fastSql($input,[['type','fullIn']]);
+ $infoSql[]=['pid','in',array_column($batch,'id')];
+ //子查询SQL
+ $existsSql=fastSql($input,[
+ ['number','fullLike'],
+ [['startTime'=>'time'],'startTime'],
+ [['endTime'=>'time'],'endTime']
+ ]);
+ $existsSql[]=['id','=',Db::raw('info.class')];
+ $existsSql=frameScope($existsSql);
+ //多源匹配
+ $union=[];
+ //数据关系表
+ $table=['buy'=>'buy','bre'=>'bre','sell'=>'sell','sre'=>'sre','swapOut'=>'swap','swapEnter'=>'swap','entry'=>'entry','extry'=>'extry'];
+ foreach ($table as $k=>$v) {
+ //匹配类型|减少查询
+ if(in_array($k,$input['type'])){
+ $union[]=Db::name($v)->where([['info.type','=',$k]])->where(array_merge($existsSql,sqlAuth($v,[])))->limit(1)->buildSql();
+ }
+ }
+ //合并子查询
+ $union=implode(' UNION ALL ',$union);
+ $count=BatchInfo::alias('info')->where($infoSql)->whereExists($union)->count();
+ $info=BatchInfo::with(['sourceData'=>['frameData']])->alias('info')->where($infoSql)->whereExists($union)->page($input['page'],$input['limit'])->order(['id'=>'desc'])->append(['extension'])->select()->toArray();
+ //处理多单位
+ if(!empty($info)){
+ $goods=Db::name('goods')->where([['id','=',$batch[0]['goods']]])->find();
+ if($goods['unit']=='-1'){
+ foreach ($info as $infoKey=>$infoVo) {
+ $info[$infoKey]['nums']=unitSwitch($infoVo['nums'],json_decode($goods['units'],true));
+ }
+ }
+ }
+ }
+ $result=[
+ 'state'=>'success',
+ 'count'=>$count,
+ 'info'=>$info
+ ];//返回数据
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //详情导出
+ public function detailExports(){
+ $input=input('get.');
+ $sheet=['buy','bre','sell','sre','swapOut','swapEnter','entry','extry'];
+ existFull($input,['batch'])||$input['batch']=[];
+ existFull($input,['type'])||$input['type']=$sheet;
+ if(existFull($input,['batch','warehouse']) && is_arrays($input,['batch','warehouse','type']) && arrayInArray($input['type'],$sheet)){
+ pushLog('导出批次详情');//日志
+ //构造SQL|batch
+ $sql=fastSql($input,[
+ [['batch'=>'id'],'fullIn'],
+ ['warehouse','fullIn']
+ ]);
+ //查询仓储数据
+ $batch=Db::name('batch')->where($sql)->field(['id','goods','number'])->select()->toArray();
+ if(empty($batch)){
+ $source=[];
+ }else{
+ //构造SQL|BATCHINFO
+ $infoSql=fastSql($input,[['type','fullIn']]);
+ $infoSql[]=['pid','in',array_column($batch,'id')];
+ //子查询SQL
+ $existsSql=fastSql($input,[
+ ['number','fullLike'],
+ [['startTime'=>'time'],'startTime'],
+ [['endTime'=>'time'],'endTime']
+ ]);
+ $existsSql[]=['id','=',Db::raw('info.class')];
+ $existsSql=frameScope($existsSql);
+ //多源匹配
+ $union=[];
+ //数据关系表
+ $table=['buy'=>'buy','bre'=>'bre','sell'=>'sell','sre'=>'sre','swapOut'=>'swap','swapEnter'=>'swap','entry'=>'entry','extry'=>'extry'];
+ foreach ($table as $k=>$v) {
+ //匹配类型|减少查询
+ if(in_array($k,$input['type'])){
+ $union[]=Db::name($v)->where([['info.type','=',$k]])->where(array_merge($existsSql,sqlAuth($v,[])))->limit(1)->buildSql();
+ }
+ }
+ //合并子查询
+ $union=implode(' UNION ALL ',$union);
+ $source=BatchInfo::with(['sourceData'=>['frameData']])->alias('info')->where($infoSql)->whereExists($union)->order(['id'=>'desc'])->append(['extension'])->select()->toArray();
+ //处理多单位
+ if(!empty($source)){
+ $goods=Db::name('goods')->where([['id','=',$batch[0]['goods']]])->find();
+ if($goods['unit']=='-1'){
+ foreach ($source as $sourceKey=>$sourceVo) {
+ $source[$sourceKey]['nums']=unitSwitch($sourceVo['nums'],json_decode($goods['units'],true));
+ }
+ }
+ }
+ }
+ //开始构造导出数据
+ $excel=[];//初始化导出数据
+ //标题数据
+ $excel[]=['type'=>'title','info'=>'批次详情'];
+ //表格数据
+ $field=[
+ 'sourceData|frameData|name'=>'所属组织',
+ 'sourceData|time'=>'操作时间',
+ 'extension|type'=>'单据类型',
+ 'sourceData|number'=>'单据编号',
+ 'extension|direction'=>'操作类型',
+ 'nums'=>'操作数量'
+ ];
+ $thead=array_values($field);//表格标题
+ $tbody=[];//表格内容
+ //构造表内数据
+ foreach ($source as $sourceVo) {
+ $rowData=[];
+ foreach (array_keys($field) as $fieldVo) {
+ $rowData[]=arraySeek($sourceVo,$fieldVo);//多键名数据赋值
+ }
+ $tbody[]=$rowData;//加入行数据
+ }
+ $excel[]=['type'=>'table','info'=>['thead'=>$thead,'tbody'=>$tbody]];//表格数据
+ //导出execl
+ buildExcel('批次详情',$excel);
+ }else{
+ return json(['state'=>'error','info'=>'传入数据不完整!']);
+ }
+ }
+}
\ No newline at end of file
diff --git a/serve/app/controller/Bill.php b/serve/app/controller/Bill.php
new file mode 100644
index 0000000..ecc783d
--- /dev/null
+++ b/serve/app/controller/Bill.php
@@ -0,0 +1,381 @@
+'time'],'startTime'],
+ [['endTime'=>'time'],'endTime'],
+ ['user','fullEq'],
+ ['examine','fullDec1'],
+ ['data','fullLike']
+ ]);//构造SQL
+ $sql=frameScope($sql);//组织数据
+ $sql=sqlAuth('bill',$sql);//数据鉴权
+ $count = Bills::where($sql)->count();//获取总条数
+ $info = Bills::with(['frameData','customerData','supplierData','userData','peopleData','recordData'])->where($sql)->append(['extension'])->page($input['page'],$input['limit'])->order(['id'=>'desc'])->select()->toArray();//查询分页数据
+ $result=[
+ 'state'=>'success',
+ 'count'=>$count,
+ 'info'=>$info
+ ];//返回数据
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //新增|更新
+ public function save(){
+ $input=input('post.');
+ if(existFull($input,['class','info']) && isset($input['class']['id'])){
+ //构造|验证CLASS
+ try {
+ $class=$input['class'];
+ $class['frame']=userInfo(getUserID(),'frame');
+ $class['user']=getUserID();
+ $class['examine']=0;
+ empty($class['id'])?$this->validate($class,'app\validate\Bill'):$this->validate($class,'app\validate\Bill.update');
+ $period=getPeriod();
+ if(strtotime($class['time'])<=$period){
+ throw new ValidateException('单据日期与结账日期冲突!');
+ }
+ } catch (ValidateException $e) {
+ return json(['state'=>'error','info'=>$e->getError()]);
+ exit;
+ }
+
+ //验证INFO
+ foreach ($input['info'] as $infoKey=>$infoVo) {
+ try {
+ $this->validate($infoVo,'app\validate\BillInfo');
+ } catch (ValidateException $e) {
+ return json(['state'=>'error','info'=>'单据数据第'.($infoKey+1).'条'.$e->getError()]);
+ exit;
+ }
+ }
+
+ //处理数据
+ Db::startTrans();
+ try {
+ //CLASS数据
+ if(empty($class['id'])){
+ //创建数据
+ $createInfo=Bills::create($class);
+ $class['id']=$createInfo['id'];//转存主键
+ Db::name('record')->insert(['type'=>'bill','source'=>$class['id'],'time'=>time(),'user'=>getUserID(),'info'=>'新增单据']);
+ pushLog('新增核销单[ '.$class['number'].' ]');//日志
+ }else{
+ //更新数据
+ $updateInfo=Bills::update($class);
+ Db::name('record')->insert(['type'=>'bill','source'=>$class['id'],'time'=>time(),'user'=>getUserID(),'info'=>'更新单据']);
+ pushLog('更新核销单[ '.$class['number'].' ]');//日志
+ }
+ //INFO数据
+ BillInfo::where([['pid','=',$class['id']]])->delete();
+ foreach ($input['info'] as $infoKey=>$infoVo) {
+ $input['info'][$infoKey]['pid']=$class['id'];
+ }
+ $model = new BillInfo;
+ $model->saveAll($input['info']);
+
+ Db::commit();
+ $result=['state'=>'success','info'=>$class['id']];
+ } catch (\Exception $e) {
+ Db::rollback();
+ $result=['state'=>'error','info'=>'内部错误,操作已撤销!'];
+ }
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //获取
+ public function get(){
+ $input=input('post.');
+ if(existFull($input,['parm'])){
+ $class=Bills::where([['id','=',$input['parm']]])->find();
+ $info=BillInfo::with(['sourceData'])->where([['pid','=',$input['parm']]])->append(['extension'])->order(['id'=>'asc'])->select()->each(function($item){
+ $item->sourceData->append(['extension']);
+ })->toArray();
+ //数据处理
+ foreach ($info as $key=>$vo) {
+ in_array($vo['mold'],['buy','bre','sell','sre','ice','oce'])&&$info[$key]['sourceData']['total']=$vo['sourceData']['actual'];
+ }
+ $result=['state'=>'success','info'=>[
+ 'class'=>$class,
+ 'info'=>$info,
+ ]];
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //删除
+ public function del(){
+ $input=input('post.');
+ if(existFull($input,['parm']) && is_array($input['parm'])){
+ //关联验证
+ $data=Db::name('bill')->where([['id','in',$input['parm']]])->order(['id'=>'desc'])->select()->toArray();
+ $search=search($data)->where([['examine','=','1']])->find();
+ if(empty($search)){
+ Db::startTrans();
+ try {
+ Db::name('bill')->where([['id','in',$input['parm']]])->delete();
+ Db::name('bill_info')->where([['pid','in',$input['parm']]])->delete();
+ Db::name('record')->where([['type','=','bill'],['source','in',$input['parm']]])->delete();
+ Db::name('log')->insert(['time'=>time(),'user'=>getUserID(),'info'=>'删除核销单[ '.implode(' | ',array_column($data,'number')).' ]']);
+
+ Db::commit();
+ $result=['state'=>'success'];
+ } catch (\Exception $e) {
+ Db::rollback();
+ $result=['state'=>'error','info'=>'内部错误,操作已撤销!'];
+ }
+ }else{
+ $result=['state'=>'error','info'=>'单据['.$search['number'].']已审核,不可删除!'];
+ }
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //审核|反审核
+ public function examine(){
+ $input=input('post.');
+ if(existFull($input,['parm']) && is_array($input['parm'])){
+ //1 基础数据
+ $period=getPeriod();
+ $classList=Db::name('bill')->where([['id','in',$input['parm']]])->order(['id'=>'desc'])->select()->toArray();
+ //2 综合处理
+ foreach ($input['parm'] as $parmVo) {
+ //1 匹配数据
+ $class=search($classList)->where([['id','=',$parmVo]])->find();
+ $info=BillInfo::with(['sourceData'])->where([['pid','=',$parmVo]])->append(['extension'])->order(['id'=>'asc'])->select()->each(function($item){
+ $item->sourceData->append(['extension']);
+ })->toArray();
+ //2 CLASS验证
+ if($class['time']<=$period){
+ return json(['state'=>'error','info'=>'操作单据[ '.$class['number'].' ]失败,原因:单据日期与结账日期冲突!']);
+ exit;
+ }
+ //3 INFO验证
+ foreach ($info as $infoKey=>$infoVo) {
+ //场景验证
+ if(empty($class['examine'])){
+ //核销金额验证
+ $anwo=$infoVo['sourceData']['extension']['anwo'];
+ if(bccomp(abs($infoVo['money']),abs($anwo))==1){
+ return json(['state'=>'error','info'=>'审核单据[ '.$class['number'].' ]失败,原因:第'.($infoKey+1).'行可核销金额不足!']);
+ exit;
+ }
+ }
+ }
+ //4 数据处理
+ Db::startTrans();
+ try {
+ //场景验证
+ if(empty($class['examine'])){
+ //审核
+
+ //1 数据处理
+ foreach ($info as $infoVo){
+ $mold=$infoVo['mold'];
+ $money=in_array($infoVo['mold'],['bre','sre'])?abs($infoVo['money']):$infoVo['money'];
+ //1.1 添加核销记录
+ Db::name($mold.'_bill')->insert([
+ 'pid'=>$infoVo['source'],
+ 'type'=>'bill',
+ 'source'=>$class['id'],
+ 'time'=>$class['time'],
+ 'money'=>$money
+ ]);
+ //1.2 读取核销状态
+ $sum=Db::name($mold.'_bill')->where(['pid'=>$infoVo['source']])->sum('money');
+ $total=in_array($infoVo['mold'],['buy','bre','sell','sre','ice','oce'])?$infoVo['sourceData']['actual']:$infoVo['sourceData']['total'];
+ $nucleus=bccomp($sum,$total)==0?2:1;
+ //1.3 更新核销状态
+ Db::name($mold)->where([['id','=',$infoVo['source']]])->update(['nucleus'=>$nucleus]);
+ }
+ //2 更新单据
+ Db::name('bill')->where([['id','=',$class['id']]])->update(['examine'=>1]);
+ //3 单据记录
+ Db::name('record')->insert(['type'=>'bill','source'=>$class['id'],'time'=>time(),'user'=>getUserID(),'info'=>'审核单据']);
+ //4 记录操作
+ pushLog('审核核销单[ '.$class['number'].' ]');//单据日志
+ }else{
+ //反审核
+
+ //1 数据处理
+ foreach ($info as $infoVo){
+ $mold=$infoVo['mold'];
+ $money=in_array($infoVo['mold'],['bre','sre'])?abs($infoVo['money']):$infoVo['money'];
+ //1.1 删除核销记录
+ Db::name($mold.'_bill')->where([
+ ['pid','=',$infoVo['source']],
+ ['type','=','bill'],
+ ['source','=',$class['id']]
+ ])->delete();
+ //1.2 读取核销状态
+ $sum=Db::name($mold.'_bill')->where(['pid'=>$infoVo['source']])->sum('money');
+ $nucleus=empty($sum)?0:1;
+ //1.3 更新核销状态
+ Db::name($mold)->where([['id','=',$infoVo['source']]])->update(['nucleus'=>$nucleus]);
+ }
+ //2 更新单据
+ Db::name('bill')->where([['id','=',$class['id']]])->update(['examine'=>0]);
+ //3 单据记录
+ Db::name('record')->insert(['type'=>'bill','source'=>$class['id'],'time'=>time(),'user'=>getUserID(),'info'=>'反审核单据']);
+ //11 记录操作
+ pushLog('反审核核销单[ '.$class['number'].' ]');//单据日志
+ }
+
+ Db::commit();
+ } catch (\Exception $e) {
+ Db::rollback();
+ return json(['state'=>'error','info'=>'内部错误,操作已撤销!']);
+ exit;
+ }
+ }
+ $result=['state'=>'success'];
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //上传
+ public function upload(){
+ $file = request()->file('file');
+ //获取上传文件
+ if (empty($file)) {
+ $result = ['state' => 'error','info' => '传入数据不完整!'];
+ } else {
+ //文件限制5MB
+ try{
+ validate(['file'=>['fileSize'=>5*1024*1024,'fileExt'=>'png,gif,jpg,jpeg,txt,doc,docx,rtf,xls,xlsx,ppt,pptx,pdf,zip,rar']])->check(['file'=>$file]);
+ $fileInfo=Filesystem::disk('upload')->putFile('bill', $file, 'uniqid');
+ $filePath=request()->domain().'/static/upload/'.$fileInfo;
+ $result=['state'=>'success','info'=>$filePath];
+ }catch(ValidateException $e) {
+ $result = ['state' => 'error','info' => $e->getMessage()];
+ }
+ }
+ return json($result);
+ }
+ //导出
+ public function exports(){
+ $input=input('get.');
+ if(existFull($input,['scene','parm']) && is_array($input['parm'])){
+ pushLog('导出核销单列表');//日志
+ $source=Bills::with(['frameData','customerData','supplierData','userData','peopleData'])->where([['id','in',$input['parm']]])->append(['extension'])->order(['id'=>'desc'])->select()->toArray();//查询CLASS数据
+ if($input['scene']=='simple'){
+ //简易报表
+ //开始构造导出数据
+ $excel=[];//初始化导出数据
+ //标题数据
+ $excel[]=['type'=>'title','info'=>'核销单列表'];
+ //表格数据
+ $field=[
+ 'frameData|name'=>'所属组织',
+ 'customerData|name'=>'客户',
+ 'supplierData|name'=>'供应商',
+ 'time'=>'单据时间',
+ 'number'=>'单据编号',
+ 'extension|type'=>'核销类型',
+ 'pmy'=>'核销金额',
+ 'peopleData|name'=>'关联人员',
+ 'extension|examine'=>'审核状态',
+ 'userData|name'=>'制单人',
+ 'data'=>'备注信息'
+ ];
+ $thead=array_values($field);//表格标题
+ $tbody=[];//表格内容
+ //构造表内数据
+ foreach ($source as $sourceVo) {
+ $rowData=[];
+ foreach (array_keys($field) as $fieldVo) {
+ $rowData[]=arraySeek($sourceVo,$fieldVo);//多键名数据赋值
+ }
+ $tbody[]=$rowData;//加入行数据
+ }
+ $excel[]=['type'=>'table','info'=>['thead'=>$thead,'tbody'=>$tbody]];//表格数据
+ //统计数据
+ $excel[]=['type'=>'node','info'=>[
+ '总数:'.count($source),
+ '总核销金额:'.mathArraySum(array_column($source,'pmy')),
+ ]];
+ //导出execl
+ buildExcel('核销单列表',$excel);
+ }else{
+ //详细报表
+ $files=[];//初始化文件列表
+ foreach ($source as $sourceVo) {
+ //开始构造导出数据
+ $excel=[];//初始化导出数据
+ //标题数据
+ $excel[]=['type'=>'title','info'=>'核销单'];
+ //节点数据
+ $excel[]=['type'=>'node','info'=>[
+ '客户:'.arraySeek($sourceVo,'customerData|name'),
+ '供应商:'.arraySeek($sourceVo,'supplierData|name'),
+ '单据日期:'.$sourceVo['time'],
+ '单据编号:'.$sourceVo['number']]
+ ];
+ //表格数据
+ $field=[
+ 'extension|bill'=>'核销类型',
+ 'extension|mold'=>'单据类型',
+ 'sourceData|time'=>'单据日期',
+ 'sourceData|number'=>'单据编号',
+ 'sourceData|total'=>'单据金额',
+ 'sourceData|extension|amount'=>'已核销',
+ 'sourceData|extension|anwo'=>'未核销',
+ 'money'=>'核销金额'
+ ];
+ //构造表内数据
+ $info=BillInfo::with(['sourceData'])->where([['pid','=',$sourceVo['id']]])->order(['id'=>'asc'])->append(['extension'])->select()->each(function($item){
+ $item->sourceData->append(['extension']);
+ })->toArray();
+ //数据处理
+ foreach ($info as $key=>$vo) {
+ in_array($vo['mold'],['buy','bre','sell','sre','ice','oce'])&&$info[$key]['sourceData']['total']=$vo['sourceData']['actual'];
+ }
+ $thead=array_values($field);//表格标题
+ $tbody=[];//表格内容
+ foreach ($info as $infoVo) {
+ $rowData=[];
+ foreach (array_keys($field) as $fieldVo) {
+ $rowData[]=arraySeek($infoVo,$fieldVo);//多键名数据赋值
+ }
+ $tbody[]=$rowData;//加入行数据
+ }
+
+ $excel[]=['type'=>'table','info'=>['thead'=>$thead,'tbody'=>$tbody]];//表格数据
+ //节点数据
+ $excel[]=['type'=>'node','info'=>[
+ '核销类型:'.arraySeek($sourceVo,'extension|type'),
+ '核销金额:'.$sourceVo['pmy'],
+ '关联人员:'.arraySeek($sourceVo,'peopleData|name'),
+ '备注信息:'.$sourceVo['data']]
+ ];
+ //生成execl
+ $files[]=buildExcel($sourceVo['number'],$excel,false);
+
+ }
+ buildZip('核销单_'.time(),$files);
+ }
+ }else{
+ return json(['state'=>'error','info'=>'传入数据不完整!']);
+ }
+ }
+}
\ No newline at end of file
diff --git a/serve/app/controller/Bor.php b/serve/app/controller/Bor.php
new file mode 100644
index 0000000..63ec638
--- /dev/null
+++ b/serve/app/controller/Bor.php
@@ -0,0 +1,633 @@
+'time'],'startTime'],
+ [['endTime'=>'time'],'endTime'],
+ [['startArrival'=>'arrival'],'startTime'],
+ [['endArrival'=>'arrival'],'endTime'],
+ ['user','fullEq'],
+ ['examine','fullDec1'],
+ ['state','fullDec1'],
+ ['data','fullLike']
+ ]);//构造SQL
+ //商品信息扩展查询
+ if(existFull($input,['goods'])){
+ $goods=array_column(Db::name('goods')->where([['name|py','like','%'.$input['goods'].'%']])->select()->toArray(),'id');
+ $sql[]=['id','in',array_column(Db::name('bor_info')->where([['goods','in',$goods]])->select()->toArray(),'pid')];
+ }
+ $sql=frameScope($sql);//组织数据
+ $sql=sqlAuth('bor',$sql);//数据鉴权
+ $count = Bors::where($sql)->count();//获取总条数
+ $info = Bors::with(['frameData','supplierData','peopleData','userData','recordData'])->where($sql)->append(['extension'])->page($input['page'],$input['limit'])->order(['id'=>'desc'])->select()->toArray();//查询分页数据
+ //关联单据
+ if(!empty($info)){
+ $sor=Db::name('sor')->where([['id','in',array_column($info,'source')]])->select()->toArray();
+ $buy=Db::name('buy')->where([['source','in',array_column($info,'id')]])->select()->toArray();
+ foreach ($info as $infoKey=>$infoVo) {
+ //销售订单
+ $sorData=array_map(function($item){
+ return ['type'=>'销售订单','time'=>date('Y-m-d',$item['time']),'number'=>$item['number'],'sort'=>$item['time'],'sort'=>$item['time'],'types'=>'sor','id'=>$item['id']];
+ },search($sor)->where([['id','=',$infoVo['source']]])->select());
+ //采购单
+ $buyData=array_map(function($item){
+ return ['type'=>'采购单','time'=>date('Y-m-d',$item['time']),'number'=>$item['number'],'sort'=>$item['time'],'sort'=>$item['time'],'types'=>'buy','id'=>$item['id']];
+ },search($buy)->where([['source','=',$infoVo['id']]])->select());
+ //合并排序
+ $merge=array_merge($sorData,$buyData);
+ array_multisort(array_column($merge,'sort'),SORT_DESC,$merge);
+ $info[$infoKey]['relation']=$merge;
+ }
+ }
+ $result=[
+ 'state'=>'success',
+ 'count'=>$count,
+ 'info'=>$info
+ ];//返回数据
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //新增|更新
+ public function save(){
+ $input=input('post.');
+ if(existFull($input,['class','info']) && isset($input['class']['id'])){
+ //构造|验证CLASS
+ try {
+ $class=$input['class'];
+ $class['frame']=userInfo(getUserID(),'frame');
+ $class['user']=getUserID();
+ $class['examine']=0;
+ empty($class['id'])?$this->validate($class,'app\validate\Bor'):$this->validate($class,'app\validate\Bor.update');
+ $period=getPeriod();
+ if(strtotime($class['time'])<=$period){
+ throw new ValidateException('单据日期与结账日期冲突!');
+ }
+ } catch (ValidateException $e) {
+ return json(['state'=>'error','info'=>$e->getError()]);
+ exit;
+ }
+
+ //验证INFO
+ foreach ($input['info'] as $infoKey=>$infoVo) {
+ try {
+ $this->validate($infoVo,'app\validate\BorInfo');
+ } catch (ValidateException $e) {
+ return json(['state'=>'error','info'=>'商品信息第'.($infoKey+1).'条'.$e->getError()]);
+ exit;
+ }
+ }
+
+ //处理数据
+ Db::startTrans();
+ try {
+ //CLASS数据
+ if(empty($class['id'])){
+ //创建数据
+ $createInfo=Bors::create($class);
+ $class['id']=$createInfo['id'];//转存主键
+ Db::name('record')->insert(['type'=>'bor','source'=>$class['id'],'time'=>time(),'user'=>getUserID(),'info'=>'新增单据']);
+ pushLog('新增采购订单[ '.$class['number'].' ]');//日志
+ }else{
+ //更新数据
+ $updateInfo=Bors::update($class);
+ Db::name('record')->insert(['type'=>'bor','source'=>$class['id'],'time'=>time(),'user'=>getUserID(),'info'=>'更新单据']);
+ pushLog('更新采购订单[ '.$class['number'].' ]');//日志
+ }
+
+ //INFO数据
+ BorInfo::where([['pid','=',$class['id']]])->delete();
+ foreach ($input['info'] as $infoKey=>$infoVo) {
+ $input['info'][$infoKey]['pid']=$class['id'];
+ $input['info'][$infoKey]['handle']=0;//初始|入库数量
+ }
+ $model = new BorInfo;
+ $model->saveAll($input['info']);
+
+ Db::commit();
+ $result=['state'=>'success','info'=>$class['id']];
+ } catch (\Exception $e) {
+ Db::rollback();
+ $result=['state'=>'error','info'=>'内部错误,操作已撤销!'];
+ }
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //获取
+ public function get(){
+ $input=input('post.');
+ if(existFull($input,['parm'])){
+ $class=Bors::where([['id','=',$input['parm']]])->find();
+ $info=BorInfo::with(['goodsData','warehouseData'])->where([['pid','=',$input['parm']]])->order(['id'=>'asc'])->select();
+ $result=['state'=>'success','info'=>[
+ 'class'=>$class,
+ 'info'=>$info,
+ ]];
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //删除
+ public function del(){
+ $input=input('post.');
+ if(existFull($input,['parm']) && is_array($input['parm'])){
+ //关联验证
+ $exist=moreTableFind([['table'=>'buy','where'=>[['source','in',$input['parm']]]]]);
+ if($exist){
+ $result=['state'=>'error','info'=>'存在数据关联,删除失败!'];
+ }else{
+ $data=Db::name('bor')->where([['id','in',$input['parm']]])->order(['id'=>'desc'])->select()->toArray();
+ $search=search($data)->where([['examine','=','1']])->find();
+ if(empty($search)){
+ Db::startTrans();
+ try {
+ Db::name('bor')->where([['id','in',$input['parm']]])->delete();
+ Db::name('bor_info')->where([['pid','in',$input['parm']]])->delete();
+ Db::name('record')->where([['type','=','bor'],['source','in',$input['parm']]])->delete();
+ Db::name('log')->insert(['time'=>time(),'user'=>getUserID(),'info'=>'删除采购订单[ '.implode(' | ',array_column($data,'number')).' ]']);
+
+ Db::commit();
+ $result=['state'=>'success'];
+ } catch (\Exception $e) {
+ Db::rollback();
+ $result=['state'=>'error','info'=>'内部错误,操作已撤销!'];
+ }
+ }else{
+ $result=['state'=>'error','info'=>'单据['.$search['number'].']已审核,不可删除!'];
+ }
+ }
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //审核|反审核
+ public function examine(){
+ $input=input('post.');
+ if(existFull($input,['parm']) && is_array($input['parm'])){
+ //1 基础数据
+ $period=getPeriod();
+ $classList=Db::name('bor')->where([['id','in',$input['parm']]])->order(['id'=>'desc'])->select()->toArray();
+ //2 综合处理
+ foreach ($classList as $class) {
+ //1 CLASS验证
+ if($class['time']<=$period){
+ return json(['state'=>'error','info'=>'操作单据[ '.$class['number'].' ]失败,原因:单据日期与结账日期冲突!']);
+ exit;
+ }
+ if(!empty($class['examine'])){
+ //采购单
+ $buy=Db::name('buy')->where([['source','=',$class['id']]])->find();
+ if(!empty($buy)){
+ return json(['state'=>'error','info'=>'反审核单据[ '.$class['number'].' ]失败,原因:该订单存在关联采购单!']);
+ exit;
+ }
+ }
+ //2 数据处理
+ Db::startTrans();
+ try {
+ //场景判断
+ if(empty($class['examine'])){
+ //审核
+ Db::name('bor')->where([['id','=',$class['id']]])->update(['examine'=>1]);
+ Db::name('record')->insert(['type'=>'bor','source'=>$class['id'],'time'=>time(),'user'=>getUserID(),'info'=>'审核单据']);
+ pushLog('审核采购订单[ '.$class['number'].' ]');//日志
+ }else{
+ //反审核
+ Db::name('bor')->where([['id','=',$class['id']]])->update(['examine'=>0]);
+ Db::name('record')->insert(['type'=>'bor','source'=>$class['id'],'time'=>time(),'user'=>getUserID(),'info'=>'反审核单据']);
+ pushLog('反审核采购订单[ '.$class['number'].' ]');//日志
+ }
+
+ Db::commit();
+ } catch (\Exception $e) {
+ Db::rollback();
+ return json(['state'=>'error','info'=>'内部错误,操作已撤销!']);
+ exit;
+ }
+ }
+ $result=['state'=>'success'];
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //开启|关闭
+ public function update(){
+ $input=input('post.');
+ if(existFull($input,['id'])){
+ $period=getPeriod();
+ $class=Db::name('bor')->where([['id','=',$input['id']]])->find();
+ if($class['time']<=$period){
+ return json(['state'=>'error','info'=>'操作单据失败,原因:单据日期与结账日期冲突!']);
+ exit;
+ }else{
+ Db::startTrans();
+ try {
+ if($class['state']==3){
+ //开启
+ Db::name('bor')->where([['id','=',$class['id']]])->update(['state'=>1]);
+ Db::name('record')->insert(['type'=>'bor','source'=>$class['id'],'time'=>time(),'user'=>getUserID(),'info'=>'开启单据']);
+ pushLog('开启采购订单[ '.$class['number'].' ]');//日志
+ }else{
+ //关闭
+ Db::name('bor')->where([['id','=',$class['id']]])->update(['state'=>3]);
+ Db::name('record')->insert(['type'=>'bor','source'=>$class['id'],'time'=>time(),'user'=>getUserID(),'info'=>'关闭单据']);
+ pushLog('关闭采购订单[ '.$class['number'].' ]');//日志
+ }
+
+ Db::commit();
+ $result=['state'=>'success'];
+ } catch (\Exception $e) {
+ Db::rollback();
+ $result=['state'=>'error','info'=>'内部错误,操作已撤销!'];
+ }
+ }
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return empty($parm)?json($result):$result;
+ }
+ //生成采购单
+ public function buildBuy(){
+ $input=input('post.');
+ if(existFull($input,['id'])){
+ //源数据
+ $source=[
+ 'class'=>Bors::where([['id','=',$input['id']]])->find(),
+ 'info'=>BorInfo::with(['goodsData','warehouseData'])->where([['pid','=',$input['id']]])->order(['id'=>'asc'])->select()->toArray()
+ ];
+ //状态验证
+ if($source['class']['state']!=2){
+ //CLASS数据
+ $class=[
+ 'source'=>$source['class']['id'],
+ 'supplier'=>$source['class']['supplier'],
+ 'total'=>0
+ ];
+ //INFO数据
+ $info=[];
+ $fun=getSys('fun');
+ foreach ($source['info'] as $infoVo) {
+ //判断入库状态
+ if(bccomp($infoVo['nums'],$infoVo['handle'])==1){
+ $infoVo['source']=$infoVo['id'];
+ $infoVo['serial']=[];
+ $infoVo['batch']='';
+ $infoVo['mfd']='';
+ $infoVo['retreat']=0;
+ //重算价格
+ $infoVo['nums']=math()->chain($infoVo['nums'])->sub($infoVo['handle'])->done();
+ $storage=math()->chain($infoVo['price'])->mul($infoVo['nums'])->round($fun['digit']['money'])->done();
+ //折扣额|金额
+ if($infoVo['discount']==0){
+ $infoVo['total']=$storage;
+ }else{
+ $infoVo['dsc']=math()->chain($storage)->div(100)->mul($infoVo['discount'])->round($fun['digit']['money'])->done();
+ $infoVo['total']=math()->chain($storage)->sub($infoVo['dsc'])->done();
+ }
+ //税额|价税合计
+ if($infoVo['tax']==0){
+ $infoVo['tpt']=$infoVo['total'];
+ }else{
+ $infoVo['tat']=math()->chain($infoVo['total'])->div(100)->mul($infoVo['tax'])->round(2)->done();
+ $infoVo['tpt']=math()->chain($infoVo['total'])->add($infoVo['tat'])->done();
+ }
+ //转存数据
+ $info[]=$infoVo;
+ $class['total']=math()->chain($class['total'])->add($infoVo['tpt'])->done();//累加单据金额
+ }
+ }
+ $result=['state'=>'success','info'=>['class'=>$class,'info'=>$info]];
+ }else{
+ $result=['state'=>'warning','info'=>'操作失败,订单状态为已入库!'];
+ }
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //上传
+ public function upload(){
+ $file = request()->file('file');
+ //获取上传文件
+ if (empty($file)) {
+ $result = ['state' => 'error','info' => '传入数据不完整!'];
+ } else {
+ //文件限制5MB
+ try{
+ validate(['file'=>['fileSize'=>5*1024*1024,'fileExt'=>'png,gif,jpg,jpeg,txt,doc,docx,rtf,xls,xlsx,ppt,pptx,pdf,zip,rar']])->check(['file'=>$file]);
+ $fileInfo=Filesystem::disk('upload')->putFile('bor', $file, 'uniqid');
+ $filePath=request()->domain().'/static/upload/'.$fileInfo;
+ $result=['state'=>'success','info'=>$filePath];
+ }catch(ValidateException $e) {
+ $result = ['state'=>'error','info'=>$e->getMessage()];
+ }
+ }
+ return json($result);
+ }
+ //导入
+ public function import(){
+ delOverdueFile('static.upload.xlsx');//删除过期文件
+ $file=request()->file('file');//获取上传文件
+ if(empty($file)){
+ $result=['state'=>'error','info'=>'传入数据不完整!'];
+ }else{
+ $fun=getSys('fun');
+ try{
+ validate(['file'=>['fileSize'=>2*1024*1024,'fileExt'=>'xlsx']])->check(['file'=>$file]);
+ $fileInfo = Filesystem::disk('upload')->putFile('xlsx', $file, 'uniqid');
+ $filePath = pathChange('static.upload').$fileInfo;
+ $data=getXlsx($filePath);
+ unset($data[1]);//删除标题行
+ unset($data[2]);//删除列名行
+ //初始化CLASS
+ $supplier=Db::name('supplier')->where([['name','=',$data[3]['A']]])->find();
+ if(empty($supplier)){
+ throw new ValidateException('供应商[ '.$data[3]['A'].' ]未匹配!');
+ }
+ //关联人员匹配
+ if(empty($data[3]['F'])){
+ $people=['id'=>0];
+ }else{
+ $people=Db::name('people')->where([['name','=',$data[3]['F']]])->find();
+ if(empty($people)){
+ throw new ValidateException('关联人员[ '.$data[3]['F'].' ]未匹配!');
+ }
+ }
+ $class=[
+ 'frame'=>userInfo(getUserID(),'frame'),
+ 'supplier'=>$supplier['id'],
+ 'time'=>$data[3]['B'],
+ 'number'=>$data[3]['C'],
+ 'total'=>0,
+ 'actual'=>$data[3]['E'],
+ 'people'=>$people['id'],
+ 'arrival'=>$data[3]['G'],
+ 'logistics'=>["key"=>"auto","name"=>"自动识别","number"=>$data[3]['H']],
+ 'file'=>[],
+ 'data'=>$data[3]['I'],
+ 'more'=>[],
+ 'examine'=>0,
+ 'state'=>0,
+ 'user'=>getUserID()
+ ];
+ $this->validate($class,'app\validate\Bor');//数据合法性验证
+ //初始化INFO
+ $info=[];
+ $goods=Goods::with(['attr'])->where([['name','in',array_column($data,'J')]])->select()->toArray();
+ $warehouse=Db::name('warehouse')->where([['name','in',array_column($data,'M')]])->select()->toArray();
+ foreach ($data as $dataKey=>$dataVo) {
+ $record=[
+ 'goods'=>$dataVo['J'],
+ 'attr'=>$dataVo['K'],
+ 'unit'=>$dataVo['L'],
+ 'warehouse'=>$dataVo['M'],
+ 'price'=>$dataVo['N'],
+ 'nums'=>$dataVo['O'],
+ 'discount'=>$dataVo['P'],
+ 'dsc'=>0,
+ 'total'=>0,
+ 'tax'=>$dataVo['S'],
+ 'tat'=>0,
+ 'tpt'=>0,
+ 'data'=>$dataVo['V'],
+ 'handle'=>0,
+ ];
+ //商品匹配
+ $goodsFind=search($goods)->where([['name','=',$record['goods']]])->find();
+ if(empty($goodsFind)){
+ throw new ValidateException('模板文件第'.$dataKey.'行商品名称[ '.$record['goods'].' ]未匹配!');
+ }else{
+ $record['goods']=$goodsFind['id'];
+ }
+ //辅助属性匹配
+ if(empty($goodsFind['attr'])){
+ $record['attr']='';
+ }else{
+ if(empty($record['attr'])){
+ throw new ValidateException('模板文件第'.$dataKey.'行辅助属性不可为空!');
+ }else{
+ $attrFind=search($goodsFind['attr'])->where([['name','=',$record['attr']]])->find();
+ if(empty($attrFind)){
+ throw new ValidateException('模板文件第'.$dataKey.'行辅助属性[ '.$record['attr'].' ]未匹配!');
+ }
+ }
+ }
+ //单位匹配
+ if($goodsFind['unit']==-1){
+ if(empty($record['unit'])){
+ throw new ValidateException('模板文件第'.$dataKey.'行单位不可为空!');
+ }else{
+ $unitFind=search($goodsFind['units'])->where([['name','=',$record['unit']]])->find();
+ if(empty($unitFind) && $goodsFind['units'][0]['source']!=$record['unit']){
+ throw new ValidateException('模板文件第'.$dataKey.'行单位[ '.$record['unit'].' ]未匹配!');
+ }
+ }
+ }else{
+ $record['unit']=$goodsFind['unit'];
+ }
+ //仓库匹配
+ if(empty($goodsFind['type'])){
+ //常规产品
+ $warehouseFind=search($warehouse)->where([['name','=',$record['warehouse']]])->find();
+ if(empty($warehouseFind)){
+ throw new ValidateException('模板文件第'.$dataKey.'行仓库[ '.$record['warehouse'].' ]未匹配!');
+ }else{
+ $record['warehouse']=$warehouseFind['id'];
+ }
+ }else{
+ //服务产品
+ $record['warehouse']=null;
+ }
+ //单价匹配
+ if(!preg_match("/^\d+(\.\d{0,".$fun['digit']['money']."})?$/",$record['price'])){
+ throw new ValidateException('模板文件第'.$dataKey.'行单价不正确!');
+ }
+ //数量匹配
+ if(!preg_match("/^\d+(\.\d{0,".$fun['digit']['nums']."})?$/",$record['nums'])){
+ throw new ValidateException('模板文件第'.$dataKey.'行数量不正确!');
+ }
+ try{
+ $this->validate($record,'app\validate\BorInfo');//数据合法性验证
+ $storage=math()->chain($record['price'])->mul($record['nums'])->round($fun['digit']['money'])->done();
+ //折扣额|金额
+ if($record['discount']==0){
+ $record['total']=$storage;
+ }else{
+ $record['dsc']=math()->chain($storage)->div(100)->mul($record['discount'])->round($fun['digit']['money'])->done();
+ $record['total']=math()->chain($storage)->sub($record['dsc'])->done();
+ }
+ //税额|价税合计
+ if($record['tax']==0){
+ $record['tpt']=$record['total'];
+ }else{
+
+ $record['tat']=math()->chain($record['total'])->div(100)->mul($record['tax'])->round(2)->done();
+ $record['tpt']=math()->chain($record['total'])->add($record['tat'])->done();
+ }
+ //转存数据
+ $class['total']=math()->chain($class['total'])->add($record['tpt'])->done();//累加单据金额
+ $info[]=$record;
+ } catch (ValidateException $e) {
+ return json(['state'=>'error','info'=>'模板文件第'.$dataKey.'行'.$e->getMessage()]);//返回错误信息
+ exit;
+ }
+ }
+ //CLASS数据验证
+ if(bccomp($class['total'],$class['actual'])==-1){
+ throw new ValidateException('实际金额不可大于单据金额[ '.$class['total'].' ]!');
+ }else{
+ Db::startTrans();
+ try {
+ //新增CLASS
+ $classData=Bors::create($class);
+ //新增INFO
+ foreach ($info as $infoKey=>$infoVo) {
+ $info[$infoKey]['pid']=$classData['id'];
+ }
+ $model = new BorInfo;
+ $model->saveAll($info);
+ Db::name('record')->insert(['type'=>'bor','source'=>$classData['id'],'time'=>time(),'user'=>getUserID(),'info'=>'导入单据']);
+ pushLog('导入采购订单[ '.$classData['number'].' ]');//日志
+
+ Db::commit();
+ $result=['state'=>'success'];
+ } catch (\Exception $e) {
+ Db::rollback();
+ $result=['state'=>'error','info'=>'内部错误,操作已撤销!'];
+ }
+ }
+ }catch(ValidateException $e) {
+ $result=['state'=>'error','info'=>$e->getMessage()];//返回错误信息
+ }
+ }
+ return json($result);
+ }
+ //导出
+ public function exports(){
+ $input=input('get.');
+ if(existFull($input,['scene','parm']) && is_array($input['parm'])){
+ pushLog('导出采购订单列表');//日志
+ $source=Bors::with(['frameData','supplierData','peopleData','userData'])->where([['id','in',$input['parm']]])->append(['extension'])->order(['id'=>'desc'])->select()->toArray();//查询CLASS数据
+ if($input['scene']=='simple'){
+ //简易报表
+ //开始构造导出数据
+ $excel=[];//初始化导出数据
+ //标题数据
+ $excel[]=['type'=>'title','info'=>'采购订单列表'];
+ //表格数据
+ $field=[
+ 'frameData|name'=>'所属组织',
+ 'supplierData|name'=>'供应商',
+ 'time'=>'单据时间',
+ 'number'=>'单据编号',
+ 'total'=>'单据金额',
+ 'actual'=>'实际金额',
+ 'arrival'=>'到货日期',
+ 'extension|examine'=>'审核状态',
+ 'extension|state'=>'入库状态',
+ 'peopleData|name'=>'关联人员',
+ 'userData|name'=>'制单人',
+ 'data'=>'备注信息'
+ ];
+ $thead=array_values($field);//表格标题
+ $tbody=[];//表格内容
+ //构造表内数据
+ foreach ($source as $sourceVo) {
+ $rowData=[];
+ foreach (array_keys($field) as $fieldVo) {
+ $rowData[]=arraySeek($sourceVo,$fieldVo);//多键名数据赋值
+ }
+ $tbody[]=$rowData;//加入行数据
+ }
+ $excel[]=['type'=>'table','info'=>['thead'=>$thead,'tbody'=>$tbody]];//表格数据
+ //统计数据
+ $excel[]=['type'=>'node','info'=>['总数:'.count($source),'总单据金额:'.mathArraySum(array_column($source,'total')),'总实际金额:'.mathArraySum(array_column($source,'actual'))]];
+ //导出execl
+ buildExcel('采购订单列表',$excel);
+ }else{
+ //详细报表
+ $files=[];//初始化文件列表
+ foreach ($source as $sourceVo) {
+ //开始构造导出数据
+ $excel=[];//初始化导出数据
+ //标题数据
+ $excel[]=['type'=>'title','info'=>'采购订单'];
+ //节点数据
+ $excel[]=['type'=>'node','info'=>[
+ '供应商:'.$sourceVo['supplierData']['name'],
+ '单据日期:'.$sourceVo['time'],
+ '单据编号:'.$sourceVo['number']]
+ ];
+ //表格数据
+ $field=[
+ 'goodsData|name'=>'商品名称',
+ 'goodsData|spec'=>'规格型号',
+ 'attr'=>'辅助属性',
+ 'unit'=>'单位',
+ 'warehouseData|name'=>'仓库',
+ 'price'=>'单价',
+ 'nums'=>'数量',
+ 'handle'=>'入库数量',
+ 'discount'=>'折扣率',
+ 'dsc'=>'折扣额',
+ 'total'=>'金额',
+ 'tax'=>'税率',
+ 'tat'=>'税额',
+ 'tpt'=>'价税合计',
+ 'data'=>'备注信息'
+ ];
+ //构造表内数据
+ $info=BorInfo::with(['goodsData','warehouseData'])->where([['pid','=',$sourceVo['id']]])->order(['id'=>'asc'])->select()->toArray();
+ //税金匹配
+ $fun=getSys('fun');
+ if(empty(search($info)->where([['tax','<>',0]])->find()) && !$fun['tax']){
+ unset($field['tax']);
+ unset($field['tat']);
+ unset($field['tpt']);
+ }
+ $thead=array_values($field);//表格标题
+ $tbody=[];//表格内容
+ foreach ($info as $infoVo) {
+ $rowData=[];
+ foreach (array_keys($field) as $fieldVo) {
+ $rowData[]=arraySeek($infoVo,$fieldVo);//多键名数据赋值
+ }
+ $tbody[]=$rowData;//加入行数据
+ }
+ $excel[]=['type'=>'table','info'=>['thead'=>$thead,'tbody'=>$tbody]];//表格数据
+ //节点数据
+ $excel[]=['type'=>'node','info'=>[
+ '单据金额:'.$sourceVo['total'],
+ '实际金额:'.$sourceVo['actual'],
+ '关联人员:'.arraySeek($sourceVo,'peopleData|name'),
+ '到货日期:'.$sourceVo['arrival'],
+ '物流信息:'.$sourceVo['extension']['logistics'],
+ '备注信息:'.$sourceVo['data']]
+ ];
+ //生成execl
+ $files[]=buildExcel($sourceVo['number'],$excel,false);
+ }
+ buildZip('采购订单_'.time(),$files);
+ }
+ }else{
+ return json(['state'=>'error','info'=>'传入数据不完整!']);
+ }
+ }
+}
diff --git a/serve/app/controller/Bre.php b/serve/app/controller/Bre.php
new file mode 100644
index 0000000..d661ee4
--- /dev/null
+++ b/serve/app/controller/Bre.php
@@ -0,0 +1,1225 @@
+'time'],'startTime'],
+ [['endTime'=>'time'],'endTime'],
+ ['examine','fullDec1'],
+ ['nucleus','fullDec1'],
+ ['cse','fullDec1'],
+ ['invoice','fullDec1'],
+ ['check','fullDec1'],
+ ['data','fullLike']
+ ]);//构造SQL
+ //商品信息扩展查询
+ if(existFull($input,['goods'])){
+ $goods=array_column(Db::name('goods')->where([['name|py','like','%'.$input['goods'].'%']])->select()->toArray(),'id');
+ $sql[]=['id','in',array_column(Db::name('bre_info')->where([['goods','in',$goods]])->select()->toArray(),'pid')];
+ }
+ $sql=frameScope($sql);//组织数据
+ $sql=sqlAuth('bre',$sql);//数据鉴权
+ $count = Bres::where($sql)->count();//获取总条数
+ $info = Bres::with(['frameData','supplierData','peopleData','userData','billData','costData','invoiceData','recordData'])->where($sql)->append(['extension'])->page($input['page'],$input['limit'])->order(['id'=>'desc'])->select()->toArray();//查询分页数据
+ //关联单据
+ if(!empty($info)){
+ $buy=Db::name('buy')->where([['id','in',array_column($info,'source')]])->select()->toArray();
+ foreach ($info as $infoKey=>$infoVo) {
+ //采购单
+ $relation=array_map(function($item){
+ return ['type'=>'采购单','time'=>date('Y-m-d',$item['time']),'number'=>$item['number'],'sort'=>$item['time'],'sort'=>$item['time'],'types'=>'buy','id'=>$item['id']];
+ },search($buy)->where([['id','=',$infoVo['source']]])->select());
+ //数据排序
+ array_multisort(array_column($relation,'sort'),SORT_DESC,$relation);
+ $info[$infoKey]['relation']=$relation;
+ }
+ }
+ $result=[
+ 'state'=>'success',
+ 'count'=>$count,
+ 'info'=>$info
+ ];//返回数据
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //新增|更新
+ public function save(){
+ $input=input('post.');
+ if(existFull($input,['class','info']) && isset($input['class']['id']) && isset($input['cost'])){
+ //构造|验证CLASS
+ try {
+ $class=$input['class'];
+ $class['frame']=userInfo(getUserID(),'frame');
+ $class['user']=getUserID();
+ $class['cse']=empty($class['cost'])?3:0;
+ $class['invoice']=empty($class['actual'])?3:0;
+ $class['examine']=0;
+ $class['nucleus']=0;
+ empty($class['id'])?$this->validate($class,'app\validate\Bre'):$this->validate($class,'app\validate\Bre.update');
+ $period=getPeriod();
+ if(strtotime($class['time'])<=$period){
+ throw new ValidateException('单据日期与结账日期冲突!');
+ }
+ } catch (ValidateException $e) {
+ return json(['state'=>'error','info'=>$e->getError()]);
+ exit;
+ }
+
+ //验证INFO
+ foreach ($input['info'] as $infoKey=>$infoVo) {
+ try {
+ $this->validate($infoVo,'app\validate\BreInfo');
+ } catch (ValidateException $e) {
+ return json(['state'=>'error','info'=>'商品信息第'.($infoKey+1).'条'.$e->getError()]);
+ exit;
+ }
+ }
+
+ //验证Cost
+ foreach ($input['cost'] as $costKey=>$costVo) {
+ try {
+ $this->validate($costVo,'app\validate\Cost');
+ } catch (ValidateException $e) {
+ return json(['state'=>'error','info'=>'单据费用第'.($infoKey+1).'条'.$e->getError()]);
+ exit;
+ }
+ }
+
+ //处理数据
+ Db::startTrans();
+ try {
+ //CLASS数据
+ if(empty($class['id'])){
+ //创建数据
+ $createInfo=Bres::create($class);
+ $class['id']=$createInfo['id'];//转存主键
+ Db::name('record')->insert(['type'=>'bre','source'=>$class['id'],'time'=>time(),'user'=>getUserID(),'info'=>'新增单据']);
+ pushLog('新增采购退货单[ '.$class['number'].' ]');//日志
+ }else{
+ //更新数据
+ $updateInfo=Bres::update($class);
+ Db::name('record')->insert(['type'=>'bre','source'=>$class['id'],'time'=>time(),'user'=>getUserID(),'info'=>'更新单据']);
+ pushLog('更新采购退货单[ '.$class['number'].' ]');//日志
+ }
+
+ //INFO数据
+ BreInfo::where([['pid','=',$class['id']]])->delete();
+ foreach ($input['info'] as $infoKey=>$infoVo) {
+ $input['info'][$infoKey]['pid']=$class['id'];
+ }
+ $model = new BreInfo;
+ $model->saveAll($input['info']);
+
+ //COST数据
+ Cost::where([['type','=','bre'],['class','=',$class['id']]])->delete();
+ foreach ($input['cost'] as $costKey=>$costVo) {
+ unset($input['cost'][$costKey]['id']);
+ $input['cost'][$costKey]['type']='bre';
+ $input['cost'][$costKey]['class']=$class['id'];
+ $input['cost'][$costKey]['time']=$class['time'];
+ $input['cost'][$costKey]['settle']=0;
+ $input['cost'][$costKey]['state']=0;
+ }
+ $model = new Cost;
+ $model->saveAll($input['cost']);
+
+ Db::commit();
+ $result=['state'=>'success','info'=>$class['id']];
+ } catch (\Exception $e) {
+ Db::rollback();
+ $result=['state'=>'error','info'=>'内部错误,操作已撤销!'];
+ }
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //获取
+ public function get(){
+ $input=input('post.');
+ if(existFull($input,['parm'])){
+ $class=Bres::where([['id','=',$input['parm']]])->find();
+ $info=BreInfo::with(['goodsData','warehouseData'])->where([['pid','=',$input['parm']]])->order(['id'=>'asc'])->select();
+ $cost=Cost::where([['type','=','bre'],['class','=',$input['parm']]])->order(['id'=>'asc'])->select();
+ $result=['state'=>'success','info'=>[
+ 'class'=>$class,
+ 'info'=>$info,
+ 'cost'=>$cost,
+ ]];
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //删除
+ public function del(){
+ $input=input('post.');
+ if(existFull($input,['parm']) && is_array($input['parm'])){
+ $data=Db::name('bre')->where([['id','in',$input['parm']]])->order(['id'=>'desc'])->select()->toArray();
+ $search=search($data)->where([['examine','=','1']])->find();
+ if(empty($search)){
+ Db::startTrans();
+ try {
+ Db::name('bre')->where([['id','in',$input['parm']]])->delete();
+ Db::name('bre_info')->where([['pid','in',$input['parm']]])->delete();
+ Db::name('cost')->where([['type','=','bre'],['class','in',$input['parm']]])->delete();
+ Db::name('record')->where([['type','=','bre'],['source','in',$input['parm']]])->delete();
+ Db::name('log')->insert(['time'=>time(),'user'=>getUserID(),'info'=>'删除采购退货单[ '.implode(' | ',array_column($data,'number')).' ]']);
+
+ Db::commit();
+ $result=['state'=>'success'];
+ } catch (\Exception $e) {
+ Db::rollback();
+ $result=['state'=>'error','info'=>'内部错误,操作已撤销!'];
+ }
+ }else{
+ $result=['state'=>'error','info'=>'单据['.$search['number'].']已审核,不可删除!'];
+ }
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //核对|反核对
+ public function check(){
+ $input=input('post.');
+ if(existFull($input,['parm']) && is_array($input['parm'])){
+ $period=getPeriod();
+ $classList=Db::name('bre')->where([['id','in',$input['parm']]])->order(['id'=>'desc'])->select()->toArray();
+ foreach ($input['parm'] as $parmVo) {
+ $class=search($classList)->where([['id','=',$parmVo]])->find();
+ if($class['time']<=$period){
+ return json(['state'=>'error','info'=>'操作单据失败,原因:单据日期与结账日期冲突!']);
+ exit;
+ }
+ if(empty($class['check'])){
+ Db::name('bre')->where([['id','=',$class['id']]])->update(['check'=>1]);
+ //1 单据记录
+ Db::name('record')->insert(['type'=>'bre','source'=>$class['id'],'time'=>time(),'user'=>getUserID(),'info'=>'核对单据']);
+ //2 记录操作
+ pushLog('核对采购退货单[ '.$class['number'].' ]');//单据日志
+ }else{
+ Db::name('bre')->where([['id','=',$class['id']]])->update(['check'=>0]);
+ //1 单据记录
+ Db::name('record')->insert(['type'=>'bre','source'=>$class['id'],'time'=>time(),'user'=>getUserID(),'info'=>'反核对单据']);
+ //2 记录操作
+ pushLog('反核对采购退货单[ '.$class['number'].' ]');//单据日志
+ }
+ }
+ $result=['state'=>'success'];
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //审核|反审核
+ public function examine(){
+ $input=input('post.');
+ if(existFull($input,['parm']) && is_array($input['parm'])){
+ //1 基础数据
+ $fun=getSys('fun');
+ $period=getPeriod();
+ $classList=Db::name('bre')->where([['id','in',$input['parm']]])->order(['id'=>'desc'])->select()->toArray();
+ $infoList=Db::name('bre_info')->where([['pid','in',$input['parm']]])->order(['id'=>'asc'])->select()->toArray();
+ //2 综合处理
+ foreach ($input['parm'] as $parmVo) {
+ //1 匹配数据
+ $class=search($classList)->where([['id','=',$parmVo]])->find();
+ $info=search($infoList)->where([['pid','=',$parmVo]])->select();
+ //1.1 商品数据
+ $goodsList=Db::name('goods')->where([['id','in',array_unique(array_column($info,'goods'))]])->select()->toArray();
+ //1.2 综合匹配
+ if(empty($class['examine'])){
+ //1 关联单据
+ empty($class['source'])||$buyInfoList=Db::name('buy_info')->where([['id','in',array_column($info,'source')]])->select()->toArray();
+ //2 构造数据
+ $batchGather=[];
+ $serialGather=[];
+ $roomWhereOrSql=[];
+ foreach ($info as $infoVo) {
+ //1 批次号
+ empty($infoVo['batch'])||$batchGather[]=$infoVo['batch'];
+ //2 序列号
+ $serialGather=array_merge($serialGather,json_decode($infoVo['serial']));
+ //3 仓储条件
+ empty($infoVo['warehouse'])||$roomWhereOrSql[]=[['warehouse','=',$infoVo['warehouse']],['goods','=',$infoVo['goods']],['attr','=',$infoVo['attr']]];
+ }
+ //3 匹配数据
+ empty($batchGather)||$batchList=Db::name('batch')->where([['number','in',$batchGather]])->select()->toArray();
+ empty($serialGather)||$serialList=Db::name('serial')->where([['number','in',$serialGather]])->select()->toArray();
+ if(!empty($roomWhereOrSql)){
+ //1 去重转存
+ $roomWhereOrSql=array_unique($roomWhereOrSql,SORT_REGULAR);
+ //2 仓储匹配
+ $roomList=Db::name('room')->whereOr($roomWhereOrSql)->select()->toArray();
+ }
+ }
+ //2 CLASS验证
+ if($class['time']<=$period){
+ return json(['state'=>'error','info'=>'操作单据[ '.$class['number'].' ]失败,原因:单据日期与结账日期冲突!']);
+ exit;
+ }
+ if(!empty($class['examine'])){
+ //1 核销单
+ $bill=Db::name('bill_info')->where([['mold','=','bre'],['source','=',$class['id']]])->find();
+ if(!empty($bill)){
+ return json(['state'=>'error','info'=>'反审核单据[ '.$class['number'].' ]失败,原因:该单据存在关联核销单!']);
+ exit;
+ }
+ //2 单据费用
+ $cost=Db::name('cost')->alias('cost')->where([['type','=','bre'],['class','=',$class['id']]])->whereExists(function($query){
+ $query->name('oce_info')->where([['source','=',Db::raw('cost.id')]])->limit(1);
+ })->find();
+ if(!empty($cost)){
+ return json(['state'=>'error','info'=>'反审核单据[ '.$class['number'].' ]失败,原因:该单据存在关联其它支出单!']);
+ exit;
+ }
+ //3 单据发票
+ $invoice=Db::name('invoice')->where([['type','=','bre'],['class','=',$class['id']]])->find();
+ if(!empty($invoice)){
+ return json(['state'=>'error','info'=>'反审核单据[ '.$class['number'].' ]失败,原因:该单据存在关联单据发票!']);
+ exit;
+ }
+ }
+ //3 INFO验证|构造
+ foreach ($info as $infoKey=>$infoVo) {
+ //1 匹配商品
+ $goods=search($goodsList)->where([['id','=',$infoVo['goods']]])->find();
+ //2 商品类型
+ if(empty($goods['type'])){
+ //场景验证
+ if(empty($class['examine'])){
+ //1 匹配数据
+ $room=search($roomList)->where([['warehouse','=',$infoVo['warehouse']],['goods','=',$infoVo['goods']],['attr','=',$infoVo['attr']]],true)->find();
+ (empty($room)||empty($infoVo['batch']))||$batch=search($batchList)->where([['room','=',$room['id']],['number','=',$infoVo['batch']],['time','=',$infoVo['mfd']]],true)->find();
+ //2 关联单据
+ if(!empty($infoVo['source'])){
+ $buyInfo=search($buyInfoList)->where([['id','=',$infoVo['source']]])->find();
+ if(!empty($buyInfo)){
+ if($buyInfo['unit']!=$infoVo['unit']){
+ //单位匹配
+ return json(['state'=>'error','info'=>'审核单据[ '.$class['number'].' ]失败,原因:第'.($infoKey+1).'行单位与采购单不匹配!']);
+ exit;
+ }elseif(bccomp(math()->chain($buyInfo['retreat'])->add($infoVo['nums'])->done(),$buyInfo['nums'])==1){
+ //数量匹配
+ return json(['state'=>'error','info'=>'审核单据[ '.$class['number'].' ]失败,原因:第'.($infoKey+1).'行超出采购单可退货数量!']);
+ exit;
+ }
+ }
+
+ }
+ //3 多单位处理
+ if($goods['unit']==-1){
+ //多单位|转存
+ $radix=unitRadix($infoVo['unit'],json_decode($goods['units'],true));
+ $info[$infoKey]['basic']=[
+ 'nums'=>math()->chain($infoVo['nums'])->mul($radix)->done(),
+ 'price'=>math()->chain($infoVo['price'])->div($radix)->round(4)->done()
+ ];
+ }else{
+ //常规单位|转存
+ $info[$infoKey]['basic']=[
+ 'nums'=>$infoVo['nums'],
+ 'price'=>$infoVo['price']
+ ];
+ }
+ //4 序列号
+ $serialData=json_decode($infoVo['serial']);
+ if(empty($serialData)){
+ $info[$infoKey]['serial']=[];
+ }else{
+ //序列号状态[不存在|未销售]
+ $serialCollect=search($serialList)->where([['goods','=',$infoVo['goods']],['number','in',$serialData]])->select();
+ foreach ($serialCollect as $serialCollectVo) {
+ if($serialCollectVo['state']==0){
+ if(empty($room) || $room['id']!=$serialCollectVo['room']){
+ return json(['state'=>'error','info'=>'审核单据[ '.$class['number'].' ]失败,原因:第'.($infoKey+1).'行序列号[ '.$serialCollectVo['number'].' ]与仓库不匹配!']);
+ exit;
+ }
+ if((empty($infoVo['batch'])&&!empty($serialCollectVo['batch']))||(!empty($infoVo['batch'])&&(empty($batch)||$batch['id']!=$serialCollectVo['batch']))){
+ return json(['state'=>'error','info'=>'审核单据[ '.$class['number'].' ]失败,原因:第'.($infoKey+1).'行序列号[ '.$serialCollectVo['number'].' ]与批次不匹配!']);
+ exit;
+ }
+ }else{
+ return json(['state'=>'error','info'=>'审核单据[ '.$class['number'].' ]失败,原因:第'.($infoKey+1).'行序列号[ '.$serialCollectVo['number'].' ]状态不正确!']);
+ exit;
+ }
+ }
+ $info[$infoKey]['serial']=$serialData;
+ }
+ //5 负库存验证
+ if($fun['overflow']==false){
+ //1 仓储验证
+ if(empty($room)){
+ return json(['state'=>'error','info'=>'审核单据[ '.$class['number'].' ]失败,原因:第'.($infoKey+1).'行仓储信息不存在!']);
+ exit;
+ }else{
+ if(bccomp($info[$infoKey]['basic']['nums'],$room['nums'])==1){
+ return json(['state'=>'error','info'=>'审核单据[ '.$class['number'].' ]失败,原因:第'.($infoKey+1).'行仓储库存不足!']);
+ exit;
+ }else{
+ $roomList[$room['rowKey']]['nums']=math()->chain($room['nums'])->sub($info[$infoKey]['basic']['nums'])->done();
+ }
+ }
+ //2 批次验证
+ if(!empty($infoVo['batch'])){
+ if(empty($batch)){
+ return json(['state'=>'error','info'=>'审核单据[ '.$class['number'].' ]失败,原因:第'.($infoKey+1).'行批次信息无效!']);
+ exit;
+ }else{
+ if(bccomp($info[$infoKey]['basic']['nums'],$batch['nums'])==1){
+ return json(['state'=>'error','info'=>'审核单据[ '.$class['number'].' ]失败,原因:第'.($infoKey+1).'行批次库存不足!']);
+ exit;
+ }else{
+ $batchList[$batch['rowKey']]['nums']=math()->chain($batch['nums'])->sub($info[$infoKey]['basic']['nums'])->done();
+ }
+ }
+ }
+ //3 序列号验证
+ if(!empty($serialData)){
+ $serialCount=search($serialList)->where([['room','=',$room['id']],['number','in',$serialData]])->count();
+ if($serialCount != count($serialData)){
+ return json(['state'=>'error','info'=>'审核单据[ '.$class['number'].' ]失败,原因:第'.($infoKey+1).'行存在无效序列号!']);
+ exit;
+ }
+ }
+ }
+ }else{
+ //1 验证序列号
+ $serialInfoCollect=Db::name('serial_info')->where([['type','=','bre'],['info','in',array_column($info,'id')]])->select()->toArray();
+ if(!empty($serialInfoCollect)){
+ //序列号状态[已退货]
+ $serialFind=Db::name('serial')->where([['id','in',array_column($serialInfoCollect,'pid')],['state','<>',3]])->find();
+ if(!empty($serialFind)){
+ return json(['state'=>'error','info'=>'反审核单据[ '.$class['number'].' ]失败,原因:第'.($infoKey+1).'行序列号[ '.$serialFind['number'].' ]状态不正确!']);
+ exit;
+ }
+ }
+ }
+ }
+ }
+ //4 数据处理
+ Db::startTrans();
+ try {
+ //场景验证
+ if(empty($class['examine'])){
+ //审核
+ //1 构造数据
+ $store=['buyInfo'=>[],'room'=>[],'roomInfo'=>[],'batch'=>[],'batchInfo'=>[],'serial'=>[],'serialInfo'=>[],'serve'=>[],'serveInfo'=>[]];
+ foreach ($info as $infoKey=>$infoVo){
+ //1 关联单据
+ empty($infoVo['source'])||$store['buyInfo'][]=['id'=>$infoVo['source'],'retreat'=>$infoVo['nums']];
+ //2 判断商品类型
+ $goods=search($goodsList)->where([['id','=',$infoVo['goods']]])->find();
+ if(empty($goods['type'])){
+ //常规商品
+ //1 仓储
+ $store['room'][]=['warehouse'=>$infoVo['warehouse'],'goods'=>$infoVo['goods'],'attr'=>$infoVo['attr'],'nums'=>$infoVo['basic']['nums']];
+ //2 仓储详情
+ $store['roomInfo'][]=['pid'=>null,'type'=>'bre','class'=>$class['id'],'info'=>$infoVo['id'],'time'=>$class['time'],'direction'=>0,'price'=>$infoVo['basic']['price'],'nums'=>$infoVo['basic']['nums']];
+ //3 批次号
+ if(empty($infoVo['batch'])){
+ $store['batch'][]=[];
+ $store['batchInfo'][]=[];
+ }else{
+ $store['batch'][]=['room'=>null,'warehouse'=>$infoVo['warehouse'],'goods'=>$infoVo['goods'],'number'=>$infoVo['batch'],'time'=>$infoVo['mfd'],'nums'=>$infoVo['basic']['nums']];
+ $store['batchInfo'][]=['pid'=>null,'type'=>'bre','class'=>$class['id'],'info'=>$infoVo['id'],'direction'=>0,'nums'=>$infoVo['basic']['nums']];
+ }
+ //4 序列号
+ if(empty($infoVo['serial'])){
+ $store['serial'][]=[];
+ $store['serialInfo'][]=[];
+ }else{
+ $serial=[];
+ $serialInfo=[];
+ foreach ($infoVo['serial'] as $serialVo) {
+ $serial[]=['room'=>null,'warehouse'=>$infoVo['warehouse'],'batch'=>null,'goods'=>$infoVo['goods'],'number'=>$serialVo,'state'=>3];
+ $serialInfo[]=['pid'=>null,'type'=>'bre','class'=>$class['id'],'info'=>$infoVo['id']];
+ }
+ $store['serial'][]=$serial;
+ $store['serialInfo'][]=$serialInfo;
+ }
+ }else{
+ //5 服务商品
+ $store['serve'][]=['goods'=>$infoVo['goods'],'attr'=>$infoVo['attr'],'nums'=>$infoVo['nums']];
+ $store['serveInfo'][]=['pid'=>null,'type'=>'bre','class'=>$class['id'],'info'=>$infoVo['id'],'time'=>$class['time'],'price'=>$infoVo['price'],'nums'=>$infoVo['nums']];
+ }
+ }
+ //2 关联单据
+ if(!empty($store['buyInfo'])){
+ //更新详情
+ Db::name('buy_info')->duplicate(['retreat'=>Db::raw('retreat + VALUES(`retreat`)')])->insertAll($store['buyInfo']);
+ $buyInfo=Db::name('buy_info')->where([['id','in',array_column($store['buyInfo'],'id')]])->select()->toArray();
+ $borInfoDuplicate=[];
+ foreach ($buyInfo as $buyVo){
+ empty($buyVo['source'])||$borInfoDuplicate[]=['id'=>$buyVo['source'],'handle'=>$buyVo['retreat']];
+ }
+ if(!empty($borInfoDuplicate)){
+ //更新详情
+ Db::name('bor_info')->duplicate(['handle'=>Db::raw('handle - VALUES(`handle`)')])->insertAll($borInfoDuplicate);
+ //2 更新销售订单CLASS
+ $borInfo=Db::name('bor_info')->where([['id','in',array_column($buyInfo,'source')]])->select()->toArray();
+ if(array_sum(array_column($borInfo,'handle'))==0){
+ $state=0;
+ }else{
+ $state=mathArraySum(array_column($borInfo,'nums'))==mathArraySum(array_column($borInfo,'handle'))?2:1;
+ }
+ Db::name('bor')->where([['id','=',$borInfo[0]['pid']]])->update(['state'=>$state]);
+ }
+
+
+ }
+ //3 仓储
+ if(!empty($store['room'])){
+ //1 构造数据
+ $roomInsert=[];
+ foreach ($store['room'] as $roomVo) {
+ $roomFind=search($roomList)->where([['warehouse','=',$roomVo['warehouse']],['goods','=',$roomVo['goods']],['attr','=',$roomVo['attr']]])->find();
+ if(empty($roomFind)){
+ $roomVo['nums']=0;
+ $roomInsert[]=$roomVo;
+ }
+ }
+ //2 创建数据|去重
+ empty($roomInsert)||Db::name('room')->insertAll(array_unique($roomInsert,SORT_REGULAR));
+ //3 匹配主键|构造更新
+ $roomDuplicate=[];
+ $room=Db::name('room')->whereOr($roomWhereOrSql)->select()->toArray();
+ foreach ($store['room'] as $roomKey=>$roomVo) {
+ $roomFind=search($room)->where([['warehouse','=',$roomVo['warehouse']],['goods','=',$roomVo['goods']],['attr','=',$roomVo['attr']]])->find();
+ $store['room'][$roomKey]['id']=$roomFind['id'];
+ $roomDuplicate[]=['id'=>$roomFind['id'],'nums'=>$roomVo['nums']];
+ }
+ //4 更新数据
+ Db::name('room')->duplicate(['nums'=>Db::raw('nums - VALUES(`nums`)')])->insertAll($roomDuplicate);
+ }
+ //4 仓储详情
+ if(!empty($store['roomInfo'])){
+ //1 填充数据
+ foreach ($store['roomInfo'] as $roomInfoKey=>$roomInfoVo) {
+ $store['roomInfo'][$roomInfoKey]['pid']=$store['room'][$roomInfoKey]['id'];
+ }
+ //2 创建数据
+ Db::name('room_info')->insertAll($store['roomInfo']);
+ }
+ //5 批次号
+ if(!empty($store['batch'])){
+ //1 构造数据
+ $batchData=[];
+ foreach ($store['batch'] as $batchKey=>$batchVo) {
+ if(!empty($batchVo)){
+ $store['batch'][$batchKey]['room']=$store['room'][$batchKey]['id'];
+ $batchData[]=$store['batch'][$batchKey];
+ }
+ }
+ //2 排除数据|[[],[],[]]
+ if(!empty($batchData)){
+ //1 构造数据
+ $batchInsert=[];
+ foreach ($batchData as $batchDataKey=>$batchDataVo) {
+ $batchFind=search($batchList)->where([['room','=',$batchDataVo['room']],['number','=',$batchDataVo['number']],['time','=',$batchDataVo['time']]])->find();
+ if(empty($batchFind)){
+ $batchDataVo['nums']=0;
+ $batchInsert[]=$batchDataVo;
+ }
+ }
+ //2 创建数据|去重
+ empty($batchInsert)||Db::name('batch')->insertAll(array_unique($batchInsert,SORT_REGULAR));
+ //3 匹配主键|构造更新
+ $batchDuplicate=[];
+ $batch=Db::name('batch')->where([['number','in',$batchGather]])->select()->toArray();
+ foreach ($store['batch'] as $batchKey=>$batchVo) {
+ if(!empty($batchVo)){
+ $batchFind=search($batch)->where([['room','=',$batchVo['room']],['number','=',$batchVo['number']],['time','=',$batchVo['time']]])->find();
+ $store['batch'][$batchKey]['id']=$batchFind['id'];
+ $batchDuplicate[]=['id'=>$batchFind['id'],'nums'=>$batchVo['nums']];
+ }
+ }
+ //4 更新数据
+ Db::name('batch')->duplicate(['nums'=>Db::raw('nums - VALUES(`nums`)')])->insertAll($batchDuplicate);
+ }
+ }
+ //6 批次号详情
+ if(!empty($store['batchInfo'])){
+ //1 构造数据
+ $batchInfoInstall=[];
+ foreach ($store['batchInfo'] as $batchInfoKey=>$batchInfoVo) {
+ if(!empty($batchInfoVo)){
+ $batchInfoVo['pid']=$store['batch'][$batchInfoKey]['id'];
+ $batchInfoInstall[]=$batchInfoVo;
+ }
+ }
+ //2 排除数据|[[],[],[]]
+ if(!empty($batchInfoInstall)){
+ //创建数据
+ Db::name('batch_info')->insertAll($batchInfoInstall);
+ }
+ }
+ //7 序列号
+ if(!empty($store['serial'])){
+ //1 构造数据
+ $serialData=[];
+ foreach ($store['serial'] as $serialKey=>$item) {
+ if(!empty($item)){
+ foreach ($item as $itemKey=>$itemVo) {
+ $store['serial'][$serialKey][$itemKey]['room']=$store['room'][$serialKey]['id'];
+ $store['serial'][$serialKey][$itemKey]['batch']=empty($store['batch'][$serialKey])?0:$store['batch'][$serialKey]['id'];
+ $serialData[]=$store['serial'][$serialKey][$itemKey];
+ }
+ }
+ }
+ //2 排除数据|[[],[],[]]
+ if(!empty($serialData)){
+ //1 构造数据
+ $serialInsert=[];
+ foreach ($serialData as $serialDataKey=>$serialDataVo) {
+ $serialFind=search($serialList)->where([['room','=',$serialDataVo['room']],['batch','=',$serialDataVo['batch']],['number','=',$serialDataVo['number']]])->find();
+ if(empty($serialFind)){
+ $serialInsert[]=$serialDataVo;
+ }
+ }
+ //2 创建数据
+ empty($serialInsert)||Db::name('serial')->insertAll($serialInsert);
+ //3 匹配主键|构造更新
+ $serialDuplicate=[];
+ $serial=Db::name('serial')->where([['number','in',$serialGather]])->select()->toArray();
+ foreach ($store['serial'] as $serialKey=>$item) {
+ if(!empty($item)){
+ foreach ($item as $itemKey=>$itemVo) {
+ $serialFind=search($serial)->where([['room','=',$itemVo['room']],['batch','=',$itemVo['batch']],['number','=',$itemVo['number']]])->find();
+ $store['serial'][$serialKey][$itemKey]['id']=$serialFind['id'];
+ $serialFind['state']==0&&$serialDuplicate[]=$serialFind['id'];
+ }
+ }
+ }
+ //4 更新数据|状态变更
+ empty($serialDuplicate)||Db::name('serial')->where([['id','in',$serialDuplicate]])->update(['state'=>3]);
+ }
+ }
+ //8 序列号详情
+ if(!empty($store['serialInfo'])){
+ //1 构造数据
+ $serialInfoInstall=[];
+ foreach ($store['serialInfo'] as $serialInfoKey=>$item) {
+ if(!empty($item)){
+ foreach ($item as $itemKey=>$itemVo) {
+ $itemVo['pid']=$store['serial'][$serialInfoKey][$itemKey]['id'];
+ $serialInfoInstall[]=$itemVo;
+ }
+ }
+ }
+ //2 排除数据|[[],[],[]]
+ if(!empty($serialInfoInstall)){
+ //创建数据
+ Db::name('serial_info')->insertAll($serialInfoInstall);
+ }
+ }
+ //9 服务商品
+ if(!empty($store['serve'])){
+ //1 匹配数据|去重
+ $serveWhereOrSql=array_unique(array_map(function($item){
+ return [['goods','=',$item['goods']],['attr','=',$item['attr']]];
+ },$store['serve']),SORT_REGULAR);
+ $serve=Db::name('serve')->whereOr($serveWhereOrSql)->select()->toArray();
+ //2 构造数据
+ $serveInsert=[];
+ foreach ($store['serve'] as $serveVo) {
+ $serveFind=search($serve)->where([['goods','=',$serveVo['goods']],['attr','=',$serveVo['attr']]])->find();
+ if(empty($serveFind)){
+ $serveVo['nums']=0;
+ $serveInsert[]=$serveVo;
+ }
+ }
+ //3 创建数据|去重
+ empty($serveInsert)||Db::name('serve')->insertAll(array_unique($serveInsert,SORT_REGULAR));
+ //4 匹配主键|构造更新
+ $serveDuplicate=[];
+ $serve=Db::name('serve')->whereOr($serveWhereOrSql)->select()->toArray();
+ foreach ($store['serve'] as $serveKey=>$serveVo) {
+ $serveFind=search($serve)->where([['goods','=',$serveVo['goods']],['attr','=',$serveVo['attr']]])->find();
+ $store['serve'][$serveKey]['id']=$serveFind['id'];
+ $serveDuplicate[]=['id'=>$serveFind['id'],'nums'=>$serveVo['nums']];
+ }
+ //5 更新数据
+ Db::name('serve')->duplicate(['nums'=>Db::raw('nums + VALUES(`nums`)')])->insertAll($serveDuplicate);
+ }
+ //10 服务商品详情
+ if(!empty($store['serveInfo'])){
+ //1 填充数据
+ foreach ($store['serveInfo'] as $serveInfoKey=>$serveInfoVo) {
+ $store['serveInfo'][$serveInfoKey]['pid']=$store['serve'][$serveInfoKey]['id'];
+ }
+ //2 创建数据
+ Db::name('serve_info')->insertAll($store['serveInfo']);
+ }
+ //11 资金|核销
+ if(!empty($class['money'])){
+ //1 更新资金账户
+ Db::name('account')->where([['id','=',$class['account']]])->inc('balance',$class['money'])->update();
+ //2 创建资金详情
+ Db::name('account_info')->insert([
+ 'pid'=>$class['account'],
+ 'type'=>'bre',
+ 'class'=>$class['id'],
+ 'time'=>$class['time'],
+ 'direction'=>1,
+ 'money'=>$class['money']
+ ]);
+ //3 创建核销记录
+ Db::name('bre_bill')->insert([
+ 'pid'=>$class['id'],
+ 'type'=>'bre',
+ 'source'=>$class['id'],
+ 'time'=>$class['time'],
+ 'money'=>$class['money']
+ ]);
+ }
+ //12 供应商|应付款余额
+ $balance=math()->chain($class['actual'])->sub($class['money'])->done();
+ if(!empty($balance)){
+ Db::name('supplier')->where([['id','=',$class['supplier']]])->dec('balance',$balance)->update();
+ }
+ //13 更新单据
+ $nucleus=$class['money']==$class['actual']?2:($class['money']==0?0:1);
+ Db::name('bre')->where([['id','=',$class['id']]])->update(['examine'=>1,'nucleus'=>$nucleus]);
+ //14 单据记录
+ Db::name('record')->insert(['type'=>'bre','source'=>$class['id'],'time'=>time(),'user'=>getUserID(),'info'=>'审核单据']);
+ //15 收发记录
+ $summary=new Summary;
+ $summary->note('bre',$class['id'],true);
+ //16 记录操作
+ pushLog('审核采购退货单[ '.$class['number'].' ]');//单据日志
+ }else{
+ //反审核
+ //1 匹配数据
+ $listSql=[['type','=','bre'],['info','in',array_column($info,'id')]];
+ $roomInfoList=Db::name('room_info')->where($listSql)->select()->toArray();
+ $batchInfoList=Db::name('batch_info')->where($listSql)->select()->toArray();
+ $serialInfoList=Db::name('serial_info')->where($listSql)->select()->toArray();
+ $serveInfoList=Db::name('serve_info')->where($listSql)->select()->toArray();
+ //2 关联单据
+ if(!empty($class['source'])){
+ //更新详情
+ $buyInfoDuplicate=[];
+ foreach ($info as $infoVo) {
+ empty($infoVo['source'])||$buyInfoDuplicate[]=['id'=>$infoVo['source'],'retreat'=>$infoVo['nums']];
+ }
+ empty($buyInfoDuplicate)||Db::name('buy_info')->duplicate(['retreat'=>Db::raw('retreat - VALUES(`retreat`)')])->insertAll($buyInfoDuplicate);
+ //查询是否关联销售订单
+ $buyInfo=Db::name('buy_info')->where([['id','in',array_column($buyInfoDuplicate,'id')]])->select()->toArray();
+ $borInfoDuplicate=[];
+ foreach ($buyInfo as $buyVo){
+ empty($buyVo['source'])||$borInfoDuplicate[]=['id'=>$buyVo['source'],'handle'=>$infoVo['nums']];
+ }
+ if(!empty($borInfoDuplicate)){
+ //更新详情
+ Db::name('bor_info')->duplicate(['handle'=>Db::raw('handle + VALUES(`handle`)')])->insertAll($borInfoDuplicate);
+ //2 更新采购订单CLASS
+ $borInfo=Db::name('bor_info')->where([['id','in',array_column($buyInfo,'source')]])->select()->toArray();
+ $state=mathArraySum(array_column($borInfo,'nums'))==mathArraySum(array_column($borInfo,'handle'))?2:1;
+ Db::name('bor')->where([['id','=',$borInfo[0]['pid']]])->update(['state'=>$state]);
+ }
+
+ }
+ //3 仓储
+ $roomDuplicate=[];
+ foreach ($roomInfoList as $roomInfoVo) {
+ $roomDuplicate[]=['id'=>$roomInfoVo['pid'],'nums'=>$roomInfoVo['nums']];
+ }
+ //3.1 更新仓储
+ Db::name('room')->duplicate(['nums'=>Db::raw('nums + VALUES(`nums`)')])->insertAll($roomDuplicate);
+ //3.2 删除仓储详情
+ Db::name('room_info')->where([['id','in',array_column($roomInfoList,'id')]])->delete();
+ //3.3 仓储|冗余
+ $roomPk=array_unique(array_column($roomInfoList,'pid'));
+ $roomInfoData=Db::name('room_info')->where([['pid','in',$roomPk]])->select()->toArray();
+ $roomDiff=array_diff($roomPk,array_unique(array_column($roomInfoData,'pid')));
+ empty($roomDiff)||Db::name('room')->where([['id','in',$roomDiff]])->delete();
+ //4 批次号
+ if(!empty($batchInfoList)){
+ //1 构造数据
+ $batchInfoDuplicate=array_map(function($item){
+ return ['id'=>$item['pid'],'nums'=>$item['nums']];
+ },$batchInfoList);
+ //2 更新批次号
+ Db::name('batch')->duplicate(['nums'=>Db::raw('nums + VALUES(`nums`)')])->insertAll($batchInfoDuplicate);
+ //3 删除批次号详情
+ Db::name('batch_info')->where([['id','in',array_column($batchInfoList,'id')]])->delete();
+ //4 批次号|冗余
+ $batchPk=array_unique(array_column($batchInfoList,'pid'));
+ $batchInfoData=Db::name('batch_info')->where([['pid','in',$batchPk]])->select()->toArray();
+ $batchDiff=array_diff($batchPk,array_unique(array_column($batchInfoData,'pid')));
+ empty($batchDiff)||Db::name('batch')->where([['id','in',$batchDiff]])->delete();
+ }
+ //5 序列号
+ if(!empty($serialInfoList)){
+ //1 更新序列号
+ Db::name('serial')->where([['id','in',array_column($serialInfoList,'pid')]])->update(['state'=>0]);
+ //2 删除序列号详情
+ Db::name('serial_info')->where([['id','in',array_column($serialInfoList,'id')]])->delete();
+ //3 序列号|冗余
+ $serialPk=array_unique(array_column($serialInfoList,'pid'));
+ $serialInfoData=Db::name('serial_info')->where([['pid','in',$serialPk]])->select()->toArray();
+ $serialDiff=array_diff($serialPk,array_unique(array_column($serialInfoData,'pid')));
+ empty($serialDiff)||Db::name('serial')->where([['id','in',$serialDiff]])->delete();
+ }
+ //6 服务
+ if(!empty($serveInfoList)){
+ //1 构造数据
+ $serveInfoDuplicate=array_map(function($item){
+ return ['id'=>$item['pid'],'nums'=>$item['nums']];
+ },$serveInfoList);
+ //2 更新服务
+ Db::name('serve')->duplicate(['nums'=>Db::raw('nums - VALUES(`nums`)')])->insertAll($serveInfoDuplicate);
+ //3 删除服务详情
+ Db::name('serve_info')->where([['id','in',array_column($serveInfoList,'id')]])->delete();
+ //4 服务|冗余
+ $servePk=array_unique(array_column($serveInfoList,'pid'));
+ $serveInfoData=Db::name('serve_info')->where([['pid','in',$servePk]])->select()->toArray();
+ $serveDiff=array_diff($servePk,array_unique(array_column($serveInfoData,'pid')));
+ empty($serveDiff)||Db::name('serve')->where([['id','in',$serveDiff]])->delete();
+ }
+ //7 资金|核销
+ if(!empty($class['money'])){
+ //6.1 更新资金账户
+ Db::name('account')->where([['id','=',$class['account']]])->dec('balance',$class['money'])->update();
+ //6.2 删除资金详情
+ Db::name('account_info')->where([['type','=','bre'],['class','=',$class['id']]])->delete();
+ //6.3 删除核销记录
+ Db::name('bre_bill')->where([['pid','=',$class['id']]])->delete();
+ }
+ //8 供应商|应付款余额
+ $balance=math()->chain($class['actual'])->sub($class['money'])->done();
+ if(!empty($balance)){
+ Db::name('supplier')->where([['id','=',$class['supplier']]])->inc('balance',$balance)->update();
+ }
+ //9 更新单据
+ Db::name('bre')->where([['id','=',$class['id']]])->update(['examine'=>0,'nucleus'=>0]);
+ //10 单据记录
+ Db::name('record')->insert(['type'=>'bre','source'=>$class['id'],'time'=>time(),'user'=>getUserID(),'info'=>'反审核单据']);
+ //11 收发记录
+ $summary=new Summary;
+ $summary->note('bre',$class['id'],false);
+ //12 记录操作
+ pushLog('反审核采购退货单[ '.$class['number'].' ]');//单据日志
+ }
+
+ Db::commit();
+ } catch (\Exception $e) {
+ Db::rollback();
+ return json(['state'=>'error','info'=>'内部错误,操作已撤销!']);
+ exit;
+ }
+ }
+ $result=['state'=>'success'];
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //上传
+ public function upload(){
+ $file = request()->file('file');
+ //获取上传文件
+ if (empty($file)) {
+ $result = ['state' => 'error','info' => '传入数据不完整!'];
+ } else {
+ //文件限制5MB
+ try{
+ validate(['file'=>['fileSize'=>5*1024*1024,'fileExt'=>'png,gif,jpg,jpeg,txt,doc,docx,rtf,xls,xlsx,ppt,pptx,pdf,zip,rar']])->check(['file'=>$file]);
+ $fileInfo=Filesystem::disk('upload')->putFile('bre', $file, 'uniqid');
+ $filePath=request()->domain().'/static/upload/'.$fileInfo;
+ $result=['state'=>'success','info'=>$filePath];
+ }catch(ValidateException $e) {
+ $result = ['state' => 'error','info' => $e->getMessage()];
+ }
+ }
+ return json($result);
+ }
+ //导入
+ public function import(){
+ delOverdueFile('static.upload.xlsx');//删除过期文件
+ $file=request()->file('file');//获取上传文件
+ if(empty($file)){
+ $result=['state'=>'error','info'=>'传入数据不完整!'];
+ }else{
+ $fun=getSys('fun');
+ try{
+ validate(['file'=>['fileSize'=>2*1024*1024,'fileExt'=>'xlsx']])->check(['file'=>$file]);
+ $fileInfo = Filesystem::disk('upload')->putFile('xlsx', $file, 'uniqid');
+ $filePath = pathChange('static.upload').$fileInfo;
+ $data=getXlsx($filePath);
+ unset($data[1]);//删除标题行
+ unset($data[2]);//删除列名行
+ //初始化CLASS
+ $supplier=Db::name('supplier')->where([['name','=',$data[3]['A']]])->find();
+ if(empty($supplier)){
+ throw new ValidateException('供应商[ '.$data[3]['A'].' ]未匹配!');
+ }
+ //结算账户匹配
+ if(empty($data[3]['F'])){
+ $account=['id'=>0];
+ }else{
+ $account=Db::name('account')->where([['name','=',$data[3]['G']]])->find();
+ if(empty($account)){
+ throw new ValidateException('结算账户[ '.$data[3]['G'].' ]不正确!');
+ }
+ }
+ //关联人员匹配
+ if(empty($data[3]['H'])){
+ $people=['id'=>0];
+ }else{
+ $people=Db::name('people')->where([['name','=',$data[3]['H']]])->find();
+ if(empty($people)){
+ throw new ValidateException('关联人员[ '.$data[3]['H'].' ]未匹配!');
+ }
+ }
+ $class=[
+ 'source'=>0,
+ 'frame'=>userInfo(getUserID(),'frame'),
+ 'supplier'=>$supplier['id'],
+ 'time'=>$data[3]['B'],
+ 'number'=>$data[3]['C'],
+ 'total'=>0,
+ 'actual'=>$data[3]['E'],
+ 'money'=>$data[3]['F'],
+ 'account'=>$account['id'],
+ 'people'=>$people['id'],
+ 'logistics'=>["key"=>"auto","name"=>"自动识别","number"=>$data[3]['I']],
+ 'file'=>[],
+ 'data'=>$data[3]['J'],
+ 'more'=>[],
+ 'examine'=>0,
+ 'nucleus'=>0,
+ 'cse'=>0,
+ 'invoice'=>0,
+ 'check'=>0,
+ 'user'=>getUserID()
+ ];
+ $this->validate($class,'app\validate\Bre');//数据合法性验证
+ //初始化INFO
+ $info=[];
+ $goods=Goods::with(['attr'])->where([['name','in',array_column($data,'K')]])->select()->toArray();
+ $warehouse=Db::name('warehouse')->where([['name','in',array_column($data,'N')]])->select()->toArray();
+ foreach ($data as $dataKey=>$dataVo) {
+ $record=[
+ 'source'=>0,
+ 'goods'=>$dataVo['K'],
+ 'attr'=>$dataVo['L'],
+ 'unit'=>$dataVo['M'],
+ 'warehouse'=>$dataVo['N'],
+ 'batch'=>$dataVo['O'],
+ 'mfd'=>$dataVo['P'],
+ 'price'=>$dataVo['Q'],
+ 'nums'=>$dataVo['R'],
+ 'serial'=>explode(',',$dataVo['S']),
+ 'discount'=>$dataVo['T'],
+ 'dsc'=>0,
+ 'total'=>0,
+ 'tax'=>$dataVo['W'],
+ 'tat'=>0,
+ 'tpt'=>0,
+ 'data'=>$dataVo['Z'],
+ ];
+ //商品匹配
+ $goodsFind=search($goods)->where([['name','=',$record['goods']]])->find();
+ if(empty($goodsFind)){
+ throw new ValidateException('模板文件第'.$dataKey.'行商品名称[ '.$record['goods'].' ]未匹配!');
+ }else{
+ $record['goods']=$goodsFind['id'];
+ }
+ //辅助属性匹配
+ if(empty($goodsFind['attr'])){
+ $record['attr']='';
+ }else{
+ if(empty($record['attr'])){
+ throw new ValidateException('模板文件第'.$dataKey.'行辅助属性不可为空!');
+ }else{
+ $attrFind=search($goodsFind['attr'])->where([['name','=',$record['attr']]])->find();
+ if(empty($attrFind)){
+ throw new ValidateException('模板文件第'.$dataKey.'行辅助属性[ '.$record['attr'].' ]未匹配!');
+ }
+ }
+ }
+ //单位匹配
+ if($goodsFind['unit']==-1){
+ if(empty($record['unit'])){
+ throw new ValidateException('模板文件第'.$dataKey.'行单位不可为空!');
+ }else{
+ $unitFind=search($goodsFind['units'])->where([['name','=',$record['unit']]])->find();
+ if(empty($unitFind) && $goodsFind['units'][0]['source']!=$record['unit']){
+ throw new ValidateException('模板文件第'.$dataKey.'行单位[ '.$record['unit'].' ]未匹配!');
+ }
+ }
+ }else{
+ $record['unit']=$goodsFind['unit'];
+ }
+ //仓库匹配
+ if(empty($goodsFind['type'])){
+ //常规产品
+ $warehouseFind=search($warehouse)->where([['name','=',$record['warehouse']]])->find();
+ if(empty($warehouseFind)){
+ throw new ValidateException('模板文件第'.$dataKey.'行仓库[ '.$record['warehouse'].' ]未匹配!');
+ }else{
+ $record['warehouse']=$warehouseFind['id'];
+ }
+ }else{
+ //服务产品
+ $record['warehouse']=null;
+ }
+ //批次号匹配
+ if(empty($goodsFind['batch'])){
+ $record['batch']='';
+ }else{
+ if(empty($record['batch'])){
+ throw new ValidateException('模板文件第'.$dataKey.'行批次号不可为空!');
+ }
+ }
+ //生产日期匹配
+ if(empty($goodsFind['validity'])){
+ $record['mfd']='';
+ }else{
+ if(empty($record['mfd'])){
+ throw new ValidateException('模板文件第'.$dataKey.'行生产日期不可为空!');
+ }
+ }
+ //单价匹配
+ if(!preg_match("/^\d+(\.\d{0,".$fun['digit']['money']."})?$/",$record['price'])){
+ throw new ValidateException('模板文件第'.$dataKey.'行单价不正确!');
+ }
+ //数量匹配
+ if(!preg_match("/^\d+(\.\d{0,".$fun['digit']['nums']."})?$/",$record['nums'])){
+ throw new ValidateException('模板文件第'.$dataKey.'行数量不正确!');
+ }
+ //序列号匹配
+ if(empty($goodsFind['serial'])){
+ $record['serial']=[];
+ }else{
+ if(count($record['serial'])==1 && empty($record['serial'][0])){
+ throw new ValidateException('模板文件第'.$dataKey.'行序列号不可为空!');
+ }else{
+ if(count($record['serial'])!=$record['nums']){
+ throw new ValidateException('模板文件第'.$dataKey.'行序列号个数与数量不符!');
+ }
+ }
+ }
+ try{
+ $this->validate($record,'app\validate\BreInfo');//数据合法性验证
+ $storage=math()->chain($record['price'])->mul($record['nums'])->round($fun['digit']['money'])->done();
+ //折扣额|金额
+ if($record['discount']==0){
+ $record['total']=$storage;
+ }else{
+ $record['dsc']=math()->chain($storage)->div(100)->mul($record['discount'])->round($fun['digit']['money'])->done();
+ $record['total']=math()->chain($storage)->sub($record['dsc'])->done();
+ }
+ //税额|价税合计
+ if($record['tax']==0){
+ $record['tpt']=$record['total'];
+ }else{
+ $record['tat']=math()->chain($record['total'])->div(100)->mul($record['tax'])->round(2)->done();
+ $record['tpt']=math()->chain($record['total'])->add($record['tat'])->done();
+ }
+ //转存数据
+ $class['total']=math()->chain($class['total'])->add($record['tpt'])->done();//累加单据金额
+ $info[]=$record;
+ } catch (ValidateException $e) {
+ return json(['state'=>'error','info'=>'模板文件第'.$dataKey.'行'.$e->getMessage()]);//返回错误信息
+ exit;
+ }
+ }
+ //序列号重复验证
+ $serials=[];
+ foreach ($info as $infoVo) {
+ $serials = array_merge($serials,$infoVo['serial']);
+ }
+ if(count($serials)!=count(array_unique($serials))){
+ throw new ValidateException('商品信息中存在重复序列号!');
+ }
+ //CLASS数据验证
+ if(bccomp($class['total'],$class['actual'])==-1){
+ throw new ValidateException('实际金额不可大于单据金额[ '.$class['total'].' ]!');
+ }else if(bccomp($class['actual'],$class['money'])==-1){
+ throw new ValidateException('实收金额不可大于实际金额[ '.floatval($class['actual']).' ]!');
+ }else{
+ Db::startTrans();
+ try {
+ //新增CLASS
+ $classData=Bres::create($class);
+ //新增INFO
+ foreach ($info as $infoKey=>$infoVo) {
+ $info[$infoKey]['pid']=$classData['id'];
+ }
+ $model = new BreInfo;
+ $model->saveAll($info);
+ Db::name('record')->insert(['type'=>'bre','source'=>$classData['id'],'time'=>time(),'user'=>getUserID(),'info'=>'导入单据']);
+ pushLog('导入采购退货单[ '.$classData['number'].' ]');//日志
+
+ Db::commit();
+ $result=['state'=>'success'];
+ } catch (\Exception $e) {
+ Db::rollback();
+ $result=['state'=>'error','info'=>'内部错误,操作已撤销!'];
+ }
+ }
+ }catch(ValidateException $e) {
+ $result=['state'=>'error','info'=>$e->getMessage()];//返回错误信息
+ }
+ }
+ return json($result);
+ }
+ //导出
+ public function exports(){
+ $input=input('get.');
+ if(existFull($input,['scene','parm']) && is_array($input['parm'])){
+ pushLog('导出采购退货单列表');//日志
+ $source=Bres::with(['frameData','supplierData','accountData','peopleData','userData'])->where([['id','in',$input['parm']]])->append(['extension'])->order(['id'=>'desc'])->select()->toArray();//查询CLASS数据
+ if($input['scene']=='simple'){
+ //简易报表
+ //开始构造导出数据
+ $excel=[];//初始化导出数据
+ //标题数据
+ $excel[]=['type'=>'title','info'=>'采购退货单列表'];
+ //表格数据
+ $field=[
+ 'frameData|name'=>'所属组织',
+ 'supplierData|name'=>'供应商',
+ 'time'=>'单据时间',
+ 'number'=>'单据编号',
+ 'total'=>'单据金额',
+ 'actual'=>'实际金额',
+ 'money'=>'单据收款',
+ 'extension|amount'=>'核销金额',
+ 'cost'=>'单据费用',
+ 'peopleData|name'=>'关联人员',
+ 'extension|examine'=>'审核状态',
+ 'extension|nucleus'=>'核销状态',
+ 'extension|cse'=>'费用状态',
+ 'extension|invoice'=>'发票状态',
+ 'extension|check'=>'核对状态',
+ 'userData|name'=>'制单人',
+ 'data'=>'备注信息'
+ ];
+ $thead=array_values($field);//表格标题
+ $tbody=[];//表格内容
+ //构造表内数据
+ foreach ($source as $sourceVo) {
+ $rowData=[];
+ foreach (array_keys($field) as $fieldVo) {
+ $rowData[]=arraySeek($sourceVo,$fieldVo);//多键名数据赋值
+ }
+ $tbody[]=$rowData;//加入行数据
+ }
+ $excel[]=['type'=>'table','info'=>['thead'=>$thead,'tbody'=>$tbody]];//表格数据
+ //统计数据
+ $excel[]=['type'=>'node','info'=>[
+ '总数:'.count($source),
+ '总单据金额:'.mathArraySum(array_column($source,'total')),
+ '总实际金额:'.mathArraySum(array_column($source,'actual')),
+ '总单据收款:'.mathArraySum(array_column($source,'money')),
+ '总核销金额:'.mathArraySum(arrayColumns($source,['extension','amount'])),
+ '总单据费用:'.mathArraySum(array_column($source,'cost'))
+ ]];
+ //导出execl
+ buildExcel('采购退货单列表',$excel);
+ }else{
+ //详细报表
+ $files=[];//初始化文件列表
+ foreach ($source as $sourceVo) {
+ //开始构造导出数据
+ $excel=[];//初始化导出数据
+ //标题数据
+ $excel[]=['type'=>'title','info'=>'采购退货单'];
+ //节点数据
+ $excel[]=['type'=>'node','info'=>[
+ '供应商:'.$sourceVo['supplierData']['name'],
+ '单据日期:'.$sourceVo['time'],
+ '单据编号:'.$sourceVo['number']]
+ ];
+ //表格数据
+ $field=[
+ 'goodsData|name'=>'商品名称',
+ 'goodsData|spec'=>'规格型号',
+ 'attr'=>'辅助属性',
+ 'unit'=>'单位',
+ 'warehouseData|name'=>'仓库',
+ 'batch'=>'批次号',
+ 'mfd'=>'生产日期',
+ 'price'=>'单价',
+ 'nums'=>'数量',
+ 'extension|serial'=>'序列号',
+ 'discount'=>'折扣率',
+ 'dsc'=>'折扣额',
+ 'total'=>'金额',
+ 'tax'=>'税率',
+ 'tat'=>'税额',
+ 'tpt'=>'价税合计',
+ 'data'=>'备注信息'
+ ];
+ //构造表内数据
+ $info=BreInfo::with(['goodsData','warehouseData'])->where([['pid','=',$sourceVo['id']]])->order(['id'=>'asc'])->append(['extension'])->select()->toArray();
+ //批次号匹配
+ if(empty(search($info)->where([['goodsData|batch','=',true]])->find())){
+ unset($field['batch']);
+ }
+ //生产日期匹配
+ if(empty(search($info)->where([['goodsData|validity','=',true]])->find())){
+ unset($field['mfd']);
+ }
+ //序列号匹配
+ if(empty(search($info)->where([['goodsData|serial','=',true]])->find())){
+ unset($field['extension|serial']);
+ }
+ //税金匹配
+ $fun=getSys('fun');
+ if(empty(search($info)->where([['tax','<>',0]])->find()) && !$fun['tax']){
+ unset($field['tax']);
+ unset($field['tat']);
+ unset($field['tpt']);
+ }
+ $thead=array_values($field);//表格标题
+ $tbody=[];//表格内容
+ foreach ($info as $infoVo) {
+ $rowData=[];
+ foreach (array_keys($field) as $fieldVo) {
+ $rowData[]=arraySeek($infoVo,$fieldVo);//多键名数据赋值
+ }
+ $tbody[]=$rowData;//加入行数据
+ }
+ $excel[]=['type'=>'table','info'=>['thead'=>$thead,'tbody'=>$tbody]];//表格数据
+ //节点数据
+ $excel[]=['type'=>'node','info'=>[
+ '单据金额:'.$sourceVo['total'],
+ '单据费用:'.$sourceVo['cost'],
+ '实际金额:'.$sourceVo['actual'],
+ '核销金额:'.$sourceVo['extension']['amount'],
+ '结算账户:'.arraySeek($sourceVo,'accountData|name'),
+ '发票信息:'.$sourceVo['invoice'],
+ '关联人员:'.arraySeek($sourceVo,'peopleData|name'),
+ '物流信息:'.$sourceVo['extension']['logistics'],
+ '备注信息:'.$sourceVo['data']]
+ ];
+ //生成execl
+ $files[]=buildExcel($sourceVo['number'],$excel,false);
+
+ }
+ buildZip('采购退货单_'.time(),$files);
+ }
+ }else{
+ return json(['state'=>'error','info'=>'传入数据不完整!']);
+ }
+ }
+}
\ No newline at end of file
diff --git a/serve/app/controller/Brt.php b/serve/app/controller/Brt.php
new file mode 100644
index 0000000..2dac79c
--- /dev/null
+++ b/serve/app/controller/Brt.php
@@ -0,0 +1,1154 @@
+'time'],'startTime'],
+ [['endTime'=>'time'],'endTime'],
+ [['startArrival'=>'arrival'],'startTime'],
+ [['endArrival'=>'arrival'],'endTime']
+ ]);
+ $sql['class'][]=['examine','=',1];
+ $sql['class']=frameScope($sql['class']);//组织数据
+ $sql['class']=sqlAuth('bor',$sql['class']);//数据鉴权
+ //INFO语句
+ $sql['info']=fastSql($input,[['warehouse','fullIn']]);
+ //商品匹配
+ if(existFull($input,['goods'])){
+ $goods=array_column(Db::name('goods')->where([['name|py','like','%'.$input['goods'].'%']])->select()->toArray(),'id');
+ $sql['info'][]=['goods','in',$goods];
+ }
+ $sql['or']=[];
+ //状态匹配
+ if(existFull($input,['state'])){
+ foreach ($input['state'] as $stateVo) {
+ $sql['or'][]=[['handle','=',0],Db::raw('handle > 0 AND handle < nums'),['handle','=',Db::raw('nums')]][$stateVo];
+ }
+ }
+ //判断排序
+ if(empty($input['type'])){
+ //单据排序
+ $record=Db::name('bor')->alias('class')->join(['is_bor_info'=>'info'],'class.id=info.pid')->where($sql['class'])->where($sql['info'])->where(function($query)use($sql){$query->whereOr($sql['or']);})->fieldRaw('class.id as class,group_concat(info.id) as info')->group('class.id')->order('class.id', 'desc')->select()->toArray();
+ $data=[];
+ $count=count($record);
+ if(!empty($record)){
+ $classList = \app\model\Bor::with(['frameData','supplierData'])->where([['id','in',array_column($record,'class')]])->append(['extension'])->page($input['page'],$input['limit'])->select()->toArray();
+ $infoList = \app\model\BorInfo::with(['goodsData','warehouseData'])->where([['pid','in',array_column($classList,'id')],['id','in',array_unique(explode(',',implode(',',array_column($record,'info'))))]])->select()->toArray();
+ foreach ($classList as $class) {
+ $class['key']=$class['id'];
+ $class['money']=$class['actual'];
+ $class['nmy']=0;
+ $info=search($infoList)->where([['pid','=',$class['id']]])->select();
+ foreach ($info as $key=>$vo) {
+ $info[$key]['key']=$class['id'].'_'.$vo['id'];
+ $info[$key]['price']=math()->chain($vo['tpt'])->div($vo['nums'])->round(2)->done();
+ $info[$key]['money']=$vo['tpt'];
+ $info[$key]['extension']['state']=$vo['handle']==0?'未入库':($vo['handle']==$vo['nums']?'已入库':'部分入库');
+ $info[$key]['nns']=math()->chain($vo['nums'])->sub($vo['handle'])->done();
+ $info[$key]['nmy']=math()->chain($info[$key]['price'])->mul($info[$key]['nns'])->done();
+ //汇总数据
+ $class['nmy']=math()->chain($class['nmy'])->add($info[$key]['nmy'])->done();
+ }
+ $class['node']=$info;
+ $data[]=$class;
+ }
+ }
+ }else{
+ //商品排序
+ $record=Db::name('bor_info')->alias('info')->join(['is_bor'=>'class'],'info.pid=class.id')->where($sql['class'])->where($sql['info'])->where(function($query)use($sql){$query->whereOr($sql['or']);})->fieldRaw('info.id as row,group_concat(info.id) as info')->group('info.goods,info.attr,info.warehouse')->order('info.id', 'desc')->select()->toArray();
+ $data=[];
+ $count=count($record);
+ if(!empty($record)){
+ $record = array_slice($record,$input['limit']*($input['page']-1),$input['limit']);
+ $infoList = \app\model\BorInfo::with(['goodsData','warehouseData'])->where([['id','in',array_unique(explode(',',implode(',',array_column($record,'info'))))]])->select()->toArray();
+ $classList = \app\model\Bor::with(['frameData','supplierData'])->where([['id','in',array_unique(array_column($infoList,'pid'))]])->append(['extension'])->select()->toArray();
+ foreach ($record as $recordVo) {
+ $info=search($infoList)->where([['id','in',explode(',',$recordVo['info'])]])->select();
+ $row=$info[0];
+ $row['key']=$row['id'];
+ $row['unit']='';
+ $row['price']='';
+ $row['nums']=0;
+ $row['money']=0;
+ $row['nns']=0;
+ $row['nmy']=0;
+ foreach ($info as $vo) {
+ $class=search($classList)->where([['id','=',$vo['pid']]])->find();
+ $class['key']=$vo['id'].'_'.$class['id'];
+ $class['unit']=$vo['unit'];
+ $class['price']=math()->chain($vo['tpt'])->div($vo['nums'])->round(2)->done();
+ $class['nums']=$vo['nums'];
+ $class['money']=$vo['tpt'];
+ $class['extension']['state']=$vo['handle']==0?'未入库':($vo['handle']==$vo['nums']?'已入库':'部分入库');
+ $class['nns']=math()->chain($vo['nums'])->sub($vo['handle'])->done();
+ $class['nmy']=math()->chain($class['price'])->mul($class['nns'])->done();
+ $class['data']=$vo['data'];
+ $class['basic']=['nums'=>$vo['nums'],'nns'=>$class['nns']];
+ //汇总数据
+ $row['money']=math()->chain($row['money'])->add($vo['tpt'])->done();
+ $row['nmy']=math()->chain($row['nmy'])->add($class['nmy'])->done();
+ //单位转换
+ if($vo['goodsData']['unit']=='-1'){
+ $radix=unitRadix($vo['unit'],$vo['goodsData']['units']);
+ $row['nums']=math()->chain($class['nums'])->mul($radix)->add($row['nums'])->done();
+ $row['nns']=math()->chain($class['nns'])->mul($radix)->add($row['nns'])->done();
+ }else{
+ $row['nums']=math()->chain($class['nums'])->add($row['nums'])->done();
+ $row['nns']=math()->chain($class['nns'])->add($row['nns'])->done();
+ }
+ $row['node'][]=$class;
+ }
+ $row['extension']['state']=$row['nns']==0?'已入库':($row['nns']==$row['nums']?'未入库':'部分入库');
+ //单位处理
+ if($row['goodsData']['unit']=='-1'){
+ $row['nums']=unitSwitch($row['nums'],$row['goodsData']['units']);
+ $row['nns']=unitSwitch($row['nns'],$row['goodsData']['units']);
+ }
+ $data[]=$row;
+ }
+ }
+ }
+ $result=[
+ 'state'=>'success',
+ 'count'=>$count,
+ 'info'=>$data
+ ];//返回数据
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //采购订单跟踪表-导出
+ public function bttExports(){
+ $input=input('get.');
+ existFull($input,['state'])||$input['state']=[];
+ existFull($input,['warehouse'])||$input['warehouse']=[];
+ if(is_arrays($input,['state','warehouse']) && isset($input['type'])){
+ pushLog('导出采购订单跟踪表');//日志
+ $sql=[];
+ //CLASS语句
+ $sql['class']=fastSql($input,[
+ ['supplier','fullEq'],
+ ['number','fullLike'],
+ [['startTime'=>'time'],'startTime'],
+ [['endTime'=>'time'],'endTime'],
+ [['startArrival'=>'arrival'],'startTime'],
+ [['endArrival'=>'arrival'],'endTime']
+ ]);
+ $sql['class'][]=['examine','=',1];
+ $sql['class']=frameScope($sql['class']);//组织数据
+ $sql['class']=sqlAuth('bor',$sql['class']);//数据鉴权
+ //INFO语句
+ $sql['info']=fastSql($input,[['warehouse','fullIn']]);
+ //商品匹配
+ if(existFull($input,['goods'])){
+ $goods=array_column(Db::name('goods')->where([['name|py','like','%'.$input['goods'].'%']])->select()->toArray(),'id');
+ $sql['info'][]=['goods','in',$goods];
+ }
+ $sql['or']=[];
+ //状态匹配
+ if(existFull($input,['state'])){
+ foreach ($input['state'] as $stateVo) {
+ $sql['or'][]=[['handle','=',0],Db::raw('handle > 0 AND handle < nums'),['handle','=',Db::raw('nums')]][$stateVo];
+ }
+ }
+ //判断排序
+ if(empty($input['type'])){
+ //单据排序
+ $record=Db::name('bor')->alias('class')->join(['is_bor_info'=>'info'],'class.id=info.pid')->where($sql['class'])->where($sql['info'])->where(function($query)use($sql){$query->whereOr($sql['or']);})->fieldRaw('class.id as class,group_concat(info.id) as info')->group('class.id')->order('class.id', 'desc')->select()->toArray();
+ $data=[];
+ $count=count($record);
+ if(!empty($record)){
+ $classList = \app\model\Bor::with(['frameData','supplierData'])->where([['id','in',array_column($record,'class')]])->append(['extension'])->select()->toArray();
+ $infoList = \app\model\BorInfo::with(['goodsData','warehouseData'])->where([['pid','in',array_column($classList,'id')],['id','in',array_unique(explode(',',implode(',',array_column($record,'info'))))]])->select()->toArray();
+ foreach ($classList as $class) {
+ $class['key']=$class['id'];
+ $class['money']=$class['actual'];
+ $class['nmy']=0;
+ $info=search($infoList)->where([['pid','=',$class['id']]])->select();
+ foreach ($info as $key=>$vo) {
+ $info[$key]['key']=$class['id'].'_'.$vo['id'];
+ $info[$key]['price']=math()->chain($vo['tpt'])->div($vo['nums'])->round(2)->done();
+ $info[$key]['money']=$vo['tpt'];
+ $info[$key]['extension']['state']=$vo['handle']==0?'未入库':($vo['handle']==$vo['nums']?'已入库':'部分入库');
+ $info[$key]['nns']=math()->chain($vo['nums'])->sub($vo['handle'])->done();
+ $info[$key]['nmy']=math()->chain($info[$key]['price'])->mul($info[$key]['nns'])->done();
+ //汇总数据
+ $class['nmy']=math()->chain($class['nmy'])->add($info[$key]['nmy'])->done();
+ }
+ $class['node']=$info;
+ $data[]=$class;
+ }
+ }
+ }else{
+ //商品排序
+ $record=Db::name('bor_info')->alias('info')->join(['is_bor'=>'class'],'info.pid=class.id')->where($sql['class'])->where($sql['info'])->where(function($query)use($sql){$query->whereOr($sql['or']);})->fieldRaw('info.id as row,group_concat(info.id) as info')->group('info.goods,info.attr,info.warehouse')->order('info.id', 'desc')->select()->toArray();
+ $data=[];
+ $count=count($record);
+ if(!empty($record)){
+ $infoList = \app\model\BorInfo::with(['goodsData','warehouseData'])->where([['id','in',array_unique(explode(',',implode(',',array_column($record,'info'))))]])->select()->toArray();
+ $classList = \app\model\Bor::with(['frameData','supplierData'])->where([['id','in',array_unique(array_column($infoList,'pid'))]])->append(['extension'])->select()->toArray();
+ foreach ($record as $recordVo) {
+ $info=search($infoList)->where([['id','in',explode(',',$recordVo['info'])]])->select();
+ $row=$info[0];
+ $row['key']=$row['id'];
+ $row['unit']='';
+ $row['price']='';
+ $row['nums']=0;
+ $row['money']=0;
+ $row['nns']=0;
+ $row['nmy']=0;
+ foreach ($info as $vo) {
+ $class=search($classList)->where([['id','=',$vo['pid']]])->find();
+ $class['key']=$vo['id'].'_'.$class['id'];
+ $class['unit']=$vo['unit'];
+ $class['price']=math()->chain($vo['tpt'])->div($vo['nums'])->round(2)->done();
+ $class['nums']=$vo['nums'];
+ $class['money']=$vo['tpt'];
+ $class['extension']['state']=$vo['handle']==0?'未入库':($vo['handle']==$vo['nums']?'已入库':'部分入库');
+ $class['nns']=math()->chain($vo['nums'])->sub($vo['handle'])->done();
+ $class['nmy']=math()->chain($class['price'])->mul($class['nns'])->done();
+ $class['data']=$vo['data'];
+ $class['basic']=['nums'=>$vo['nums'],'nns'=>$class['nns']];
+ //汇总数据
+ $row['money']=math()->chain($row['money'])->add($vo['tpt'])->done();
+ $row['nmy']=math()->chain($row['nmy'])->add($class['nmy'])->done();
+ //单位转换
+ if($vo['goodsData']['unit']=='-1'){
+ $radix=unitRadix($vo['unit'],$vo['goodsData']['units']);
+ $row['nums']=math()->chain($class['nums'])->mul($radix)->add($row['nums'])->done();
+ $row['nns']=math()->chain($class['nns'])->mul($radix)->add($row['nns'])->done();
+ }else{
+ $row['nums']=math()->chain($class['nums'])->add($row['nums'])->done();
+ $row['nns']=math()->chain($class['nns'])->add($row['nns'])->done();
+ }
+ $row['node'][]=$class;
+ }
+ $row['extension']['state']=$row['nns']==0?'已入库':($row['nns']==$row['nums']?'未入库':'部分入库');
+ //单位处理
+ if($row['goodsData']['unit']=='-1'){
+ $row['nums']=unitSwitch($row['nums'],$row['goodsData']['units']);
+ $row['nns']=unitSwitch($row['nns'],$row['goodsData']['units']);
+ }
+ $data[]=$row;
+ }
+ }
+ }
+ //结构重组
+ $source=[];
+ foreach ($data as $dataVo) {
+ $source[]=$dataVo;
+ if(!empty($dataVo['node'])){
+ foreach ($dataVo['node'] as $node) {
+ $source[]=$node;
+ }
+ }
+ }
+ //开始构造导出数据
+ $excel=[];//初始化导出数据
+ //标题数据
+ $excel[]=['type'=>'title','info'=>'采购订单跟踪表'];
+ //表格数据
+ $field=[
+ [
+ 'frameData|name'=>'所属组织',
+ 'supplierData|name'=>'供应商',
+ 'time'=>'单据时间',
+ 'number'=>'单据编号',
+ 'goodsData|name'=>'商品名称',
+ 'attr'=>'辅助属性',
+ 'warehouseData|name'=>'仓库',
+ ],[
+ 'goodsData|name'=>'商品名称',
+ 'attr'=>'辅助属性',
+ 'warehouseData|name'=>'仓库',
+ 'frameData|name'=>'所属组织',
+ 'supplierData|name'=>'供应商',
+ 'time'=>'单据时间',
+ 'number'=>'单据编号'
+ ],[
+ 'unit'=>'单位',
+ 'price'=>'单价',
+ 'nums'=>'数量',
+ 'money'=>'金额',
+ 'extension|state'=>'入库状态',
+ 'nns'=>'未入库数量',
+ 'nmy'=>'未入库金额',
+ 'arrival'=>'到货日期',
+ 'data'=>'备注信息'
+ ]
+ ];
+ $field=array_merge(empty($input['type'])?$field[0]:$field[1],$field[2]);
+ $thead=array_values($field);//表格标题
+ $tbody=[];//表格内容
+ //构造表内数据
+ foreach ($source as $sourceVo) {
+ $rowData=[];
+ foreach (array_keys($field) as $fieldVo) {
+ $rowData[]=arraySeek($sourceVo,$fieldVo);//多键名数据赋值
+ }
+ $tbody[]=$rowData;//加入行数据
+ }
+ $excel[]=['type'=>'table','info'=>['thead'=>$thead,'tbody'=>$tbody]];//表格数据
+ //导出execl
+ buildExcel('采购订单跟踪表',$excel);
+ }else{
+ return json(['state'=>'error','info'=>'传入参数不完整!']);
+ }
+ }
+ //采购明细表
+ public function blt(){
+ $input=input('post.');
+ $sheet=['buy','bre'];
+ existFull($input,['mold'])||$input['mold']=$sheet;
+ if(existFull($input,['page','limit']) && is_arrays($input,['warehouse','mold']) && arrayInArray($input['mold'],$sheet)){
+ $sql=[];
+ //CLASS语句
+ $sql['class']=fastSql($input,[
+ ['supplier','fullEq'],
+ ['number','fullLike'],
+ [['startTime'=>'time'],'startTime'],
+ [['endTime'=>'time'],'endTime'],
+ [['data'=>'class.data'],'fullLike']
+ ]);
+ $sql['class'][]=['examine','=',1];
+ $sql['class']=frameScope($sql['class']);//组织数据
+ //数据鉴权[结构一致]
+ $sql['class']=sqlAuth('buy',$sql['class']);
+ //INFO语句
+ $sql['info']=fastSql($input,[['warehouse','fullIn']]);
+ //商品匹配
+ if(existFull($input,['goods'])){
+ $goods=array_column(Db::name('goods')->where([['name|py','like','%'.$input['goods'].'%']])->select()->toArray(),'id');
+ $sql['info'][]=['goods','in',$goods];
+ }
+ //组装查询语句
+ $union=[];
+ foreach ($input['mold'] as $mold) {
+ $union[]=Db::name($mold.'_info')->alias('info')->join(['is_'.$mold=>'class'],'info.pid=class.id')->where($sql['info'])->where($sql['class'])->fieldRaw('info.id as info,class.id as class,time,"'.$mold.'" as mold')->buildSql();
+ }
+ $union=implode(' UNION ALL ',$union);
+ //获取总条数
+ $count=DB::query('SELECT COUNT(*) as count FROM ('.$union.') as nodcloud')[0]["count"];
+ $record=DB::query('SELECT * FROM ('.$union.') as nodcloud ORDER BY `time` DESC LIMIT '.pageCalc($input['page'],$input['limit'],'str'));
+ $list=[];
+ foreach ($input['mold'] as $mold) {
+ $gather=search($record)->where([['mold','=',$mold]])->select();
+ $table=[
+ "class"=>"app\\model\\".ucfirst($mold),
+ 'info'=>"app\\model\\".ucfirst($mold).'Info',
+ ];
+ $list[$mold]['info']=$table['info']::with(['goodsData','warehouseData'])->where([['id','in',array_column($gather,'info')]])->select()->toArray();
+ $list[$mold]['class']=$table['class']::with(['frameData','supplierData'])->where([['id','in',array_column($list[$mold]['info'],'pid')]])->append(['extension'])->select()->toArray();
+ }
+ $data=[];
+ foreach ($record as $recordVo) {
+ $mold=$recordVo['mold'];
+ $data[]=[
+ 'mold'=>$mold,
+ 'name'=>['buy'=>'采购单','bre'=>'采购退货单'][$mold],
+ 'class'=>search($list[$mold]['class'])->where([['id','=',$recordVo['class']]])->find(),
+ 'info'=>search($list[$mold]['info'])->where([['id','=',$recordVo['info']]])->find()
+ ];
+ }
+ $result=[
+ 'state'=>'success',
+ 'count'=>$count,
+ 'info'=>$data
+ ];//返回数据
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //采购明细表-导出
+ public function bltExports(){
+ $input=input('get.');
+ $sheet=['buy','bre'];
+ existFull($input,['warehouse'])||$input['warehouse']=[];
+ existFull($input,['mold'])||$input['mold']=$sheet;
+ if(is_arrays($input,['warehouse','mold']) && arrayInArray($input['mold'],$sheet)){
+ pushLog('导出采购明细表');//日志
+ $sql=[];
+ //CLASS语句
+ $sql['class']=fastSql($input,[
+ ['supplier','fullEq'],
+ ['number','fullLike'],
+ [['startTime'=>'time'],'startTime'],
+ [['endTime'=>'time'],'endTime'],
+ [['data'=>'class.data'],'fullLike']
+ ]);
+ $sql['class'][]=['examine','=',1];
+ $sql['class']=frameScope($sql['class']);//组织数据
+ //数据鉴权[结构一致]
+ $sql['class']=sqlAuth('buy',$sql['class']);
+ //INFO语句
+ $sql['info']=fastSql($input,[['warehouse','fullIn']]);
+ //商品匹配
+ if(existFull($input,['goods'])){
+ $goods=array_column(Db::name('goods')->where([['name|py','like','%'.$input['goods'].'%']])->select()->toArray(),'id');
+ $sql['info'][]=['goods','in',$goods];
+ }
+ //组装查询语句
+ $union=[];
+ foreach ($input['mold'] as $mold) {
+ $union[]=Db::name($mold.'_info')->alias('info')->join(['is_'.$mold=>'class'],'info.pid=class.id')->where($sql['info'])->where($sql['class'])->fieldRaw('info.id as info,class.id as class,time,"'.$mold.'" as mold')->buildSql();
+ }
+ $union=implode(' UNION ALL ',$union);
+ //获取总条数
+ $record=DB::query('SELECT * FROM ('.$union.') as nodcloud ORDER BY `time` DESC');
+ $list=[];
+ foreach ($input['mold'] as $mold) {
+ $gather=search($record)->where([['mold','=',$mold]])->select();
+ $table=[
+ "class"=>"app\\model\\".ucfirst($mold),
+ 'info'=>"app\\model\\".ucfirst($mold).'Info',
+ ];
+ $list[$mold]['info']=$table['info']::with(['goodsData','warehouseData'])->where([['id','in',array_column($gather,'info')]])->select()->toArray();
+ $list[$mold]['class']=$table['class']::with(['frameData','supplierData'])->where([['id','in',array_column($list[$mold]['info'],'pid')]])->append(['extension'])->select()->toArray();
+ }
+ $data=[];
+ foreach ($record as $recordVo) {
+ $mold=$recordVo['mold'];
+ $data[]=[
+ 'mold'=>$mold,
+ 'name'=>['buy'=>'采购单','bre'=>'采购退货单'][$mold],
+ 'class'=>search($list[$mold]['class'])->where([['id','=',$recordVo['class']]])->find(),
+ 'info'=>search($list[$mold]['info'])->where([['id','=',$recordVo['info']]])->find()
+ ];
+ }
+ $source=$data;
+ //开始构造导出数据
+ $excel=[];//初始化导出数据
+ //标题数据
+ $excel[]=['type'=>'title','info'=>'采购明细表'];
+ //表格数据
+ $field=[
+ 'name'=>'单据类型',
+ 'class|frameData|name'=>'所属组织',
+ 'class|supplierData|name'=>'供应商',
+ 'class|time'=>'单据时间',
+ 'class|number'=>'单据编号',
+ 'info|goodsData|name'=>'商品名称',
+ 'info|attr'=>'辅助属性',
+ 'info|warehouseData|name'=>'仓库',
+ 'info|unit'=>'单位',
+ 'info|price'=>'单价',
+ 'info|nums'=>'数量',
+ 'info|dsc'=>'折扣额',
+ 'info|total'=>'金额',
+ 'info|tat'=>'税额',
+ 'info|tpt'=>'价税合计',
+ 'class|data'=>'备注信息',
+ ];
+ $thead=array_values($field);//表格标题
+ $tbody=[];//表格内容
+ //构造表内数据
+ foreach ($source as $sourceVo) {
+ $rowData=[];
+ foreach (array_keys($field) as $fieldVo) {
+ $rowData[]=arraySeek($sourceVo,$fieldVo);//多键名数据赋值
+ }
+ $tbody[]=$rowData;//加入行数据
+ }
+ $excel[]=['type'=>'table','info'=>['thead'=>$thead,'tbody'=>$tbody]];//表格数据
+ //汇总数据
+ $math=['buy'=>[],'bre'=>[]];
+ foreach ($source as $sourceVo) {
+ $math[$sourceVo['mold']][]=$sourceVo['info']['tpt'];
+ }
+ $excel[]=['type'=>'node','info'=>[
+ '总数:'.count($source),
+ '采购总金额:'.mathArraySum($math['buy']),
+ '采购退货总金额:'.mathArraySum($math['bre'])
+ ]];
+ //导出execl
+ buildExcel('采购明细表',$excel);
+ }else{
+ return json(['state'=>'error','info'=>'传入参数不完整!']);
+ }
+ }
+ //采购汇总表
+ public function bsy(){
+ $input=input('post.');
+ if(existFull($input,['page','limit']) && is_array($input['warehouse']) && isset($input['type'])){
+ $sql=[];
+ //CLASS语句
+ $sql['class']=fastSql($input,[
+ ['supplier','fullEq'],
+ ['user','fullEq'],
+ ['people','fullEq'],
+ [['startTime'=>'time'],'startTime'],
+ [['endTime'=>'time'],'endTime']
+ ]);
+ $sql['class'][]=['examine','=',1];
+ $sql['class']=frameScope($sql['class']);//组织数据
+ $sql['class']=sqlAuth('buy',$sql['class']);//数据鉴权[结构一致]
+ //INFO语句
+ $sql['info']=fastSql($input,[['warehouse','fullIn']]);
+ //商品匹配
+ if(existFull($input,['goods'])){
+ $goods=array_column(Db::name('goods')->where([['name|py','like','%'.$input['goods'].'%']])->select()->toArray(),'id');
+ $sql['info'][]=['goods','in',$goods];
+ }
+ //构造语句
+ $union=[];
+ $tab=['buy','bre'];
+ foreach ($tab as $t) {
+ $union[]=Db::name($t.'_info')->alias('info')->join(['is_'.$t=>'class'],'info.pid=class.id')->where($sql['class'])->where($sql['info'])->fieldRaw('"'.$t.'" as mold,class.supplier as supplier,class.user as user,class.people as people,info.id as info,goods,attr,warehouse,unit,nums,tpt')->buildSql();
+ }
+ $union=implode(' UNION ALL ',$union);
+ //判断类型
+ if($input['type']==0){
+ //按商品
+ $count=count(DB::query('SELECT COUNT(*) as count FROM ('.$union.') as nodcloud group by goods,attr,warehouse'));
+ $record = DB::query('SELECT group_concat(mold) as mold,group_concat(info) as info,group_concat(unit) as unit,group_concat(nums) as nums,group_concat(tpt) as tpt FROM ( '.$union.' ) as nodcloud group by goods,attr,warehouse ORDER BY `goods` DESC LIMIT '.pageCalc($input['page'],$input['limit'],'str'));
+ }else if($input['type']==1){
+ //按供应商
+ $count=count(DB::query('SELECT COUNT(*) as count FROM ('.$union.') as nodcloud group by supplier,goods,attr,warehouse'));
+ $record = DB::query('SELECT group_concat(mold) as mold,supplier,group_concat(info) as info,group_concat(unit) as unit,group_concat(nums) as nums,group_concat(tpt) as tpt FROM ( '.$union.' ) as nodcloud group by supplier,goods,attr,warehouse ORDER BY `supplier` DESC LIMIT '.pageCalc($input['page'],$input['limit'],'str'));
+ }else if($input['type']==2){
+ //按用户
+ $count=count(DB::query('SELECT COUNT(*) as count FROM ('.$union.') as nodcloud group by user,goods,attr,warehouse'));
+ $record = DB::query('SELECT group_concat(mold) as mold,user,group_concat(info) as info,group_concat(unit) as unit,group_concat(nums) as nums,group_concat(tpt) as tpt FROM ( '.$union.' ) as nodcloud group by user,goods,attr,warehouse ORDER BY `user` DESC LIMIT '.pageCalc($input['page'],$input['limit'],'str'));
+ }else{
+ //按人员
+ $count=count(DB::query('SELECT COUNT(*) as count FROM ('.$union.') as nodcloud group by people,goods,attr,warehouse'));
+ $record = DB::query('SELECT group_concat(mold) as mold,people,group_concat(info) as info,group_concat(unit) as unit,group_concat(nums) as nums,group_concat(tpt) as tpt FROM ( '.$union.' ) as nodcloud group by people,goods,attr,warehouse ORDER BY `people` DESC LIMIT '.pageCalc($input['page'],$input['limit'],'str'));
+ }
+ //构造数据
+ $group = [];
+ foreach($record as $vo){
+ $moldList = explode(",", $vo['mold']);
+ $infoList = explode(",", $vo['info']);
+ $unitList = explode(",", $vo['unit']);
+ $numsList = explode(",", $vo['nums']);
+ $tptList = explode(",", $vo['tpt']);
+ $row=['mold'=>$moldList[0],'info'=>$infoList[0]];
+ foreach ($moldList as $key => $mold) {
+ $row[$mold]['unit'][]=$unitList[$key];
+ $row[$mold]['nums'][]=$numsList[$key]??0;
+ $row[$mold]['tpt'][]=$tptList[$key]??0;
+ }
+ $input['type']==1&&$row['supplier']=$vo['supplier'];//供应商转存
+ $input['type']==2&&$row['user']=$vo['user'];//用户转存
+ $input['type']==3&&$row['people']=$vo['people'];//人员转存
+ $group[]=$row;
+ }
+ //数据匹配
+ $infoList=[];
+ foreach ($tab as $t) {
+ $mold="app\\model\\".ucfirst($t).'Info';
+ $gather=search($group)->where([['mold','=',$t]])->select();
+ $infoList[$t]=$mold::with(['goodsData','warehouseData'])->where([['id','in',array_column($gather,'info')]])->select()->toArray();
+ }
+ //查询类型-匹配供应商
+ $input['type']==1&&$supplierList=db::name('supplier')->where([['id','in',array_column($group,'supplier')]])->select()->toArray();
+ //查询类型-匹配用户
+ $input['type']==2&&$userList=db::name('user')->where([['id','in',array_column($group,'user')]])->select()->toArray();
+ //查询类型-匹配人员
+ $input['type']==3&&$peopleList=db::name('people')->where([['id','in',array_column($group,'people')]])->select()->toArray();
+ //数据处理
+ $data=[];
+ foreach ($group as $groupVo) {
+ $row=search($infoList[$groupVo['mold']])->where([['id','=',$groupVo['info']]])->find();
+ $row['unit']=$row['goodsData']['unit']==-1?'多单位':$row['unit'];
+ foreach ($tab as $t) {
+ if(isset($groupVo[$t])){
+ if($row['goodsData']['unit']==-1){
+ $base=0;
+ foreach ($groupVo[$t]['unit'] as $key=> $unit) {
+ $radix=unitRadix($unit,$row['goodsData']['units']);
+ $base=math()->chain($groupVo[$t]['nums'][$key])->mul($radix)->add($base)->done();
+ }
+ $row[$t]=['base'=>$base,'nums'=>unitSwitch($base,$row['goodsData']['units']),'money'=>mathArraySum($groupVo[$t]['tpt'])];
+ $row[$t]['price']=math()->chain($row[$t]['money'])->div($base)->round(2)->done();
+ }else{
+ $row[$t]=['nums'=>mathArraySum($groupVo[$t]['nums']),'money'=>mathArraySum($groupVo[$t]['tpt'])];
+ $row[$t]['price']=math()->chain($row[$t]['money'])->div($row[$t]['nums'])->round(2)->done();
+ $row[$t]['base']=$row[$t]['nums'];
+ }
+ }else{
+ $row[$t]=['base'=>0,'price'=>0,'nums'=>0,'money'=>0];
+ }
+ }
+ $row['summary']['nums']=math()->chain($row['buy']['base'])->sub($row['bre']['base'])->done();
+ $row['goodsData']['unit']==-1&&$row['summary']['nums']=unitSwitch($row['summary']['nums'],$row['goodsData']['units']);
+ $row['summary']['money']=math()->chain($row['buy']['money'])->sub($row['bre']['money'])->done();
+ //类型匹配
+ $input['type']==1&&$row['supplier']=search($supplierList)->where([['id','=',$groupVo['supplier']]])->find();//匹配供应商
+ $input['type']==2&&$row['user']=search($userList)->where([['id','=',$groupVo['user']]])->find();//匹配用户
+ $input['type']==3&&$row['people']=search($peopleList)->where([['id','=',$groupVo['people']]])->find();//匹配人员
+ $data[]=$row;
+ }
+ $result=[
+ 'state'=>'success',
+ 'count'=>$count,
+ 'info'=>$data
+ ];//返回数据
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //采购汇总表-导出
+ public function bsyExports(){
+ $input=input('get.');
+ existFull($input,['warehouse'])||$input['warehouse']=[];
+ if(is_array($input['warehouse']) && isset($input['type'])){
+ pushLog('导出采购汇总表');//日志
+ $sql=[];
+ //CLASS语句
+ $sql['class']=fastSql($input,[
+ ['supplier','fullEq'],
+ ['user','fullEq'],
+ ['people','fullEq'],
+ [['startTime'=>'time'],'startTime'],
+ [['endTime'=>'time'],'endTime']
+ ]);
+ $sql['class'][]=['examine','=',1];
+ $sql['class']=frameScope($sql['class']);//组织数据
+ $sql['class']=sqlAuth('buy',$sql['class']);//数据鉴权[结构一致]
+ //INFO语句
+ $sql['info']=fastSql($input,[['warehouse','fullIn']]);
+ //商品匹配
+ if(existFull($input,['goods'])){
+ $goods=array_column(Db::name('goods')->where([['name|py','like','%'.$input['goods'].'%']])->select()->toArray(),'id');
+ $sql['info'][]=['goods','in',$goods];
+ }
+ //构造语句
+ $union=[];
+ $tab=['buy','bre'];
+ foreach ($tab as $t) {
+ $union[]=Db::name($t.'_info')->alias('info')->join(['is_'.$t=>'class'],'info.pid=class.id')->where($sql['class'])->where($sql['info'])->fieldRaw('"'.$t.'" as mold,class.supplier as supplier,class.user as user,class.people as people,info.id as info,goods,attr,warehouse,unit,nums,tpt')->buildSql();
+ }
+ $union=implode(' UNION ALL ',$union);
+ //判断类型
+ if($input['type']==0){
+ //按商品
+ $count=count(DB::query('SELECT COUNT(*) as count FROM ('.$union.') as nodcloud group by goods,attr,warehouse'));
+ $record = DB::query('SELECT group_concat(mold) as mold,group_concat(info) as info,group_concat(unit) as unit,group_concat(nums) as nums,group_concat(tpt) as tpt FROM ( '.$union.' ) as nodcloud group by goods,attr,warehouse ORDER BY `goods` DESC');
+ }else if($input['type']==1){
+ //按供应商
+ $count=count(DB::query('SELECT COUNT(*) as count FROM ('.$union.') as nodcloud group by supplier,goods,attr,warehouse'));
+ $record = DB::query('SELECT group_concat(mold) as mold,supplier,group_concat(info) as info,group_concat(unit) as unit,group_concat(nums) as nums,group_concat(tpt) as tpt FROM ( '.$union.' ) as nodcloud group by supplier,goods,attr,warehouse ORDER BY `supplier` DESC');
+ }else if($input['type']==2){
+ //按用户
+ $count=count(DB::query('SELECT COUNT(*) as count FROM ('.$union.') as nodcloud group by user,goods,attr,warehouse'));
+ $record = DB::query('SELECT group_concat(mold) as mold,user,group_concat(info) as info,group_concat(unit) as unit,group_concat(nums) as nums,group_concat(tpt) as tpt FROM ( '.$union.' ) as nodcloud group by user,goods,attr,warehouse ORDER BY `user` DESC');
+ }else{
+ //按人员
+ $count=count(DB::query('SELECT COUNT(*) as count FROM ('.$union.') as nodcloud group by people,goods,attr,warehouse'));
+ $record = DB::query('SELECT group_concat(mold) as mold,people,group_concat(info) as info,group_concat(unit) as unit,group_concat(nums) as nums,group_concat(tpt) as tpt FROM ( '.$union.' ) as nodcloud group by people,goods,attr,warehouse ORDER BY `people` DESC');
+ }
+ //构造数据
+ $group = [];
+ foreach($record as $vo){
+ $moldList = explode(",", $vo['mold']);
+ $infoList = explode(",", $vo['info']);
+ $unitList = explode(",", $vo['unit']);
+ $numsList = explode(",", $vo['nums']);
+ $tptList = explode(",", $vo['tpt']);
+ $row=['mold'=>$moldList[0],'info'=>$infoList[0]];
+ foreach ($moldList as $key => $mold) {
+ $row[$mold]['unit'][]=$unitList[$key];
+ $row[$mold]['nums'][]=$numsList[$key]??0;
+ $row[$mold]['tpt'][]=$tptList[$key]??0;
+ }
+ $input['type']==1&&$row['supplier']=$vo['supplier'];//供应商转存
+ $input['type']==2&&$row['user']=$vo['user'];//用户转存
+ $input['type']==3&&$row['people']=$vo['people'];//人员转存
+ $group[]=$row;
+ }
+ //数据匹配
+ $infoList=[];
+ foreach ($tab as $t) {
+ $mold="app\\model\\".ucfirst($t).'Info';
+ $gather=search($group)->where([['mold','=',$t]])->select();
+ $infoList[$t]=$mold::with(['goodsData','warehouseData'])->where([['id','in',array_column($gather,'info')]])->select()->toArray();
+ }
+ //查询类型-匹配供应商
+ $input['type']==1&&$supplierList=db::name('supplier')->where([['id','in',array_column($group,'supplier')]])->select()->toArray();
+ //查询类型-匹配用户
+ $input['type']==2&&$userList=db::name('user')->where([['id','in',array_column($group,'user')]])->select()->toArray();
+ //查询类型-匹配人员
+ $input['type']==3&&$peopleList=db::name('people')->where([['id','in',array_column($group,'people')]])->select()->toArray();
+ //数据处理
+ $data=[];
+ foreach ($group as $groupVo) {
+ $row=search($infoList[$groupVo['mold']])->where([['id','=',$groupVo['info']]])->find();
+ $row['unit']=$row['goodsData']['unit']==-1?'多单位':$row['unit'];
+ foreach ($tab as $t) {
+ if(isset($groupVo[$t])){
+ if($row['goodsData']['unit']==-1){
+ $base=0;
+ foreach ($groupVo[$t]['unit'] as $key=> $unit) {
+ $radix=unitRadix($unit,$row['goodsData']['units']);
+ $base=math()->chain($groupVo[$t]['nums'][$key])->mul($radix)->add($base)->done();
+ }
+ $row[$t]=['base'=>$base,'nums'=>unitSwitch($base,$row['goodsData']['units']),'money'=>mathArraySum($groupVo[$t]['tpt'])];
+ $row[$t]['price']=math()->chain($row[$t]['money'])->div($base)->round(2)->done();
+ }else{
+ $row[$t]=['nums'=>mathArraySum($groupVo[$t]['nums']),'money'=>mathArraySum($groupVo[$t]['tpt'])];
+ $row[$t]['price']=math()->chain($row[$t]['money'])->div($row[$t]['nums'])->round(2)->done();
+ $row[$t]['base']=$row[$t]['nums'];
+ }
+ }else{
+ $row[$t]=['base'=>0,'price'=>0,'nums'=>0,'money'=>0];
+ }
+ }
+ $row['summary']['nums']=math()->chain($row['buy']['base'])->sub($row['bre']['base'])->done();
+ $row['goodsData']['unit']==-1&&$row['summary']['nums']=unitSwitch($row['summary']['nums'],$row['goodsData']['units']);
+ $row['summary']['money']=math()->chain($row['buy']['money'])->sub($row['bre']['money'])->done();
+ //类型匹配
+ $input['type']==1&&$row['supplier']=search($supplierList)->where([['id','=',$groupVo['supplier']]])->find();//匹配供应商
+ $input['type']==2&&$row['user']=search($userList)->where([['id','=',$groupVo['user']]])->find();//匹配用户
+ $input['type']==3&&$row['people']=search($peopleList)->where([['id','=',$groupVo['people']]])->find();//匹配人员
+ $data[]=$row;
+ }
+ $source=$data;
+ //开始构造导出数据
+ $excel=[];//初始化导出数据
+ //标题数据
+ $excel[]=['type'=>'title','info'=>'采购汇总表'];
+ //表格数据
+ $field=[
+ [
+ "supplier|name"=>"供应商"
+ ],
+ [
+ "user|name"=>"用户"
+ ],
+ [
+ "people|name"=>"关联人员"
+ ],
+ [
+ "goodsData|name"=>"商品名称",
+ "attr"=>"辅助属性",
+ "warehouseData|name"=>"仓库",
+ "unit"=>"单位",
+ "buy|price"=>"采购单价",
+ "buy|nums"=>"采购数量",
+ "buy|money"=>"采购金额",
+ "bre|price"=>"购退单价",
+ "bre|nums"=>"购退数量",
+ "bre|money"=>"购退金额",
+ "summary|nums"=>"汇总数量",
+ "summary|money"=>"汇总金额"
+ ]
+ ];
+ $field=[$field[3],array_merge($field[0],$field[3]),array_merge($field[1],$field[3]),array_merge($field[2],$field[3]),][$input['type']];
+ $thead=array_values($field);//表格标题
+ $tbody=[];//表格内容
+ //构造表内数据
+ foreach ($source as $sourceVo) {
+ $rowData=[];
+ foreach (array_keys($field) as $fieldVo) {
+ $rowData[]=arraySeek($sourceVo,$fieldVo);//多键名数据赋值
+ }
+ $tbody[]=$rowData;//加入行数据
+ }
+ $excel[]=['type'=>'table','info'=>['thead'=>$thead,'tbody'=>$tbody]];//表格数据
+ //汇总数据
+ $excel[]=['type'=>'node','info'=>[
+ '总数:'.count($source),
+ '采购总金额:'.mathArraySum(arrayColumns($source,['buy','money'])),
+ '采购退货总金额:'.mathArraySum(arrayColumns($source,['bre','money'])),
+ '汇总金额:'.mathArraySum(arrayColumns($source,['summary','money']))
+ ]];
+ //导出execl
+ buildExcel('采购汇总表',$excel);
+ }else{
+ return json(['state'=>'error','info'=>'传入参数不完整!']);
+ }
+ }
+ //采购付款表
+ public function bbt(){
+ $input=input('post.');
+ $sheet=['buy','bre'];
+ existFull($input,['mold'])||$input['mold']=$sheet;
+ if(existFull($input,['page','limit']) && is_arrays($input,['nucleus','mold']) && arrayInArray($input['mold'],$sheet)){
+ $sql=[];
+ //CLASS语句
+ $sql=fastSql($input,[
+ ['supplier','fullEq'],
+ ['number','fullLike'],
+ [['startTime'=>'time'],'startTime'],
+ [['endTime'=>'time'],'endTime'],
+ ['nucleus','fullIn']
+ ]);
+ $sql[]=['examine','=',1];
+ $sql=frameScope($sql);//组织数据
+ $sql=sqlAuth('buy',$sql);//数据鉴权[结构一致]
+ //组装语句
+ $union=[];
+ foreach ($input['mold'] as $mold) {
+ $union[]=Db::name($mold)->where($sql)->fieldRaw('"'.$mold.'" as mold,id,time')->buildSql();
+ }
+ $union=implode(' UNION ALL ',$union);
+ //获取总条数
+ $count=DB::query('SELECT COUNT(*) as count FROM ('.$union.') as nodcloud')[0]["count"];
+ $record=DB::query('SELECT * FROM ('.$union.') as nodcloud ORDER BY `time` DESC LIMIT '.pageCalc($input['page'],$input['limit'],'str'));
+ //匹配数据
+ $list=[];
+ foreach ($input['mold'] as $mold) {
+ $gather=search($record)->where([['mold','=',$mold]])->select();
+ $db="app\\model\\".ucfirst($mold);
+ $list[$mold]=$db::with(['frameData','supplierData','billData'])->where([['id','in',array_column($gather,'id')]])->append(['extension'])->select()->toArray();
+ }
+ //构造数据
+ $data=[];
+ foreach ($record as $recordVo) {
+ $mold=$recordVo['mold'];
+ $row=search($list[$mold])->where([['id','=',$recordVo['id']]])->find();
+ $row['key']=$mold.'_'.$recordVo['id'];
+ $row['name']=['buy'=>'采购单','bre'=>'采购退货单'][$mold];
+ $row['balance']=$row['extension']['anwo'];
+ $row['rate']=in_array($row['nucleus'],['0','2'])?['0%','','100%'][$row['nucleus']]:math()->chain($row['extension']['amount'])->div($row['actual'])->mul(100)->round(2)->done().'%';
+ $row['node']=[];
+ $bill=search($row['billData'])->where([['type','=','bill']])->select();
+ foreach ($bill as $billVo) {
+ $node=[
+ 'key'=>$row['key'].'_'.$billVo['id'],
+ 'name'=>'核销单',
+ 'time'=>$billVo['time'],
+ 'number'=>$billVo['sourceData']['number'],
+ 'money'=>$billVo['money'],
+ ];
+ //反转金额
+ in_array($mold,['bre'])&&$node['money']*=-1;
+ $row['node'][]=$node;
+ }
+ //反转金额
+ if(in_array($mold,['bre'])){
+ $row['total']*=-1;
+ $row['actual']*=-1;
+ $row['money']*=-1;
+ $row['balance']*=-1;
+ }
+ $data[]=$row;
+ }
+ $result=[
+ 'state'=>'success',
+ 'count'=>$count,
+ 'info'=>$data
+ ];//返回数据
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //采购付款表-导出
+ public function bbtExports(){
+ $input=input('get.');
+ $sheet=['buy','bre'];
+ existFull($input,['nucleus'])||$input['nucleus']=[];
+ existFull($input,['mold'])||$input['mold']=$sheet;
+ if(is_arrays($input,['nucleus','mold']) && arrayInArray($input['mold'],$sheet)){
+ pushLog('导出采购付款表');//日志
+ $sql=[];
+ //CLASS语句
+ $sql=fastSql($input,[
+ ['supplier','fullEq'],
+ ['number','fullLike'],
+ [['startTime'=>'time'],'startTime'],
+ [['endTime'=>'time'],'endTime'],
+ ['nucleus','fullIn']
+ ]);
+ $sql[]=['examine','=',1];
+ $sql=frameScope($sql);//组织数据
+ $sql=sqlAuth('buy',$sql);//数据鉴权[结构一致]
+ //组装语句
+ $union=[];
+ foreach ($input['mold'] as $mold) {
+ $union[]=Db::name($mold)->where($sql)->fieldRaw('"'.$mold.'" as mold,id,time')->buildSql();
+ }
+ $union=implode(' UNION ALL ',$union);
+ //获取总条数
+ $record=DB::query('SELECT * FROM ('.$union.') as nodcloud ORDER BY `time` DESC');
+ //匹配数据
+ $list=[];
+ foreach ($input['mold'] as $mold) {
+ $gather=search($record)->where([['mold','=',$mold]])->select();
+ $db="app\\model\\".ucfirst($mold);
+ $list[$mold]=$db::with(['frameData','supplierData','billData'])->where([['id','in',array_column($gather,'id')]])->append(['extension'])->select()->toArray();
+ }
+ //构造数据
+ $data=[];
+ foreach ($record as $recordVo) {
+ $mold=$recordVo['mold'];
+ $row=search($list[$mold])->where([['id','=',$recordVo['id']]])->find();
+ $row['key']=$mold.'_'.$recordVo['id'];
+ $row['name']=['buy'=>'采购单','bre'=>'采购退货单'][$mold];
+ $row['balance']=$row['extension']['anwo'];
+ $row['rate']=in_array($row['nucleus'],['0','2'])?['0%','','100%'][$row['nucleus']]:math()->chain($row['extension']['amount'])->div($row['actual'])->mul(100)->round(2)->done().'%';
+ $row['node']=[];
+ $bill=search($row['billData'])->where([['type','=','bill']])->select();
+ foreach ($bill as $billVo) {
+ $node=[
+ 'key'=>$row['key'].'_'.$billVo['id'],
+ 'name'=>'核销单',
+ 'time'=>$billVo['time'],
+ 'number'=>$billVo['sourceData']['number'],
+ 'money'=>$billVo['money'],
+ ];
+ //反转金额
+ in_array($mold,['bre'])&&$node['money']*=-1;
+ $row['node'][]=$node;
+ }
+ //反转金额
+ if(in_array($mold,['bre'])){
+ $row['total']*=-1;
+ $row['actual']*=-1;
+ $row['money']*=-1;
+ $row['balance']*=-1;
+ }
+ $data[]=$row;
+ }
+ $source=[];
+ foreach ($data as $dataVo) {
+ $source[]=$dataVo;
+ if(!empty($dataVo['node'])){
+ foreach ($dataVo['node'] as $node) {
+ $source[]=$node;
+ }
+ }
+ }
+ //开始构造导出数据
+ $excel=[];//初始化导出数据
+ //标题数据
+ $excel[]=['type'=>'title','info'=>'采购付款表'];
+ //表格数据
+ $field=[
+ "name"=>"单据类型",
+ "frameData|name"=>"所属组织",
+ "supplierData|name"=>"供应商",
+ "time"=>"单据时间",
+ "number"=>"单据编号",
+ "total"=>"单据金额",
+ "actual"=>"实际金额",
+ "money"=>"单据付款",
+ "balance"=>"应付款余额",
+ "rate"=>"付款率",
+ "extension|nucleus"=>"核销状态",
+ "data"=>"备注信息"
+ ];
+ $thead=array_values($field);//表格标题
+ $tbody=[];//表格内容
+ //构造表内数据
+ foreach ($source as $sourceVo) {
+ $rowData=[];
+ foreach (array_keys($field) as $fieldVo) {
+ $rowData[]=arraySeek($sourceVo,$fieldVo);//多键名数据赋值
+ }
+ $tbody[]=$rowData;//加入行数据
+ }
+ $excel[]=['type'=>'table','info'=>['thead'=>$thead,'tbody'=>$tbody]];//表格数据
+ //汇总数据
+ $excel[]=['type'=>'node','info'=>[
+ '总数:'.count($source),
+ '应付款总余额:'.mathArraySum(array_column($source,'balance'))
+ ]];
+ //导出execl
+ buildExcel('采购付款表',$excel);
+ }else{
+ return json(['state'=>'error','info'=>'传入参数不完整!']);
+ }
+ }
+ //采购排行表
+ public function bot(){
+ $input=input('post.');
+ if(existFull($input,['page','limit'])){
+ $sql=fastSql($input,[
+ [['name'=>'name|py'],'fullLike'],
+ ['number','fullLike']
+ ]);
+ $goods=Db::name('goods')->where($sql)->select()->toArray();
+ //数据匹配
+ $existsSql=fastSql($input,[
+ [['startTime'=>'time'],'startTime'],
+ [['endTime'=>'time'],'endTime']
+ ]);
+ $existsSql[]=['goods','in',array_column($goods,'id')];
+ $existsSql[]=['examine','=',1];
+ $existsSql=frameScope($existsSql);
+ $existsSql=sqlAuth('buy',$existsSql);//结构一致
+ //多源匹配
+ $union=[];
+ $tab=['buy','bre'];
+ foreach ($tab as $t) {
+ $union[0][]=Db::name($t.'_info')->alias('info')->join(['is_'.$t=>'class'],'info.pid=class.id')->where($existsSql)->fieldRaw('goods,attr,sum(nums) as nums')->group(['goods,attr'])->buildSql();
+ }
+ $union_0=implode(' UNION ALL ',$union[0]);
+ $count=DB::query('select count(*) as count from ( SELECT count(*) FROM ('.$union_0.') as f GROUP BY goods,attr ) as nodcloud')[0]["count"];
+ $record=DB::query('SELECT * FROM ('.$union_0.') as nodcloud GROUP BY goods,attr ORDER BY `nums` DESC LIMIT '.pageCalc($input['page'],$input['limit'],'str'));
+ //构造条件|减少查询
+ foreach ($existsSql as $k=>$v) {
+ if($v[0]=='goods'){
+ $existsSql[$k][2]=array_column($record,'goods');
+ break;
+ }
+ }
+ foreach ($tab as $t) {
+ $union[1][]=Db::name($t.'_info')->alias('info')->join(['is_'.$t=>'class'],'info.pid=class.id')->where($existsSql)->fieldRaw('"'.$t.'" as mold,goods,attr,group_concat(info.id) as id,sum(dsc) as dsc,sum(tat) as tat,sum(tpt) as tpt')->group(['goods,attr'])->buildSql();
+ }
+ $union_1=implode(' UNION ALL ',$union[1]);
+ $list=DB::query('SELECT * FROM ('.$union_1.') as nodcloud');
+ //获取数据
+ $summary=[];
+ foreach ($tab as $t) {
+ $gather=explode(',',implode(',',array_column(search($list)->where([['mold','=',$t]])->select(),'id')));
+ $summary[$t]=Db::name('summary')->where([['type','=',$t],['info','in',$gather]])->select()->toArray();
+ }
+ $data=[];
+ //统计数据
+ foreach ($record as $vo) {
+ $row=[];
+ $g=search($goods)->where([['id','=',$vo['goods']]])->find();
+ $row['goodsData']=$g;
+ $row['attr']=$vo['attr'];
+ $row['unit']=$g['unit']==-1?'多单位':$g['unit'];
+ $base=[['goods','=',$vo['goods']],['attr','=',$vo['attr']]];
+ $gather=[];
+ foreach ($tab as $t) {
+ $b=search($list)->where(array_merge($base,[['mold','=',$t]]))->find();
+ $s=search($summary[$t])->where(array_merge($base,[['type','=',$t]]))->select();
+ $gather['nums'][$t]=mathArraySum(array_column($s,'nums'));
+ $gather['dsc'][$t]=empty($b)?0:$b['dsc'];
+ $gather['tat'][$t]=empty($b)?0:$b['tat'];
+ $gather['tpt'][$t]=empty($b)?0:$b['tpt'];
+ $gather['bct'][$t]=mathArraySum(array_column($s,'bct'));
+ }
+ $nums=math()->chain($gather['nums']['buy'])->sub($gather['nums']['bre'])->done();
+ $row['nums']=$g['unit']==-1?unitSwitch($nums,json_decode($g['units'],true)):$nums;
+ $row['dsc']=math()->chain($gather['dsc']['buy'])->sub($gather['dsc']['bre'])->done();
+ $row['tat']=math()->chain($gather['tat']['buy'])->sub($gather['tat']['bre'])->done();
+ $row['tpt']=math()->chain($gather['tpt']['buy'])->sub($gather['tpt']['bre'])->done();
+ $row['bct']=math()->chain($gather['bct']['buy'])->sub($gather['bct']['bre'])->done();
+ $row['uct']=empty($nums)?0:math()->chain($row['bct'])->div($nums)->round(2)->abs()->done();
+ $data[]=$row;
+ }
+ $result=[
+ 'state'=>'success',
+ 'count'=>$count,
+ 'info'=>$data
+ ];//返回数据
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //采购排行表-导出
+ public function botExports(){
+ $input=input('get.');
+ pushLog('导出采购排行表');//日志
+ $sql=fastSql($input,[
+ [['name'=>'name|py'],'fullLike'],
+ ['number','fullLike']
+ ]);
+ $goods=Db::name('goods')->where($sql)->select()->toArray();
+ //数据匹配
+ $existsSql=fastSql($input,[
+ [['startTime'=>'time'],'startTime'],
+ [['endTime'=>'time'],'endTime']
+ ]);
+ $existsSql[]=['goods','in',array_column($goods,'id')];
+ $existsSql[]=['examine','=',1];
+ $existsSql=frameScope($existsSql);
+ $existsSql=sqlAuth('buy',$existsSql);//结构一致
+ //多源匹配
+ $union=[];
+ $tab=['buy','bre'];
+ foreach ($tab as $t) {
+ $union[0][]=Db::name($t.'_info')->alias('info')->join(['is_'.$t=>'class'],'info.pid=class.id')->where($existsSql)->fieldRaw('goods,attr,sum(nums) as nums')->group(['goods,attr'])->buildSql();
+ }
+ $union_0=implode(' UNION ALL ',$union[0]);
+ $record=DB::query('SELECT * FROM ('.$union_0.') as nodcloud GROUP BY goods,attr ORDER BY `nums` DESC');
+ //匹配数据
+ foreach ($tab as $t) {
+ $union[1][]=Db::name($t.'_info')->alias('info')->join(['is_'.$t=>'class'],'info.pid=class.id')->where($existsSql)->fieldRaw('"'.$t.'" as mold,goods,attr,group_concat(info.id) as id,sum(dsc) as dsc,sum(tat) as tat,sum(tpt) as tpt')->group(['goods,attr'])->buildSql();
+ }
+ $union_1=implode(' UNION ALL ',$union[1]);
+ $list=DB::query('SELECT * FROM ('.$union_1.') as nodcloud');
+ //获取数据
+ $summary=[];
+ foreach ($tab as $t) {
+ $gather=explode(',',implode(',',array_column(search($list)->where([['mold','=',$t]])->select(),'id')));
+ $summary[$t]=Db::name('summary')->where([['type','=',$t],['info','in',$gather]])->select()->toArray();
+ }
+ $data=[];
+ //统计数据
+ foreach ($record as $vo) {
+ $row=[];
+ $g=search($goods)->where([['id','=',$vo['goods']]])->find();
+ $row['goodsData']=$g;
+ $row['attr']=$vo['attr'];
+ $row['unit']=$g['unit']==-1?'多单位':$g['unit'];
+ $base=[['goods','=',$vo['goods']],['attr','=',$vo['attr']]];
+ $gather=[];
+ foreach ($tab as $t) {
+ $b=search($list)->where(array_merge($base,[['mold','=',$t]]))->find();
+ $s=search($summary[$t])->where(array_merge($base,[['type','=',$t]]))->select();
+ $gather['nums'][$t]=mathArraySum(array_column($s,'nums'));
+ $gather['dsc'][$t]=empty($b)?0:$b['dsc'];
+ $gather['tat'][$t]=empty($b)?0:$b['tat'];
+ $gather['tpt'][$t]=empty($b)?0:$b['tpt'];
+ $gather['bct'][$t]=mathArraySum(array_column($s,'bct'));
+ }
+ $nums=math()->chain($gather['nums']['buy'])->sub($gather['nums']['bre'])->done();
+ $row['nums']=$g['unit']==-1?unitSwitch($nums,json_decode($g['units'],true)):$nums;
+ $row['dsc']=math()->chain($gather['dsc']['buy'])->sub($gather['dsc']['bre'])->done();
+ $row['tat']=math()->chain($gather['tat']['buy'])->sub($gather['tat']['bre'])->done();
+ $row['tpt']=math()->chain($gather['tpt']['buy'])->sub($gather['tpt']['bre'])->done();
+ $row['bct']=math()->chain($gather['bct']['buy'])->sub($gather['bct']['bre'])->done();
+ $row['uct']=empty($nums)?0:math()->chain($row['bct'])->div($nums)->round(2)->abs()->done();
+ $data[]=$row;
+ }
+ $source=$data;
+ //开始构造导出数据
+ $excel=[];//初始化导出数据
+ //标题数据
+ $excel[]=['type'=>'title','info'=>'采购排行表'];
+ //表格数据
+ $field=[
+ 'goodsData|name'=>'商品名称',
+ 'attr'=>'辅助属性',
+ 'goodsData|number'=>'商品编号',
+ 'goodsData|spec'=>'规格型号',
+ 'unit'=>'单位',
+ 'nums'=>'数量',
+ 'dsc'=>'折扣额',
+ 'tat'=>'税额',
+ 'tpt'=>'价税合计',
+ 'uct'=>'成本',
+ 'bct'=>'总成本'
+ ];
+ $thead=array_values($field);//表格标题
+ $tbody=[];//表格内容
+ //构造表内数据
+ foreach ($source as $sourceVo) {
+ $rowData=[];
+ foreach (array_keys($field) as $fieldVo) {
+ $rowData[]=arraySeek($sourceVo,$fieldVo);//多键名数据赋值
+ }
+ $tbody[]=$rowData;//加入行数据
+ }
+ $excel[]=['type'=>'table','info'=>['thead'=>$thead,'tbody'=>$tbody]];//表格数据
+ //汇总数据
+ $excel[]=['type'=>'node','info'=>[
+ '总数:'.count($source)
+ ]];
+ //导出execl
+ buildExcel('采购排行表',$excel);
+ }
+}
diff --git a/serve/app/controller/Buy.php b/serve/app/controller/Buy.php
new file mode 100644
index 0000000..d70e745
--- /dev/null
+++ b/serve/app/controller/Buy.php
@@ -0,0 +1,1246 @@
+'time'],'startTime'],
+ [['endTime'=>'time'],'endTime'],
+ ['examine','fullDec1'],
+ ['nucleus','fullDec1'],
+ ['cse','fullDec1'],
+ ['invoice','fullDec1'],
+ ['check','fullDec1'],
+ ['data','fullLike']
+ ]);//构造SQL
+ //商品信息扩展查询
+ if(existFull($input,['goods'])){
+ $goods=array_column(Db::name('goods')->where([['name|py','like','%'.$input['goods'].'%']])->select()->toArray(),'id');
+ $sql[]=['id','in',array_column(Db::name('buy_info')->where([['goods','in',$goods]])->select()->toArray(),'pid')];
+ }
+ $sql=frameScope($sql);//组织数据
+ $sql=sqlAuth('buy',$sql);//数据鉴权
+ $count = Buys::where($sql)->count();//获取总条数
+ $info = Buys::with(['frameData','supplierData','peopleData','userData','billData','costData','invoiceData','recordData'])->where($sql)->append(['extension'])->page($input['page'],$input['limit'])->order(['id'=>'desc'])->select()->toArray();//查询分页数据
+ //关联单据
+ if(!empty($info)){
+ $bor=Db::name('bor')->where([['id','in',array_column($info,'source')]])->select()->toArray();
+ $bre=Db::name('bre')->where([['source','in',array_column($info,'id')]])->select()->toArray();
+ foreach ($info as $infoKey=>$infoVo) {
+ //采购订单
+ $borData=array_map(function($item){
+ return ['type'=>'采购订单','time'=>date('Y-m-d',$item['time']),'number'=>$item['number'],'sort'=>$item['time'],'sort'=>$item['time'],'types'=>'bor','id'=>$item['id']];
+ },search($bor)->where([['id','=',$infoVo['source']]])->select());
+ //采购退货单
+ $breData=array_map(function($item){
+ return ['type'=>'采购退货单','time'=>date('Y-m-d',$item['time']),'number'=>$item['number'],'sort'=>$item['time'],'sort'=>$item['time'],'types'=>'bre','id'=>$item['id']];
+ },search($bre)->where([['source','=',$infoVo['id']]])->select());
+ $merge=array_merge($borData,$breData);
+ //合并排序
+ array_multisort(array_column($merge,'sort'),SORT_DESC,$merge);
+ $info[$infoKey]['relation']=$merge;
+ }
+ }
+ $result=[
+ 'state'=>'success',
+ 'count'=>$count,
+ 'info'=>$info
+ ];//返回数据
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //新增|更新
+ public function save(){
+ $input=input('post.');
+ if(existFull($input,['class','info']) && isset($input['class']['id']) && isset($input['cost'])){
+ //构造|验证CLASS
+ try {
+ $class=$input['class'];
+ $class['frame']=userInfo(getUserID(),'frame');
+ $class['user']=getUserID();
+ $class['cse']=empty($class['cost'])?3:0;
+ $class['invoice']=empty($class['actual'])?3:0;
+ $class['examine']=0;
+ $class['nucleus']=0;
+ empty($class['id'])?$this->validate($class,'app\validate\Buy'):$this->validate($class,'app\validate\Buy.update');
+ $period=getPeriod();
+ if(strtotime($class['time'])<=$period){
+ throw new ValidateException('单据日期与结账日期冲突!');
+ }
+ } catch (ValidateException $e) {
+ return json(['state'=>'error','info'=>$e->getError()]);
+ exit;
+ }
+
+ //验证INFO
+ foreach ($input['info'] as $infoKey=>$infoVo) {
+ try {
+ $this->validate($infoVo,'app\validate\BuyInfo');
+ } catch (ValidateException $e) {
+ return json(['state'=>'error','info'=>'商品信息第'.($infoKey+1).'条'.$e->getError()]);
+ exit;
+ }
+ }
+
+ //验证Cost
+ foreach ($input['cost'] as $costKey=>$costVo) {
+ try {
+ $this->validate($costVo,'app\validate\Cost');
+ } catch (ValidateException $e) {
+ return json(['state'=>'error','info'=>'单据费用第'.($infoKey+1).'条'.$e->getError()]);
+ exit;
+ }
+ }
+
+ //处理数据
+ Db::startTrans();
+ try {
+ //CLASS数据
+ if(empty($class['id'])){
+ //创建数据
+ $createInfo=Buys::create($class);
+ $class['id']=$createInfo['id'];//转存主键
+ Db::name('record')->insert(['type'=>'buy','source'=>$class['id'],'time'=>time(),'user'=>getUserID(),'info'=>'新增单据']);
+ pushLog('新增采购单[ '.$class['number'].' ]');//日志
+ }else{
+ //更新数据
+ $updateInfo=Buys::update($class);
+ Db::name('record')->insert(['type'=>'buy','source'=>$class['id'],'time'=>time(),'user'=>getUserID(),'info'=>'更新单据']);
+ pushLog('更新采购单[ '.$class['number'].' ]');//日志
+ }
+
+ //INFO数据
+ BuyInfo::where([['pid','=',$class['id']]])->delete();
+ foreach ($input['info'] as $infoKey=>$infoVo) {
+ $input['info'][$infoKey]['pid']=$class['id'];
+ $input['info'][$infoKey]['retreat']=0;//初始|退货数量
+ }
+ $model = new BuyInfo;
+ $model->saveAll($input['info']);
+
+ //COST数据
+ Cost::where([['type','=','buy'],['class','=',$class['id']]])->delete();
+ foreach ($input['cost'] as $costKey=>$costVo) {
+ unset($input['cost'][$costKey]['id']);
+ $input['cost'][$costKey]['type']='buy';
+ $input['cost'][$costKey]['class']=$class['id'];
+ $input['cost'][$costKey]['time']=$class['time'];
+ $input['cost'][$costKey]['settle']=0;
+ $input['cost'][$costKey]['state']=0;
+ }
+ $model = new Cost;
+ $model->saveAll($input['cost']);
+
+ Db::commit();
+ $result=['state'=>'success','info'=>$class['id']];
+ } catch (\Exception $e) {
+ Db::rollback();
+ $result=['state'=>'error','info'=>'内部错误,操作已撤销!'];
+ }
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //获取
+ public function get(){
+ $input=input('post.');
+ if(existFull($input,['parm'])){
+ $class=Buys::where([['id','=',$input['parm']]])->find();
+ $info=BuyInfo::with(['goodsData','warehouseData'])->where([['pid','=',$input['parm']]])->order(['id'=>'asc'])->select();
+ $cost=Cost::where([['type','=','buy'],['class','=',$input['parm']]])->order(['id'=>'asc'])->select();
+ $result=['state'=>'success','info'=>[
+ 'class'=>$class,
+ 'info'=>$info,
+ 'cost'=>$cost
+ ]];
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //删除
+ public function del(){
+ $input=input('post.');
+ if(existFull($input,['parm']) && is_array($input['parm'])){
+ //关联验证
+ $exist=moreTableFind([['table'=>'bre','where'=>[['source','in',$input['parm']]]]]);
+ if($exist){
+ $result=['state'=>'error','info'=>'存在数据关联,删除失败!'];
+ }else{
+ $data=Db::name('buy')->where([['id','in',$input['parm']]])->order(['id'=>'desc'])->select()->toArray();
+ $search=search($data)->where([['examine','=','1']])->find();
+ if(empty($search)){
+ Db::startTrans();
+ try {
+ Db::name('buy')->where([['id','in',$input['parm']]])->delete();
+ Db::name('buy_info')->where([['pid','in',$input['parm']]])->delete();
+ Db::name('cost')->where([['type','=','buy'],['class','in',$input['parm']]])->delete();
+ Db::name('record')->where([['type','=','buy'],['source','in',$input['parm']]])->delete();
+ Db::name('log')->insert(['time'=>time(),'user'=>getUserID(),'info'=>'删除采购单[ '.implode(' | ',array_column($data,'number')).' ]']);
+
+ Db::commit();
+ $result=['state'=>'success'];
+ } catch (\Exception $e) {
+ Db::rollback();
+ $result=['state'=>'error','info'=>'内部错误,操作已撤销!'];
+ }
+ }else{
+ $result=['state'=>'error','info'=>'单据['.$search['number'].']已审核,不可删除!'];
+ }
+ }
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //核对|反核对
+ public function check(){
+ $input=input('post.');
+ if(existFull($input,['parm']) && is_array($input['parm'])){
+ $period=getPeriod();
+ $classList=Db::name('buy')->where([['id','in',$input['parm']]])->order(['id'=>'desc'])->select()->toArray();
+ foreach ($input['parm'] as $parmVo) {
+ $class=search($classList)->where([['id','=',$parmVo]])->find();
+ if($class['time']<=$period){
+ return json(['state'=>'error','info'=>'操作单据失败,原因:单据日期与结账日期冲突!']);
+ exit;
+ }
+ if(empty($class['check'])){
+ Db::name('buy')->where([['id','=',$class['id']]])->update(['check'=>1]);
+ //1 单据记录
+ Db::name('record')->insert(['type'=>'buy','source'=>$class['id'],'time'=>time(),'user'=>getUserID(),'info'=>'核对单据']);
+ //2 记录操作
+ pushLog('核对采购单[ '.$class['number'].' ]');//单据日志
+ }else{
+ Db::name('buy')->where([['id','=',$class['id']]])->update(['check'=>0]);
+ //1 单据记录
+ Db::name('record')->insert(['type'=>'buy','source'=>$class['id'],'time'=>time(),'user'=>getUserID(),'info'=>'反核对单据']);
+ //2 记录操作
+ pushLog('反核对采购单[ '.$class['number'].' ]');//单据日志
+ }
+ }
+ $result=['state'=>'success'];
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //审核|反审核
+ public function examine(){
+ $input=input('post.');
+ if(existFull($input,['parm']) && is_array($input['parm'])){
+ //1 基础数据
+ $period=getPeriod();
+ $classList=Db::name('buy')->where([['id','in',$input['parm']]])->order(['id'=>'desc'])->select()->toArray();
+ $infoList=Db::name('buy_info')->where([['pid','in',$input['parm']]])->order(['id'=>'asc'])->select()->toArray();
+ //2 综合处理
+ foreach ($input['parm'] as $parmVo) {
+ //1 匹配数据
+ $class=search($classList)->where([['id','=',$parmVo]])->find();
+ $info=search($infoList)->where([['pid','=',$parmVo]])->select();
+ //1.1 商品数据
+ $goodsList=Db::name('goods')->where([['id','in',array_unique(array_column($info,'goods'))]])->select()->toArray();
+ //1.2 综合匹配
+ if(empty($class['examine'])){
+ //1 关联单据
+ empty($class['source'])||$borInfoList=Db::name('bor_info')->where([['id','in',array_column($info,'source')]])->select()->toArray();
+ //2 构造数据
+ $batchGather=[];
+ $serialGather=[];
+ $roomWhereOrSql=[];
+ foreach ($info as $infoVo) {
+ //1 批次号
+ empty($infoVo['batch'])||$batchGather[]=$infoVo['batch'];
+ //2 序列号
+ $serialGather=array_merge($serialGather,json_decode($infoVo['serial']));
+ //3 仓储条件
+ empty($infoVo['warehouse'])||$roomWhereOrSql[]=[['warehouse','=',$infoVo['warehouse']],['goods','=',$infoVo['goods']],['attr','=',$infoVo['attr']]];
+ }
+ //3 匹配数据
+ empty($batchGather)||$batchList=Db::name('batch')->where([['number','in',$batchGather]])->select()->toArray();
+ empty($serialGather)||$serialList=Db::name('serial')->where([['number','in',$serialGather]])->select()->toArray();
+ if(!empty($roomWhereOrSql)){
+ //1 去重转存
+ $roomWhereOrSql=array_unique($roomWhereOrSql,SORT_REGULAR);
+ //2 仓储匹配
+ $roomList=Db::name('room')->whereOr($roomWhereOrSql)->select()->toArray();
+ }
+ }
+ //2 CLASS验证
+ if($class['time']<=$period){
+ return json(['state'=>'error','info'=>'操作单据[ '.$class['number'].' ]失败,原因:单据日期与结账日期冲突!']);
+ exit;
+ }
+ if(empty($class['examine'])){
+ //采购订单
+ if(!empty($class['source'])){
+ $bor=Db::name('bor')->where([['id','=',$class['source']]])->find();
+ if(in_array($bor['state'],[2,3])){
+ return json(['state'=>'error','info'=>'反审核单据[ '.$class['number'].' ]失败,原因:关联订单状态不正确!']);
+ exit;
+ }
+ }
+ }else{
+ //1 采购订单
+ if(!empty($class['source'])){
+ $bor=Db::name('bor')->where([['id','=',$class['source']]])->find();
+ if(in_array($bor['state'],[0,3])){
+ return json(['state'=>'error','info'=>'反审核单据[ '.$class['number'].' ]失败,原因:关联订单状态不正确!']);
+ exit;
+ }
+ }
+ //2 采购退货单
+ $bre=Db::name('bre')->where([['source','=',$class['id']]])->find();
+ if(!empty($bre)){
+ return json(['state'=>'error','info'=>'反审核单据[ '.$class['number'].' ]失败,原因:该单据存在关联采购退货单!']);
+ exit;
+ }
+ //3 核销单
+ $bill=Db::name('bill_info')->where([['mold','=','buy'],['source','=',$class['id']]])->find();
+ if(!empty($bill)){
+ return json(['state'=>'error','info'=>'反审核单据[ '.$class['number'].' ]失败,原因:该单据存在关联核销单!']);
+ exit;
+ }
+ //4 单据费用
+ $cost=Db::name('cost')->alias('cost')->where([['type','=','buy'],['class','=',$class['id']]])->whereExists(function($query){
+ $query->name('oce_info')->where([['source','=',Db::raw('cost.id')]])->limit(1);
+ })->find();
+ if(!empty($cost)){
+ return json(['state'=>'error','info'=>'反审核单据[ '.$class['number'].' ]失败,原因:该单据存在关联其它支出单!']);
+ exit;
+ }
+ //5 单据发票
+ $invoice=Db::name('invoice')->where([['type','=','buy'],['class','=',$class['id']]])->find();
+ if(!empty($invoice)){
+ return json(['state'=>'error','info'=>'反审核单据[ '.$class['number'].' ]失败,原因:该单据存在关联单据发票!']);
+ exit;
+ }
+ }
+ //3 INFO验证|构造
+ foreach ($info as $infoKey=>$infoVo) {
+ //1 匹配商品
+ $goods=search($goodsList)->where([['id','=',$infoVo['goods']]])->find();
+ //2 商品类型
+ if(empty($goods['type'])){
+ //场景验证
+ if(empty($class['examine'])){
+ //1 关联单据
+ if(!empty($infoVo['source'])){
+ $borInfo=search($borInfoList)->where([['id','=',$infoVo['source']]])->find();
+ if(!empty($borInfo)){
+ if($borInfo['unit']!=$infoVo['unit']){
+ //单位匹配
+ return json(['state'=>'error','info'=>'审核单据[ '.$class['number'].' ]失败,原因:第'.($infoKey+1).'行单位与采购订单不匹配!']);
+ exit;
+ }elseif(bccomp(math()->chain($borInfo['handle'])->add($infoVo['nums'])->done(),$borInfo['nums'])==1){
+ //数量匹配
+ return json(['state'=>'error','info'=>'审核单据[ '.$class['number'].' ]失败,原因:第'.($infoKey+1).'行超出采购订单可入库数量!']);
+ exit;
+ }
+ }
+ }
+ //2 多单位处理
+ if($goods['unit']==-1){
+ //多单位|转存
+ $radix=unitRadix($infoVo['unit'],json_decode($goods['units'],true));
+ $info[$infoKey]['basic']=[
+ 'nums'=>math()->chain($infoVo['nums'])->mul($radix)->done(),
+ 'price'=>math()->chain($infoVo['price'])->div($radix)->round(4)->done()
+ ];
+ }else{
+ //常规单位|转存
+ $info[$infoKey]['basic']=[
+ 'nums'=>$infoVo['nums'],
+ 'price'=>$infoVo['price']
+ ];
+ }
+ //3 序列号
+ $serialData=json_decode($infoVo['serial']);
+ if(empty($serialData)){
+ $info[$infoKey]['serial']=[];
+ }else{
+ //序列号状态[不存在|已退货]
+ $serialFind=search($serialList)->where([['goods','=',$infoVo['goods']],['number','in',$serialData],['state','<>',3]])->find();
+ if(empty($serialFind)){
+ $info[$infoKey]['serial']=$serialData;
+ }else{
+ return json(['state'=>'error','info'=>'审核单据[ '.$class['number'].' ]失败,原因:第'.($infoKey+1).'行序列号[ '.$serialFind['number'].' ]状态不正确!']);
+ exit;
+ }
+ }
+ }else{
+ //1 验证序列号
+ $serialInfoCollect=Db::name('serial_info')->where([['type','=','buy'],['info','in',array_column($info,'id')]])->select()->toArray();
+ if(!empty($serialInfoCollect)){
+ //序列号状态[未销售]
+ $serialFind=Db::name('serial')->where([['id','in',array_column($serialInfoCollect,'pid')],['state','<>',0]])->find();
+ if(!empty($serialFind)){
+ return json(['state'=>'error','info'=>'反审核单据[ '.$class['number'].' ]失败,原因:第'.($infoKey+1).'行序列号[ '.$serialFind['number'].' ]状态不正确!']);
+ exit;
+ }
+ }
+ }
+ }
+ }
+ //4 数据处理
+ Db::startTrans();
+ try {
+ //场景验证
+ if(empty($class['examine'])){
+ //审核
+ //1 构造数据
+ $store=['borInfo'=>[],'room'=>[],'roomInfo'=>[],'batch'=>[],'batchInfo'=>[],'serial'=>[],'serialInfo'=>[],'serve'=>[],'serveInfo'=>[]];
+ foreach ($info as $infoKey=>$infoVo){
+ //1 关联单据
+ empty($infoVo['source'])||$store['borInfo'][]=['id'=>$infoVo['source'],'handle'=>$infoVo['nums']];
+ //2 判断商品类型
+ $goods=search($goodsList)->where([['id','=',$infoVo['goods']]])->find();
+ if(empty($goods['type'])){
+ //常规商品
+ //1 仓储
+ $store['room'][]=['warehouse'=>$infoVo['warehouse'],'goods'=>$infoVo['goods'],'attr'=>$infoVo['attr'],'nums'=>$infoVo['basic']['nums']];
+ //2 仓储详情
+ $store['roomInfo'][]=['pid'=>null,'type'=>'buy','class'=>$class['id'],'info'=>$infoVo['id'],'time'=>$class['time'],'direction'=>1,'price'=>$infoVo['basic']['price'],'nums'=>$infoVo['basic']['nums']];
+ //3 批次号
+ if(empty($infoVo['batch'])){
+ $store['batch'][]=[];
+ $store['batchInfo'][]=[];
+ }else{
+ $store['batch'][]=['room'=>null,'warehouse'=>$infoVo['warehouse'],'goods'=>$infoVo['goods'],'number'=>$infoVo['batch'],'time'=>$infoVo['mfd'],'nums'=>$infoVo['basic']['nums']];
+ $store['batchInfo'][]=['pid'=>null,'type'=>'buy','class'=>$class['id'],'info'=>$infoVo['id'],'direction'=>1,'nums'=>$infoVo['basic']['nums']];
+ }
+ //4 序列号
+ if(empty($infoVo['serial'])){
+ $store['serial'][]=[];
+ $store['serialInfo'][]=[];
+ }else{
+ $serial=[];
+ $serialInfo=[];
+ foreach ($infoVo['serial'] as $serialVo) {
+ $serial[]=['room'=>null,'warehouse'=>$infoVo['warehouse'],'batch'=>null,'goods'=>$infoVo['goods'],'number'=>$serialVo,'state'=>0];
+ $serialInfo[]=['pid'=>null,'type'=>'buy','class'=>$class['id'],'info'=>$infoVo['id']];
+ }
+ $store['serial'][]=$serial;
+ $store['serialInfo'][]=$serialInfo;
+ }
+ }else{
+ //5 服务商品
+ $store['serve'][]=['goods'=>$infoVo['goods'],'attr'=>$infoVo['attr'],'nums'=>$infoVo['nums']];
+ $store['serveInfo'][]=['pid'=>null,'type'=>'buy','class'=>$class['id'],'info'=>$infoVo['id'],'time'=>$class['time'],'price'=>$infoVo['price'],'nums'=>$infoVo['nums']];
+ }
+ }
+ //2 关联单据
+ if(!empty($store['borInfo'])){
+ //1 更新详情
+ Db::name('bor_info')->duplicate(['handle'=>Db::raw('handle + VALUES(`handle`)')])->insertAll($store['borInfo']);
+ //2 更新CLASS
+ $borInfo=Db::name('bor_info')->where([['pid','=',$class['source']]])->select()->toArray();
+ $state=mathArraySum(array_column($borInfo,'nums'))==mathArraySum(array_column($borInfo,'handle'))?2:1;
+ Db::name('bor')->where([['id','=',$class['source']]])->update(['state'=>$state]);
+ }
+ //3 仓储
+ if(!empty($store['room'])){
+ //1 构造数据
+ $roomInsert=[];
+ foreach ($store['room'] as $roomVo) {
+ $roomFind=search($roomList)->where([['warehouse','=',$roomVo['warehouse']],['goods','=',$roomVo['goods']],['attr','=',$roomVo['attr']]])->find();
+ if(empty($roomFind)){
+ $roomVo['nums']=0;
+ $roomInsert[]=$roomVo;
+ }
+ }
+ //2 创建数据|去重
+ empty($roomInsert)||Db::name('room')->insertAll(array_unique($roomInsert,SORT_REGULAR));
+ //3 匹配主键|构造更新
+ $roomDuplicate=[];
+ $room=Db::name('room')->whereOr($roomWhereOrSql)->select()->toArray();
+ foreach ($store['room'] as $roomKey=>$roomVo) {
+ $roomFind=search($room)->where([['warehouse','=',$roomVo['warehouse']],['goods','=',$roomVo['goods']],['attr','=',$roomVo['attr']]])->find();
+ $store['room'][$roomKey]['id']=$roomFind['id'];
+ $roomDuplicate[]=['id'=>$roomFind['id'],'nums'=>$roomVo['nums']];
+ }
+ //4 更新数据
+ Db::name('room')->duplicate(['nums'=>Db::raw('nums + VALUES(`nums`)')])->insertAll($roomDuplicate);
+ }
+ //4 仓储详情
+ if(!empty($store['roomInfo'])){
+ //1 填充数据
+ foreach ($store['roomInfo'] as $roomInfoKey=>$roomInfoVo) {
+ $store['roomInfo'][$roomInfoKey]['pid']=$store['room'][$roomInfoKey]['id'];
+ }
+ //2 创建数据
+ Db::name('room_info')->insertAll($store['roomInfo']);
+ }
+ //5 批次号
+ if(!empty($store['batch'])){
+ //1 构造数据
+ $batchData=[];
+ foreach ($store['batch'] as $batchKey=>$batchVo) {
+ if(!empty($batchVo)){
+ $store['batch'][$batchKey]['room']=$store['room'][$batchKey]['id'];
+ $batchData[]=$store['batch'][$batchKey];
+ }
+ }
+ //2 排除数据|[[],[],[]]
+ if(!empty($batchData)){
+ //1 构造数据
+ $batchInsert=[];
+ foreach ($batchData as $batchDataKey=>$batchDataVo) {
+ $batchFind=search($batchList)->where([['room','=',$batchDataVo['room']],['number','=',$batchDataVo['number']],['time','=',$batchDataVo['time']]])->find();
+ if(empty($batchFind)){
+ $batchDataVo['nums']=0;
+ $batchInsert[]=$batchDataVo;
+ }
+ }
+ //2 创建数据|去重
+ empty($batchInsert)||Db::name('batch')->insertAll(array_unique($batchInsert,SORT_REGULAR));
+ //3 匹配主键|构造更新
+ $batchDuplicate=[];
+ $batch=Db::name('batch')->where([['number','in',$batchGather]])->select()->toArray();
+ foreach ($store['batch'] as $batchKey=>$batchVo) {
+ if(!empty($batchVo)){
+ $batchFind=search($batch)->where([['room','=',$batchVo['room']],['number','=',$batchVo['number']],['time','=',$batchVo['time']]])->find();
+ $store['batch'][$batchKey]['id']=$batchFind['id'];
+ $batchDuplicate[]=['id'=>$batchFind['id'],'nums'=>$batchVo['nums']];
+ }
+ }
+ //4 更新数据
+ Db::name('batch')->duplicate(['nums'=>Db::raw('nums + VALUES(`nums`)')])->insertAll($batchDuplicate);
+ }
+ }
+ //6 批次号详情
+ if(!empty($store['batchInfo'])){
+ //1 构造数据
+ $batchInfoInstall=[];
+ foreach ($store['batchInfo'] as $batchInfoKey=>$batchInfoVo) {
+ if(!empty($batchInfoVo)){
+ $batchInfoVo['pid']=$store['batch'][$batchInfoKey]['id'];
+ $batchInfoInstall[]=$batchInfoVo;
+ }
+ }
+ //2 排除数据|[[],[],[]]
+ if(!empty($batchInfoInstall)){
+ //创建数据
+ Db::name('batch_info')->insertAll($batchInfoInstall);
+ }
+ }
+ //7 序列号
+ if(!empty($store['serial'])){
+ //1 构造数据
+ $serialData=[];
+ foreach ($store['serial'] as $serialKey=>$item) {
+ if(!empty($item)){
+ foreach ($item as $itemKey=>$itemVo) {
+ $store['serial'][$serialKey][$itemKey]['room']=$store['room'][$serialKey]['id'];
+ $store['serial'][$serialKey][$itemKey]['batch']=empty($store['batch'][$serialKey])?0:$store['batch'][$serialKey]['id'];
+ $serialData[]=$store['serial'][$serialKey][$itemKey];
+ }
+ }
+ }
+ //2 排除数据|[[],[],[]]
+ if(!empty($serialData)){
+ //1 构造数据
+ $serialInsert=[];
+ foreach ($serialData as $serialDataKey=>$serialDataVo) {
+ $serialFind=search($serialList)->where([['room','=',$serialDataVo['room']],['batch','=',$serialDataVo['batch']],['number','=',$serialDataVo['number']]])->find();
+ if(empty($serialFind)){
+ $serialInsert[]=$serialDataVo;
+ }
+ }
+ //2 创建数据
+ empty($serialInsert)||Db::name('serial')->insertAll($serialInsert);
+ //3 匹配主键|构造更新
+ $serialDuplicate=[];
+ $serial=Db::name('serial')->where([['number','in',$serialGather]])->select()->toArray();
+ foreach ($store['serial'] as $serialKey=>$item) {
+ if(!empty($item)){
+ foreach ($item as $itemKey=>$itemVo) {
+ $serialFind=search($serial)->where([['room','=',$itemVo['room']],['batch','=',$itemVo['batch']],['number','=',$itemVo['number']]])->find();
+ $store['serial'][$serialKey][$itemKey]['id']=$serialFind['id'];
+ $serialFind['state']==3&&$serialDuplicate[]=$serialFind['id'];
+ }
+ }
+ }
+ //4 更新数据|状态变更
+ empty($serialDuplicate)||Db::name('serial')->where([['id','in',$serialDuplicate]])->update(['state'=>0]);
+ }
+ }
+ //8 序列号详情
+ if(!empty($store['serialInfo'])){
+ //1 构造数据
+ $serialInfoInstall=[];
+ foreach ($store['serialInfo'] as $serialInfoKey=>$item) {
+ if(!empty($item)){
+ foreach ($item as $itemKey=>$itemVo) {
+ $itemVo['pid']=$store['serial'][$serialInfoKey][$itemKey]['id'];
+ $serialInfoInstall[]=$itemVo;
+ }
+ }
+ }
+ //2 排除数据|[[],[],[]]
+ if(!empty($serialInfoInstall)){
+ //创建数据
+ Db::name('serial_info')->insertAll($serialInfoInstall);
+ }
+ }
+ //9 服务商品
+ if(!empty($store['serve'])){
+ //1 匹配数据|去重
+ $serveWhereOrSql=array_unique(array_map(function($item){
+ return [['goods','=',$item['goods']],['attr','=',$item['attr']]];
+ },$store['serve']),SORT_REGULAR);
+ $serve=Db::name('serve')->whereOr($serveWhereOrSql)->select()->toArray();
+ //2 构造数据
+ $serveInsert=[];
+ foreach ($store['serve'] as $serveVo) {
+ $serveFind=search($serve)->where([['goods','=',$serveVo['goods']],['attr','=',$serveVo['attr']]])->find();
+ if(empty($serveFind)){
+ $serveVo['nums']=0;
+ $serveInsert[]=$serveVo;
+ }
+ }
+ //3 创建数据|去重
+ empty($serveInsert)||Db::name('serve')->insertAll(array_unique($serveInsert,SORT_REGULAR));
+ //4 匹配主键|构造更新
+ $serveDuplicate=[];
+ $serve=Db::name('serve')->whereOr($serveWhereOrSql)->select()->toArray();
+ foreach ($store['serve'] as $serveKey=>$serveVo) {
+ $serveFind=search($serve)->where([['goods','=',$serveVo['goods']],['attr','=',$serveVo['attr']]])->find();
+ $store['serve'][$serveKey]['id']=$serveFind['id'];
+ $serveDuplicate[]=['id'=>$serveFind['id'],'nums'=>$serveVo['nums']];
+ }
+ //5 更新数据
+ Db::name('serve')->duplicate(['nums'=>Db::raw('nums + VALUES(`nums`)')])->insertAll($serveDuplicate);
+ }
+ //10 服务商品详情
+ if(!empty($store['serveInfo'])){
+ //1 填充数据
+ foreach ($store['serveInfo'] as $serveInfoKey=>$serveInfoVo) {
+ $store['serveInfo'][$serveInfoKey]['pid']=$store['serve'][$serveInfoKey]['id'];
+ }
+ //2 创建数据
+ Db::name('serve_info')->insertAll($store['serveInfo']);
+ }
+ //11 资金|核销
+ if(!empty($class['money'])){
+ //1 更新资金账户
+ Db::name('account')->where([['id','=',$class['account']]])->dec('balance',$class['money'])->update();
+ //2 创建资金详情
+ Db::name('account_info')->insert([
+ 'pid'=>$class['account'],
+ 'type'=>'buy',
+ 'class'=>$class['id'],
+ 'time'=>$class['time'],
+ 'direction'=>0,
+ 'money'=>$class['money']
+ ]);
+ //3 创建核销记录
+ Db::name('buy_bill')->insert([
+ 'pid'=>$class['id'],
+ 'type'=>'buy',
+ 'source'=>$class['id'],
+ 'time'=>$class['time'],
+ 'money'=>$class['money']
+ ]);
+ }
+ //12 供应商|应付款余额
+ $balance=math()->chain($class['actual'])->sub($class['money'])->done();
+ if(!empty($balance)){
+ Db::name('supplier')->where([['id','=',$class['supplier']]])->inc('balance',$balance)->update();
+ }
+ //13 更新单据
+ $nucleus=$class['money']==$class['actual']?2:($class['money']==0?0:1);
+ Db::name('buy')->where([['id','=',$class['id']]])->update(['examine'=>1,'nucleus'=>$nucleus]);
+ //14 单据记录
+ Db::name('record')->insert(['type'=>'buy','source'=>$class['id'],'time'=>time(),'user'=>getUserID(),'info'=>'审核单据']);
+ //15 收发记录
+ $summary=new Summary;
+ $summary->note('buy',$class['id'],true);
+ //16 记录操作
+ pushLog('审核采购单[ '.$class['number'].' ]');//单据日志
+ }else{
+ //反审核
+ //1 匹配数据
+ $listSql=[['type','=','buy'],['info','in',array_column($info,'id')]];
+ $roomInfoList=Db::name('room_info')->where($listSql)->select()->toArray();
+ $batchInfoList=Db::name('batch_info')->where($listSql)->select()->toArray();
+ $serialInfoList=Db::name('serial_info')->where($listSql)->select()->toArray();
+ $serveInfoList=Db::name('serve_info')->where($listSql)->select()->toArray();
+ //2 关联单据
+ if(!empty($class['source'])){
+ //1 更新详情
+ $borInfoDuplicate=[];
+ foreach ($info as $infoVo) {
+ empty($infoVo['source'])||$borInfoDuplicate[]=['id'=>$infoVo['source'],'handle'=>$infoVo['nums']];
+ }
+ empty($borInfoDuplicate)||Db::name('bor_info')->duplicate(['handle'=>Db::raw('handle - VALUES(`handle`)')])->insertAll($borInfoDuplicate);
+ //2 更新CALSS
+ $borInfo=Db::name('bor_info')->where([['pid','=',$class['source']]])->select()->toArray();
+ $state=empty(mathArraySum(array_column($borInfo,'handle')))?0:1;
+ Db::name('bor')->where([['id','=',$class['source']]])->update(['state'=>$state]);
+ }
+ //3 仓储
+ $roomDuplicate=[];
+ foreach ($roomInfoList as $roomInfoVo) {
+ $roomDuplicate[]=['id'=>$roomInfoVo['pid'],'nums'=>$roomInfoVo['nums']];
+ }
+ //3.1 更新仓储
+ Db::name('room')->duplicate(['nums'=>Db::raw('nums - VALUES(`nums`)')])->insertAll($roomDuplicate);
+ //3.2 删除仓储详情
+ Db::name('room_info')->where([['id','in',array_column($roomInfoList,'id')]])->delete();
+ //3.3 仓储|冗余
+ $roomPk=array_unique(array_column($roomInfoList,'pid'));
+ $roomInfoData=Db::name('room_info')->where([['pid','in',$roomPk]])->select()->toArray();
+ $roomDiff=array_diff($roomPk,array_unique(array_column($roomInfoData,'pid')));
+ empty($roomDiff)||Db::name('room')->where([['id','in',$roomDiff]])->delete();
+ //4 批次号
+ if(!empty($batchInfoList)){
+ //1 构造数据
+ $batchInfoDuplicate=array_map(function($item){
+ return ['id'=>$item['pid'],'nums'=>$item['nums']];
+ },$batchInfoList);
+ //2 更新批次号
+ Db::name('batch')->duplicate(['nums'=>Db::raw('nums - VALUES(`nums`)')])->insertAll($batchInfoDuplicate);
+ //3 删除批次号详情
+ Db::name('batch_info')->where([['id','in',array_column($batchInfoList,'id')]])->delete();
+ //4 批次号|冗余
+ $batchPk=array_unique(array_column($batchInfoList,'pid'));
+ $batchInfoData=Db::name('batch_info')->where([['pid','in',$batchPk]])->select()->toArray();
+ $batchDiff=array_diff($batchPk,array_unique(array_column($batchInfoData,'pid')));
+ empty($batchDiff)||Db::name('batch')->where([['id','in',$batchDiff]])->delete();
+ }
+ //5 序列号
+ if(!empty($serialInfoList)){
+ //1 更新序列号
+ Db::name('serial')->where([['id','in',array_column($serialInfoList,'pid')]])->update(['state'=>3]);
+ //2 删除序列号详情
+ Db::name('serial_info')->where([['id','in',array_column($serialInfoList,'id')]])->delete();
+ //3 序列号|冗余
+ $serialPk=array_unique(array_column($serialInfoList,'pid'));
+ $serialInfoData=Db::name('serial_info')->where([['pid','in',$serialPk]])->select()->toArray();
+ $serialDiff=array_diff($serialPk,array_unique(array_column($serialInfoData,'pid')));
+ empty($serialDiff)||Db::name('serial')->where([['id','in',$serialDiff]])->delete();
+ }
+ //6 服务
+ if(!empty($serveInfoList)){
+ //1 构造数据
+ $serveInfoDuplicate=array_map(function($item){
+ return ['id'=>$item['pid'],'nums'=>$item['nums']];
+ },$serveInfoList);
+ //2 更新服务
+ Db::name('serve')->duplicate(['nums'=>Db::raw('nums - VALUES(`nums`)')])->insertAll($serveInfoDuplicate);
+ //3 删除服务详情
+ Db::name('serve_info')->where([['id','in',array_column($serveInfoList,'id')]])->delete();
+ //4 服务|冗余
+ $servePk=array_unique(array_column($serveInfoList,'pid'));
+ $serveInfoData=Db::name('serve_info')->where([['pid','in',$servePk]])->select()->toArray();
+ $serveDiff=array_diff($servePk,array_unique(array_column($serveInfoData,'pid')));
+ empty($serveDiff)||Db::name('serve')->where([['id','in',$serveDiff]])->delete();
+ }
+ //7 资金|核销
+ if(!empty($class['money'])){
+ //1 更新资金账户
+ Db::name('account')->where([['id','=',$class['account']]])->inc('balance',$class['money'])->update();
+ //2 删除资金详情
+ Db::name('account_info')->where([['type','=','buy'],['class','=',$class['id']]])->delete();
+ //3 删除核销记录
+ Db::name('buy_bill')->where([['pid','=',$class['id']]])->delete();
+ }
+ //8 供应商|应付款余额
+ $balance=math()->chain($class['actual'])->sub($class['money'])->done();
+ if(!empty($balance)){
+ Db::name('supplier')->where([['id','=',$class['supplier']]])->dec('balance',$balance)->update();
+ }
+ //9 更新单据
+ Db::name('buy')->where([['id','=',$class['id']]])->update(['examine'=>0,'nucleus'=>0]);
+ //10 单据记录
+ Db::name('record')->insert(['type'=>'buy','source'=>$class['id'],'time'=>time(),'user'=>getUserID(),'info'=>'反审核单据']);
+ //11 收发记录
+ $summary=new Summary;
+ $summary->note('buy',$class['id'],false);
+ //12 记录操作
+ pushLog('反审核采购单[ '.$class['number'].' ]');//单据日志
+ }
+
+ Db::commit();
+ } catch (\Exception $e) {
+ Db::rollback();
+ return json(['state'=>'error','info'=>'内部错误,操作已撤销!']);
+ exit;
+ }
+ }
+ $result=['state'=>'success'];
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //上传
+ public function upload(){
+ $file = request()->file('file');
+ //获取上传文件
+ if (empty($file)) {
+ $result = ['state' => 'error','info' => '传入数据不完整!'];
+ } else {
+ //文件限制5MB
+ try{
+ validate(['file'=>['fileSize'=>5*1024*1024,'fileExt'=>'png,gif,jpg,jpeg,txt,doc,docx,rtf,xls,xlsx,ppt,pptx,pdf,zip,rar']])->check(['file'=>$file]);
+ $fileInfo=Filesystem::disk('upload')->putFile('buy', $file, 'uniqid');
+ $filePath=request()->domain().'/static/upload/'.$fileInfo;
+ $result=['state'=>'success','info'=>$filePath];
+ }catch(ValidateException $e) {
+ $result = ['state' => 'error','info' => $e->getMessage()];
+ }
+ }
+ return json($result);
+ }
+ //生成采购退货单
+ public function buildBre(){
+ $input=input('post.');
+ if(existFull($input,['id'])){
+ //源数据
+ $source=[
+ 'class'=>Buys::where([['id','=',$input['id']]])->find(),
+ 'info'=>BuyInfo::with(['goodsData','warehouseData'])->where([['pid','=',$input['id']]])->order(['id'=>'asc'])->select()->toArray()
+ ];
+ //状态验证
+ if(mathArraySum(array_column($source['info'],'nums'))==mathArraySum(array_column($source['info'],'retreat'))){
+ $result=['state'=>'warning','info'=>'操作失败,无可生成的数据!'];
+ }else{
+ //CLASS数据
+ $class=[
+ 'source'=>$source['class']['id'],
+ 'supplier'=>$source['class']['supplier'],
+ 'total'=>0
+ ];
+ //INFO数据
+ $info=[];
+ $fun=getSys('fun');
+ foreach ($source['info'] as $infoVo) {
+ //判断入库状态
+ if(bccomp($infoVo['nums'],$infoVo['retreat'])==1){
+ $infoVo['source']=$infoVo['id'];
+ $infoVo['serial']=[];
+ //重算价格
+ $infoVo['nums']=math()->chain($infoVo['nums'])->sub($infoVo['retreat'])->done();
+ $storage=math()->chain($infoVo['price'])->mul($infoVo['nums'])->round($fun['digit']['money'])->done();
+ //折扣额|金额
+ if($infoVo['discount']==0){
+ $infoVo['total']=$storage;
+ }else{
+ $infoVo['dsc']=math()->chain($storage)->div(100)->mul($infoVo['discount'])->round($fun['digit']['money'])->done();
+ $infoVo['total']=math()->chain($storage)->sub($infoVo['dsc'])->done();
+ }
+ //税额|价税合计
+ if($infoVo['tax']==0){
+ $infoVo['tpt']=$infoVo['total'];
+ }else{
+ $infoVo['tat']=math()->chain($infoVo['total'])->div(100)->mul($infoVo['tax'])->round(2)->done();
+ $infoVo['tpt']=math()->chain($infoVo['total'])->add($infoVo['tat'])->done();
+ }
+ //转存数据
+ $info[]=$infoVo;
+ $class['total']=math()->chain($class['total'])->add($infoVo['tpt'])->done();//累加单据金额
+ }
+ }
+ $result=['state'=>'success','info'=>['class'=>$class,'info'=>$info]];
+ }
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //导入
+ public function import(){
+ delOverdueFile('static.upload.xlsx');//删除过期文件
+ $file=request()->file('file');//获取上传文件
+ if(empty($file)){
+ $result=['state'=>'error','info'=>'传入数据不完整!'];
+ }else{
+ $fun=getSys('fun');
+ try{
+ validate(['file'=>['fileSize'=>2*1024*1024,'fileExt'=>'xlsx']])->check(['file'=>$file]);
+ $fileInfo = Filesystem::disk('upload')->putFile('xlsx', $file, 'uniqid');
+ $filePath = pathChange('static.upload').$fileInfo;
+ $data=getXlsx($filePath);
+ unset($data[1]);//删除标题行
+ unset($data[2]);//删除列名行
+ //初始化CLASS
+ //供应商匹配
+ $supplier=Db::name('supplier')->where([['name','=',$data[3]['A']]])->find();
+ if(empty($supplier)){
+ throw new ValidateException('供应商[ '.$data[3]['A'].' ]未匹配!');
+ }
+ //结算账户匹配
+ if(empty($data[3]['F'])){
+ $account=['id'=>0];
+ }else{
+ $account=Db::name('account')->where([['name','=',$data[3]['G']]])->find();
+ if(empty($account)){
+ throw new ValidateException('结算账户[ '.$data[3]['G'].' ]不正确!');
+ }
+ }
+ //关联人员匹配
+ if(empty($data[3]['H'])){
+ $people=['id'=>0];
+ }else{
+ $people=Db::name('people')->where([['name','=',$data[3]['H']]])->find();
+ if(empty($people)){
+ throw new ValidateException('关联人员[ '.$data[3]['H'].' ]未匹配!');
+ }
+ }
+ $class=[
+ 'source'=>0,
+ 'frame'=>userInfo(getUserID(),'frame'),
+ 'supplier'=>$supplier['id'],
+ 'time'=>$data[3]['B'],
+ 'number'=>$data[3]['C'],
+ 'total'=>0,
+ 'actual'=>$data[3]['E'],
+ 'money'=>$data[3]['F'],
+ 'account'=>$account['id'],
+ 'people'=>$people['id'],
+ 'logistics'=>["key"=>"auto","name"=>"自动识别","number"=>$data[3]['I']],
+ 'file'=>[],
+ 'data'=>$data[3]['J'],
+ 'more'=>[],
+ 'examine'=>0,
+ 'nucleus'=>0,
+ 'cse'=>0,
+ 'invoice'=>0,
+ 'check'=>0,
+ 'user'=>getUserID()
+ ];
+ $this->validate($class,'app\validate\Buy');//数据合法性验证
+ //初始化INFO
+ $info=[];
+ $goods=Goods::with(['attr'])->where([['name','in',array_column($data,'K')]])->select()->toArray();
+ $warehouse=Db::name('warehouse')->where([['name','in',array_column($data,'N')]])->select()->toArray();
+ foreach ($data as $dataKey=>$dataVo) {
+ $record=[
+ 'source'=>0,
+ 'goods'=>$dataVo['K'],
+ 'attr'=>$dataVo['L'],
+ 'unit'=>$dataVo['M'],
+ 'warehouse'=>$dataVo['N'],
+ 'batch'=>$dataVo['O'],
+ 'mfd'=>$dataVo['P'],
+ 'price'=>$dataVo['Q'],
+ 'nums'=>$dataVo['R'],
+ 'serial'=>explode(',',$dataVo['S']),
+ 'discount'=>$dataVo['T'],
+ 'dsc'=>0,
+ 'total'=>0,
+ 'tax'=>$dataVo['W'],
+ 'tat'=>0,
+ 'tpt'=>0,
+ 'data'=>$dataVo['Z'],
+ 'retreat'=>0,
+ ];
+ //商品匹配
+ $goodsFind=search($goods)->where([['name','=',$record['goods']]])->find();
+ if(empty($goodsFind)){
+ throw new ValidateException('模板文件第'.$dataKey.'行商品名称[ '.$record['goods'].' ]未匹配!');
+ }else{
+ $record['goods']=$goodsFind['id'];
+ }
+ //辅助属性匹配
+ if(empty($goodsFind['attr'])){
+ $record['attr']='';
+ }else{
+ if(empty($record['attr'])){
+ throw new ValidateException('模板文件第'.$dataKey.'行辅助属性不可为空!');
+ }else{
+ $attrFind=search($goodsFind['attr'])->where([['name','=',$record['attr']]])->find();
+ if(empty($attrFind)){
+ throw new ValidateException('模板文件第'.$dataKey.'行辅助属性[ '.$record['attr'].' ]未匹配!');
+ }
+ }
+ }
+ //单位匹配
+ if($goodsFind['unit']==-1){
+ if(empty($record['unit'])){
+ throw new ValidateException('模板文件第'.$dataKey.'行单位不可为空!');
+ }else{
+ $unitFind=search($goodsFind['units'])->where([['name','=',$record['unit']]])->find();
+ if(empty($unitFind) && $goodsFind['units'][0]['source']!=$record['unit']){
+ throw new ValidateException('模板文件第'.$dataKey.'行单位[ '.$record['unit'].' ]未匹配!');
+ }
+ }
+ }else{
+ $record['unit']=$goodsFind['unit'];
+ }
+ //仓库匹配
+ if(empty($goodsFind['type'])){
+ //常规产品
+ $warehouseFind=search($warehouse)->where([['name','=',$record['warehouse']]])->find();
+ if(empty($warehouseFind)){
+ throw new ValidateException('模板文件第'.$dataKey.'行仓库[ '.$record['warehouse'].' ]未匹配!');
+ }else{
+ $record['warehouse']=$warehouseFind['id'];
+ }
+ }else{
+ //服务产品
+ $record['warehouse']=null;
+ }
+ //批次号匹配
+ if(empty($goodsFind['batch'])){
+ $record['batch']='';
+ }else{
+ if(empty($record['batch'])){
+ throw new ValidateException('模板文件第'.$dataKey.'行批次号不可为空!');
+ }
+ }
+ //生产日期匹配
+ if(empty($goodsFind['validity'])){
+ $record['mfd']='';
+ }else{
+ if(empty($record['mfd'])){
+ throw new ValidateException('模板文件第'.$dataKey.'行生产日期不可为空!');
+ }
+ }
+ //单价匹配
+ if(!preg_match("/^\d+(\.\d{0,".$fun['digit']['money']."})?$/",$record['price'])){
+ throw new ValidateException('模板文件第'.$dataKey.'行单价不正确!');
+ }
+ //数量匹配
+ if(!preg_match("/^\d+(\.\d{0,".$fun['digit']['nums']."})?$/",$record['nums'])){
+ throw new ValidateException('模板文件第'.$dataKey.'行数量不正确!');
+ }
+ //序列号匹配
+ if(empty($goodsFind['serial'])){
+ $record['serial']=[];
+ }else{
+ if(count($record['serial'])==1 && empty($record['serial'][0])){
+ throw new ValidateException('模板文件第'.$dataKey.'行序列号不可为空!');
+ }else{
+ if(count($record['serial'])!=$record['nums']){
+ throw new ValidateException('模板文件第'.$dataKey.'行序列号个数与数量不符!');
+ }
+ }
+ }
+ try{
+ $this->validate($record,'app\validate\BuyInfo');//数据合法性验证
+ $storage=math()->chain($record['price'])->mul($record['nums'])->round($fun['digit']['money'])->done();
+ //折扣额|金额
+ if($record['discount']==0){
+ $record['total']=$storage;
+ }else{
+ $record['dsc']=math()->chain($storage)->div(100)->mul($record['discount'])->round($fun['digit']['money'])->done();
+ $record['total']=math()->chain($storage)->sub($record['dsc'])->done();
+ }
+ //税额|价税合计
+ if($record['tax']==0){
+ $record['tpt']=$record['total'];
+ }else{
+ $record['tat']=math()->chain($record['total'])->div(100)->mul($record['tax'])->round(2)->done();
+ $record['tpt']=math()->chain($record['total'])->add($record['tat'])->done();
+ }
+ //转存数据
+ $class['total']=math()->chain($class['total'])->add($record['tpt'])->done();//累加单据金额
+ $info[]=$record;
+ } catch (ValidateException $e) {
+ return json(['state'=>'error','info'=>'模板文件第'.$dataKey.'行'.$e->getMessage()]);//返回错误信息
+ exit;
+ }
+ }
+ //序列号重复验证
+ $serials=[];
+ foreach ($info as $infoVo) {
+ $serials = array_merge($serials,$infoVo['serial']);
+ }
+ if(count($serials)!=count(array_unique($serials))){
+ throw new ValidateException('商品信息中存在重复序列号!');
+ }
+ //CLASS数据验证
+ if(bccomp($class['total'],$class['actual'])==-1){
+ throw new ValidateException('实际金额不可大于单据金额[ '.$class['total'].' ]!');
+ }else if(bccomp($class['actual'],$class['money'])==-1){
+ throw new ValidateException('实付金额不可大于实际金额[ '.floatval($class['actual']).' ]!');
+ }else{
+ Db::startTrans();
+ try {
+ //新增CLASS
+ $classData=Buys::create($class);
+ //新增INFO
+ foreach ($info as $infoKey=>$infoVo) {
+ $info[$infoKey]['pid']=$classData['id'];
+ }
+ $model = new BuyInfo;
+ $model->saveAll($info);
+ Db::name('record')->insert(['type'=>'buy','source'=>$classData['id'],'time'=>time(),'user'=>getUserID(),'info'=>'导入单据']);
+ pushLog('导入采购单[ '.$classData['number'].' ]');//日志
+
+ Db::commit();
+ $result=['state'=>'success'];
+ } catch (\Exception $e) {
+ Db::rollback();
+ $result=['state'=>'error','info'=>'内部错误,操作已撤销!'];
+ }
+ }
+ }catch(ValidateException $e) {
+ $result=['state'=>'error','info'=>$e->getMessage()];//返回错误信息
+ }
+ }
+ return json($result);
+ }
+ //导出
+ public function exports(){
+ $input=input('get.');
+ if(existFull($input,['scene','parm']) && is_array($input['parm'])){
+ pushLog('导出采购单列表');//日志
+ $source=Buys::with(['frameData','supplierData','accountData','userData','peopleData'])->where([['id','in',$input['parm']]])->append(['extension'])->order(['id'=>'desc'])->select()->toArray();//查询CLASS数据
+ if($input['scene']=='simple'){
+ //简易报表
+ //开始构造导出数据
+ $excel=[];//初始化导出数据
+ //标题数据
+ $excel[]=['type'=>'title','info'=>'采购单列表'];
+ //表格数据
+ $field=[
+ 'frameData|name'=>'所属组织',
+ 'supplierData|name'=>'供应商',
+ 'time'=>'单据时间',
+ 'number'=>'单据编号',
+ 'total'=>'单据金额',
+ 'actual'=>'实际金额',
+ 'money'=>'单据付款',
+ 'extension|amount'=>'核销金额',
+ 'cost'=>'单据费用',
+ 'peopleData|name'=>'关联人员',
+ 'extension|examine'=>'审核状态',
+ 'extension|nucleus'=>'核销状态',
+ 'extension|cse'=>'费用状态',
+ 'extension|invoice'=>'发票状态',
+ 'extension|check'=>'核对状态',
+ 'userData|name'=>'制单人',
+ 'data'=>'备注信息'
+ ];
+ $thead=array_values($field);//表格标题
+ $tbody=[];//表格内容
+ //构造表内数据
+ foreach ($source as $sourceVo) {
+ $rowData=[];
+ foreach (array_keys($field) as $fieldVo) {
+ $rowData[]=arraySeek($sourceVo,$fieldVo);//多键名数据赋值
+ }
+ $tbody[]=$rowData;//加入行数据
+ }
+ $excel[]=['type'=>'table','info'=>['thead'=>$thead,'tbody'=>$tbody]];//表格数据
+ //统计数据
+ $excel[]=['type'=>'node','info'=>[
+ '总数:'.count($source),
+ '总单据金额:'.mathArraySum(array_column($source,'total')),
+ '总实际金额:'.mathArraySum(array_column($source,'actual')),
+ '总单据付款:'.mathArraySum(array_column($source,'money')),
+ '总核销金额:'.mathArraySum(arrayColumns($source,['extension','amount'])),
+ '总单据费用:'.mathArraySum(array_column($source,'cost'))
+ ]];
+ //导出execl
+ buildExcel('采购单列表',$excel);
+ }else{
+ //详细报表
+ $files=[];//初始化文件列表
+ foreach ($source as $sourceVo) {
+ //开始构造导出数据
+ $excel=[];//初始化导出数据
+ //标题数据
+ $excel[]=['type'=>'title','info'=>'采购单'];
+ //节点数据
+ $excel[]=['type'=>'node','info'=>[
+ '供应商:'.$sourceVo['supplierData']['name'],
+ '单据日期:'.$sourceVo['time'],
+ '单据编号:'.$sourceVo['number']]
+ ];
+ //表格数据
+ $field=[
+ 'goodsData|name'=>'商品名称',
+ 'goodsData|spec'=>'规格型号',
+ 'attr'=>'辅助属性',
+ 'unit'=>'单位',
+ 'warehouseData|name'=>'仓库',
+ 'batch'=>'批次号',
+ 'mfd'=>'生产日期',
+ 'price'=>'单价',
+ 'nums'=>'数量',
+ 'extension|serial'=>'序列号',
+ 'retreat'=>'退货数量',
+ 'discount'=>'折扣率',
+ 'dsc'=>'折扣额',
+ 'total'=>'金额',
+ 'tax'=>'税率',
+ 'tat'=>'税额',
+ 'tpt'=>'价税合计',
+ 'data'=>'备注信息'
+ ];
+ //构造表内数据
+ $info=BuyInfo::with(['goodsData','warehouseData'])->where([['pid','=',$sourceVo['id']]])->order(['id'=>'asc'])->append(['extension'])->select()->toArray();
+ //批次号匹配
+ if(empty(search($info)->where([['goodsData|batch','=',true]])->find())){
+ unset($field['batch']);
+ }
+ //生产日期匹配
+ if(empty(search($info)->where([['goodsData|validity','=',true]])->find())){
+ unset($field['mfd']);
+ }
+ //序列号匹配
+ if(empty(search($info)->where([['goodsData|serial','=',true]])->find())){
+ unset($field['extension|serial']);
+ }
+ //退货数量匹配
+ if(empty(search($info)->where([['retreat','<>',0]])->find())){
+ unset($field['retreat']);
+ }
+ //税金匹配
+ $fun=getSys('fun');
+ if(empty(search($info)->where([['tax','<>',0]])->find()) && !$fun['tax']){
+ unset($field['tax']);
+ unset($field['tat']);
+ unset($field['tpt']);
+ }
+ $thead=array_values($field);//表格标题
+ $tbody=[];//表格内容
+ foreach ($info as $infoVo) {
+ $rowData=[];
+ foreach (array_keys($field) as $fieldVo) {
+ $rowData[]=arraySeek($infoVo,$fieldVo);//多键名数据赋值
+ }
+ $tbody[]=$rowData;//加入行数据
+ }
+ $excel[]=['type'=>'table','info'=>['thead'=>$thead,'tbody'=>$tbody]];//表格数据
+ //节点数据
+ $excel[]=['type'=>'node','info'=>[
+ '单据金额:'.$sourceVo['total'],
+ '单据费用:'.$sourceVo['cost'],
+ '实际金额:'.$sourceVo['actual'],
+ '核销金额:'.$sourceVo['extension']['amount'],
+ '结算账户:'.arraySeek($sourceVo,'accountData|name'),
+ '发票信息:'.$sourceVo['invoice'],
+ '关联人员:'.arraySeek($sourceVo,'peopleData|name'),
+ '物流信息:'.$sourceVo['extension']['logistics'],
+ '备注信息:'.$sourceVo['data']]
+ ];
+ //生成execl
+ $files[]=buildExcel($sourceVo['number'],$excel,false);
+
+ }
+ buildZip('采购单_'.time(),$files);
+ }
+ }else{
+ return json(['state'=>'error','info'=>'传入数据不完整!']);
+ }
+ }
+}
\ No newline at end of file
diff --git a/serve/app/controller/Category.php b/serve/app/controller/Category.php
new file mode 100644
index 0000000..e517a3c
--- /dev/null
+++ b/serve/app/controller/Category.php
@@ -0,0 +1,106 @@
+'asc'])->select());
+ return json(['state'=>'success','info'=>$category]);
+ }
+ //新增|更新
+ public function save(){
+ $input=input('post.');
+ if(isset($input['id'])){
+ //验证数据
+ try {
+ if(empty($input['id'])){
+ $this->validate($input,'app\validate\Category');
+ }else{
+ $this->validate($input,'app\validate\Category.update');
+ //所属不可等于或包含当前
+ if(in_array($input['pid'],findTreeArr('category',$input['id'],'id'))){
+ throw new ValidateException('所属类别选择不正确!');
+ }
+ }
+ } catch (ValidateException $e) {
+ return json(['state'=>'error','info'=>$e->getError()]);
+ exit;
+ }
+
+ //处理数据
+ Db::startTrans();
+ try {
+ if(empty($input['id'])){
+ //创建数据
+ Categorys::create($input);
+ pushLog('新增商品类别[ '.$input['name'].' ]');//日志
+ }else{
+ //更新数据
+ Categorys::update($input);
+ pushLog('更新商品类别[ '.$input['name'].' ]');//日志
+ }
+
+ Db::commit();
+ $result=['state'=>'success'];
+ } catch (\Exception $e) {
+ Db::rollback();
+ $result=['state'=>'error','info'=>'内部错误,操作已撤销!'];
+ }
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //获取
+ public function get(){
+ $input=input('post.');
+ if(existFull($input,['id'])){
+ $result=[
+ 'state'=>'success',
+ 'info'=>Categorys::where([['id','=',$input['id']]])->find()
+ ];
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //删除
+ public function del(){
+ $input=input('post.');
+ if(existFull($input,['id'])){
+ $subFind=Db::name('category')->where([['pid','=',$input['id']]])->find();
+ if(empty($subFind)){
+ //关联判断
+ $exist=moreTableFind([
+ ['table'=>'goods','where'=>[['category','=',$input['id']]]],
+ ]);
+ if(empty($exist)){
+ //逻辑处理
+ $find=Db::name('category')->where([['id','=',$input['id']]])->find();
+ Db::startTrans();
+ try {
+ Db::name('category')->where([['id','=',$input['id']]])->delete();
+ pushLog('删除商品类别[ '.$find['name'].' ]');//日志
+
+ Db::commit();
+ $result=['state'=>'success'];
+ } catch (\Exception $e) {
+ Db::rollback();
+ $result=['state'=>'error','info'=>'内部错误,操作已撤销!'];
+ }
+ }else{
+ $result=['state'=>'error','info'=>'存在数据关联,删除失败!'];
+ }
+ }else{
+ $result=['state'=>'error','info'=>'存在子数据,删除失败!'];
+ }
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+}
diff --git a/serve/app/controller/Code.php b/serve/app/controller/Code.php
new file mode 100644
index 0000000..80ccf70
--- /dev/null
+++ b/serve/app/controller/Code.php
@@ -0,0 +1,207 @@
+count();//获取总条数
+ $info = Codes::where($sql)->append(['extension'])->page($input['page'],$input['limit'])->order(['id'=>'desc'])->select();//查询分页数据
+ $result=[
+ 'state'=>'success',
+ 'count'=>$count,
+ 'info'=>$info
+ ];//返回数据
+ return json($result);
+ }
+ //新增|更新
+ public function save(){
+ $input=input('post.');
+ if(isset($input['id'])){
+ //验证数据
+ try {
+ empty($input['id'])?$this->validate($input,'app\validate\Code'):$this->validate($input,'app\validate\Code.update');
+ } catch (ValidateException $e) {
+ return json(['state'=>'error','info'=>$e->getError()]);
+ exit;
+ }
+
+ //处理数据
+ Db::startTrans();
+ try {
+ if(empty($input['id'])){
+ //创建数据
+ Codes::create($input);
+ pushLog('新增条码[ '.$input['name'].' ]');//日志
+ }else{
+ //更新数据
+ Codes::update($input);
+ pushLog('更新条码[ '.$input['name'].' ]');//日志
+ }
+
+ Db::commit();
+ $result=['state'=>'success'];
+ } catch (\Exception $e) {
+ Db::rollback();
+ $result=['state'=>'error','info'=>'内部错误,操作已撤销!'];
+ }
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //获取
+ public function get(){
+ $input=input('post.');
+ if(existFull($input,['id'])){
+ $result=[
+ 'state'=>'success',
+ 'info'=>Codes::where([['id','=',$input['id']]])->find()
+ ];
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //删除
+ public function del(){
+ $input=input('post.');
+ if(existFull($input,['parm']) && is_array($input['parm'])){
+ $data=Db::name('code')->where([['id','in',$input['parm']]])->order(['id'=>'desc'])->select()->toArray();
+ Db::startTrans();
+ try {
+ Db::name('code')->where([['id','in',$input['parm']]])->delete();
+ Db::name('log')->insert(['time'=>time(),'user'=>getUserID(),'info'=>'删除条码信息[ '.implode(' | ',array_column($data,'name')).' ]']);
+
+ Db::commit();
+ $result=['state'=>'success'];
+ } catch (\Exception $e) {
+ Db::rollback();
+ $result=['state'=>'error','info'=>'内部错误,操作已撤销!'];
+ }
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //导入
+ public function import(){
+ delOverdueFile('static.upload.xlsx');//删除过期文件
+ $file=request()->file('file');//获取上传文件
+ if(empty($file)){
+ $result=['state'=>'error','info'=>'传入数据不完整!'];
+ }else{
+ try{
+ validate(['file'=>['fileSize'=>2*1024*1024,'fileExt'=>'xlsx']])->check(['file'=>$file]);
+ $fileInfo = Filesystem::disk('upload')->putFile('xlsx', $file, 'uniqid');
+ $filePath = pathChange('static.upload').$fileInfo;
+ $data=getXlsx($filePath);
+ unset($data[1]);//删除标题行
+ $sql=[];//初始化SQL
+ foreach ($data as $dataKey=>$dataVo) {
+ $record=[
+ 'name'=>$dataVo['A'],
+ 'info'=>$dataVo['B'],
+ 'type'=>$dataVo['C']=="条形码"?0:1,
+ 'data'=>$dataVo['D']
+ ];
+ //数据合法性验证
+ try {
+ $this->validate($record,'app\validate\Code');
+ $sql[]=$record;//加入SQL
+ } catch (ValidateException $e) {
+ //返回错误信息
+ return json(['state'=>'error','info'=>'模板文件第[ '.$dataKey.' ]行'.$e->getError()]);
+ exit;
+ }
+ }
+ //新增数据
+ $code = new Codes;
+ $code->saveAll($sql);
+ $result=['state'=>'success','info'=>'成功导入'.count($sql).'行条码数据'];
+ }catch(ValidateException $e) {
+ $result=['state'=>'error','info'=>$e->getMessage()];//返回错误信息
+ }
+ }
+ return json($result);
+ }
+ //导出
+ public function exports(){
+ $input=input('get.');
+ if(existFull($input,['parm']) && is_array($input['parm'])){
+ $info=Codes::where([['id','in',$input['parm']]])->append(['extension'])->order(['id'=>'desc'])->select()->toArray();//查询数据
+ //生成并关联图像信息
+ foreach ($info as $infoKey=>$infoVo) {
+ if($infoVo['type']==0){
+ $info[$infoKey]['img']=[
+ 'type'=>'img',
+ 'info'=>txm($infoVo['info'],false)
+ ];
+ }else if($infoVo['type']==1){
+ $info[$infoKey]['img']=[
+ 'type'=>'img',
+ 'info'=>ewm($infoVo['info'],false)
+ ];
+ }else{
+ exit("Error");
+ }
+ }
+ $field=[
+ 'name'=>'条码名称',
+ 'info'=>'条码内容',
+ 'extension|type'=>'条码类型',
+ 'img'=>'条码图像',
+ 'data'=>'备注信息'
+ ];
+ //开始构造导出数据
+ $excel=[];//初始化导出数据
+ //标题数据
+ $excel[]=['type'=>'title','info'=>'条码信息'];
+ //表格数据
+ $thead=array_values($field);//表格标题
+ $tbody=[];//表格内容
+ //构造表内数据
+ foreach ($info as $infoVo) {
+ $rowData=[];
+ foreach (array_keys($field) as $fieldVo) {
+ $rowData[]=arraySeek($infoVo,$fieldVo);//多键名数据赋值
+ }
+ $tbody[]=$rowData;//加入行数据
+ }
+ $excel[]=['type'=>'table','info'=>['thead'=>$thead,'tbody'=>$tbody]];//表格数据
+ //统计数据
+ $excel[]=['type'=>'node','info'=>['总数:'.count($info)]];
+ //导出execl
+ pushLog('导出条码信息');//日志
+ buildExcel('条码信息',$excel);
+ }else{
+ return json(['state'=>'error','info'=>'传入数据不完整!']);
+ }
+ }
+ //图像
+ public function view(){
+ $input=input('get.');
+ if(existFull($input,['text','type']) && in_array($input['type'],['txm','ewm'])){
+ if($input['type']=='txm'){
+ //条形码
+ txm($input['text']);
+ }else if($input['type']=='ewm'){
+ //二维条
+ ewm($input['text']);
+ }else{
+ exit('error');
+ }
+ }else{
+ return json(['state'=>'error','info'=>'传入参数不完整!']);
+ }
+ }
+}
\ No newline at end of file
diff --git a/serve/app/controller/Cost.php b/serve/app/controller/Cost.php
new file mode 100644
index 0000000..045e720
--- /dev/null
+++ b/serve/app/controller/Cost.php
@@ -0,0 +1,420 @@
+'type'],'fullIn'],
+ ['iet','fullIn'],
+ ['state','fullIn']
+ ]);
+ //基础语句
+ $sql['base']=fastSql($input,[
+ [['number'=>'number'],'fullLike'],
+ [['startTime'=>'time'],'startTime'],
+ [['endTime'=>'time'],'endTime']
+ ]);
+ $sql['base'][]=['examine','=',1];
+ $sql['base'][]=['id','=',Db::raw('cost.class')];
+ $sql['base']=frameScope($sql['base']);
+ //场景匹配
+ foreach ($input['mold'] as $mold) {
+ if(in_array($mold,['buy','bre','entry'])){
+ //供应商
+ $sql[$mold]=array_merge($sql['base'],fastSql($input,[['supplier','fullEq']]));
+ }else if(in_array($mold,['sell','sre','extry'])){
+ //客户
+ $sql[$mold]=array_merge($sql['base'],fastSql($input,[['customer','fullEq']]));
+ }else{
+ //调拨单
+ $sql[$mold]=$sql['base'];
+ }
+ $sql[$mold]=sqlAuth($mold,$sql[$mold]);//数据鉴权
+ }
+ //构造查询
+ $union=[];
+ foreach ($input['mold'] as $mold) {
+ $union[]=Db::name($mold)->alias('class')->where([['cost.type','=',$mold]])->where($sql[$mold])->limit(1)->buildSql();
+ }
+ $union=implode(' UNION ALL ',$union);
+ $count=Costs::alias('cost')->where($sql['cost'])->whereExists($union)->count();
+ $info=Costs::with(['sourceData'=>['frameData'],'ietData'])->alias('cost')->where($sql['cost'])->whereExists($union)->page($input['page'],$input['limit'])->order(['id'=>'desc'])->append(['extension'])->select()->toArray();
+ //匹配往来单位
+ $currentList=['customer'=>[],'supplier'=>[]];
+ //匹配客戶
+ foreach (search($info)->where([['type','in',['sell','sre','extry']]])->select() as $item) {
+ $currentList['customer'][]=$item['sourceData']['customer'];
+ }
+ empty($currentList['customer'])||$currentList['customer']=Db::name('customer')->where([['id','in',array_unique($currentList['customer'])]])->select()->toArray();
+ //匹配供应商
+ foreach (search($info)->where([['type','in',['buy','bre','entry']]])->select() as $item) {
+ $currentList['supplier'][]=$item['sourceData']['supplier'];
+ }
+ empty($currentList['supplier'])||$currentList['supplier']=Db::name('supplier')->where([['id','in',array_unique($currentList['supplier'])]])->select()->toArray();
+ foreach ($info as $key=>$vo) {
+ //未结算金额
+ $info[$key]['uat']=math()->chain($vo['money'])->sub($vo['settle'])->done();
+ //往来单位
+ if(in_array($vo['type'],['buy','bre','entry'])){
+ $info[$key]['current']=search($currentList['supplier'])->where([['id','=',$vo['sourceData']['supplier']]])->find();
+ }else if(in_array($vo['type'],['sell','sre','extry'])){
+ $info[$key]['current']=search($currentList['customer'])->where([['id','=',$vo['sourceData']['customer']]])->find();
+ }else{
+ $info[$key]['current']=[];
+ }
+ $info[$key]['csa']='';
+ }
+ $result=[
+ 'state'=>'success',
+ 'count'=>$count,
+ 'info'=>$info
+ ];//返回数据
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //购销费用-导出
+ public function exports(){
+ $input=input('get.');
+ if(existFull($input,['parm']) && is_array($input['parm'])){
+ pushLog('导出购销费用');//日志
+ $info=Costs::with(['sourceData'=>['frameData'],'ietData'])->alias('cost')->where([['id','in',$input['parm']]])->order(['id'=>'desc'])->append(['extension'])->select()->toArray();
+ //匹配往来单位
+ $currentList=['customer'=>[],'supplier'=>[]];
+ //匹配客戶
+ foreach (search($info)->where([['type','in',['sell','sre','extry']]])->select() as $item) {
+ $currentList['customer'][]=$item['sourceData']['customer'];
+ }
+ empty($currentList['customer'])||$currentList['customer']=Db::name('customer')->where([['id','in',array_unique($currentList['customer'])]])->select()->toArray();
+ //匹配供应商
+ foreach (search($info)->where([['type','in',['buy','bre','entry']]])->select() as $item) {
+ $currentList['supplier'][]=$item['sourceData']['supplier'];
+ }
+ empty($currentList['supplier'])||$currentList['supplier']=Db::name('supplier')->where([['id','in',array_unique($currentList['supplier'])]])->select()->toArray();
+ foreach ($info as $key=>$vo) {
+ //未结算金额
+ $info[$key]['uat']=math()->chain($vo['money'])->sub($vo['settle'])->done();
+ //往来单位
+ if(in_array($vo['type'],['buy','bre','entry'])){
+ $info[$key]['current']=search($currentList['supplier'])->where([['id','=',$vo['sourceData']['supplier']]])->find();
+ }else if(in_array($vo['type'],['sell','sre','extry'])){
+ $info[$key]['current']=search($currentList['customer'])->where([['id','=',$vo['sourceData']['customer']]])->find();
+ }else{
+ $info[$key]['current']=[];
+ }
+ }
+ $source=$info;
+ //开始构造导出数据
+ $excel=[];//初始化导出数据
+ //标题数据
+ $excel[]=['type'=>'title','info'=>'购销费用'];
+ //表格数据
+ $field=[
+ 'extension|type'=>'单据类型',
+ 'sourceData|frameData|name'=>'所属组织',
+ 'current|name'=>'往来单位',
+ 'sourceData|time'=>'单据时间',
+ 'sourceData|number'=>'单据编号',
+ 'ietData|name'=>'支出类别',
+ 'extension|state'=>'结算状态',
+ 'money'=>'金额',
+ 'settle'=>'已结算金额',
+ 'uat'=>'未结算金额'
+ ];
+ $thead=array_values($field);//表格标题
+ $tbody=[];//表格内容
+ //构造表内数据
+ foreach ($source as $sourceVo) {
+ $rowData=[];
+ foreach (array_keys($field) as $fieldVo) {
+ $rowData[]=arraySeek($sourceVo,$fieldVo);//多键名数据赋值
+ }
+ $tbody[]=$rowData;//加入行数据
+ }
+ $excel[]=['type'=>'table','info'=>['thead'=>$thead,'tbody'=>$tbody]];//表格数据
+ $excel[]=['type'=>'node','info'=>[
+ '总数:'.count($source),
+ '单据总金额:'.mathArraySum(array_column($source,'money')),
+ '已结算总金额:'.mathArraySum(array_column($source,'settle')),
+ '未结算总金额:'.mathArraySum(array_column($source,'uat'))
+ ]];
+ //导出execl
+ buildExcel('购销费用',$excel);
+ }else{
+ return json(['state'=>'error','info'=>'传入参数不完整!']);
+ }
+ }
+ //生成其它支出单
+ public function buildOce(){
+ $input=input('post.');
+ if(existFull($input,['parm']) && is_array($input['parm'])){
+ //源数据
+ $list=Costs::with(['ietData'])->where([['id','in',array_column($input['parm'],'id')],['state','<>',2]])->order(['id'=>'asc'])->select()->toArray();
+ if(empty($list)){
+ $result=['state'=>'warning','info'=>'操作失败,无可结算数据!'];
+ }else{
+ //CLASS数据
+ $class=[
+ 'total'=>0
+ ];
+ //INFO数据
+ $info=[];
+ foreach ($list as $vo) {
+ $find=search($input['parm'])->where([['id','=',$vo['id']]])->find();
+ //判断结算金额
+ if(bccomp($find['csa'],math()->chain($vo['money'])->sub($vo['settle'])->done())==1){
+ $item=Costs::with(['sourceData'])->where([['id','=',$vo['id']]])->find();
+ return json(['state'=>'warning','info'=>'单据编号[ '.$item['sourceData']['number'].' ]结算金额不可大于未结算金额!']);
+ exit;
+ }else{
+ //转存数据
+ $info[]=[
+ 'source'=>$vo['id'],
+ 'iet'=>$vo['iet'],
+ 'ietData'=>$vo['ietData'],
+ 'money'=>$find['csa'],
+ 'data'=>''
+ ];
+ $class['total']=math()->chain($class['total'])->add($find['csa'])->done();//累加单据金额
+ }
+ }
+ $result=['state'=>'success','info'=>['class'=>$class,'info'=>$info]];
+ }
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+
+ //报表数据
+ public function form(){
+ $input=input('post.');
+ $sheet=['buy','bre','sell','sre','entry','extry'];
+ existFull($input,['state'])||$input['state']=[1,2];
+ existFull($input,['mold'])||$input['mold']=$sheet;
+ if(existFull($input,['page','limit']) && is_arrays($input,['iet','state','mold']) && arrayInArray($input['state'],[1,2]) && arrayInArray($input['mold'],$sheet)){
+ $sql=[];
+ //查询语句
+ $sql['cost']=fastSql($input,[
+ [['mold'=>'type'],'fullIn'],
+ ['iet','fullIn'],
+ ['state','fullIn']
+ ]);
+ //基础语句
+ $sql['base']=fastSql($input,[
+ [['number'=>'number'],'fullLike'],
+ [['startTime'=>'time'],'startTime'],
+ [['endTime'=>'time'],'endTime']
+ ]);
+ $sql['base'][]=['examine','=',1];
+ $sql['base'][]=['id','=',Db::raw('cost.class')];
+ $sql['base']=frameScope($sql['base']);
+ //场景匹配
+ foreach ($input['mold'] as $mold) {
+ if(in_array($mold,['buy','bre','entry'])){
+ $sql[$mold]=array_merge($sql['base'],fastSql($input,[['supplier','fullEq']]));
+ }else{
+ $sql[$mold]=array_merge($sql['base'],fastSql($input,[['customer','fullEq']]));
+ }
+ $sql[$mold]=sqlAuth($mold,$sql[$mold]);//数据鉴权
+ }
+ //构造查询
+ $union=[];
+ foreach ($input['mold'] as $mold) {
+ $union[]=Db::name($mold)->alias('class')->where([['cost.type','=',$mold]])->where($sql[$mold])->limit(1)->buildSql();
+ }
+ $union=implode(' UNION ALL ',$union);
+ $count=Costs::alias('cost')->where($sql['cost'])->whereExists($union)->count();
+ $info=Costs::with(['sourceData'=>['frameData'],'ietData'])->alias('cost')->where($sql['cost'])->whereExists($union)->page($input['page'],$input['limit'])->order(['id'=>'desc'])->append(['extension'])->select()->toArray();
+ //匹配往来单位
+ $currentList=['customer'=>[],'supplier'=>[]];
+ //匹配客戶
+ foreach (search($info)->where([['type','in',['sell','sre','extry']]])->select() as $item) {
+ $currentList['customer'][]=$item['sourceData']['customer'];
+ }
+ empty($currentList['customer'])||$currentList['customer']=Db::name('customer')->where([['id','in',array_unique($currentList['customer'])]])->select()->toArray();
+ //匹配供应商
+ foreach (search($info)->where([['type','in',['buy','bre','entry']]])->select() as $item) {
+ $currentList['supplier'][]=$item['sourceData']['supplier'];
+ }
+ empty($currentList['supplier'])||$currentList['supplier']=Db::name('supplier')->where([['id','in',array_unique($currentList['supplier'])]])->select()->toArray();
+ //查询子节点
+ if(!empty($info)){
+ $gather=CostInfo::with(['oceData'=>['frameData','supplierData']])->where([['pid','in',array_column($info,'id')]])->select()->toArray();
+ }
+ foreach ($info as $key=>$vo) {
+ $info[$key]['key']=$vo['id'];
+ //往来单位
+ if(in_array($vo['type'],['buy','bre','entry'])){
+ $info[$key]['current']=search($currentList['supplier'])->where([['id','=',$vo['sourceData']['supplier']]])->find();
+ }else if(in_array($vo['type'],['sell','sre','extry'])){
+ $info[$key]['current']=search($currentList['customer'])->where([['id','=',$vo['sourceData']['customer']]])->find();
+ }else{
+ $info[$key]['current']=[];
+ }
+ $node=[];
+ $costInfo=search($gather)->where([['pid','=',$vo['id']]])->select();
+ foreach($costInfo as $costInfoVo){
+ $node[]=[
+ 'key'=>$costInfoVo['pid'].'_'.$costInfoVo['id'],
+ 'extension'=>['type'=>'其它支出单','state'=>'-'],
+ 'sourceData'=>$costInfoVo['oceData'],
+ 'current'=>empty($costInfoVo['oceData']['supplier'])?['name'=>'']:$costInfoVo['oceData']['supplierData'],
+ 'ietData'=>['name'=>'-'],
+ 'money'=>$costInfoVo['money']
+ ];
+ }
+ //匹配子节点
+ $info[$key]['node']=$node;
+ }
+ $result=[
+ 'state'=>'success',
+ 'count'=>$count,
+ 'info'=>$info
+ ];//返回数据
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //购销费用报表-导出
+ public function formExports(){
+ $input=input('get.');
+ $sheet=['buy','bre','sell','sre','entry','extry'];
+ existFull($input,['iet'])||$input['iet']=[];
+ existFull($input,['state'])||$input['state']=[1,2];
+ existFull($input,['mold'])||$input['mold']=$sheet;
+ if(is_arrays($input,['iet','state','mold']) && arrayInArray($input['state'],[1,2]) && arrayInArray($input['mold'],$sheet)){
+ pushLog('导出购销费用报表');//日志
+ $sql=[];
+ //查询语句
+ $sql['cost']=fastSql($input,[
+ [['mold'=>'type'],'fullIn'],
+ ['iet','fullIn'],
+ ['state','fullIn']
+ ]);
+ //基础语句
+ $sql['base']=fastSql($input,[
+ [['number'=>'number'],'fullLike'],
+ [['startTime'=>'time'],'startTime'],
+ [['endTime'=>'time'],'endTime']
+ ]);
+ $sql['base'][]=['examine','=',1];
+ $sql['base'][]=['id','=',Db::raw('cost.class')];
+ $sql['base']=frameScope($sql['base']);
+ //场景匹配
+ foreach ($input['mold'] as $mold) {
+ if(in_array($mold,['buy','bre','entry'])){
+ $sql[$mold]=array_merge($sql['base'],fastSql($input,[['supplier','fullEq']]));
+ }else{
+ $sql[$mold]=array_merge($sql['base'],fastSql($input,[['customer','fullEq']]));
+ }
+ $sql[$mold]=sqlAuth($mold,$sql[$mold]);//数据鉴权
+ }
+ //构造查询
+ $union=[];
+ foreach ($input['mold'] as $mold) {
+ $union[]=Db::name($mold)->alias('class')->where([['cost.type','=',$mold]])->where($sql[$mold])->limit(1)->buildSql();
+ }
+ $union=implode(' UNION ALL ',$union);
+ $info=Costs::with(['sourceData'=>['frameData'],'ietData'])->alias('cost')->where($sql['cost'])->whereExists($union)->order(['id'=>'desc'])->append(['extension'])->select()->toArray();
+ //匹配往来单位
+ $currentList=['customer'=>[],'supplier'=>[]];
+ //匹配客戶
+ foreach (search($info)->where([['type','in',['sell','sre','extry']]])->select() as $item) {
+ $currentList['customer'][]=$item['sourceData']['customer'];
+ }
+ empty($currentList['customer'])||$currentList['customer']=Db::name('customer')->where([['id','in',array_unique($currentList['customer'])]])->select()->toArray();
+ //匹配供应商
+ foreach (search($info)->where([['type','in',['buy','bre','entry']]])->select() as $item) {
+ $currentList['supplier'][]=$item['sourceData']['supplier'];
+ }
+ empty($currentList['supplier'])||$currentList['supplier']=Db::name('supplier')->where([['id','in',array_unique($currentList['supplier'])]])->select()->toArray();
+ //查询子节点
+ if(!empty($info)){
+ $gather=CostInfo::with(['oceData'=>['frameData','supplierData']])->where([['pid','in',array_column($info,'id')]])->select()->toArray();
+ }
+ foreach ($info as $key=>$vo) {
+ $info[$key]['key']=$vo['id'];
+ //往来单位
+ if(in_array($vo['type'],['buy','bre','entry'])){
+ $info[$key]['current']=search($currentList['supplier'])->where([['id','=',$vo['sourceData']['supplier']]])->find();
+ }else if(in_array($vo['type'],['sell','sre','extry'])){
+ $info[$key]['current']=search($currentList['customer'])->where([['id','=',$vo['sourceData']['customer']]])->find();
+ }else{
+ $info[$key]['current']=[];
+ }
+ $node=[];
+ $costInfo=search($gather)->where([['pid','=',$vo['id']]])->select();
+ foreach($costInfo as $costInfoVo){
+ $node[]=[
+ 'key'=>$costInfoVo['pid'].'_'.$costInfoVo['id'],
+ 'extension'=>['type'=>'其它支出单','state'=>'-'],
+ 'sourceData'=>$costInfoVo['oceData'],
+ 'current'=>empty($costInfoVo['oceData']['supplier'])?['name'=>'']:$costInfoVo['oceData']['supplierData'],
+ 'ietData'=>['name'=>'-'],
+ 'money'=>$costInfoVo['money']
+ ];
+ }
+ //匹配子节点
+ $info[$key]['node']=$node;
+ }
+ //结构重组
+ $source=[];
+ foreach ($info as $infoVo) {
+ $source[]=$infoVo;
+ if(!empty($infoVo['node'])){
+ foreach ($infoVo['node'] as $nodeVo) {
+ $nodeVo['extension']['type']='|- '.$nodeVo['extension']['type'];
+ $source[]=$nodeVo;
+ }
+ }
+ }
+ //开始构造导出数据
+ $excel=[];//初始化导出数据
+ //标题数据
+ $excel[]=['type'=>'title','info'=>'购销费用报表'];
+ //表格数据
+ $field=[
+ 'extension|type'=>'单据类型',
+ 'sourceData|frameData|name'=>'所属组织',
+ 'current|name'=>'往来单位',
+ 'sourceData|time'=>'单据时间',
+ 'sourceData|number'=>'单据编号',
+ 'ietData|name'=>'支出类别',
+ 'extension|state'=>'结算状态',
+ 'money'=>'金额'
+ ];
+ $thead=array_values($field);//表格标题
+ $tbody=[];//表格内容
+ //构造表内数据
+ foreach ($source as $sourceVo) {
+ $rowData=[];
+ foreach (array_keys($field) as $fieldVo) {
+ $rowData[]=arraySeek($sourceVo,$fieldVo);//多键名数据赋值
+ }
+ $tbody[]=$rowData;//加入行数据
+ }
+ $excel[]=['type'=>'table','info'=>['thead'=>$thead,'tbody'=>$tbody]];//表格数据
+ $excel[]=['type'=>'node','info'=>[
+ '总数:'.count($source)
+ ]];
+ //导出execl
+ buildExcel('购销费用报表',$excel);
+ }else{
+ return json(['state'=>'error','info'=>'传入参数不完整!']);
+ }
+ }
+}
diff --git a/serve/app/controller/Crt.php b/serve/app/controller/Crt.php
new file mode 100644
index 0000000..d8fb9bd
--- /dev/null
+++ b/serve/app/controller/Crt.php
@@ -0,0 +1,1869 @@
+'id'],'fullEq'],
+ ]);
+ $sql=frameScope($sql);//组织数据
+ $sql=sqlAuth('account',$sql);//数据鉴权
+ //数据查询
+ $count=Db::name('account')->where($sql)->count();
+ $data=Db::name('account')->where($sql)->page($input['page'],$input['limit'])->order(['id'=>'desc'])->select()->toArray();
+ //子查询
+ $existsSql=fastSql($input,[
+ [['startTime'=>'time'],'startTime'],
+ [['endTime'=>'time'],'endTime'],
+ ['user','fullEq']
+ ]);
+ $existsSql[]=['id','=',Db::raw('info.class')];
+ $existsSql=frameScope($existsSql);
+ //多源匹配
+ $union=[];
+ $where=[['pid','in',array_column($data,'id')]];
+ //数据关系表
+ $table=['buy'=>'buy','bre'=>'bre','sell'=>'sell','sre'=>'sre','imy'=>'imy','omy'=>'omy','allotOut'=>'allot','allotEnter'=>'allot','ice'=>'ice','oce'=>'oce'];
+ foreach ($table as $k=>$v) {
+ $unionSql=array_merge([['info.type','=',$k]],$existsSql);
+ if(existFull($input,['supplier','customer'])){
+ //供应商-客户
+ if(!in_array($v,['allot'])){
+ in_array($v,['buy','bre','omy','oce'])&&$unionSql=array_merge($unionSql,fastSql($input,[['supplier','fullEq']]));
+ in_array($v,['sell','sre','imy','ice'])&&$unionSql=array_merge($unionSql,fastSql($input,[['customer','fullEq']]));
+ $unionSql=sqlAuth($v,$unionSql);
+ $union[]=Db::name($v)->where($unionSql)->limit(1)->buildSql();
+ }
+ count($where)==1&&$where[]=['type','in',['buy','bre','omy','oce','sell','sre','imy','ice']];
+ }else{
+ if(existFull($input,['supplier'])){
+ //供应商
+ if(in_array($v,['buy','bre','omy','oce'])){
+ $unionSql=array_merge($unionSql,fastSql($input,[['supplier','fullEq']]));
+ $unionSql=sqlAuth($v,$unionSql);
+ $union[]=Db::name($v)->where($unionSql)->limit(1)->buildSql();
+ }
+ count($where)==1&&$where[]=['type','in',['buy','bre','omy','oce']];
+ }elseif(existFull($input,['customer'])){
+ //客户
+ if(in_array($v,['sell','sre','imy','ice'])){
+ $unionSql=array_merge($unionSql,fastSql($input,[['customer','fullEq']]));
+ $unionSql=sqlAuth($v,$unionSql);
+ $union[]=Db::name($v)->where($unionSql)->limit(1)->buildSql();
+ }
+ count($where)==1&&$where[]=['type','in',['sell','sre','imy','ice']];
+ }else{
+ //空
+ $unionSql=sqlAuth($v,$unionSql);
+ $union[]=Db::name($v)->where($unionSql)->limit(1)->buildSql();
+ }
+ }
+ }
+ //合并子查询
+ $union=implode(' UNION ALL ',$union);
+ $infoList=AccountInfo::with(['sourceData'=>['frameData','userData']])->alias('info')->where($where)->whereExists($union)->append(['extension'])->order('time asc')->select()->toArray();
+ //匹配往来单位
+ $currentList=['customer'=>[],'supplier'=>[]];
+ //匹配客戶
+ foreach (search($infoList)->where([['type','in',['sell','sre','imy','ice']]])->select() as $item) {
+ $currentList['customer'][]=$item['sourceData']['customer'];
+ }
+ empty($currentList['customer'])||$currentList['customer']=Db::name('customer')->where([['id','in',array_unique($currentList['customer'])]])->select()->toArray();
+ //匹配供应商
+ foreach (search($infoList)->where([['type','in',['buy','bre','omy','oce']]])->select() as $item) {
+ $currentList['supplier'][]=$item['sourceData']['supplier'];
+ }
+ empty($currentList['supplier'])||$currentList['supplier']=Db::name('supplier')->where([['id','in',array_unique($currentList['supplier'])]])->select()->toArray();
+ //匹配节点
+ foreach($data as $key => $vo){
+ $data[$key]['key'] = $vo['id'];
+ $data[$key]['number'] = '';
+ $data[$key]['time'] = '';
+ $node = search($infoList)->where([['pid', '=', $vo['id']]])->select();
+ //计算期初
+ $stats=Db::name('account_info')->where([['pid','=',$vo['id']],['time','<',existFull($input,['startTime'])?strtotime($input['startTime']):0]])->group('direction')->fieldRaw('direction,sum(money) as money')->order('direction desc')->select()->toArray();
+ if(empty($stats)){
+ $balance=floatval($vo['initial']);
+ }else if(count($stats)==1){
+ if(empty($stats[0]['direction'])){
+ //纯出
+ $balance=math()->chain($stats[0]['money'])->mul(-1)->add($vo['initial'])->done();
+ }else{
+ //纯入
+ $balance=math()->chain($stats[0]['money'])->add($vo['initial'])->done();
+ }
+ }else{
+ $balance=math()->chain($stats[0]['money'])->sub($stats[1]['money'])->add($vo['initial'])->done();
+ }
+ //赋值期初
+ array_unshift($node,['key'=>$vo['id'].'_'.'0','extension'=>['type'=>'期初余额'],'balance'=>$balance]);
+ //节点赋值
+ foreach($node as $nodeKey => $nodeVo){
+ //排除期初
+ if(!empty($nodeKey)){
+ $node[$nodeKey]['key'] = $nodeVo['pid']."_".$nodeVo['id'];
+ //类型判断
+ if(empty($nodeVo['direction'])){
+ $node[$nodeKey]['in'] = 0;
+ $node[$nodeKey]['out'] = $nodeVo['money'];
+ $node[$nodeKey]['balance'] = math()->chain($node[$nodeKey-1]['balance'])->sub($nodeVo['money'])->done();
+ }else{
+ $node[$nodeKey]['in'] = $nodeVo['money'];
+ $node[$nodeKey]['out'] = 0;
+ $node[$nodeKey]['balance'] = math()->chain($node[$nodeKey-1]['balance'])->add($nodeVo['money'])->done();
+ }
+ //往来单位
+ if(in_array($nodeVo['type'],['buy','bre','omy','oce'])){
+ $node[$nodeKey]['current']=search($currentList['supplier'])->where([['id','=',$nodeVo['sourceData']['supplier']]])->find();
+ }else if(in_array($nodeVo['type'],['sell','sre','imy','ice'])){
+ $node[$nodeKey]['current']=search($currentList['customer'])->where([['id','=',$nodeVo['sourceData']['customer']]])->find();
+ }else{
+ $node[$nodeKey]['current']=[];
+ }
+ }
+ }
+ //汇总数据
+ $data[$key]['in']=mathArraySum(array_column($node,'in'));
+ $data[$key]['out']=mathArraySum(array_column($node,'out'));
+ $data[$key]['balance']=$node[count($node)-1]['balance'];
+ $data[$key]['node'] = $node;
+ }
+ $result=[
+ 'state'=>'success',
+ 'count'=>$count,
+ 'info'=>$data
+ ];//返回数据
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //现金银行报表-导出
+ public function cbfExports(){
+ $input=input('get.');
+ $sql=[];
+ //CLASS语句
+ $sql=fastSql($input,[
+ [['account'=>'id'],'fullEq'],
+ ]);
+ $sql=frameScope($sql);//组织数据
+ $sql=sqlAuth('account',$sql);//数据鉴权
+ //数据查询
+ $data=Db::name('account')->where($sql)->order(['id'=>'desc'])->select()->toArray();
+ //子查询
+ $existsSql=fastSql($input,[
+ [['startTime'=>'time'],'startTime'],
+ [['endTime'=>'time'],'endTime'],
+ ['user','fullEq']
+ ]);
+ $existsSql[]=['id','=',Db::raw('info.class')];
+ $existsSql=frameScope($existsSql);
+ //多源匹配
+ $union=[];
+ $where=[['pid','in',array_column($data,'id')]];
+ //数据关系表
+ $table=['buy'=>'buy','bre'=>'bre','sell'=>'sell','sre'=>'sre','imy'=>'imy','omy'=>'omy','allotOut'=>'allot','allotEnter'=>'allot','ice'=>'ice','oce'=>'oce'];
+ foreach ($table as $k=>$v) {
+ $unionSql=array_merge([['info.type','=',$k]],$existsSql);
+ if(existFull($input,['supplier','customer'])){
+ //供应商-客户
+ if(!in_array($v,['allot'])){
+ in_array($v,['buy','bre','omy','oce'])&&$unionSql=array_merge($unionSql,fastSql($input,[['supplier','fullEq']]));
+ in_array($v,['sell','sre','imy','ice'])&&$unionSql=array_merge($unionSql,fastSql($input,[['customer','fullEq']]));
+ $unionSql=sqlAuth($v,$unionSql);
+ $union[]=Db::name($v)->where($unionSql)->limit(1)->buildSql();
+ }
+ count($where)==1&&$where[]=['type','in',['buy','bre','omy','oce','sell','sre','imy','ice']];
+ }else{
+ if(existFull($input,['supplier'])){
+ //供应商
+ if(in_array($v,['buy','bre','omy','oce'])){
+ $unionSql=array_merge($unionSql,fastSql($input,[['supplier','fullEq']]));
+ $unionSql=sqlAuth($v,$unionSql);
+ $union[]=Db::name($v)->where($unionSql)->limit(1)->buildSql();
+ }
+ count($where)==1&&$where[]=['type','in',['buy','bre','omy','oce']];
+ }elseif(existFull($input,['customer'])){
+ //客户
+ if(in_array($v,['sell','sre','imy','ice'])){
+ $unionSql=array_merge($unionSql,fastSql($input,[['customer','fullEq']]));
+ $unionSql=sqlAuth($v,$unionSql);
+ $union[]=Db::name($v)->where($unionSql)->limit(1)->buildSql();
+ }
+ count($where)==1&&$where[]=['type','in',['sell','sre','imy','ice']];
+ }else{
+ //空
+ $unionSql=sqlAuth($v,$unionSql);
+ $union[]=Db::name($v)->where($unionSql)->limit(1)->buildSql();
+ }
+ }
+ }
+ //合并子查询
+ $union=implode(' UNION ALL ',$union);
+ $infoList=AccountInfo::with(['sourceData'=>['frameData','userData']])->alias('info')->where($where)->whereExists($union)->append(['extension'])->order('time asc')->select()->toArray();
+ //匹配往来单位
+ $currentList=['customer'=>[],'supplier'=>[]];
+ //匹配客戶
+ foreach (search($infoList)->where([['type','in',['sell','sre','imy','ice']]])->select() as $item) {
+ $currentList['customer'][]=$item['sourceData']['customer'];
+ }
+ empty($currentList['customer'])||$currentList['customer']=Db::name('customer')->where([['id','in',array_unique($currentList['customer'])]])->select()->toArray();
+ //匹配供应商
+ foreach (search($infoList)->where([['type','in',['buy','bre','omy','oce']]])->select() as $item) {
+ $currentList['supplier'][]=$item['sourceData']['supplier'];
+ }
+ empty($currentList['supplier'])||$currentList['supplier']=Db::name('supplier')->where([['id','in',array_unique($currentList['supplier'])]])->select()->toArray();
+ //匹配节点
+ foreach($data as $key => $vo){
+ $data[$key]['key'] = $vo['id'];
+ $data[$key]['number'] = '';
+ $data[$key]['time'] = '';
+ $node = search($infoList)->where([['pid', '=', $vo['id']]])->select();
+ //计算期初
+ $stats=Db::name('account_info')->where([['pid','=',$vo['id']],['time','<',existFull($input,['startTime'])?strtotime($input['startTime']):0]])->group('direction')->fieldRaw('direction,sum(money) as money')->order('direction desc')->select()->toArray();
+ if(empty($stats)){
+ $balance=floatval($vo['initial']);
+ }else if(count($stats)==1){
+ if(empty($stats[0]['direction'])){
+ //纯出
+ $balance=math()->chain($stats[0]['money'])->mul(-1)->add($vo['initial'])->done();
+ }else{
+ //纯入
+ $balance=math()->chain($stats[0]['money'])->add($vo['initial'])->done();
+ }
+ }else{
+ $balance=math()->chain($stats[0]['money'])->sub($stats[1]['money'])->add($vo['initial'])->done();
+ }
+ //赋值期初
+ array_unshift($node,['key'=>$vo['id'].'_'.'0','extension'=>['type'=>'期初余额'],'balance'=>$balance]);
+ //节点赋值
+ foreach($node as $nodeKey => $nodeVo){
+ //排除期初
+ if(!empty($nodeKey)){
+ $node[$nodeKey]['key'] = $nodeVo['pid']."_".$nodeVo['id'];
+ //类型判断
+ if(empty($nodeVo['direction'])){
+ $node[$nodeKey]['in'] = 0;
+ $node[$nodeKey]['out'] = $nodeVo['money'];
+ $node[$nodeKey]['balance'] = math()->chain($node[$nodeKey-1]['balance'])->sub($nodeVo['money'])->done();
+ }else{
+ $node[$nodeKey]['in'] = $nodeVo['money'];
+ $node[$nodeKey]['out'] = 0;
+ $node[$nodeKey]['balance'] = math()->chain($node[$nodeKey-1]['balance'])->add($nodeVo['money'])->done();
+ }
+ //往来单位
+ if(in_array($nodeVo['type'],['buy','bre','omy','oce'])){
+ $node[$nodeKey]['current']=search($currentList['supplier'])->where([['id','=',$nodeVo['sourceData']['supplier']]])->find();
+ }else if(in_array($nodeVo['type'],['sell','sre','imy','ice'])){
+ $node[$nodeKey]['current']=search($currentList['customer'])->where([['id','=',$nodeVo['sourceData']['customer']]])->find();
+ }else{
+ $node[$nodeKey]['current']=[];
+ }
+ }
+ }
+ //汇总数据
+ $data[$key]['in']=mathArraySum(array_column($node,'in'));
+ $data[$key]['out']=mathArraySum(array_column($node,'out'));
+ $data[$key]['balance']=$node[count($node)-1]['balance'];
+ $data[$key]['node'] = $node;
+ }
+ $source=[];
+ foreach ($data as $dataVo) {
+ $source[]=$dataVo;
+ if(!empty($dataVo['node'])){
+ foreach ($dataVo['node'] as $node) {
+ $source[]=$node;
+ }
+ }
+ }
+ //开始构造导出数据
+ $excel=[];//初始化导出数据
+ //标题数据
+ $excel[]=['type'=>'title','info'=>'现金银行报表'];
+ //表格数据
+ $field=[
+ 'name'=>'账户名称',
+ 'extension|type'=>'单据类型',
+ 'sourceData|frameData|name'=>'所属组织',
+ 'current|name'=>'往来单位',
+ 'sourceData|time'=>'单据时间',
+ 'sourceData|number'=>'单据编号',
+ 'in'=>'收入',
+ 'out'=>'支出',
+ 'balance'=>'账户余额',
+ 'sourceData|userData|name'=>'制单人',
+ 'sourceData|data'=>'备注',
+ ];
+ $thead=array_values($field);//表格标题
+ $tbody=[];//表格内容
+ //构造表内数据
+ foreach ($source as $sourceVo) {
+ $rowData=[];
+ foreach (array_keys($field) as $fieldVo) {
+ $rowData[]=arraySeek($sourceVo,$fieldVo);//多键名数据赋值
+ }
+ $tbody[]=$rowData;//加入行数据
+ }
+ $excel[]=['type'=>'table','info'=>['thead'=>$thead,'tbody'=>$tbody]];//表格数据
+ //汇总数据
+ $excel[]=['type'=>'node','info'=>[
+ '总数:'.count($source),
+ ]];
+ //导出execl
+ buildExcel('现金银行报表',$excel);
+ }
+ //应收账款明细表
+ public function crs(){
+ $input=input('post.');
+ if(existFull($input,['page','limit']) && isset($input['type'])){
+ $sql=[];
+ //CLASS语句
+ $sql=fastSql($input,[
+ [['customer'=>'id'],'fullEq'],
+ ]);
+ //查询类型
+ empty($input['type'])||$sql[]=['balance','>',0];
+ $sql=frameScope($sql);//组织数据
+ $sql=sqlAuth('customer',$sql);//数据鉴权
+ //数据查询
+ $count=Db::name('customer')->where($sql)->count();
+ $data=Db::name('customer')->where($sql)->page($input['page'],$input['limit'])->order(['id'=>'desc'])->select()->toArray();
+ //子查询
+ $existsSql=fastSql($input,[
+ [['startTime'=>'time'],'startTime'],
+ [['endTime'=>'time'],'endTime']
+ ]);
+ $existsSql[]=['examine','=',1];
+ $existsSql[]=['customer','in',array_column($data,'id')];
+ $existsSql=frameScope($existsSql);
+ //构造语句
+ $union=[];
+ $tab=['sell','sre','imy','ice'];
+ foreach ($tab as $t) {
+ $union[]=Db::name($t)->where(sqlAuth($t,$existsSql))->fieldRaw('"'.$t.'" as mold,id')->buildSql();
+ }
+ $union=implode(' UNION ALL ',$union);
+ $record=DB::query('SELECT * FROM ('.$union.') as nodcloud');
+ //匹配单据
+ $bill=[];
+ foreach ($tab as $t) {
+ $gather=search($record)->where([['mold','=',$t]])->select();
+ $db="app\\model\\".ucfirst($t);
+ $bill=array_merge($bill,$db::with(['frameData'])->fieldRaw('*,"'.$t.'" as mold,time as t')->where([['id','in',array_column($gather,'id')]])->append(['extension'])->select()->toArray());
+ }
+ //匹配数据
+ foreach ($data as $key=>$vo) {
+ $data[$key]['key']=$vo['id'];
+ $data[$key]['cw']=0;
+ $data[$key]['pia']=0;
+ $data[$key]['balance']=0;
+ $node=search($bill)->where([['customer','=',$vo['id']]])->select();
+ arraySort($node,'t',SORT_ASC);
+ //期初查询
+ $nodeUnion=[];
+ $nodeUnionSql=[
+ ['examine','=',1],
+ ['customer','=',$vo['id']],
+ ['time','<',existFull($input,['startTime'])?strtotime($input['startTime']):0]
+ ];
+ $nodeUnionSql=frameScope($nodeUnionSql);
+
+ $nodeUnion=implode(' UNION ALL ',$nodeUnion);
+ $stats=DB::query('SELECT * FROM ('.$nodeUnion.') as nodcloud');
+ $calc=[];
+
+ $balance=math()->chain($calc['sell'])->sub($calc['sre'])->sub($calc['imy'])->add($calc['ice'])->done();
+ array_unshift($node,['key'=>$vo['id'].'_'.'0','bill'=>'期初余额','balance'=>$balance]);
+ foreach ($node as $nodeKey=>$nodeVo) {
+ //跳过期初
+ if(!empty($nodeKey)){
+ $node[$nodeKey]['key']=$vo['id'].'_'.$nodeVo['id'].'_'.$nodeVo['mold'];
+ $node[$nodeKey]['bill']=['sell'=>'销售单','sre'=>'销售退货单','imy'=>'收款单','ice'=>'其它收入单'][$nodeVo['mold']];
+ if($nodeVo['mold']=='sell'){
+ $node[$nodeKey]['cw']=math()->chain($nodeVo['actual'])->sub($nodeVo['money'])->done();
+ $node[$nodeKey]['pia']=0;
+ }else if($nodeVo['mold']=='sre'){
+ $node[$nodeKey]['cw']=math()->chain($nodeVo['actual'])->sub($nodeVo['money'])->mul(-1)->done();
+ $node[$nodeKey]['pia']=0;
+ }else if($nodeVo['mold']=='imy'){
+ $node[$nodeKey]['cw']=0;
+ $node[$nodeKey]['pia']=$nodeVo['total'];
+ }else if($nodeVo['mold']=='ice'){
+ $node[$nodeKey]['cw']=math()->chain($nodeVo['actual'])->sub($nodeVo['money'])->done();
+ $node[$nodeKey]['pia']=0;
+ }
+ $node[$nodeKey]['balance'] = math()->chain($node[$nodeKey-1]['balance'])->add($node[$nodeKey]['cw'])->sub($node[$nodeKey]['pia'])->done();
+ }
+ }
+ $data[$key]['cw']=mathArraySum(array_column($node,'cw'));
+ $data[$key]['pia']=mathArraySum(array_column($node,'pia'));
+ $data[$key]['balance']=$node[count($node)-1]['balance'];
+ $data[$key]['node']=$node;
+ }
+ $result=[
+ 'state'=>'success',
+ 'count'=>$count,
+ 'info'=>$data
+ ];//返回数据
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //应收账款明细表-导出
+ public function crsExports(){
+ $input=input('get.');
+ if(isset($input['type'])){
+ $sql=[];
+ //CLASS语句
+ $sql=fastSql($input,[
+ [['customer'=>'id'],'fullEq'],
+ ]);
+ //查询类型
+ empty($input['type'])||$sql[]=['balance','>',0];
+ $sql=frameScope($sql);//组织数据
+ $sql=sqlAuth('customer',$sql);//数据鉴权
+ //数据查询
+ $count=Db::name('customer')->where($sql)->count();
+ $data=Db::name('customer')->where($sql)->order(['id'=>'desc'])->select()->toArray();
+ //子查询
+ $existsSql=fastSql($input,[
+ [['startTime'=>'time'],'startTime'],
+ [['endTime'=>'time'],'endTime']
+ ]);
+ $existsSql[]=['examine','=',1];
+ $existsSql[]=['customer','in',array_column($data,'id')];
+ $existsSql=frameScope($existsSql);
+ //构造语句
+ $union=[];
+ $tab=['sell','sre','imy','ice'];
+ foreach ($tab as $t) {
+ $union[]=Db::name($t)->where(sqlAuth($t,$existsSql))->fieldRaw('"'.$t.'" as mold,id')->buildSql();
+ }
+ $union=implode(' UNION ALL ',$union);
+ $record=DB::query('SELECT * FROM ('.$union.') as nodcloud');
+ //匹配单据
+ $bill=[];
+ foreach ($tab as $t) {
+ $gather=search($record)->where([['mold','=',$t]])->select();
+ $db="app\\model\\".ucfirst($t);
+ $bill=array_merge($bill,$db::with(['frameData'])->fieldRaw('*,"'.$t.'" as mold,time as t')->where([['id','in',array_column($gather,'id')]])->append(['extension'])->select()->toArray());
+ }
+ //匹配数据
+ foreach ($data as $key=>$vo) {
+ $data[$key]['cw']=0;
+ $data[$key]['pia']=0;
+ $data[$key]['balance']=0;
+ $node=search($bill)->where([['customer','=',$vo['id']]])->select();
+ arraySort($node,'t',SORT_ASC);
+ //期初查询
+ $nodeUnion=[];
+ $nodeUnionSql=[
+ ['examine','=',1],
+ ['customer','=',$vo['id']],
+ ['time','<',existFull($input,['startTime'])?strtotime($input['startTime']):0]
+ ];
+ $nodeUnionSql=frameScope($nodeUnionSql);
+
+ $nodeUnion=implode(' UNION ALL ',$nodeUnion);
+ $stats=DB::query('SELECT * FROM ('.$nodeUnion.') as nodcloud');
+ $calc=[];
+
+ $balance=math()->chain($calc['sell'])->sub($calc['sre'])->sub($calc['imy'])->add($calc['ice'])->done();
+ array_unshift($node,['bill'=>'期初余额','balance'=>$balance]);
+ foreach ($node as $nodeKey=>$nodeVo) {
+ //跳过期初
+ if(!empty($nodeKey)){
+ $node[$nodeKey]['bill']=['sell'=>'销售单','sre'=>'销售退货单','imy'=>'收款单','ice'=>'其它收入单'][$nodeVo['mold']];
+ if($nodeVo['mold']=='sell'){
+ $node[$nodeKey]['cw']=math()->chain($nodeVo['actual'])->sub($nodeVo['money'])->done();
+ $node[$nodeKey]['pia']=0;
+ }else if($nodeVo['mold']=='sre'){
+ $node[$nodeKey]['cw']=math()->chain($nodeVo['actual'])->sub($nodeVo['money'])->mul(-1)->done();
+ $node[$nodeKey]['pia']=0;
+ }else if($nodeVo['mold']=='imy'){
+ $node[$nodeKey]['cw']=0;
+ $node[$nodeKey]['pia']=$nodeVo['total'];
+ }else if($nodeVo['mold']=='ice'){
+ $node[$nodeKey]['cw']=math()->chain($nodeVo['actual'])->sub($nodeVo['money'])->done();
+ $node[$nodeKey]['pia']=0;
+ }
+ $node[$nodeKey]['balance'] = math()->chain($node[$nodeKey-1]['balance'])->add($node[$nodeKey]['cw'])->sub($node[$nodeKey]['pia'])->done();
+ }
+ }
+ $data[$key]['cw']=mathArraySum(array_column($node,'cw'));
+ $data[$key]['pia']=mathArraySum(array_column($node,'pia'));
+ $data[$key]['balance']=$node[count($node)-1]['balance'];
+ $data[$key]['node']=$node;
+ }
+ $source=[];
+ foreach ($data as $dataVo) {
+ $source[]=$dataVo;
+ if(!empty($dataVo['node'])){
+ foreach ($dataVo['node'] as $node) {
+ $source[]=$node;
+ }
+ }
+ }
+ //开始构造导出数据
+ $excel=[];//初始化导出数据
+ //标题数据
+ $excel[]=['type'=>'title','info'=>'应收账款明细表'];
+ //表格数据
+ $field=[
+ 'name'=>'客户',
+ 'bill'=>'单据类型',
+ 'frameData|name'=>'所属组织',
+ 'time'=>'单据时间',
+ 'number'=>'单据编号',
+ 'cw'=>'增加应收款',
+ 'pia'=>'增加预收款',
+ 'balance'=>'应收款余额',
+ 'data'=>'备注',
+ ];
+ $thead=array_values($field);//表格标题
+ $tbody=[];//表格内容
+ //构造表内数据
+ foreach ($source as $sourceVo) {
+ $rowData=[];
+ foreach (array_keys($field) as $fieldVo) {
+ $rowData[]=arraySeek($sourceVo,$fieldVo);//多键名数据赋值
+ }
+ $tbody[]=$rowData;//加入行数据
+ }
+ $excel[]=['type'=>'table','info'=>['thead'=>$thead,'tbody'=>$tbody]];//表格数据
+ //汇总数据
+ $excel[]=['type'=>'node','info'=>[
+ '总数:'.count($source),
+ ]];
+ //导出execl
+ buildExcel('应收账款明细表',$excel);
+ }else{
+ return json(['state'=>'error','info'=>'传入参数不完整!']);
+ }
+ }
+ //应付账款明细表
+ public function cps(){
+ $input=input('post.');
+ if(existFull($input,['page','limit']) && isset($input['type'])){
+ $sql=[];
+ //CLASS语句
+ $sql=fastSql($input,[
+ [['supplier'=>'id'],'fullEq'],
+ ]);
+ //查询类型
+ empty($input['type'])||$sql[]=['balance','>',0];
+ $sql=frameScope($sql);//组织数据
+ $sql=sqlAuth('supplier',$sql);//数据鉴权
+ //数据查询
+ $count=Db::name('supplier')->where($sql)->count();
+ $data=Db::name('supplier')->where($sql)->page($input['page'],$input['limit'])->order(['id'=>'desc'])->select()->toArray();
+ //子查询
+ $existsSql=fastSql($input,[
+ [['startTime'=>'time'],'startTime'],
+ [['endTime'=>'time'],'endTime']
+ ]);
+ $existsSql[]=['examine','=',1];
+ $existsSql[]=['supplier','in',array_column($data,'id')];
+ $existsSql=frameScope($existsSql);
+ //构造语句
+ $union=[];
+ $tab=['buy','bre','omy','oce'];
+ foreach ($tab as $t) {
+ $union[]=Db::name($t)->where(sqlAuth($t,$existsSql))->fieldRaw('"'.$t.'" as mold,id')->buildSql();
+ }
+ $union=implode(' UNION ALL ',$union);
+ $record=DB::query('SELECT * FROM ('.$union.') as nodcloud');
+ //匹配单据
+ $bill=[];
+ foreach ($tab as $t) {
+ $gather=search($record)->where([['mold','=',$t]])->select();
+ $db="app\\model\\".ucfirst($t);
+ $bill=array_merge($bill,$db::with(['frameData'])->fieldRaw('*,"'.$t.'" as mold,time as t')->where([['id','in',array_column($gather,'id')]])->append(['extension'])->select()->toArray());
+ }
+ //匹配数据
+ foreach ($data as $key=>$vo) {
+ $data[$key]['key']=$vo['id'];
+ $data[$key]['cw']=0;
+ $data[$key]['pia']=0;
+ $data[$key]['balance']=0;
+ $node=search($bill)->where([['supplier','=',$vo['id']]])->select();
+ arraySort($node,'t',SORT_ASC);
+ //期初查询
+ $nodeUnion=[];
+ $nodeUnionSql=[
+ ['examine','=',1],
+ ['supplier','=',$vo['id']],
+ ['time','<',existFull($input,['startTime'])?strtotime($input['startTime']):0]
+ ];
+ $nodeUnionSql=frameScope($nodeUnionSql);
+ foreach ($tab as $t) {
+ $nodeUnion[]=Db::name($t)->where(sqlAuth($t,$nodeUnionSql))->fieldRaw('"'.$t.'" as mold,sum('.(in_array($t,['buy','bre','oce'])?'actual - money':'total').') as calc')->group(['mold'])->buildSql();
+ }
+ $nodeUnion=implode(' UNION ALL ',$nodeUnion);
+ $stats=DB::query('SELECT * FROM ('.$nodeUnion.') as nodcloud');
+ $calc=[];
+ foreach ($tab as $t) {
+ $find=search($stats)->where([['mold','=',$t]])->find();
+ if(empty($find)){
+ $calc[$t]=0;
+ }else{
+ $calc[$t]=$find['calc'];
+ }
+ }
+ $balance=math()->chain($calc['buy'])->sub($calc['bre'])->sub($calc['omy'])->add($calc['oce'])->done();
+ array_unshift($node,['key'=>$vo['id'].'_'.'0','bill'=>'期初余额','balance'=>$balance]);
+ foreach ($node as $nodeKey=>$nodeVo) {
+ //跳过期初
+ if(!empty($nodeKey)){
+ $node[$nodeKey]['key']=$vo['id'].'_'.$nodeVo['id'].'_'.$nodeVo['mold'];
+ $node[$nodeKey]['bill']=['buy'=>'采购单','bre'=>'采购退货单','omy'=>'付款单','oce'=>'其它支出单'][$nodeVo['mold']];
+ if($nodeVo['mold']=='buy'){
+ $node[$nodeKey]['cw']=math()->chain($nodeVo['actual'])->sub($nodeVo['money'])->done();
+ $node[$nodeKey]['pia']=0;
+ }else if($nodeVo['mold']=='bre'){
+ $node[$nodeKey]['cw']=math()->chain($nodeVo['actual'])->sub($nodeVo['money'])->mul(-1)->done();
+ $node[$nodeKey]['pia']=0;
+ }else if($nodeVo['mold']=='omy'){
+ $node[$nodeKey]['cw']=0;
+ $node[$nodeKey]['pia']=$nodeVo['total'];
+ }else if($nodeVo['mold']=='oce'){
+ $node[$nodeKey]['cw']=math()->chain($nodeVo['actual'])->sub($nodeVo['money'])->done();
+ $node[$nodeKey]['pia']=0;
+ }
+ $node[$nodeKey]['balance'] = math()->chain($node[$nodeKey-1]['balance'])->add($node[$nodeKey]['cw'])->sub($node[$nodeKey]['pia'])->done();
+ }
+ }
+ $data[$key]['cw']=mathArraySum(array_column($node,'cw'));
+ $data[$key]['pia']=mathArraySum(array_column($node,'pia'));
+ $data[$key]['balance']=$node[count($node)-1]['balance'];
+ $data[$key]['node']=$node;
+ }
+ $result=[
+ 'state'=>'success',
+ 'count'=>$count,
+ 'info'=>$data
+ ];//返回数据
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //应付账款明细表-导出
+ public function cpsExports(){
+ $input=input('get.');
+ if(isset($input['type'])){
+ $sql=[];
+ //CLASS语句
+ $sql=fastSql($input,[
+ [['supplier'=>'id'],'fullEq'],
+ ]);
+ //查询类型
+ empty($input['type'])||$sql[]=['balance','>',0];
+ $sql=frameScope($sql);//组织数据
+ $sql=sqlAuth('supplier',$sql);//数据鉴权
+ //数据查询
+ $count=Db::name('supplier')->where($sql)->count();
+ $data=Db::name('supplier')->where($sql)->order(['id'=>'desc'])->select()->toArray();
+ //子查询
+ $existsSql=fastSql($input,[
+ [['startTime'=>'time'],'startTime'],
+ [['endTime'=>'time'],'endTime']
+ ]);
+ $existsSql[]=['examine','=',1];
+ $existsSql[]=['supplier','in',array_column($data,'id')];
+ $existsSql=frameScope($existsSql);
+ //构造语句
+ $union=[];
+ $tab=['buy','bre','omy','oce'];
+ foreach ($tab as $t) {
+ $union[]=Db::name($t)->where(sqlAuth($t,$existsSql))->fieldRaw('"'.$t.'" as mold,id')->buildSql();
+ }
+ $union=implode(' UNION ALL ',$union);
+ $record=DB::query('SELECT * FROM ('.$union.') as nodcloud');
+ //匹配单据
+ $bill=[];
+ foreach ($tab as $t) {
+ $gather=search($record)->where([['mold','=',$t]])->select();
+ $db="app\\model\\".ucfirst($t);
+ $bill=array_merge($bill,$db::with(['frameData'])->fieldRaw('*,"'.$t.'" as mold,time as t')->where([['id','in',array_column($gather,'id')]])->append(['extension'])->select()->toArray());
+ }
+ //匹配数据
+ foreach ($data as $key=>$vo) {
+ $data[$key]['cw']=0;
+ $data[$key]['pia']=0;
+ $data[$key]['balance']=0;
+ $node=search($bill)->where([['supplier','=',$vo['id']]])->select();
+ arraySort($node,'t',SORT_ASC);
+ //期初查询
+ $nodeUnion=[];
+ $nodeUnionSql=[
+ ['examine','=',1],
+ ['supplier','=',$vo['id']],
+ ['time','<',existFull($input,['startTime'])?strtotime($input['startTime']):0]
+ ];
+ $nodeUnionSql=frameScope($nodeUnionSql);
+ foreach ($tab as $t) {
+ $nodeUnion[]=Db::name($t)->where(sqlAuth($t,$nodeUnionSql))->fieldRaw('"'.$t.'" as mold,sum('.(in_array($t,['buy','bre','oce'])?'actual - money':'total').') as calc')->group(['mold'])->buildSql();
+ }
+ $nodeUnion=implode(' UNION ALL ',$nodeUnion);
+ $stats=DB::query('SELECT * FROM ('.$nodeUnion.') as nodcloud');
+ $calc=[];
+ foreach ($tab as $t) {
+ $find=search($stats)->where([['mold','=',$t]])->find();
+ if(empty($find)){
+ $calc[$t]=0;
+ }else{
+ $calc[$t]=$find['calc'];
+ }
+ }
+ $balance=math()->chain($calc['buy'])->sub($calc['bre'])->sub($calc['omy'])->add($calc['oce'])->done();
+ array_unshift($node,['bill'=>'期初余额','balance'=>$balance]);
+ foreach ($node as $nodeKey=>$nodeVo) {
+ //跳过期初
+ if(!empty($nodeKey)){
+ $node[$nodeKey]['bill']=['buy'=>'采购单','bre'=>'采购退货单','omy'=>'付款单','oce'=>'其它支出单'][$nodeVo['mold']];
+ if($nodeVo['mold']=='buy'){
+ $node[$nodeKey]['cw']=math()->chain($nodeVo['actual'])->sub($nodeVo['money'])->done();
+ $node[$nodeKey]['pia']=0;
+ }else if($nodeVo['mold']=='bre'){
+ $node[$nodeKey]['cw']=math()->chain($nodeVo['actual'])->sub($nodeVo['money'])->mul(-1)->done();
+ $node[$nodeKey]['pia']=0;
+ }else if($nodeVo['mold']=='omy'){
+ $node[$nodeKey]['cw']=0;
+ $node[$nodeKey]['pia']=$nodeVo['total'];
+ }else if($nodeVo['mold']=='oce'){
+ $node[$nodeKey]['cw']=math()->chain($nodeVo['actual'])->sub($nodeVo['money'])->done();
+ $node[$nodeKey]['pia']=0;
+ }
+ $node[$nodeKey]['balance'] = math()->chain($node[$nodeKey-1]['balance'])->add($node[$nodeKey]['cw'])->sub($node[$nodeKey]['pia'])->done();
+ }
+ }
+ $data[$key]['cw']=mathArraySum(array_column($node,'cw'));
+ $data[$key]['pia']=mathArraySum(array_column($node,'pia'));
+ $data[$key]['balance']=$node[count($node)-1]['balance'];
+ $data[$key]['node']=$node;
+ }
+ $source=[];
+ foreach ($data as $dataVo) {
+ $source[]=$dataVo;
+ if(!empty($dataVo['node'])){
+ foreach ($dataVo['node'] as $node) {
+ $source[]=$node;
+ }
+ }
+ }
+ //开始构造导出数据
+ $excel=[];//初始化导出数据
+ //标题数据
+ $excel[]=['type'=>'title','info'=>'应付账款明细表'];
+ //表格数据
+ $field=[
+ 'name'=>'供应商',
+ 'bill'=>'单据类型',
+ 'frameData|name'=>'所属组织',
+ 'time'=>'单据时间',
+ 'number'=>'单据编号',
+ 'cw'=>'增加应付款',
+ 'pia'=>'增加预付款',
+ 'balance'=>'应付款余额',
+ 'data'=>'备注',
+ ];
+ $thead=array_values($field);//表格标题
+ $tbody=[];//表格内容
+ //构造表内数据
+ foreach ($source as $sourceVo) {
+ $rowData=[];
+ foreach (array_keys($field) as $fieldVo) {
+ $rowData[]=arraySeek($sourceVo,$fieldVo);//多键名数据赋值
+ }
+ $tbody[]=$rowData;//加入行数据
+ }
+ $excel[]=['type'=>'table','info'=>['thead'=>$thead,'tbody'=>$tbody]];//表格数据
+ //汇总数据
+ $excel[]=['type'=>'node','info'=>[
+ '总数:'.count($source),
+ ]];
+ //导出execl
+ buildExcel('应付账款明细表',$excel);
+ }else{
+ return json(['state'=>'error','info'=>'传入参数不完整!']);
+ }
+ }
+ //客户对账单
+ public function cct(){
+ $input=input('post.');
+ if(existFull($input,['customer']) && isset($input['type'])){
+ //子查询
+ $existsSql=fastSql($input,[
+ [['startTime'=>'time'],'startTime'],
+ [['endTime'=>'time'],'endTime']
+ ]);
+ $existsSql[]=['examine','=',1];
+ $existsSql[]=['customer','=',$input['customer']];
+ $existsSql=frameScope($existsSql);
+ //构造语句
+ $union=[];
+ $tab=['sell','sre','imy','ice'];
+ foreach ($tab as $t) {
+ $union[]=Db::name($t)->where(sqlAuth($t,$existsSql))->fieldRaw('"'.$t.'" as mold,id')->buildSql();
+ }
+ $union=implode(' UNION ALL ',$union);
+ $record=DB::query('SELECT * FROM ('.$union.') as nodcloud');
+ //匹配单据
+ $bill=['class'=>[],'info'=>[]];
+ foreach ($tab as $t) {
+ $gather=search($record)->where([['mold','=',$t]])->select();
+ $db=['class'=>"app\\model\\".ucfirst($t),'info'=>"app\\model\\".ucfirst($t).'Info'];
+ $bill['class']=array_merge($bill['class'],$db['class']::with(['frameData'])->fieldRaw('*,"'.$t.'" as mold,time as t')->where([['id','in',array_column($gather,'id')]])->append(['extension'])->select()->toArray());
+ //匹配明细
+ if(!empty($input['type'])){
+ if(in_array($t,['sell','sre'])){
+ $detail=$db['info']::with(['goodsData'])->where([['pid','in',array_column($gather,'id')]])->select()->toArray();
+ }else if($t=='imy'){
+ $detail=$db['info']::with(['accountData'])->where([['pid','in',array_column($gather,'id')]])->select()->toArray();
+ }else if($t=='ice'){
+ $detail=$db['info']::with(['ietData'])->where([['pid','in',array_column($gather,'id')]])->select()->toArray();
+ }
+ $bill['info'][$t]=$detail;
+ }
+ }
+ arraySort($bill['class'],'t',SORT_ASC);
+ //期初查询
+ $firstUnion=[];
+ $firstUnionSql=[
+ ['examine','=',1],
+ ['customer','=',$input['customer']],
+ ['time','<',existFull($input,['startTime'])?strtotime($input['startTime']):0]
+ ];
+ $firstUnionSql=frameScope($firstUnionSql);
+
+ $firstUnion=implode(' UNION ALL ',$firstUnion);
+ $stats=DB::query('SELECT * FROM ('.$firstUnion.') as nodcloud');
+ $calc=[];
+
+ $balance=math()->chain($calc['sell'])->sub($calc['sre'])->sub($calc['imy'])->add($calc['ice'])->done();
+ $data=[
+ ['key'=>'0','node'=>[],'bill'=>'期初余额','balance'=>$balance],
+ ];
+ //匹配数据
+ foreach ($bill['class'] as $classVo) {
+ $row=$classVo;
+ $row['key']=$row['id'].'_'.$row['mold'];
+ $row['bill']=['sell'=>'销售单','sre'=>'销售退货单','imy'=>'收款单','ice'=>'其它收入单'][$row['mold']];
+ if($row['mold']=='sell'){
+ $row['discount']=math()->chain($row['total'])->sub($row['actual'])->done();
+ }else if($row['mold']=='sre'){
+ $row['total']=math()->chain($row['total'])->mul(-1)->done();
+ $row['actual']=math()->chain($row['actual'])->mul(-1)->done();
+ $row['money']=math()->chain($row['money'])->mul(-1)->done();
+ $row['discount']=math()->chain($row['total'])->sub($row['actual'])->done();
+ }else if($row['mold']=='imy'){
+ $row['actual']=0;
+ $row['money']=$row['total'];
+ $row['discount']=0;
+ }else if($row['mold']=='ice'){
+ $row['discount']=math()->chain($row['total'])->sub($row['actual'])->done();
+ }
+ $row['balance'] = math()->chain($data[count($data)-1]['balance'])->add($row['actual'])->sub($row['money'])->done();
+ //匹配明细
+ $node=[];
+ if(!empty($input['type'])){
+ $list=search($bill['info'][$row['mold']])->where([['pid','=',$row['id']]])->select();
+ foreach ($list as $listVo) {
+ if(in_array($row['mold'],['sell','sre'])){
+ $detail=[
+ 'name'=>$listVo['goodsData']['name'],
+ 'attr'=>$listVo['attr'],
+ 'unit'=>$listVo['unit'],
+ 'price'=>$listVo['price'],
+ 'nums'=>$listVo['nums'],
+ 'dsc'=>$listVo['dsc'],
+ 'total'=>$listVo['total'],
+ 'tat'=>$listVo['tat'],
+ 'tpt'=>$listVo['tpt']
+ ];
+ }else if($row['mold']=='imy'){
+ $detail=[
+ 'name'=>$listVo['accountData']['name'],
+ 'attr'=>'',
+ 'unit'=>'',
+ 'price'=>$listVo['money'],
+ 'nums'=>1,
+ 'dsc'=>0,
+ 'total'=>$listVo['money'],
+ 'tat'=>0,
+ 'tpt'=>$listVo['money']
+ ];
+ }else if($row['mold']=='ice'){
+ $detail=[
+ 'name'=>$listVo['ietData']['name'],
+ 'attr'=>'',
+ 'unit'=>'',
+ 'price'=>$listVo['money'],
+ 'nums'=>1,
+ 'dsc'=>0,
+ 'total'=>$listVo['money'],
+ 'tat'=>0,
+ 'tpt'=>$listVo['money']
+ ];
+ }else{
+ $detail=[];
+ }
+ $node[]=['key'=>$row['id'].'_'.$listVo['id'].'_'.$row['mold'],'detail'=>$detail];
+ }
+ }
+ $row['node']=$node;
+ $data[]=$row;
+ }
+ $result=[
+ 'state'=>'success',
+ 'info'=>$data
+ ];//返回数据
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //客户对账单-导出
+ public function cctExports(){
+ $input=input('get.');
+ if(existFull($input,['customer']) && isset($input['type'])){
+ //子查询
+ $existsSql=fastSql($input,[
+ [['startTime'=>'time'],'startTime'],
+ [['endTime'=>'time'],'endTime']
+ ]);
+ $existsSql[]=['examine','=',1];
+ $existsSql[]=['customer','=',$input['customer']];
+ $existsSql=frameScope($existsSql);
+ //构造语句
+ $union=[];
+ $tab=['sell','sre','imy','ice'];
+ foreach ($tab as $t) {
+ $union[]=Db::name($t)->where(sqlAuth($t,$existsSql))->fieldRaw('"'.$t.'" as mold,id')->buildSql();
+ }
+ $union=implode(' UNION ALL ',$union);
+ $record=DB::query('SELECT * FROM ('.$union.') as nodcloud');
+ //匹配单据
+ $bill=['class'=>[],'info'=>[]];
+ foreach ($tab as $t) {
+ $gather=search($record)->where([['mold','=',$t]])->select();
+ $db=['class'=>"app\\model\\".ucfirst($t),'info'=>"app\\model\\".ucfirst($t).'Info'];
+ $bill['class']=array_merge($bill['class'],$db['class']::with(['frameData'])->fieldRaw('*,"'.$t.'" as mold,time as t')->where([['id','in',array_column($gather,'id')]])->append(['extension'])->select()->toArray());
+ //匹配明细
+ if(!empty($input['type'])){
+ if(in_array($t,['sell','sre'])){
+ $detail=$db['info']::with(['goodsData'])->where([['pid','in',array_column($gather,'id')]])->select()->toArray();
+ }else if($t=='imy'){
+ $detail=$db['info']::with(['accountData'])->where([['pid','in',array_column($gather,'id')]])->select()->toArray();
+ }else if($t=='ice'){
+ $detail=$db['info']::with(['ietData'])->where([['pid','in',array_column($gather,'id')]])->select()->toArray();
+ }
+ $bill['info'][$t]=$detail;
+ }
+ }
+ arraySort($bill['class'],'t',SORT_ASC);
+ //期初查询
+ $firstUnion=[];
+ $firstUnionSql=[
+ ['examine','=',1],
+ ['customer','=',$input['customer']],
+ ['time','<',existFull($input,['startTime'])?strtotime($input['startTime']):0]
+ ];
+ $firstUnionSql=frameScope($firstUnionSql);
+
+ $firstUnion=implode(' UNION ALL ',$firstUnion);
+ $stats=DB::query('SELECT * FROM ('.$firstUnion.') as nodcloud');
+ $calc=[];
+
+ $balance=math()->chain($calc['sell'])->sub($calc['sre'])->sub($calc['imy'])->add($calc['ice'])->done();
+ $data=[
+ ['node'=>[],'bill'=>'期初余额','balance'=>$balance],
+ ];
+ //匹配数据
+ foreach ($bill['class'] as $classVo) {
+ $row=$classVo;
+ $row['bill']=['sell'=>'销售单','sre'=>'销售退货单','imy'=>'收款单','ice'=>'其它收入单'][$row['mold']];
+ if($row['mold']=='sell'){
+ $row['discount']=math()->chain($row['total'])->sub($row['actual'])->done();
+ }else if($row['mold']=='sre'){
+ $row['total']=math()->chain($row['total'])->mul(-1)->done();
+ $row['actual']=math()->chain($row['actual'])->mul(-1)->done();
+ $row['money']=math()->chain($row['money'])->mul(-1)->done();
+ $row['discount']=math()->chain($row['total'])->sub($row['actual'])->done();
+ }else if($row['mold']=='imy'){
+ $row['actual']=0;
+ $row['money']=$row['total'];
+ $row['discount']=0;
+ }else if($row['mold']=='ice'){
+ $row['discount']=math()->chain($row['total'])->sub($row['actual'])->done();
+ }
+ $row['balance'] = math()->chain($data[count($data)-1]['balance'])->add($row['actual'])->sub($row['money'])->done();
+ //匹配明细
+ $node=[];
+ if(!empty($input['type'])){
+ $list=search($bill['info'][$row['mold']])->where([['pid','=',$row['id']]])->select();
+ foreach ($list as $listVo) {
+ if(in_array($row['mold'],['sell','sre'])){
+ $detail=[
+ 'name'=>$listVo['goodsData']['name'],
+ 'attr'=>$listVo['attr'],
+ 'unit'=>$listVo['unit'],
+ 'price'=>$listVo['price'],
+ 'nums'=>$listVo['nums'],
+ 'dsc'=>$listVo['dsc'],
+ 'total'=>$listVo['total'],
+ 'tat'=>$listVo['tat'],
+ 'tpt'=>$listVo['tpt']
+ ];
+ }else if($row['mold']=='imy'){
+ $detail=[
+ 'name'=>$listVo['accountData']['name'],
+ 'attr'=>'',
+ 'unit'=>'',
+ 'price'=>$listVo['money'],
+ 'nums'=>1,
+ 'dsc'=>0,
+ 'total'=>$listVo['money'],
+ 'tat'=>0,
+ 'tpt'=>$listVo['money']
+ ];
+ }else if($row['mold']=='ice'){
+ $detail=[
+ 'name'=>$listVo['ietData']['name'],
+ 'attr'=>'',
+ 'unit'=>'',
+ 'price'=>$listVo['money'],
+ 'nums'=>1,
+ 'dsc'=>0,
+ 'total'=>$listVo['money'],
+ 'tat'=>0,
+ 'tpt'=>$listVo['money']
+ ];
+ }else{
+ $detail=[];
+ }
+ $node[]=['detail'=>$detail];
+ }
+ }
+ $row['node']=$node;
+ $data[]=$row;
+ }
+ $customer=Db::name('customer')->where([['id','=',$input['customer']]])->find();
+ $source=[];
+ foreach ($data as $dataVo) {
+ $source[]=$dataVo;
+ if(!empty($dataVo['node'])){
+ foreach ($dataVo['node'] as $node) {
+ $source[]=$node;
+ }
+ }
+ }
+ //开始构造导出数据
+ $excel=[];//初始化导出数据
+ //标题数据
+ $excel[]=['type'=>'title','info'=>'客户对账单 [ '.$customer['name'].' ]'];
+ //表格数据
+ $field=[
+ [
+ 'bill'=>'单据类型',
+ 'frameData|name'=>'所属组织',
+ 'time'=>'单据时间',
+ 'number'=>'单据编号'
+ ],
+ [
+ 'detail|name'=>'名称',
+ 'detail|attr'=>'属性',
+ 'detail|unit'=>'单位',
+ 'detail|price'=>'单价',
+ 'detail|nums'=>'数量',
+ 'detail|dsc'=>'折扣额',
+ 'detail|total'=>'金额',
+ 'detail|tat'=>'税额',
+ 'detail|tpt'=>'价税合计',
+ ],
+ [
+ 'total'=>'单据金额',
+ 'discount'=>'优惠金额',
+ 'actual'=>'应收金额',
+ 'money'=>'实收金额',
+ 'balance'=>'应收款余额',
+ 'data'=>'备注'
+ ]
+ ];
+ $field=empty($input['type'])?array_merge($field[0],$field[2]):array_merge($field[0],$field[1],$field[2]);
+ $thead=array_values($field);//表格标题
+ $tbody=[];//表格内容
+ //构造表内数据
+ foreach ($source as $sourceVo) {
+ $rowData=[];
+ foreach (array_keys($field) as $fieldVo) {
+ $rowData[]=arraySeek($sourceVo,$fieldVo);//多键名数据赋值
+ }
+ $tbody[]=$rowData;//加入行数据
+ }
+ $excel[]=['type'=>'table','info'=>['thead'=>$thead,'tbody'=>$tbody]];//表格数据
+ //汇总数据
+ $excel[]=['type'=>'node','info'=>[
+ '总数:'.count($source),
+ ]];
+ //导出execl
+ buildExcel('客户对账单',$excel);
+ }else{
+ return json(['state'=>'error','info'=>'传入参数不完整!']);
+ }
+ }
+ //供应商对账单
+ public function cst(){
+ $input=input('post.');
+ if(existFull($input,['supplier']) && isset($input['type'])){
+ //子查询
+ $existsSql=fastSql($input,[
+ [['startTime'=>'time'],'startTime'],
+ [['endTime'=>'time'],'endTime']
+ ]);
+ $existsSql[]=['examine','=',1];
+ $existsSql[]=['supplier','=',$input['supplier']];
+ $existsSql=frameScope($existsSql);
+ //构造语句
+ $union=[];
+ $tab=['buy','bre','omy','oce'];
+ foreach ($tab as $t) {
+ $union[]=Db::name($t)->where(sqlAuth($t,$existsSql))->fieldRaw('"'.$t.'" as mold,id')->buildSql();
+ }
+ $union=implode(' UNION ALL ',$union);
+ $record=DB::query('SELECT * FROM ('.$union.') as nodcloud');
+ //匹配单据
+ $bill=['class'=>[],'info'=>[]];
+ foreach ($tab as $t) {
+ $gather=search($record)->where([['mold','=',$t]])->select();
+ $db=['class'=>"app\\model\\".ucfirst($t),'info'=>"app\\model\\".ucfirst($t).'Info'];
+ $bill['class']=array_merge($bill['class'],$db['class']::with(['frameData'])->fieldRaw('*,"'.$t.'" as mold,time as t')->where([['id','in',array_column($gather,'id')]])->append(['extension'])->select()->toArray());
+ //匹配明细
+ if(!empty($input['type'])){
+ if(in_array($t,['buy','bre'])){
+ $detail=$db['info']::with(['goodsData'])->where([['pid','in',array_column($gather,'id')]])->select()->toArray();
+ }else if($t=='omy'){
+ $detail=$db['info']::with(['accountData'])->where([['pid','in',array_column($gather,'id')]])->select()->toArray();
+ }else if($t=='oce'){
+ $detail=$db['info']::with(['ietData'])->where([['pid','in',array_column($gather,'id')]])->select()->toArray();
+ }
+ $bill['info'][$t]=$detail;
+ }
+ }
+ arraySort($bill['class'],'t',SORT_ASC);
+ //期初查询
+ $firstUnion=[];
+ $firstUnionSql=[
+ ['examine','=',1],
+ ['supplier','=',$input['supplier']],
+ ['time','<',existFull($input,['startTime'])?strtotime($input['startTime']):0]
+ ];
+ $firstUnionSql=frameScope($firstUnionSql);
+ foreach ($tab as $t) {
+ $firstUnion[]=Db::name($t)->where(sqlAuth($t,$firstUnionSql))->fieldRaw('"'.$t.'" as mold,sum('.(in_array($t,['buy','bre','oce'])?'actual - money':'total').') as calc')->group(['mold'])->buildSql();
+ }
+ $firstUnion=implode(' UNION ALL ',$firstUnion);
+ $stats=DB::query('SELECT * FROM ('.$firstUnion.') as nodcloud');
+ $calc=[];
+ foreach ($tab as $t) {
+ $find=search($stats)->where([['mold','=',$t]])->find();
+ if(empty($find)){
+ $calc[$t]=0;
+ }else{
+ $calc[$t]=$find['calc'];
+ }
+ }
+ $balance=math()->chain($calc['buy'])->sub($calc['bre'])->sub($calc['omy'])->add($calc['oce'])->done();
+ $data=[
+ ['key'=>'0','node'=>[],'bill'=>'期初余额','balance'=>$balance],
+ ];
+ //匹配数据
+ foreach ($bill['class'] as $classVo) {
+ $row=$classVo;
+ $row['key']=$row['id'].'_'.$row['mold'];
+ $row['bill']=['buy'=>'采购单','bre'=>'采购退货单','omy'=>'付款单','oce'=>'其它收入单'][$row['mold']];
+ if($row['mold']=='buy'){
+ $row['discount']=math()->chain($row['total'])->sub($row['actual'])->done();
+ }else if($row['mold']=='bre'){
+ $row['total']=math()->chain($row['total'])->mul(-1)->done();
+ $row['actual']=math()->chain($row['actual'])->mul(-1)->done();
+ $row['money']=math()->chain($row['money'])->mul(-1)->done();
+ $row['discount']=math()->chain($row['total'])->sub($row['actual'])->done();
+ }else if($row['mold']=='omy'){
+ $row['actual']=0;
+ $row['money']=$row['total'];
+ $row['discount']=0;
+ }else if($row['mold']=='oce'){
+ $row['discount']=math()->chain($row['total'])->sub($row['actual'])->done();
+ }
+ $row['balance'] = math()->chain($data[count($data)-1]['balance'])->add($row['actual'])->sub($row['money'])->done();
+ //匹配明细
+ $node=[];
+ if(!empty($input['type'])){
+ $list=search($bill['info'][$row['mold']])->where([['pid','=',$row['id']]])->select();
+ foreach ($list as $listVo) {
+ if(in_array($row['mold'],['buy','bre'])){
+ $detail=[
+ 'name'=>$listVo['goodsData']['name'],
+ 'attr'=>$listVo['attr'],
+ 'unit'=>$listVo['unit'],
+ 'price'=>$listVo['price'],
+ 'nums'=>$listVo['nums'],
+ 'dsc'=>$listVo['dsc'],
+ 'total'=>$listVo['total'],
+ 'tat'=>$listVo['tat'],
+ 'tpt'=>$listVo['tpt']
+ ];
+ }else if($row['mold']=='omy'){
+ $detail=[
+ 'name'=>$listVo['accountData']['name'],
+ 'attr'=>'',
+ 'unit'=>'',
+ 'price'=>$listVo['money'],
+ 'nums'=>1,
+ 'dsc'=>0,
+ 'total'=>$listVo['money'],
+ 'tat'=>0,
+ 'tpt'=>$listVo['money']
+ ];
+ }else if($row['mold']=='oce'){
+ $detail=[
+ 'name'=>$listVo['ietData']['name'],
+ 'attr'=>'',
+ 'unit'=>'',
+ 'price'=>$listVo['money'],
+ 'nums'=>1,
+ 'dsc'=>0,
+ 'total'=>$listVo['money'],
+ 'tat'=>0,
+ 'tpt'=>$listVo['money']
+ ];
+ }else{
+ $detail=[];
+ }
+ $node[]=['key'=>$row['id'].'_'.$listVo['id'].'_'.$row['mold'],'detail'=>$detail];
+ }
+ }
+ $row['node']=$node;
+ $data[]=$row;
+ }
+ $result=[
+ 'state'=>'success',
+ 'info'=>$data
+ ];//返回数据
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //供应商对账单-导出
+ public function cstExports(){
+ $input=input('get.');
+ if(existFull($input,['supplier']) && isset($input['type'])){
+ //子查询
+ $existsSql=fastSql($input,[
+ [['startTime'=>'time'],'startTime'],
+ [['endTime'=>'time'],'endTime']
+ ]);
+ $existsSql[]=['examine','=',1];
+ $existsSql[]=['supplier','=',$input['supplier']];
+ $existsSql=frameScope($existsSql);
+ //构造语句
+ $union=[];
+ $tab=['buy','bre','omy','oce'];
+ foreach ($tab as $t) {
+ $union[]=Db::name($t)->where(sqlAuth($t,$existsSql))->fieldRaw('"'.$t.'" as mold,id')->buildSql();
+ }
+ $union=implode(' UNION ALL ',$union);
+ $record=DB::query('SELECT * FROM ('.$union.') as nodcloud');
+ //匹配单据
+ $bill=['class'=>[],'info'=>[]];
+ foreach ($tab as $t) {
+ $gather=search($record)->where([['mold','=',$t]])->select();
+ $db=['class'=>"app\\model\\".ucfirst($t),'info'=>"app\\model\\".ucfirst($t).'Info'];
+ $bill['class']=array_merge($bill['class'],$db['class']::with(['frameData'])->fieldRaw('*,"'.$t.'" as mold,time as t')->where([['id','in',array_column($gather,'id')]])->append(['extension'])->select()->toArray());
+ //匹配明细
+ if(!empty($input['type'])){
+ if(in_array($t,['buy','bre'])){
+ $detail=$db['info']::with(['goodsData'])->where([['pid','in',array_column($gather,'id')]])->select()->toArray();
+ }else if($t=='omy'){
+ $detail=$db['info']::with(['accountData'])->where([['pid','in',array_column($gather,'id')]])->select()->toArray();
+ }else if($t=='oce'){
+ $detail=$db['info']::with(['ietData'])->where([['pid','in',array_column($gather,'id')]])->select()->toArray();
+ }
+ $bill['info'][$t]=$detail;
+ }
+ }
+ arraySort($bill['class'],'t',SORT_ASC);
+ //期初查询
+ $firstUnion=[];
+ $firstUnionSql=[
+ ['examine','=',1],
+ ['supplier','=',$input['supplier']],
+ ['time','<',existFull($input,['startTime'])?strtotime($input['startTime']):0]
+ ];
+ $firstUnionSql=frameScope($firstUnionSql);
+ foreach ($tab as $t) {
+ $firstUnion[]=Db::name($t)->where(sqlAuth($t,$firstUnionSql))->fieldRaw('"'.$t.'" as mold,sum('.(in_array($t,['buy','bre','oce'])?'actual - money':'total').') as calc')->group(['mold'])->buildSql();
+ }
+ $firstUnion=implode(' UNION ALL ',$firstUnion);
+ $stats=DB::query('SELECT * FROM ('.$firstUnion.') as nodcloud');
+ $calc=[];
+ foreach ($tab as $t) {
+ $find=search($stats)->where([['mold','=',$t]])->find();
+ if(empty($find)){
+ $calc[$t]=0;
+ }else{
+ $calc[$t]=$find['calc'];
+ }
+ }
+ $balance=math()->chain($calc['buy'])->sub($calc['bre'])->sub($calc['omy'])->add($calc['oce'])->done();
+ $data=[
+ ['node'=>[],'bill'=>'期初余额','balance'=>$balance],
+ ];
+ //匹配数据
+ foreach ($bill['class'] as $classVo) {
+ $row=$classVo;
+ $row['bill']=['buy'=>'采购单','bre'=>'采购退货单','omy'=>'付款单','oce'=>'其它收入单'][$row['mold']];
+ if($row['mold']=='buy'){
+ $row['discount']=math()->chain($row['total'])->sub($row['actual'])->done();
+ }else if($row['mold']=='bre'){
+ $row['total']=math()->chain($row['total'])->mul(-1)->done();
+ $row['actual']=math()->chain($row['actual'])->mul(-1)->done();
+ $row['money']=math()->chain($row['money'])->mul(-1)->done();
+ $row['discount']=math()->chain($row['total'])->sub($row['actual'])->done();
+ }else if($row['mold']=='omy'){
+ $row['actual']=0;
+ $row['money']=$row['total'];
+ $row['discount']=0;
+ }else if($row['mold']=='oce'){
+ $row['discount']=math()->chain($row['total'])->sub($row['actual'])->done();
+ }
+ $row['balance'] = math()->chain($data[count($data)-1]['balance'])->add($row['actual'])->sub($row['money'])->done();
+ //匹配明细
+ $node=[];
+ if(!empty($input['type'])){
+ $list=search($bill['info'][$row['mold']])->where([['pid','=',$row['id']]])->select();
+ foreach ($list as $listVo) {
+ if(in_array($row['mold'],['buy','bre'])){
+ $detail=[
+ 'name'=>$listVo['goodsData']['name'],
+ 'attr'=>$listVo['attr'],
+ 'unit'=>$listVo['unit'],
+ 'price'=>$listVo['price'],
+ 'nums'=>$listVo['nums'],
+ 'dsc'=>$listVo['dsc'],
+ 'total'=>$listVo['total'],
+ 'tat'=>$listVo['tat'],
+ 'tpt'=>$listVo['tpt']
+ ];
+ }else if($row['mold']=='omy'){
+ $detail=[
+ 'name'=>$listVo['accountData']['name'],
+ 'attr'=>'',
+ 'unit'=>'',
+ 'price'=>$listVo['money'],
+ 'nums'=>1,
+ 'dsc'=>0,
+ 'total'=>$listVo['money'],
+ 'tat'=>0,
+ 'tpt'=>$listVo['money']
+ ];
+ }else if($row['mold']=='oce'){
+ $detail=[
+ 'name'=>$listVo['ietData']['name'],
+ 'attr'=>'',
+ 'unit'=>'',
+ 'price'=>$listVo['money'],
+ 'nums'=>1,
+ 'dsc'=>0,
+ 'total'=>$listVo['money'],
+ 'tat'=>0,
+ 'tpt'=>$listVo['money']
+ ];
+ }else{
+ $detail=[];
+ }
+ $node[]=['detail'=>$detail];
+ }
+ }
+ $row['node']=$node;
+ $data[]=$row;
+ }
+ $supplier=Db::name('supplier')->where([['id','=',$input['supplier']]])->find();
+ $source=[];
+ foreach ($data as $dataVo) {
+ $source[]=$dataVo;
+ if(!empty($dataVo['node'])){
+ foreach ($dataVo['node'] as $node) {
+ $source[]=$node;
+ }
+ }
+ }
+ //开始构造导出数据
+ $excel=[];//初始化导出数据
+ //标题数据
+ $excel[]=['type'=>'title','info'=>'供应商对账单 [ '.$supplier['name'].' ]'];
+ //表格数据
+ $field=[
+ [
+ 'bill'=>'单据类型',
+ 'frameData|name'=>'所属组织',
+ 'time'=>'单据时间',
+ 'number'=>'单据编号'
+ ],
+ [
+ 'detail|name'=>'名称',
+ 'detail|attr'=>'属性',
+ 'detail|unit'=>'单位',
+ 'detail|price'=>'单价',
+ 'detail|nums'=>'数量',
+ 'detail|dsc'=>'折扣额',
+ 'detail|total'=>'金额',
+ 'detail|tat'=>'税额',
+ 'detail|tpt'=>'价税合计',
+ ],
+ [
+ 'total'=>'单据金额',
+ 'discount'=>'优惠金额',
+ 'actual'=>'应付金额',
+ 'money'=>'实付金额',
+ 'balance'=>'应付款余额',
+ 'data'=>'备注'
+ ]
+ ];
+ $field=empty($input['type'])?array_merge($field[0],$field[2]):array_merge($field[0],$field[1],$field[2]);
+ $thead=array_values($field);//表格标题
+ $tbody=[];//表格内容
+ //构造表内数据
+ foreach ($source as $sourceVo) {
+ $rowData=[];
+ foreach (array_keys($field) as $fieldVo) {
+ $rowData[]=arraySeek($sourceVo,$fieldVo);//多键名数据赋值
+ }
+ $tbody[]=$rowData;//加入行数据
+ }
+ $excel[]=['type'=>'table','info'=>['thead'=>$thead,'tbody'=>$tbody]];//表格数据
+ //汇总数据
+ $excel[]=['type'=>'node','info'=>[
+ '总数:'.count($source),
+ ]];
+ //导出execl
+ buildExcel('供应商对账单',$excel);
+ }else{
+ return json(['state'=>'error','info'=>'传入参数不完整!']);
+ }
+ }
+ //其它收支明细表
+ public function cos(){
+ $input=input('post.');
+ $sheet=['ice','oce'];
+ existFull($input,['mold'])||$input['mold']=$sheet;
+ if(existFull($input,['page','limit']) && is_array($input['mold']) && arrayInArray($input['mold'],$sheet)){
+ $sql=[];
+ //CLASS语句
+ $sql['class']=fastSql($input,[
+ ['number','fullLike'],
+ [['startTime'=>'time'],'startTime'],
+ [['endTime'=>'time'],'endTime'],
+ ['account','fullEq'],
+ [['data'=>'class.data'],'fullLike']
+ ]);
+ $sql['class'][]=['examine','=',1];
+ $sql['class']=frameScope($sql['class']);//组织数据
+
+ $sql_class=[];
+ foreach ($input['mold'] as $mold) {
+ $sql_class[$mold]=sqlAuth($mold,$sql['class']);
+ }
+ //INFO语句
+ $sql['info']=fastSql($input,[['iet','fullEq']]);
+ $union=[];
+ foreach ($input['mold'] as $mold) {
+ $union[]=Db::name($mold.'_info')->alias('info')->join(['is_'.$mold=>'class'],'info.pid=class.id')->where($sql['info'])->where($sql_class[$mold])->fieldRaw('info.id as info,class.id as class,time,"'.$mold.'" as mold')->buildSql();
+ }
+ $union=implode(' UNION ALL ',$union);
+ //获取总条数
+ $count=DB::query('SELECT COUNT(*) as count FROM ('.$union.') as nodcloud')[0]["count"];
+ $record=DB::query('SELECT * FROM ('.$union.') as nodcloud ORDER BY `time` DESC LIMIT '.pageCalc($input['page'],$input['limit'],'str'));
+ $list=[];
+ foreach ($input['mold'] as $mold) {
+ $gather=search($record)->where([['mold','=',$mold]])->select();
+ $table=[
+ "class"=>"app\\model\\".ucfirst($mold),
+ 'info'=>"app\\model\\".ucfirst($mold).'Info',
+ ];
+ $list[$mold]['info']=$table['info']::with(['ietData'])->where([['id','in',array_column($gather,'info')]])->select()->toArray();
+ $list[$mold]['class']=$table['class']::with(['frameData','accountData',$mold=='ice'?'customerData':'supplierData'])->where([['id','in',array_column($list[$mold]['info'],'pid')]])->append(['extension'])->select()->toArray();
+ }
+ $data=[];
+ foreach ($record as $recordVo) {
+ $mold=$recordVo['mold'];
+ $class=search($list[$mold]['class'])->where([['id','=',$recordVo['class']]])->find();
+ $info=search($list[$mold]['info'])->where([['id','=',$recordVo['info']]])->find();
+ $data[]=[
+ 'mold'=>$mold,
+ 'name'=>['ice'=>'其它收入单','oce'=>'其它支出单'][$mold],
+ 'current'=>$mold=='ice'?$class['customerData']??[]:$class['supplierData']??[],
+ 'class'=>$class,
+ 'info'=>$info,
+ 'in'=>$mold=='ice'?$info['money']:0,
+ 'out'=>$mold=='ice'?0:$info['money']
+ ];
+ }
+ $result=[
+ 'state'=>'success',
+ 'count'=>$count,
+ 'info'=>$data
+ ];//返回数据
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //其它收支明细表-导出
+ public function cosExports(){
+ $input=input('get.');
+ $sheet=['ice','oce'];
+ existFull($input,['mold'])||$input['mold']=$sheet;
+ if(is_array($input['mold']) && arrayInArray($input['mold'],$sheet)){
+ $sql=[];
+ //CLASS语句
+ $sql['class']=fastSql($input,[
+ ['number','fullLike'],
+ [['startTime'=>'time'],'startTime'],
+ [['endTime'=>'time'],'endTime'],
+ ['account','fullEq'],
+ [['data'=>'class.data'],'fullLike']
+ ]);
+ $sql['class'][]=['examine','=',1];
+ $sql['class']=frameScope($sql['class']);//组织数据
+ $sql_class=[];
+ foreach ($input['mold'] as $mold) {
+ $sql_class[$mold]=sqlAuth($mold,$sql['class']);
+ }
+ //INFO语句
+ $sql['info']=fastSql($input,[['iet','fullEq']]);
+ $union=[];
+ foreach ($input['mold'] as $mold) {
+ $union[]=Db::name($mold.'_info')->alias('info')->join(['is_'.$mold=>'class'],'info.pid=class.id')->where($sql['info'])->where($sql_class[$mold])->fieldRaw('info.id as info,class.id as class,time,"'.$mold.'" as mold')->buildSql();
+ }
+ $union=implode(' UNION ALL ',$union);
+ //获取总条数
+ $record=DB::query('SELECT * FROM ('.$union.') as nodcloud ORDER BY `time` DESC');
+ $list=[];
+ foreach ($input['mold'] as $mold) {
+ $gather=search($record)->where([['mold','=',$mold]])->select();
+ $table=[
+ "class"=>"app\\model\\".ucfirst($mold),
+ 'info'=>"app\\model\\".ucfirst($mold).'Info',
+ ];
+ $list[$mold]['info']=$table['info']::with(['ietData'])->where([['id','in',array_column($gather,'info')]])->select()->toArray();
+ $list[$mold]['class']=$table['class']::with(['frameData','accountData',$mold=='ice'?'customerData':'supplierData'])->where([['id','in',array_column($list[$mold]['info'],'pid')]])->append(['extension'])->select()->toArray();
+ }
+ $data=[];
+ foreach ($record as $recordVo) {
+ $mold=$recordVo['mold'];
+ $class=search($list[$mold]['class'])->where([['id','=',$recordVo['class']]])->find();
+ $info=search($list[$mold]['info'])->where([['id','=',$recordVo['info']]])->find();
+ $data[]=[
+ 'mold'=>$mold,
+ 'name'=>['ice'=>'其它收入单','oce'=>'其它支出单'][$mold],
+ 'current'=>$mold=='ice'?$class['customerData']??[]:$class['supplierData']??[],
+ 'class'=>$class,
+ 'info'=>$info,
+ 'in'=>$mold=='ice'?$info['money']:0,
+ 'out'=>$mold=='ice'?0:$info['money']
+ ];
+ }
+ $source=$data;
+
+ //开始构造导出数据
+ $excel=[];//初始化导出数据
+ //标题数据
+ $excel[]=['type'=>'title','info'=>'其它收支明细表'];
+ //表格数据
+ $field=[
+ "name"=>"单据类型",
+ "class|frameData|name"=>"所属组织",
+ "current|name"=>"往来单位",
+ "class|time"=>"单据时间",
+ "class|number"=>"单据编号",
+ "info|ietData|name"=>"收支类别",
+ "in"=>"收入",
+ "out"=>"支出",
+ "class|accountData|name"=>"结算账户",
+ "class|data"=>"备注信息"
+ ];
+ $thead=array_values($field);//表格标题
+ $tbody=[];//表格内容
+ //构造表内数据
+ foreach ($source as $sourceVo) {
+ $rowData=[];
+ foreach (array_keys($field) as $fieldVo) {
+ $rowData[]=arraySeek($sourceVo,$fieldVo);//多键名数据赋值
+ }
+ $tbody[]=$rowData;//加入行数据
+ }
+ $excel[]=['type'=>'table','info'=>['thead'=>$thead,'tbody'=>$tbody]];//表格数据
+ //汇总数据
+ $excel[]=['type'=>'node','info'=>[
+ '总数:'.count($source),
+ '总收入:'.mathArraySum(array_column($source,'in')),
+ '总支出:'.mathArraySum(array_column($source,'out'))
+ ]];
+ //导出execl
+ buildExcel('其它收支明细表',$excel);
+ }else{
+ return json(['state'=>'error','info'=>'传入参数不完整!']);
+ }
+ }
+ //利润表
+ public function cit(){
+ $input=input('post.');
+ $sql=fastSql($input,[
+ [['startTime'=>'time'],'startTime'],
+ [['endTime'=>'time'],'endTime']
+ ]);
+ $sql[]=['examine','=',1];
+ $sql=frameScope($sql);//组织数据
+ $sql=sqlAuth('sell',$sql);//数据鉴权[结构一致]
+ //匹配数据
+ $union=[];
+ $tab=['sell','sre'];
+ foreach ($tab as $t) {
+ $union[]=Db::name($t)->where($sql)->fieldRaw('"'.$t.'" as mold,group_concat(id) as id,sum(actual) as money,sum(cost) as cost')->buildSql();
+ }
+ $union=implode(' UNION ALL ',$union);
+ $record=DB::query('SELECT * FROM ('.$union.') as nodcloud');
+ //成本统计
+ $summary=[];
+ foreach ($record as $v) {
+ if(empty($v['id'])){
+ $summary[]=['mold'=>$v['mold'],'bct'=>0];
+ }else{
+ $where=[['class','in',explode(',',$v['id'])],['type','=',$v['mold']]
+ ];
+ $summary[]=Db::name('summary')->where($where)->fieldRaw('"'.$v['mold'].'" as mold,sum(bct) as bct')->select()->toArray()[0];
+ }
+ }
+ //计算数据
+ $si=math()->chain($record[0]['money'])->sub($record[1]['money'])->add($record[2]['money'])->sub($record[3]['money'])->done();
+ $cost=math()->chain($record[0]['cost'])->add($record[1]['cost'])->add($record[2]['cost'])->add($record[3]['cost'])->done();
+ $bct=math()->chain($summary[0]['bct'])->sub($summary[1]['bct'])->add($summary[2]['bct'])->sub($summary[3]['bct'])->done();
+ $profit=math()->chain($si)->sub($cost)->sub($bct)->done();
+ $data=[
+ ['name'=>'主营业务','money'=>''],
+ ['name'=>'| - 销售收入','money'=>$si],
+ ['name'=>'| - 业务成本','money'=>$cost],
+ ['name'=>'| - 销售成本','money'=>$bct],
+ ['name'=>'','money'=>''],
+ ['name'=>'利润','money'=>$profit]
+ ];
+ $result=[
+ 'state'=>'success',
+ 'info'=>$data
+ ];//返回数据
+ return json($result);
+ }
+ //利润表-导出
+ public function citExports(){
+ $input=input('post.');
+ $sql=fastSql($input,[
+ [['startTime'=>'time'],'startTime'],
+ [['endTime'=>'time'],'endTime']
+ ]);
+ $sql[]=['examine','=',1];
+ $sql=frameScope($sql);//组织数据
+ $sql=sqlAuth('sell',$sql);//数据鉴权[结构一致]
+ //匹配数据
+ $union=[];
+ $tab=['sell','sre'];
+ foreach ($tab as $t) {
+ $union[]=Db::name($t)->where($sql)->fieldRaw('"'.$t.'" as mold,group_concat(id) as id,sum(actual) as money,sum(cost) as cost')->buildSql();
+ }
+ $union=implode(' UNION ALL ',$union);
+ $record=DB::query('SELECT * FROM ('.$union.') as nodcloud');
+ //成本统计
+ $summary=[];
+ foreach ($record as $v) {
+ if(empty($v['id'])){
+ $summary[]=['mold'=>$v['mold'],'bct'=>0];
+ }else{
+ $where=[
+ ['class','in',explode(',',$v['id'])],
+ ['type','=',$v['mold']]
+ ];
+ $summary[]=Db::name('summary')->where($where)->fieldRaw('"'.$v['mold'].'" as mold,sum(bct) as bct')->select()->toArray()[0];
+ }
+ }
+ //计算数据
+ $si=math()->chain($record[0]['money'])->sub($record[1]['money'])->add($record[2]['money'])->sub($record[3]['money'])->done();
+ $cost=math()->chain($record[0]['cost'])->add($record[1]['cost'])->add($record[2]['cost'])->add($record[3]['cost'])->done();
+ $bct=math()->chain($summary[0]['bct'])->sub($summary[1]['bct'])->add($summary[2]['bct'])->sub($summary[3]['bct'])->done();
+ $profit=math()->chain($si)->sub($cost)->sub($bct)->done();
+ $data=[
+ ['name'=>'主营业务','money'=>''],
+ ['name'=>'销售收入','money'=>$si],
+ ['name'=>'业务成本','money'=>$cost],
+ ['name'=>'销售成本','money'=>$bct],
+ ['name'=>'','money'=>''],
+ ['name'=>'利润','money'=>$profit]
+ ];
+ $source=$data;
+ //开始构造导出数据
+ $excel=[];//初始化导出数据
+ //标题数据
+ $excel[]=['type'=>'title','info'=>'利润表'];
+ //表格数据
+ $field=[
+ "name"=>"项目",
+ "money"=>"金额"
+ ];
+ $thead=array_values($field);//表格标题
+ $tbody=[];//表格内容
+ //构造表内数据
+ foreach ($source as $sourceVo) {
+ $rowData=[];
+ foreach (array_keys($field) as $fieldVo) {
+ $rowData[]=arraySeek($sourceVo,$fieldVo);//多键名数据赋值
+ }
+ $tbody[]=$rowData;//加入行数据
+ }
+ $excel[]=['type'=>'table','info'=>['thead'=>$thead,'tbody'=>$tbody]];//表格数据
+ //导出execl
+ buildExcel('利润表',$excel);
+ }
+ //往来单位欠款表
+ public function cds(){
+ $input=input('post.');
+ $sheet=['customer','supplier'];
+ existFull($input,['mold'])||$input['mold']=$sheet;
+ if(existFull($input,['page','limit']) && is_array($input['mold']) && arrayInArray($input['mold'],$sheet)){
+ $base=fastSql($input,[
+ ['name','fullLike'],
+ ['number','fullLike'],
+ ['data','fullLike']
+ ]);
+ $base=frameScope($base);//组织数据
+ $sql=[];
+ foreach ($input['mold'] as $mold) {
+ if($mold=='customer'){
+ $sql[$mold]=sqlAuth('customer',$base);//数据鉴权
+ }else{
+ $sql[$mold]=sqlAuth('supplier',$base);//数据鉴权
+ }
+ }
+ $union=[];
+ foreach ($input['mold'] as $mold) {
+ $union[]=Db::name($mold)->where($sql[$mold])->fieldRaw('"'.$mold.'" as mold,id,name,number,data,balance')->buildSql();
+ }
+ $union=implode(' UNION ALL ',$union);
+ //获取总条数
+ $count=DB::query('SELECT COUNT(*) as count FROM ('.$union.') as nodcloud')[0]["count"];
+ $record=DB::query('SELECT * FROM ('.$union.') as nodcloud LIMIT '.pageCalc($input['page'],$input['limit'],'str'));
+ foreach ($record as $key=>$vo) {
+ $record[$key]['mold']=['customer'=>'客户','supplier'=>'供应商'][$vo['mold']];
+ if($vo['mold']=='customer'){
+ $record[$key]['collection']=floatval($vo['balance']);
+ $record[$key]['payment']=0;
+ }else{
+ $record[$key]['collection']=0;
+ $record[$key]['payment']=floatval($vo['balance']);
+ }
+ }
+ $result=[
+ 'state'=>'success',
+ 'count'=>$count,
+ 'info'=>$record
+ ];//返回数据
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //往来单位欠款表-导出
+ public function cdsExports(){
+ $input=input('get.');
+ $sheet=['customer','supplier'];
+ existFull($input,['mold'])||$input['mold']=$sheet;
+ if(is_array($input['mold']) && arrayInArray($input['mold'],$sheet)){
+ $base=fastSql($input,[
+ ['name','fullLike'],
+ ['number','fullLike'],
+ ['data','fullLike']
+ ]);
+ $base=frameScope($base);//组织数据
+ $sql=[];
+ foreach ($input['mold'] as $mold) {
+ if($mold=='customer'){
+ $sql[$mold]=sqlAuth('customer',$base);//数据鉴权
+ }else{
+ $sql[$mold]=sqlAuth('supplier',$base);//数据鉴权
+ }
+ }
+ $union=[];
+ foreach ($input['mold'] as $mold) {
+ $union[]=Db::name($mold)->where($sql[$mold])->fieldRaw('"'.$mold.'" as mold,id,name,number,data,balance')->buildSql();
+ }
+ $union=implode(' UNION ALL ',$union);
+ //获取总条数
+ $record=DB::query('SELECT * FROM ('.$union.') as nodcloud');
+ foreach ($record as $key=>$vo) {
+ $record[$key]['mold']=['customer'=>'客户','supplier'=>'供应商'][$vo['mold']];
+ if($vo['mold']=='customer'){
+ $record[$key]['collection']=floatval($vo['balance']);
+ $record[$key]['payment']=0;
+ }else{
+ $record[$key]['collection']=0;
+ $record[$key]['payment']=floatval($vo['balance']);
+ }
+ }
+ $source=$record;
+ //开始构造导出数据
+ $excel=[];//初始化导出数据
+ //标题数据
+ $excel[]=['type'=>'title','info'=>'往来单位欠款表'];
+ //表格数据
+ $field=[
+ "mold"=>"单位类型",
+ "name"=>"单位名称",
+ "number"=>"单位编号",
+ "collection"=>"应收款余额",
+ "payment"=>"应付款余额",
+ "data"=>"备注信息"
+ ];
+ $thead=array_values($field);//表格标题
+ $tbody=[];//表格内容
+ //构造表内数据
+ foreach ($source as $sourceVo) {
+ $rowData=[];
+ foreach (array_keys($field) as $fieldVo) {
+ $rowData[]=arraySeek($sourceVo,$fieldVo);//多键名数据赋值
+ }
+ $tbody[]=$rowData;//加入行数据
+ }
+ $excel[]=['type'=>'table','info'=>['thead'=>$thead,'tbody'=>$tbody]];//表格数据
+ //汇总数据
+ $excel[]=['type'=>'node','info'=>[
+ '总数:'.count($source),
+ '总应收款余额:'.mathArraySum(array_column($source,'collection')),
+ '总应付款余额:'.mathArraySum(array_column($source,'payment'))
+ ]];
+ //导出execl
+ buildExcel('往来单位欠款表',$excel);
+ }else{
+ return json(['state'=>'error','info'=>'传入参数不完整!']);
+ }
+ }
+}
diff --git a/serve/app/controller/Customer.php b/serve/app/controller/Customer.php
new file mode 100644
index 0000000..0c703a2
--- /dev/null
+++ b/serve/app/controller/Customer.php
@@ -0,0 +1,258 @@
+'name|py'],'fullLike'],
+ ['number','fullLike'],
+ ['category','fullEq'],
+ ['grade','fullEq'],
+ ['contacts','fullLike'],
+ [['tel'=>'contacts'],'fullLike'],
+ ['user','fullEq'],
+ ['data','fullLike']
+ ]);//构造SQL
+ $sql=frameScope($sql);//组织数据
+ $sql=sqlAuth('customer',$sql);//数据鉴权
+ $count = Customers::where($sql)->count();//获取总条数
+ $info = Customers::with(['frameData','userData'])->where($sql)->page($input['page'],$input['limit'])->order(['id'=>'desc'])->select();//查询分页数据
+ $result=[
+ 'state'=>'success',
+ 'count'=>$count,
+ 'info'=>$info
+ ];//返回数据
+ return json($result);
+ }
+ //新增|更新
+ public function save(){
+ $input=input('post.');
+ if(isset($input['id'])){
+ //构造|验证
+ try {
+ //排除balance字段|防止更新应收款余额
+ unset($input['balance']);
+ $input['py']=zhToPy($input['name']);//首拼信息
+ empty($input['id'])?$this->validate($input,'app\validate\Customer'):$this->validate($input,'app\validate\Customer.update');
+ } catch (ValidateException $e) {
+ return json(['state'=>'error','info'=>$e->getError()]);
+ exit;
+ }
+
+ //处理数据
+ Db::startTrans();
+ try {
+ if(empty($input['id'])){
+ //创建数据
+ Customers::create($input);
+ pushLog('新增客户[ '.$input['name'].' ]');//日志
+ }else{
+ //更新数据
+ Customers::update($input);
+ pushLog('更新客户[ '.$input['name'].' ]');//日志
+ }
+
+ Db::commit();
+ $result=['state'=>'success'];
+ } catch (\Exception $e) {
+ Db::rollback();
+ $result=['state'=>'error','info'=>'内部错误,操作已撤销!'];
+ }
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //获取
+ public function get(){
+ $input=input('post.');
+ if(existFull($input,['id'])){
+ $result=[
+ 'state'=>'success',
+ 'info'=>Customers::where([['id','=',$input['id']]])->find()
+ ];
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //删除
+ public function del(){
+ $input=input('post.');
+ if(existFull($input,['parm']) && is_array($input['parm'])){
+ //关联判断
+ $exists=[
+ ['table'=>'sor','where'=>[['customer','in',$input['parm']]]],
+ ['table'=>'sell','where'=>[['customer','in',$input['parm']]]],
+ ['table'=>'sre','where'=>[['customer','in',$input['parm']]]],
+ ['table'=>'extry','where'=>[['customer','in',$input['parm']]]],
+ ['table'=>'imy','where'=>[['customer','in',$input['parm']]]],
+ ['table'=>'bill','where'=>[['customer','in',$input['parm']]]],
+ ['table'=>'ice','where'=>[['customer','in',$input['parm']]]]
+ ];
+ //多值匹配
+ foreach($input['parm'] as $v){
+ $exists[]=['table'=>'deploy','where'=>[['source','like','%"customer":'.$v.'%']]];
+ }
+ $exist=moreTableFind($exists);
+ if(empty($exist)){
+ //逻辑处理
+ $data=Db::name('customer')->where([['id','in',$input['parm']]])->order(['id'=>'desc'])->select()->toArray();
+ Db::startTrans();
+ try {
+ Db::name('customer')->where([['id','in',$input['parm']]])->delete();
+ Db::name('log')->insert(['time'=>time(),'user'=>getUserID(),'info'=>'删除客户[ '.implode(' | ',array_column($data,'name')).' ]']);
+
+ Db::commit();
+ $result=['state'=>'success'];
+ } catch (\Exception $e) {
+ Db::rollback();
+ $result=['state'=>'error','info'=>'内部错误,操作已撤销!'];
+ }
+ }else{
+ $result=['state'=>'error','info'=>'存在数据关联,删除失败!'];
+ }
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //导入
+ public function import(){
+ delOverdueFile('static.upload.xlsx');//删除过期文件
+ $file=request()->file('file');//获取上传文件
+ if(empty($file)){
+ $result=['state'=>'error','info'=>'传入数据不完整!'];
+ }else{
+ try{
+ validate(['file'=>['fileSize'=>2*1024*1024,'fileExt'=>'xlsx']])->check(['file'=>$file]);
+ $fileInfo = Filesystem::disk('upload')->putFile('xlsx', $file, 'uniqid');
+ $filePath = pathChange('static.upload').$fileInfo;
+ $data=getXlsx($filePath);
+ unset($data[1]);//删除标题行
+ unset($data[2]);//删除列名行
+ $sql=[];//初始化SQL
+ $frame=Db::name('frame')->where([['name','in',array_column($data,'C')]])->select()->toArray();
+ foreach ($data as $dataKey=>$dataVo) {
+ $record=[
+ 'name'=>$dataVo['A'],
+ 'py'=>zhToPy($dataVo['A']),
+ 'number'=>$dataVo['B'],
+ 'frame'=>$dataVo['C'],
+ 'user'=>getUserID(),
+ 'category'=>$dataVo['D'],
+ 'grade'=>$dataVo['E'],
+ 'bank'=>$dataVo['F'],
+ 'account'=>$dataVo['G'],
+ 'tax'=>$dataVo['H'],
+ 'data'=>$dataVo['I'],
+ 'contacts'=>(empty($dataVo['J'])&&empty($dataVo['K']))?[]:[['main'=>true,'name'=>$dataVo['J'],'tel'=>$dataVo['K'],'add'=>$dataVo['L'],'data'=>$dataVo['M']]],
+ 'more'=>[]
+ ];
+
+ //所属组织匹配
+ $frameFind=search($frame)->where([['name','=',$record['frame']]])->find();
+ if(empty($frameFind)){
+ throw new ValidateException('模板文件第'.$dataKey.'行所属组织[ '.$record['frame'].' ]未匹配!');
+ }else{
+ $record['frame']=$frameFind['id'];
+ }
+ try {
+ //数据合法性验证
+ $this->validate($record,'app\validate\Customer');
+ $sql[]=$record;//加入SQL
+ } catch (ValidateException $e) {
+ return json(['state'=>'error','info'=>'模板文件第[ '.$dataKey.' ]行'.$e->getError()]);
+ exit;
+ }
+ }
+ //判断编号重复
+ $column=array_column($sql,'number');
+ $unique=array_unique($column);
+ $diff=array_diff_assoc($column,$unique);
+ if(!empty($diff)){
+ //返回错误信息
+ return json(['state'=>'error','info'=>'模板文件客户编号[ '.implode(' | ',$diff).' ]重复!']);
+ }
+ //处理关联数据
+ foreach($sql as $sqlKey=>$sqlVo){
+ $sys=getSys(['crCategory','crGrade']);
+ //客户类别
+ if(!in_array($sqlVo['category'],$sys['crCategory'])){
+ $sys['crCategory'][]=$sqlVo['category'];
+ Sys::where([['name','=','crCategory']])->update(['info'=>json_encode($sys['crCategory'])]);
+ }
+ //客户等级
+ if(!in_array($sqlVo['grade'],$sys['crGrade'])){
+ $sys['crGrade'][]=$sqlVo['grade'];
+ Sys::where([['name','=','crGrade']])->update(['info'=>json_encode($sys['crGrade'])]);
+ }
+ }
+ //新增数据
+ $customer = new Customers;
+ $customer->saveAll($sql);
+ pushLog('批量导入[ '.count($sql).' ]条客户数据');//日志
+ $result=['state'=>'success','info'=>'成功导入'.count($sql).'行客户数据'];
+ }catch(ValidateException $e) {
+ $result=['state'=>'error','info'=>$e->getMessage()];//返回错误信息
+ }
+ }
+ return json($result);
+ }
+ //导出
+ public function exports(){
+ $input=input('get.');
+ if(existFull($input,['parm']) && is_array($input['parm'])){
+ $info=Customers::with(['frameData','userData'])->where([['id','in',$input['parm']]])->order(['id'=>'desc'])->select()->toArray();//查询数据
+ foreach ($info as $infoKey=>$infoVo) {
+ $contactsArr=[];
+ foreach ($infoVo['contacts'] as $contactsVo) {
+ $contactsArr[]=$contactsVo['name'].' | '.$contactsVo['tel'].' | '.$contactsVo['add'].' | '.$contactsVo['data'];
+ }
+ $info[$infoKey]['contacts']=implode(chr(10),$contactsArr);
+ }
+ $field=[
+ 'name'=>'客户名称',
+ 'number'=>'客户编号',
+ 'category'=>'客户类别',
+ 'grade'=>'客户等级',
+ 'bank'=>'开户银行',
+ 'account'=>'银行账号',
+ 'tax'=>'纳税号码',
+ 'balance'=>'应收款余额',
+ 'frameData|name'=>'所属组织',
+ 'userData|name'=>'所属用户',
+ 'data'=>'备注信息',
+ 'contacts'=>'联系资料'
+ ];
+ //开始构造导出数据
+ $excel=[];//初始化导出数据
+ //标题数据
+ $excel[]=['type'=>'title','info'=>'客户信息'];
+ //表格数据
+ $thead=array_values($field);//表格标题
+ $tbody=[];//表格内容
+ //构造表内数据
+ foreach ($info as $infoVo) {
+ $rowData=[];
+ foreach (array_keys($field) as $fieldVo) {
+ $rowData[]=arraySeek($infoVo,$fieldVo);//多键名数据赋值
+ }
+ $tbody[]=$rowData;//加入行数据
+ }
+ $excel[]=['type'=>'table','info'=>['thead'=>$thead,'tbody'=>$tbody]];//表格数据
+ //统计数据
+ $excel[]=['type'=>'node','info'=>['总数:'.count($info)]];
+ //导出execl
+ pushLog('导出客户信息');//日志
+ buildExcel('客户信息',$excel);
+ }else{
+ return json(['state'=>'error','info'=>'传入数据不完整!']);
+ }
+ }
+}
\ No newline at end of file
diff --git a/serve/app/controller/Deploy.php b/serve/app/controller/Deploy.php
new file mode 100644
index 0000000..86b4bd3
--- /dev/null
+++ b/serve/app/controller/Deploy.php
@@ -0,0 +1,93 @@
+count();//获取总条数
+ $info = Deploys::with(['frameData'])->where($sql)->page($input['page'],$input['limit'])->order(['id'=>'desc'])->select();//查询分页数据
+ $result=[
+ 'state'=>'success',
+ 'count'=>$count,
+ 'info'=>$info
+ ];//返回数据
+ return json($result);
+ }
+ //新增|更新
+ public function save(){
+ $input=input('post.');
+ if(isset($input['id'])){
+ //验证数据
+ try {
+ empty($input['id'])?$this->validate($input,'app\validate\Deploy'):$this->validate($input,'app\validate\Deploy.update');
+ } catch (ValidateException $e) {
+ return json(['state'=>'error','info'=>$e->getError()]);
+ exit;
+ }
+
+ //处理数据
+ Db::startTrans();
+ try {
+ if(empty($input['id'])){
+ //创建数据
+ Deploys::create($input);
+ pushLog('新增零售配置');//日志
+ }else{
+ //更新数据
+ Deploys::update($input);
+ pushLog('更新零售配置');//日志
+ }
+
+ Db::commit();
+ $result=['state'=>'success'];
+ } catch (\Exception $e) {
+ Db::rollback();
+ $result=['state'=>'error','info'=>'内部错误,操作已撤销!'];
+ }
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //获取
+ public function get(){
+ $input=input('post.');
+ if(existFull($input,['id'])){
+ $result=[
+ 'state'=>'success',
+ 'info'=>Deploys::where([['id','=',$input['id']]])->find()
+ ];
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //删除
+ public function del(){
+ $input=input('post.');
+ if(existFull($input,['id'])){
+ Db::startTrans();
+ try {
+ Db::name('deploy')->where([['id','=',$input['id']]])->delete();
+ pushLog('删除零售配置');//日志
+
+ Db::commit();
+ $result=['state'=>'success'];
+ } catch (\Exception $e) {
+ Db::rollback();
+ $result=['state'=>'error','info'=>'内部错误,操作已撤销!'];
+ }
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+}
\ No newline at end of file
diff --git a/serve/app/controller/Entry.php b/serve/app/controller/Entry.php
new file mode 100644
index 0000000..c73214d
--- /dev/null
+++ b/serve/app/controller/Entry.php
@@ -0,0 +1,976 @@
+'time'],'startTime'],
+ [['endTime'=>'time'],'endTime'],
+ ['type','fullDec1'],
+ ['examine','fullDec1'],
+ ['cse','fullDec1'],
+ ['check','fullDec1'],
+ ['user','fullEq'],
+ ['data','fullLike']
+ ]);//构造SQL
+ //商品信息扩展查询
+ if(existFull($input,['goods'])){
+ $goods=array_column(Db::name('goods')->where([['name|py','like','%'.$input['goods'].'%']])->select()->toArray(),'id');
+ $sql[]=['id','in',array_column(Db::name('entry_info')->where([['goods','in',$goods]])->select()->toArray(),'pid')];
+ }
+ $sql=frameScope($sql);//组织数据
+ $sql=sqlAuth('entry',$sql);//数据鉴权
+ $count = Entrys::where($sql)->count();//获取总条数
+ $info = Entrys::with(['frameData','peopleData','userData','costData','recordData','supplierData'])->where($sql)->append(['extension'])->page($input['page'],$input['limit'])->order(['id'=>'desc'])->select()->toArray();//查询分页数据
+ $result=[
+ 'state'=>'success',
+ 'count'=>$count,
+ 'info'=>$info
+ ];//返回数据
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //新增|更新
+ public function save(){
+ $input=input('post.');
+ if(existFull($input,['class','info']) && isset($input['class']['id']) && isset($input['cost'])){
+ //构造|验证CLASS
+ try {
+ $class=$input['class'];
+ $class['frame']=userInfo(getUserID(),'frame');
+ $class['user']=getUserID();
+ $class['cse']=empty($class['cost'])?3:0;
+ $class['examine']=0;
+ empty($class['id'])?$this->validate($class,'app\validate\Entry'):$this->validate($class,'app\validate\Entry.update');
+ $period=getPeriod();
+ if(strtotime($class['time'])<=$period){
+ throw new ValidateException('单据日期与结账日期冲突!');
+ }
+ } catch (ValidateException $e) {
+ return json(['state'=>'error','info'=>$e->getError()]);
+ exit;
+ }
+ //验证INFO
+ foreach ($input['info'] as $infoKey=>$infoVo) {
+ try {
+ $this->validate($infoVo,'app\validate\EntryInfo');
+ } catch (ValidateException $e) {
+ return json(['state'=>'error','info'=>'商品信息第'.($infoKey+1).'条'.$e->getError()]);
+ exit;
+ }
+ }
+
+ //验证Cost
+ foreach ($input['cost'] as $costKey=>$costVo) {
+ try {
+ $this->validate($costVo,'app\validate\Cost');
+ } catch (ValidateException $e) {
+ return json(['state'=>'error','info'=>'单据费用第'.($infoKey+1).'条'.$e->getError()]);
+ exit;
+ }
+ }
+
+ //处理数据
+ Db::startTrans();
+ try {
+ //CLASS数据
+ if(empty($class['id'])){
+ //创建数据
+ $createInfo=Entrys::create($class);
+ $class['id']=$createInfo['id'];//转存主键
+ Db::name('record')->insert(['type'=>'entry','source'=>$class['id'],'time'=>time(),'user'=>getUserID(),'info'=>'新增单据']);
+ pushLog('新增其它入库单[ '.$class['number'].' ]');//日志
+ }else{
+ //更新数据
+ $updateInfo=Entrys::update($class);
+ Db::name('record')->insert(['type'=>'entry','source'=>$class['id'],'time'=>time(),'user'=>getUserID(),'info'=>'更新单据']);
+ pushLog('更新其它入库单[ '.$class['number'].' ]');//日志
+ }
+
+ //INFO数据
+ EntryInfo::where([['pid','=',$class['id']]])->delete();
+ foreach ($input['info'] as $infoKey=>$infoVo) {
+ $input['info'][$infoKey]['pid']=$class['id'];
+ }
+ $model = new EntryInfo;
+ $model->saveAll($input['info']);
+
+ //COST数据
+ Cost::where([['type','=','entry'],['class','=',$class['id']]])->delete();
+ foreach ($input['cost'] as $costKey=>$costVo) {
+ unset($input['cost'][$costKey]['id']);
+ $input['cost'][$costKey]['type']='entry';
+ $input['cost'][$costKey]['class']=$class['id'];
+ $input['cost'][$costKey]['time']=$class['time'];
+ $input['cost'][$costKey]['settle']=0;
+ $input['cost'][$costKey]['state']=0;
+ }
+ $model = new Cost;
+ $model->saveAll($input['cost']);
+
+ Db::commit();
+ $result=['state'=>'success','info'=>$class['id']];
+ } catch (\Exception $e) {
+ Db::rollback();
+ $result=['state'=>'error','info'=>'内部错误,操作已撤销!'];
+ }
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //获取
+ public function get(){
+ $input=input('post.');
+ if(existFull($input,['parm'])){
+ $class=Entrys::where([['id','=',$input['parm']]])->find();
+ $info=EntryInfo::with(['goodsData','warehouseData'])->where([['pid','=',$input['parm']]])->order(['id'=>'asc'])->select();
+ $cost=Cost::where([['type','=','entry'],['class','=',$input['parm']]])->order(['id'=>'asc'])->select();
+ $result=['state'=>'success','info'=>[
+ 'class'=>$class,
+ 'info'=>$info,
+ 'cost'=>$cost
+ ]];
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //删除
+ public function del(){
+ $input=input('post.');
+ if(existFull($input,['parm']) && is_array($input['parm'])){
+ $data=Db::name('entry')->where([['id','in',$input['parm']]])->order(['id'=>'desc'])->select()->toArray();
+ $search=search($data)->where([['examine','=','1']])->find();
+ if(empty($search)){
+ Db::startTrans();
+ try {
+ Db::name('entry')->where([['id','in',$input['parm']]])->delete();
+ Db::name('entry_info')->where([['pid','in',$input['parm']]])->delete();
+ Db::name('cost')->where([['type','=','entry'],['class','in',$input['parm']]])->delete();
+ Db::name('record')->where([['type','=','entry'],['source','in',$input['parm']]])->delete();
+ Db::name('log')->insert(['time'=>time(),'user'=>getUserID(),'info'=>'删除其它入库单[ '.implode(' | ',array_column($data,'number')).' ]']);
+
+ Db::commit();
+ $result=['state'=>'success'];
+ } catch (\Exception $e) {
+ Db::rollback();
+ $result=['state'=>'error','info'=>'内部错误,操作已撤销!'];
+ }
+ }else{
+ $result=['state'=>'error','info'=>'单据['.$search['number'].']已审核,不可删除!'];
+ }
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //核对|反核对
+ public function check(){
+ $input=input('post.');
+ if(existFull($input,['parm']) && is_array($input['parm'])){
+ $period=getPeriod();
+ $classList=Db::name('entry')->where([['id','in',$input['parm']]])->order(['id'=>'desc'])->select()->toArray();
+ foreach ($input['parm'] as $parmVo) {
+ $class=search($classList)->where([['id','=',$parmVo]])->find();
+ if($class['time']<=$period){
+ return json(['state'=>'error','info'=>'操作单据失败,原因:单据日期与结账日期冲突!']);
+ exit;
+ }
+ if(empty($class['check'])){
+ Db::name('entry')->where([['id','=',$class['id']]])->update(['check'=>1]);
+ //1 单据记录
+ Db::name('record')->insert(['type'=>'entry','source'=>$class['id'],'time'=>time(),'user'=>getUserID(),'info'=>'核对单据']);
+ //2 记录操作
+ pushLog('核对其它入库单[ '.$class['number'].' ]');//单据日志
+ }else{
+ Db::name('entry')->where([['id','=',$class['id']]])->update(['check'=>0]);
+ //1 单据记录
+ Db::name('record')->insert(['type'=>'entry','source'=>$class['id'],'time'=>time(),'user'=>getUserID(),'info'=>'反核对单据']);
+ //2 记录操作
+ pushLog('反核对其它入库单[ '.$class['number'].' ]');//单据日志
+ }
+ }
+ $result=['state'=>'success'];
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //审核|反审核
+ public function examine(){
+ $input=input('post.');
+ if(existFull($input,['parm']) && is_array($input['parm'])){
+ //1 基础数据
+ $period=getPeriod();
+ $classList=Db::name('entry')->where([['id','in',$input['parm']]])->order(['id'=>'desc'])->select()->toArray();
+ $infoList=Db::name('entry_info')->where([['pid','in',$input['parm']]])->order(['id'=>'asc'])->select()->toArray();
+ //2 综合处理
+ foreach ($input['parm'] as $parmVo) {
+ //1 匹配数据
+ $class=search($classList)->where([['id','=',$parmVo]])->find();
+ $info=search($infoList)->where([['pid','=',$parmVo]])->select();
+ //1.1 商品数据
+ $goodsList=Db::name('goods')->where([['id','in',array_unique(array_column($info,'goods'))]])->select()->toArray();
+ //1.2 综合匹配
+ if(empty($class['examine'])){
+ //1 构造数据
+ $batchGather=[];
+ $serialGather=[];
+ $roomWhereOrSql=[];
+ foreach ($info as $infoVo) {
+ //1 批次号
+ empty($infoVo['batch'])||$batchGather[]=$infoVo['batch'];
+ //2 序列号
+ $serialGather=array_merge($serialGather,json_decode($infoVo['serial']));
+ //3 仓储条件
+ empty($infoVo['warehouse'])||$roomWhereOrSql[]=[['warehouse','=',$infoVo['warehouse']],['goods','=',$infoVo['goods']],['attr','=',$infoVo['attr']]];
+ }
+ //2 匹配数据
+ empty($batchGather)||$batchList=Db::name('batch')->where([['number','in',$batchGather]])->select()->toArray();
+ empty($serialGather)||$serialList=Db::name('serial')->where([['number','in',$serialGather]])->select()->toArray();
+ if(!empty($roomWhereOrSql)){
+ //1 去重转存
+ $roomWhereOrSql=array_unique($roomWhereOrSql,SORT_REGULAR);
+ //2 仓储匹配
+ $roomList=Db::name('room')->whereOr($roomWhereOrSql)->select()->toArray();
+ }
+ }
+
+ //2 CLASS验证
+ if($class['time']<=$period){
+ return json(['state'=>'error','info'=>'操作单据[ '.$class['number'].' ]失败,原因:单据日期与结账日期冲突!']);
+ exit;
+ }
+ if(!empty($class['examine'])){
+ //单据费用
+ $cost=Db::name('cost')->alias('cost')->where([['type','=','entry'],['class','=',$class['id']]])->whereExists(function($query){
+ $query->name('oce_info')->where([['source','=',Db::raw('cost.id')]])->limit(1);
+ })->find();
+ if(!empty($cost)){
+ return json(['state'=>'error','info'=>'反审核单据[ '.$class['number'].' ]失败,原因:该单据存在关联其它支出单!']);
+ exit;
+ }
+ }
+
+ //3 INFO验证|构造
+ foreach ($info as $infoKey=>$infoVo) {
+ //1 匹配商品
+ $goods=search($goodsList)->where([['id','=',$infoVo['goods']]])->find();
+ //2 商品类型
+ if(empty($goods['type'])){
+ //场景验证
+ if(empty($class['examine'])){
+ //1 多单位处理
+ if($goods['unit']==-1){
+ //多单位|转存
+ $radix=unitRadix($infoVo['unit'],json_decode($goods['units'],true));
+ $info[$infoKey]['basic']=[
+ 'nums'=>math()->chain($infoVo['nums'])->mul($radix)->done(),
+ 'price'=>math()->chain($infoVo['price'])->div($radix)->round(4)->done()
+ ];
+ }else{
+ //常规单位|转存
+ $info[$infoKey]['basic']=[
+ 'nums'=>$infoVo['nums'],
+ 'price'=>$infoVo['price']
+ ];
+ }
+ //2 序列号
+ $serialData=json_decode($infoVo['serial']);
+ if(empty($serialData)){
+ $info[$infoKey]['serial']=[];
+ }else{
+ //序列号状态[不存在|已退货]
+ $serialFind=search($serialList)->where([['goods','=',$infoVo['goods']],['number','in',$serialData],['state','<>',3]])->find();
+ if(empty($serialFind)){
+ $info[$infoKey]['serial']=$serialData;
+ }else{
+ return json(['state'=>'error','info'=>'审核单据[ '.$class['number'].' ]失败,原因:第'.($infoKey+1).'行序列号[ '.$serialFind['number'].' ]状态不正确!']);
+ exit;
+ }
+ }
+ }else{
+ //1 验证序列号
+ $serialInfoCollect=Db::name('serial_info')->where([['type','=','entry'],['info','in',array_column($info,'id')]])->select()->toArray();
+ if(!empty($serialInfoCollect)){
+ //序列号状态[未销售]
+ $serialFind=Db::name('serial')->where([['id','in',array_column($serialInfoCollect,'pid')],['state','<>',0]])->find();
+ if(!empty($serialFind)){
+ return json(['state'=>'error','info'=>'反审核单据[ '.$class['number'].' ]失败,原因:第'.($infoKey+1).'行序列号[ '.$serialFind['number'].' ]状态不正确!']);
+ exit;
+ }
+ }
+ }
+ }
+ }
+ //4 数据处理
+ Db::startTrans();
+ try {
+ //场景验证
+ if(empty($class['examine'])){
+ //审核
+ //1 构造数据
+ $store=['room'=>[],'roomInfo'=>[],'batch'=>[],'batchInfo'=>[],'serial'=>[],'serialInfo'=>[],'serve'=>[],'serveInfo'=>[]];
+ foreach ($info as $infoKey=>$infoVo){
+ //判断商品类型
+ $goods=search($goodsList)->where([['id','=',$infoVo['goods']]])->find();
+ if(empty($goods['type'])){
+ //常规商品
+ //1 仓储
+ $store['room'][]=['warehouse'=>$infoVo['warehouse'],'goods'=>$infoVo['goods'],'attr'=>$infoVo['attr'],'nums'=>$infoVo['basic']['nums']];
+ //2 仓储详情
+ $store['roomInfo'][]=['pid'=>null,'type'=>'entry','class'=>$class['id'],'info'=>$infoVo['id'],'time'=>$class['time'],'direction'=>1,'price'=>$infoVo['basic']['price'],'nums'=>$infoVo['basic']['nums']];
+ //3 批次号
+ if(empty($infoVo['batch'])){
+ $store['batch'][]=[];
+ $store['batchInfo'][]=[];
+ }else{
+ $store['batch'][]=['room'=>null,'warehouse'=>$infoVo['warehouse'],'goods'=>$infoVo['goods'],'number'=>$infoVo['batch'],'time'=>$infoVo['mfd'],'nums'=>$infoVo['basic']['nums']];
+ $store['batchInfo'][]=['pid'=>null,'type'=>'entry','class'=>$class['id'],'info'=>$infoVo['id'],'direction'=>1,'nums'=>$infoVo['basic']['nums']];
+ }
+ //4 序列号
+ if(empty($infoVo['serial'])){
+ $store['serial'][]=[];
+ $store['serialInfo'][]=[];
+ }else{
+ $serial=[];
+ $serialInfo=[];
+ foreach ($infoVo['serial'] as $serialVo) {
+ $serial[]=['room'=>null,'warehouse'=>$infoVo['warehouse'],'batch'=>null,'goods'=>$infoVo['goods'],'number'=>$serialVo,'state'=>0];
+ $serialInfo[]=['pid'=>null,'type'=>'entry','class'=>$class['id'],'info'=>$infoVo['id']];
+ }
+ $store['serial'][]=$serial;
+ $store['serialInfo'][]=$serialInfo;
+ }
+ }else{
+ //5 服务商品
+ $store['serve'][]=['goods'=>$infoVo['goods'],'attr'=>$infoVo['attr'],'nums'=>$infoVo['nums']];
+ $store['serveInfo'][]=['pid'=>null,'type'=>'entry','class'=>$class['id'],'info'=>$infoVo['id'],'time'=>$class['time'],'price'=>$infoVo['price'],'nums'=>$infoVo['nums']];
+ }
+ }
+ //2 仓储
+ if(!empty($store['room'])){
+ //1 构造数据
+ $roomInsert=[];
+ foreach ($store['room'] as $roomVo) {
+ $roomFind=search($roomList)->where([['warehouse','=',$roomVo['warehouse']],['goods','=',$roomVo['goods']],['attr','=',$roomVo['attr']]])->find();
+ if(empty($roomFind)){
+ $roomVo['nums']=0;
+ $roomInsert[]=$roomVo;
+ }
+ }
+ //2 创建数据|去重
+ empty($roomInsert)||Db::name('room')->insertAll(array_unique($roomInsert,SORT_REGULAR));
+ //3 匹配主键|构造更新
+ $roomDuplicate=[];
+ $room=Db::name('room')->whereOr($roomWhereOrSql)->select()->toArray();
+ foreach ($store['room'] as $roomKey=>$roomVo) {
+ $roomFind=search($room)->where([['warehouse','=',$roomVo['warehouse']],['goods','=',$roomVo['goods']],['attr','=',$roomVo['attr']]])->find();
+ $store['room'][$roomKey]['id']=$roomFind['id'];
+ $roomDuplicate[]=['id'=>$roomFind['id'],'nums'=>$roomVo['nums']];
+ }
+ //4 更新数据
+ Db::name('room')->duplicate(['nums'=>Db::raw('nums + VALUES(`nums`)')])->insertAll($roomDuplicate);
+ }
+ //3 仓储详情
+ if(!empty($store['roomInfo'])){
+ //1 填充数据
+ foreach ($store['roomInfo'] as $roomInfoKey=>$roomInfoVo) {
+ $store['roomInfo'][$roomInfoKey]['pid']=$store['room'][$roomInfoKey]['id'];
+ }
+ //2 创建数据
+ Db::name('room_info')->insertAll($store['roomInfo']);
+ }
+ //4 批次号
+ if(!empty($store['batch'])){
+ //1 构造数据
+ $batchData=[];
+ foreach ($store['batch'] as $batchKey=>$batchVo) {
+ if(!empty($batchVo)){
+ $store['batch'][$batchKey]['room']=$store['room'][$batchKey]['id'];
+ $batchData[]=$store['batch'][$batchKey];
+ }
+ }
+ //2 排除数据|[[],[],[]]
+ if(!empty($batchData)){
+ //1 构造数据
+ $batchInsert=[];
+ foreach ($batchData as $batchDataKey=>$batchDataVo) {
+ $batchFind=search($batchList)->where([['room','=',$batchDataVo['room']],['number','=',$batchDataVo['number']],['time','=',$batchDataVo['time']]])->find();
+ if(empty($batchFind)){
+ $batchDataVo['nums']=0;
+ $batchInsert[]=$batchDataVo;
+ }
+ }
+ //2 创建数据|去重
+ empty($batchInsert)||Db::name('batch')->insertAll(array_unique($batchInsert,SORT_REGULAR));
+ //3 匹配主键|构造更新
+ $batchDuplicate=[];
+ $batch=Db::name('batch')->where([['number','in',$batchGather]])->select()->toArray();
+ foreach ($store['batch'] as $batchKey=>$batchVo) {
+ if(!empty($batchVo)){
+ $batchFind=search($batch)->where([['room','=',$batchVo['room']],['number','=',$batchVo['number']],['time','=',$batchVo['time']]])->find();
+ $store['batch'][$batchKey]['id']=$batchFind['id'];
+ $batchDuplicate[]=['id'=>$batchFind['id'],'nums'=>$batchVo['nums']];
+ }
+ }
+ //4 更新数据
+ Db::name('batch')->duplicate(['nums'=>Db::raw('nums + VALUES(`nums`)')])->insertAll($batchDuplicate);
+ }
+ }
+ //5 批次号详情
+ if(!empty($store['batchInfo'])){
+ //1 构造数据
+ $batchInfoInstall=[];
+ foreach ($store['batchInfo'] as $batchInfoKey=>$batchInfoVo) {
+ if(!empty($batchInfoVo)){
+ $batchInfoVo['pid']=$store['batch'][$batchInfoKey]['id'];
+ $batchInfoInstall[]=$batchInfoVo;
+ }
+ }
+ //2 排除数据|[[],[],[]]
+ if(!empty($batchInfoInstall)){
+ //创建数据
+ Db::name('batch_info')->insertAll($batchInfoInstall);
+ }
+ }
+ //6 序列号
+ if(!empty($store['serial'])){
+ //1 构造数据
+ $serialData=[];
+ foreach ($store['serial'] as $serialKey=>$item) {
+ if(!empty($item)){
+ foreach ($item as $itemKey=>$itemVo) {
+ $store['serial'][$serialKey][$itemKey]['room']=$store['room'][$serialKey]['id'];
+ $store['serial'][$serialKey][$itemKey]['batch']=empty($store['batch'][$serialKey])?0:$store['batch'][$serialKey]['id'];
+ $serialData[]=$store['serial'][$serialKey][$itemKey];
+ }
+ }
+ }
+ //2 排除数据|[[],[],[]]
+ if(!empty($serialData)){
+ //1 构造数据
+ $serialInsert=[];
+ foreach ($serialData as $serialDataKey=>$serialDataVo) {
+ $serialFind=search($serialList)->where([['room','=',$serialDataVo['room']],['batch','=',$serialDataVo['batch']],['number','=',$serialDataVo['number']]])->find();
+ if(empty($serialFind)){
+ $serialInsert[]=$serialDataVo;
+ }
+ }
+ //2 创建数据
+ empty($serialInsert)||Db::name('serial')->insertAll($serialInsert);
+ //3 匹配主键|构造更新
+ $serialDuplicate=[];
+ $serial=Db::name('serial')->where([['number','in',$serialGather]])->select()->toArray();
+ foreach ($store['serial'] as $serialKey=>$item) {
+ if(!empty($item)){
+ foreach ($item as $itemKey=>$itemVo) {
+ $serialFind=search($serial)->where([['room','=',$itemVo['room']],['batch','=',$itemVo['batch']],['number','=',$itemVo['number']]])->find();
+ $store['serial'][$serialKey][$itemKey]['id']=$serialFind['id'];
+ $serialFind['state']==3&&$serialDuplicate[]=$serialFind['id'];
+ }
+ }
+ }
+ //4 更新数据|状态变更
+ empty($serialDuplicate)||Db::name('serial')->where([['id','in',$serialDuplicate]])->update(['state'=>0]);
+ }
+ }
+ //7 序列号详情
+ if(!empty($store['serialInfo'])){
+ //1 构造数据
+ $serialInfoInstall=[];
+ foreach ($store['serialInfo'] as $serialInfoKey=>$item) {
+ if(!empty($item)){
+ foreach ($item as $itemKey=>$itemVo) {
+ $itemVo['pid']=$store['serial'][$serialInfoKey][$itemKey]['id'];
+ $serialInfoInstall[]=$itemVo;
+ }
+ }
+ }
+ //2 排除数据|[[],[],[]]
+ if(!empty($serialInfoInstall)){
+ //创建数据
+ Db::name('serial_info')->insertAll($serialInfoInstall);
+ }
+ }
+ //8 服务商品
+ if(!empty($store['serve'])){
+ //1 匹配数据|去重
+ $serveWhereOrSql=array_unique(array_map(function($item){
+ return [['goods','=',$item['goods']],['attr','=',$item['attr']]];
+ },$store['serve']),SORT_REGULAR);
+ $serve=Db::name('serve')->whereOr($serveWhereOrSql)->select()->toArray();
+ //2 构造数据
+ $serveInsert=[];
+ foreach ($store['serve'] as $serveVo) {
+ $serveFind=search($serve)->where([['goods','=',$serveVo['goods']],['attr','=',$serveVo['attr']]])->find();
+ if(empty($serveFind)){
+ $serveVo['nums']=0;
+ $serveInsert[]=$serveVo;
+ }
+ }
+ //3 创建数据|去重
+ empty($serveInsert)||Db::name('serve')->insertAll(array_unique($serveInsert,SORT_REGULAR));
+ //4 匹配主键|构造更新
+ $serveDuplicate=[];
+ $serve=Db::name('serve')->whereOr($serveWhereOrSql)->select()->toArray();
+ foreach ($store['serve'] as $serveKey=>$serveVo) {
+ $serveFind=search($serve)->where([['goods','=',$serveVo['goods']],['attr','=',$serveVo['attr']]])->find();
+ $store['serve'][$serveKey]['id']=$serveFind['id'];
+ $serveDuplicate[]=['id'=>$serveFind['id'],'nums'=>$serveVo['nums']];
+ }
+ //5 更新数据
+ Db::name('serve')->duplicate(['nums'=>Db::raw('nums + VALUES(`nums`)')])->insertAll($serveDuplicate);
+ }
+ //9 服务商品详情
+ if(!empty($store['serveInfo'])){
+ //1 填充数据
+ foreach ($store['serveInfo'] as $serveInfoKey=>$serveInfoVo) {
+ $store['serveInfo'][$serveInfoKey]['pid']=$store['serve'][$serveInfoKey]['id'];
+ }
+ //2 创建数据
+ Db::name('serve_info')->insertAll($store['serveInfo']);
+ }
+ //10 更新单据
+ Db::name('entry')->where([['id','=',$class['id']]])->update(['examine'=>1]);
+ //11 单据记录
+ Db::name('record')->insert(['type'=>'entry','source'=>$class['id'],'time'=>time(),'user'=>getUserID(),'info'=>'审核单据']);
+ //12 收发记录
+ $summary=new Summary;
+ $summary->note('entry',$class['id'],true);
+ //13 记录操作
+ pushLog('审核其它入库单[ '.$class['number'].' ]');//单据日志
+ }else{
+ //反审核
+ //1 匹配数据
+ $listSql=[['type','=','entry'],['info','in',array_column($info,'id')]];
+ $roomInfoList=Db::name('room_info')->where($listSql)->select()->toArray();
+ $batchInfoList=Db::name('batch_info')->where($listSql)->select()->toArray();
+ $serialInfoList=Db::name('serial_info')->where($listSql)->select()->toArray();
+ $serveInfoList=Db::name('serve_info')->where($listSql)->select()->toArray();
+ //1 仓储
+ $roomDuplicate=[];
+ foreach ($roomInfoList as $roomInfoVo) {
+ $roomDuplicate[]=['id'=>$roomInfoVo['pid'],'nums'=>$roomInfoVo['nums']];
+ }
+ //2.1 更新仓储
+ Db::name('room')->duplicate(['nums'=>Db::raw('nums - VALUES(`nums`)')])->insertAll($roomDuplicate);
+ //2.2 删除仓储详情
+ Db::name('room_info')->where([['id','in',array_column($roomInfoList,'id')]])->delete();
+ //2.3 仓储|冗余
+ $roomPk=array_unique(array_column($roomInfoList,'pid'));
+ $roomInfoData=Db::name('room_info')->where([['pid','in',$roomPk]])->select()->toArray();
+ $roomDiff=array_diff($roomPk,array_unique(array_column($roomInfoData,'pid')));
+ empty($roomDiff)||Db::name('room')->where([['id','in',$roomDiff]])->delete();
+ //3 批次号
+ if(!empty($batchInfoList)){
+ //1 构造数据
+ $batchInfoDuplicate=array_map(function($item){
+ return ['id'=>$item['pid'],'nums'=>$item['nums']];
+ },$batchInfoList);
+ //2 更新批次号
+ Db::name('batch')->duplicate(['nums'=>Db::raw('nums - VALUES(`nums`)')])->insertAll($batchInfoDuplicate);
+ //3 删除批次号详情
+ Db::name('batch_info')->where([['id','in',array_column($batchInfoList,'id')]])->delete();
+ //4 批次号|冗余
+ $batchPk=array_unique(array_column($batchInfoList,'pid'));
+ $batchInfoData=Db::name('batch_info')->where([['pid','in',$batchPk]])->select()->toArray();
+ $batchDiff=array_diff($batchPk,array_unique(array_column($batchInfoData,'pid')));
+ empty($batchDiff)||Db::name('batch')->where([['id','in',$batchDiff]])->delete();
+ }
+ //4 序列号
+ if(!empty($serialInfoList)){
+ //1 更新序列号
+ Db::name('serial')->where([['id','in',array_column($serialInfoList,'pid')]])->update(['state'=>3]);
+ //2 删除序列号详情
+ Db::name('serial_info')->where([['id','in',array_column($serialInfoList,'id')]])->delete();
+ //3 序列号|冗余
+ $serialPk=array_unique(array_column($serialInfoList,'pid'));
+ $serialInfoData=Db::name('serial_info')->where([['pid','in',$serialPk]])->select()->toArray();
+ $serialDiff=array_diff($serialPk,array_unique(array_column($serialInfoData,'pid')));
+ empty($serialDiff)||Db::name('serial')->where([['id','in',$serialDiff]])->delete();
+ }
+ //5 服务
+ if(!empty($serveInfoList)){
+ //1 构造数据
+ $serveInfoDuplicate=array_map(function($item){
+ return ['id'=>$item['pid'],'nums'=>$item['nums']];
+ },$serveInfoList);
+ //2 更新服务
+ Db::name('serve')->duplicate(['nums'=>Db::raw('nums - VALUES(`nums`)')])->insertAll($serveInfoDuplicate);
+ //3 删除服务详情
+ Db::name('serve_info')->where([['id','in',array_column($serveInfoList,'id')]])->delete();
+ //4 服务|冗余
+ $servePk=array_unique(array_column($serveInfoList,'pid'));
+ $serveInfoData=Db::name('serve_info')->where([['pid','in',$servePk]])->select()->toArray();
+ $serveDiff=array_diff($servePk,array_unique(array_column($serveInfoData,'pid')));
+ empty($serveDiff)||Db::name('serve')->where([['id','in',$serveDiff]])->delete();
+ }
+ //6 更新单据
+ Db::name('entry')->where([['id','=',$class['id']]])->update(['examine'=>0]);
+ //7 单据记录
+ Db::name('record')->insert(['type'=>'entry','source'=>$class['id'],'time'=>time(),'user'=>getUserID(),'info'=>'反审核单据']);
+ //8 收发记录
+ $summary=new Summary;
+ $summary->note('entry',$class['id'],false);
+ //9 记录操作
+ pushLog('反审核其它入库单[ '.$class['number'].' ]');//单据日志
+ }
+
+ Db::commit();
+ } catch (\Exception $e) {
+ Db::rollback();
+ return json(['state'=>'error','info'=>'内部错误,操作已撤销!']);
+ exit;
+ }
+ }
+ $result=['state'=>'success'];
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //上传
+ public function upload(){
+ $file = request()->file('file');
+ //获取上传文件
+ if (empty($file)) {
+ $result = ['state' => 'error','info' => '传入数据不完整!'];
+ } else {
+ //文件限制5MB
+ try{
+ validate(['file'=>['fileSize'=>5*1024*1024,'fileExt'=>'png,gif,jpg,jpeg,txt,doc,docx,rtf,xls,xlsx,ppt,pptx,pdf,zip,rar']])->check(['file'=>$file]);
+ $fileInfo=Filesystem::disk('upload')->putFile('entry', $file, 'uniqid');
+ $filePath=request()->domain().'/static/upload/'.$fileInfo;
+ $result=['state'=>'success','info'=>$filePath];
+ }catch(ValidateException $e) {
+ $result = ['state' => 'error','info' => $e->getMessage()];
+ }
+ }
+ return json($result);
+ }
+ //导入
+ public function import(){
+ delOverdueFile('static.upload.xlsx');//删除过期文件
+ $file=request()->file('file');//获取上传文件
+ if(empty($file)){
+ $result=['state'=>'error','info'=>'传入数据不完整!'];
+ }else{
+ $fun=getSys('fun');
+ try{
+ validate(['file'=>['fileSize'=>2*1024*1024,'fileExt'=>'xlsx']])->check(['file'=>$file]);
+ $fileInfo = Filesystem::disk('upload')->putFile('xlsx', $file, 'uniqid');
+ $filePath = pathChange('static.upload').$fileInfo;
+ $data=getXlsx($filePath);
+ unset($data[1]);//删除标题行
+ unset($data[2]);//删除列名行
+ //初始化CLASS
+ //单据类型匹配
+ if(in_array($data[3]['D'],['其它入库单','盘盈单'])){
+ $type=$data[3]['D']=="其它入库单"?0:1;
+ }else{
+ throw new ValidateException('单据类型[ '.$data[3]['D'].' ]未匹配!');
+ }
+ //关联人员匹配
+ if(empty($data[3]['F'])){
+ $people=['id'=>0];
+ }else{
+ $people=Db::name('people')->where([['name','=',$data[3]['F']]])->find();
+ if(empty($people)){
+ throw new ValidateException('关联人员[ '.$data[3]['F'].' ]未匹配!');
+ }
+ }
+ $class=[
+ 'frame'=>userInfo(getUserID(),'frame'),
+ 'supplier'=>$data[3]['A'],
+ 'time'=>$data[3]['B'],
+ 'number'=>$data[3]['C'],
+ 'type'=>$type,
+ 'total'=>0,
+ 'people'=>$people['id'],
+ 'logistics'=>["key"=>"auto","name"=>"自动识别","number"=>$data[3]['G']],
+ 'file'=>[],
+ 'data'=>$data[3]['H'],
+ 'more'=>[],
+ 'examine'=>0,
+ 'cse'=>0,
+ 'check'=>0,
+ 'user'=>getUserID()
+ ];
+ $this->validate($class,'app\validate\Entry');//数据合法性验证
+ //初始化INFO
+ $info=[];
+ $goods=Goods::with(['attr'])->where([['name','in',array_column($data,'I')]])->select()->toArray();
+ $warehouse=Db::name('warehouse')->where([['name','in',array_column($data,'L')]])->select()->toArray();
+ foreach ($data as $dataKey=>$dataVo) {
+ $record=[
+ 'goods'=>$dataVo['I'],
+ 'attr'=>$dataVo['J'],
+ 'unit'=>$dataVo['K'],
+ 'warehouse'=>$dataVo['L'],
+ 'batch'=>$dataVo['M'],
+ 'mfd'=>$dataVo['N'],
+ 'price'=>$dataVo['O'],
+ 'nums'=>$dataVo['P'],
+ 'serial'=>explode(',',$dataVo['Q']),
+ 'total'=>0,
+ 'data'=>$dataVo['S']
+ ];
+ //商品匹配
+ $goodsFind=search($goods)->where([['name','=',$record['goods']]])->find();
+ if(empty($goodsFind)){
+ throw new ValidateException('模板文件第'.$dataKey.'行商品名称[ '.$record['goods'].' ]未匹配!');
+ }else{
+ $record['goods']=$goodsFind['id'];
+ }
+ //辅助属性匹配
+ if(empty($goodsFind['attr'])){
+ $record['attr']='';
+ }else{
+ if(empty($record['attr'])){
+ throw new ValidateException('模板文件第'.$dataKey.'行辅助属性不可为空!');
+ }else{
+ $attrFind=search($goodsFind['attr'])->where([['name','=',$record['attr']]])->find();
+ if(empty($attrFind)){
+ throw new ValidateException('模板文件第'.$dataKey.'行辅助属性[ '.$record['attr'].' ]未匹配!');
+ }
+ }
+ }
+ //单位匹配
+ if($goodsFind['unit']==-1){
+ if(empty($record['unit'])){
+ throw new ValidateException('模板文件第'.$dataKey.'行单位不可为空!');
+ }else{
+ $unitFind=search($goodsFind['units'])->where([['name','=',$record['unit']]])->find();
+ if(empty($unitFind) && $goodsFind['units'][0]['source']!=$record['unit']){
+ throw new ValidateException('模板文件第'.$dataKey.'行单位[ '.$record['unit'].' ]未匹配!');
+ }
+ }
+ }else{
+ $record['unit']=$goodsFind['unit'];
+ }
+ //仓库匹配
+ if(empty($goodsFind['type'])){
+ //常规产品
+ $warehouseFind=search($warehouse)->where([['name','=',$record['warehouse']]])->find();
+ if(empty($warehouseFind)){
+ throw new ValidateException('模板文件第'.$dataKey.'行仓库[ '.$record['warehouse'].' ]未匹配!');
+ }else{
+ $record['warehouse']=$warehouseFind['id'];
+ }
+ }else{
+ //服务产品
+ $record['warehouse']=null;
+ }
+ //批次号匹配
+ if(empty($goodsFind['batch'])){
+ $record['batch']='';
+ }else{
+ if(empty($record['batch'])){
+ throw new ValidateException('模板文件第'.$dataKey.'行批次号不可为空!');
+ }
+ }
+ //生产日期匹配
+ if(empty($goodsFind['validity'])){
+ $record['mfd']='';
+ }else{
+ if(empty($record['mfd'])){
+ throw new ValidateException('模板文件第'.$dataKey.'行生产日期不可为空!');
+ }
+ }
+ //成本匹配
+ if(!preg_match("/^\d+(\.\d{0,".$fun['digit']['money']."})?$/",$record['price'])){
+ throw new ValidateException('模板文件第'.$dataKey.'行成本不正确!');
+ }
+ //数量匹配
+ if(!preg_match("/^\d+(\.\d{0,".$fun['digit']['nums']."})?$/",$record['nums'])){
+ throw new ValidateException('模板文件第'.$dataKey.'行数量不正确!');
+ }
+ //序列号匹配
+ if(empty($goodsFind['serial'])){
+ $record['serial']=[];
+ }else{
+ if(count($record['serial'])==1 && empty($record['serial'][0])){
+ throw new ValidateException('模板文件第'.$dataKey.'行序列号不可为空!');
+ }else{
+ if(count($record['serial'])!=$record['nums']){
+ throw new ValidateException('模板文件第'.$dataKey.'行序列号个数与数量不符!');
+ }
+ }
+ }
+ try{
+ $this->validate($record,'app\validate\EntryInfo');//数据合法性验证
+ $record['total']=math()->chain($record['price'])->mul($record['nums'])->round($fun['digit']['money'])->done();
+ //转存数据
+ $class['total']=math()->chain($class['total'])->add($record['total'])->done();//累加单据成本
+ $info[]=$record;
+ } catch (ValidateException $e) {
+ return json(['state'=>'error','info'=>'模板文件第'.$dataKey.'行'.$e->getMessage()]);//返回错误信息
+ exit;
+ }
+ }
+ //序列号重复验证
+ $serials=[];
+ foreach ($info as $infoVo) {
+ $serials = array_merge($serials,$infoVo['serial']);
+ }
+ if(count($serials)!=count(array_unique($serials))){
+ throw new ValidateException('商品信息中存在重复序列号!');
+ }
+ Db::startTrans();
+ try {
+ //新增CLASS
+ $classData=Entrys::create($class);
+ //新增INFO
+ foreach ($info as $infoKey=>$infoVo) {
+ $info[$infoKey]['pid']=$classData['id'];
+ }
+ $model = new EntryInfo;
+ $model->saveAll($info);
+ Db::name('record')->insert(['type'=>'entry','source'=>$classData['id'],'time'=>time(),'user'=>getUserID(),'info'=>'导入单据']);
+ pushLog('导入其它入库单[ '.$classData['number'].' ]');//日志
+
+ Db::commit();
+ $result=['state'=>'success'];
+ } catch (\Exception $e) {
+ Db::rollback();
+ $result=['state'=>'error','info'=>'内部错误,操作已撤销!'];
+ }
+ }catch(ValidateException $e) {
+ $result=['state'=>'error','info'=>$e->getMessage()];//返回错误信息
+ }
+ }
+ return json($result);
+ }
+ //导出
+ public function exports(){
+ $input=input('get.');
+ if(existFull($input,['scene','parm']) && is_array($input['parm'])){
+ pushLog('导出其它入库单列表');//日志
+ $source=Entrys::with(['frameData','peopleData','userData','recordData','supplierData'])->where([['id','in',$input['parm']]])->append(['extension'])->order(['id'=>'desc'])->select()->toArray();//查询CLASS数据
+ if($input['scene']=='simple'){
+ //简易报表
+ //开始构造导出数据
+ $excel=[];//初始化导出数据
+ //标题数据
+ $excel[]=['type'=>'title','info'=>'其它入库单列表'];
+ //表格数据
+ $field=[
+ 'frameData|name'=>'所属组织',
+ 'supplierData|name'=>'供应商',
+ 'extension|type'=>'单据类型',
+ 'time'=>'单据时间',
+ 'number'=>'单据编号',
+ 'total'=>'单据成本',
+ 'cost'=>'单据费用',
+ 'peopleData|name'=>'关联人员',
+ 'extension|examine'=>'审核状态',
+ 'extension|cse'=>'费用状态',
+ 'extension|check'=>'核对状态',
+ 'userData|name'=>'制单人',
+ 'data'=>'备注信息'
+ ];
+ $thead=array_values($field);//表格标题
+ $tbody=[];//表格内容
+ //构造表内数据
+ foreach ($source as $sourceVo) {
+ $rowData=[];
+ foreach (array_keys($field) as $fieldVo) {
+ $rowData[]=arraySeek($sourceVo,$fieldVo);//多键名数据赋值
+ }
+ $tbody[]=$rowData;//加入行数据
+ }
+ $excel[]=['type'=>'table','info'=>['thead'=>$thead,'tbody'=>$tbody]];//表格数据
+ //统计数据
+ $excel[]=['type'=>'node','info'=>[
+ '总数:'.count($source),
+ '总单据成本:'.mathArraySum(array_column($source,'total')),
+ '总单据费用:'.mathArraySum(array_column($source,'cost'))
+ ]];
+ //导出execl
+ buildExcel('其它入库单列表',$excel);
+ }else{
+ //详细报表
+ $files=[];//初始化文件列表
+ foreach ($source as $sourceVo) {
+ //开始构造导出数据
+ $excel=[];//初始化导出数据
+ //标题数据
+ $excel[]=['type'=>'title','info'=>'其它入库单'];
+ //节点数据
+ $excel[]=['type'=>'node','info'=>[
+ '供应商:'.$sourceVo['supplierData']['name'],
+ '单据日期:'.$sourceVo['time'],
+ '单据编号:'.$sourceVo['number']]
+ ];
+ //表格数据
+ $field=[
+ 'goodsData|name'=>'商品名称',
+ 'goodsData|spec'=>'规格型号',
+ 'attr'=>'辅助属性',
+ 'unit'=>'单位',
+ 'warehouseData|name'=>'仓库',
+ 'batch'=>'批次号',
+ 'mfd'=>'生产日期',
+ 'price'=>'成本',
+ 'nums'=>'数量',
+ 'extension|serial'=>'序列号',
+ 'total'=>'总成本',
+ 'data'=>'备注信息'
+ ];
+ //构造表内数据
+ $info=EntryInfo::with(['goodsData','warehouseData'])->where([['pid','=',$sourceVo['id']]])->order(['id'=>'asc'])->append(['extension'])->select()->toArray();
+ //批次号匹配
+ if(empty(search($info)->where([['goodsData|batch','=',true]])->find())){
+ unset($field['batch']);
+ }
+ //生产日期匹配
+ if(empty(search($info)->where([['goodsData|validity','=',true]])->find())){
+ unset($field['mfd']);
+ }
+ //序列号匹配
+ if(empty(search($info)->where([['goodsData|serial','=',true]])->find())){
+ unset($field['extension|serial']);
+ }
+ $thead=array_values($field);//表格标题
+ $tbody=[];//表格内容
+ foreach ($info as $infoVo) {
+ $rowData=[];
+ foreach (array_keys($field) as $fieldVo) {
+ $rowData[]=arraySeek($infoVo,$fieldVo);//多键名数据赋值
+ }
+ $tbody[]=$rowData;//加入行数据
+ }
+ $excel[]=['type'=>'table','info'=>['thead'=>$thead,'tbody'=>$tbody]];//表格数据
+ //节点数据
+ $excel[]=['type'=>'node','info'=>[
+ '单据类型:'.$sourceVo['extension']['type'],
+ '单据成本:'.$sourceVo['total'],
+ '单据费用:'.$sourceVo['cost'],
+ '关联人员:'.arraySeek($sourceVo,'peopleData|name'),
+ '物流信息:'.$sourceVo['extension']['logistics'],
+ '备注信息:'.$sourceVo['data']]
+ ];
+ //生成execl
+ $files[]=buildExcel($sourceVo['number'],$excel,false);
+
+ }
+ buildZip('其它入库单_'.time(),$files);
+ }
+ }else{
+ return json(['state'=>'error','info'=>'传入数据不完整!']);
+ }
+ }
+}
\ No newline at end of file
diff --git a/serve/app/controller/Extry.php b/serve/app/controller/Extry.php
new file mode 100644
index 0000000..82896f5
--- /dev/null
+++ b/serve/app/controller/Extry.php
@@ -0,0 +1,1027 @@
+'time'],'startTime'],
+ [['endTime'=>'time'],'endTime'],
+ ['type','fullDec1'],
+ ['examine','fullDec1'],
+ ['cse','fullDec1'],
+ ['check','fullDec1'],
+ ['user','fullEq'],
+ ['data','fullLike']
+ ]);//构造SQL
+ //商品信息扩展查询
+ if(existFull($input,['goods'])){
+ $goods=array_column(Db::name('goods')->where([['name|py','like','%'.$input['goods'].'%']])->select()->toArray(),'id');
+ $sql[]=['id','in',array_column(Db::name('extry_info')->where([['goods','in',$goods]])->select()->toArray(),'pid')];
+ }
+ $sql=frameScope($sql);//组织数据
+ $sql=sqlAuth('extry',$sql);//数据鉴权
+ $count = Extrys::where($sql)->count();//获取总条数
+ $info = Extrys::with(['frameData','peopleData','userData','costData','recordData','customerData'])->where($sql)->append(['extension'])->page($input['page'],$input['limit'])->order(['id'=>'desc'])->select()->toArray();//查询分页数据
+ $result=[
+ 'state'=>'success',
+ 'count'=>$count,
+ 'info'=>$info
+ ];//返回数据
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //新增|更新
+ public function save(){
+ $input=input('post.');
+ if(existFull($input,['class','info']) && isset($input['class']['id']) && isset($input['cost'])){
+ //构造|验证CLASS
+ try {
+ $class=$input['class'];
+ $class['frame']=userInfo(getUserID(),'frame');
+ $class['user']=getUserID();
+ $class['cse']=empty($class['cost'])?3:0;
+ $class['examine']=0;
+ empty($class['id'])?$this->validate($class,'app\validate\Extry'):$this->validate($class,'app\validate\Extry.update');
+ $period=getPeriod();
+ if(strtotime($class['time'])<=$period){
+ throw new ValidateException('单据日期与结账日期冲突!');
+ }
+ } catch (ValidateException $e) {
+ return json(['state'=>'error','info'=>$e->getError()]);
+ exit;
+ }
+
+ //验证INFO
+ foreach ($input['info'] as $infoKey=>$infoVo) {
+ try {
+ $this->validate($infoVo,'app\validate\ExtryInfo');
+ } catch (ValidateException $e) {
+ return json(['state'=>'error','info'=>'商品信息第'.($infoKey+1).'条'.$e->getError()]);
+ exit;
+ }
+ }
+
+ //验证Cost
+ foreach ($input['cost'] as $costKey=>$costVo) {
+ try {
+ $this->validate($costVo,'app\validate\Cost');
+ } catch (ValidateException $e) {
+ return json(['state'=>'error','info'=>'单据费用第'.($infoKey+1).'条'.$e->getError()]);
+ exit;
+ }
+ }
+
+ //处理数据
+ Db::startTrans();
+ try {
+ //CLASS数据
+ if(empty($class['id'])){
+ //创建数据
+ $createInfo=Extrys::create($class);
+ $class['id']=$createInfo['id'];//转存主键
+ Db::name('record')->insert(['type'=>'extry','source'=>$class['id'],'time'=>time(),'user'=>getUserID(),'info'=>'新增单据']);
+ pushLog('新增其它出库单[ '.$class['number'].' ]');//日志
+ }else{
+ //更新数据
+ $updateInfo=Extrys::update($class);
+ Db::name('record')->insert(['type'=>'extry','source'=>$class['id'],'time'=>time(),'user'=>getUserID(),'info'=>'更新单据']);
+ pushLog('更新其它出库单[ '.$class['number'].' ]');//日志
+ }
+
+ //INFO数据
+ ExtryInfo::where([['pid','=',$class['id']]])->delete();
+ foreach ($input['info'] as $infoKey=>$infoVo) {
+ $input['info'][$infoKey]['pid']=$class['id'];
+ }
+ $model = new ExtryInfo;
+ $model->saveAll($input['info']);
+
+ //COST数据
+ Cost::where([['type','=','extry'],['class','=',$class['id']]])->delete();
+ foreach ($input['cost'] as $costKey=>$costVo) {
+ unset($input['cost'][$costKey]['id']);
+ $input['cost'][$costKey]['type']='extry';
+ $input['cost'][$costKey]['class']=$class['id'];
+ $input['cost'][$costKey]['time']=$class['time'];
+ $input['cost'][$costKey]['settle']=0;
+ $input['cost'][$costKey]['state']=0;
+ }
+ $model = new Cost;
+ $model->saveAll($input['cost']);
+
+ Db::commit();
+ $result=['state'=>'success','info'=>$class['id']];
+ } catch (\Exception $e) {
+ Db::rollback();
+ $result=['state'=>'error','info'=>'内部错误,操作已撤销!'];
+ }
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //获取
+ public function get(){
+ $input=input('post.');
+ if(existFull($input,['parm'])){
+ $class=Extrys::where([['id','=',$input['parm']]])->find();
+ $info=ExtryInfo::with(['goodsData','warehouseData'])->where([['pid','=',$input['parm']]])->order(['id'=>'asc'])->select();
+ $cost=Cost::where([['type','=','extry'],['class','=',$input['parm']]])->order(['id'=>'asc'])->select();
+ $result=['state'=>'success','info'=>[
+ 'class'=>$class,
+ 'info'=>$info,
+ 'cost'=>$cost
+ ]];
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //删除
+ public function del(){
+ $input=input('post.');
+ if(existFull($input,['parm']) && is_array($input['parm'])){
+ $data=Db::name('extry')->where([['id','in',$input['parm']]])->order(['id'=>'desc'])->select()->toArray();
+ $search=search($data)->where([['examine','=','1']])->find();
+ if(empty($search)){
+ Db::startTrans();
+ try {
+ Db::name('extry')->where([['id','in',$input['parm']]])->delete();
+ Db::name('extry_info')->where([['pid','in',$input['parm']]])->delete();
+ Db::name('cost')->where([['type','=','extry'],['class','in',$input['parm']]])->delete();
+ Db::name('record')->where([['type','=','extry'],['source','in',$input['parm']]])->delete();
+ Db::name('log')->insert(['time'=>time(),'user'=>getUserID(),'info'=>'删除其它出库单[ '.implode(' | ',array_column($data,'number')).' ]']);
+
+ Db::commit();
+ $result=['state'=>'success'];
+ } catch (\Exception $e) {
+ Db::rollback();
+ $result=['state'=>'error','info'=>'内部错误,操作已撤销!'];
+ }
+ }else{
+ $result=['state'=>'error','info'=>'单据['.$search['number'].']已审核,不可删除!'];
+ }
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //核对|反核对
+ public function check(){
+ $input=input('post.');
+ if(existFull($input,['parm']) && is_array($input['parm'])){
+ $period=getPeriod();
+ $classList=Db::name('extry')->where([['id','in',$input['parm']]])->order(['id'=>'desc'])->select()->toArray();
+ foreach ($input['parm'] as $parmVo) {
+ $class=search($classList)->where([['id','=',$parmVo]])->find();
+ if($class['time']<=$period){
+ return json(['state'=>'error','info'=>'操作单据失败,原因:单据日期与结账日期冲突!']);
+ exit;
+ }
+ if(empty($class['check'])){
+ Db::name('extry')->where([['id','=',$class['id']]])->update(['check'=>1]);
+ //14 单据记录
+ Db::name('record')->insert(['type'=>'extry','source'=>$class['id'],'time'=>time(),'user'=>getUserID(),'info'=>'核对单据']);
+ //15 记录操作
+ pushLog('核对其它出库单[ '.$class['number'].' ]');//单据日志
+ }else{
+ Db::name('extry')->where([['id','=',$class['id']]])->update(['check'=>0]);
+ //14 单据记录
+ Db::name('record')->insert(['type'=>'extry','source'=>$class['id'],'time'=>time(),'user'=>getUserID(),'info'=>'反核对单据']);
+ //15 记录操作
+ pushLog('反核对其它出库单[ '.$class['number'].' ]');//单据日志
+ }
+ }
+ $result=['state'=>'success'];
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //审核|反审核
+ public function examine(){
+ $input=input('post.');
+ if(existFull($input,['parm']) && is_array($input['parm'])){
+ //1 基础数据
+ $fun=getSys('fun');
+ $period=getPeriod();
+ $classList=Db::name('extry')->where([['id','in',$input['parm']]])->order(['id'=>'desc'])->select()->toArray();
+ $infoList=Db::name('extry_info')->where([['pid','in',$input['parm']]])->order(['id'=>'asc'])->select()->toArray();
+ //2 综合处理
+ foreach ($input['parm'] as $parmVo) {
+ //1 匹配数据
+ $class=search($classList)->where([['id','=',$parmVo]])->find();
+ $info=search($infoList)->where([['pid','=',$parmVo]])->select();
+ //1.1 商品数据
+ $goodsList=Db::name('goods')->where([['id','in',array_unique(array_column($info,'goods'))]])->select()->toArray();
+ //1.2 综合匹配
+ if(empty($class['examine'])){
+ //1 构造数据
+ $batchGather=[];
+ $serialGather=[];
+ $roomWhereOrSql=[];
+ foreach ($info as $infoVo) {
+ //1 批次号
+ empty($infoVo['batch'])||$batchGather[]=$infoVo['batch'];
+ //2 序列号
+ $serialGather=array_merge($serialGather,json_decode($infoVo['serial']));
+ //3 仓储条件
+ empty($infoVo['warehouse'])||$roomWhereOrSql[]=[['warehouse','=',$infoVo['warehouse']],['goods','=',$infoVo['goods']],['attr','=',$infoVo['attr']]];
+ }
+ //2 匹配数据
+ empty($batchGather)||$batchList=Db::name('batch')->where([['number','in',$batchGather]])->select()->toArray();
+ empty($serialGather)||$serialList=Db::name('serial')->where([['number','in',$serialGather]])->select()->toArray();
+ if(!empty($roomWhereOrSql)){
+ //1 去重转存
+ $roomWhereOrSql=array_unique($roomWhereOrSql,SORT_REGULAR);
+ //2 仓储匹配
+ $roomList=Db::name('room')->whereOr($roomWhereOrSql)->select()->toArray();
+ }
+ }
+
+ //2 CLASS验证
+ if($class['time']<=$period){
+ return json(['state'=>'error','info'=>'操作单据[ '.$class['number'].' ]失败,原因:单据日期与结账日期冲突!']);
+ exit;
+ }
+ if(!empty($class['examine'])){
+ //单据费用
+ $cost=Db::name('cost')->alias('cost')->where([['type','=','extry'],['class','=',$class['id']]])->whereExists(function($query){
+ $query->name('oce_info')->where([['source','=',Db::raw('cost.id')]])->limit(1);
+ })->find();
+ if(!empty($cost)){
+ return json(['state'=>'error','info'=>'反审核单据[ '.$class['number'].' ]失败,原因:该单据存在关联其它支出单!']);
+ exit;
+ }
+ }
+
+ //3 INFO验证|构造
+ foreach ($info as $infoKey=>$infoVo) {
+ //1 匹配商品
+ $goods=search($goodsList)->where([['id','=',$infoVo['goods']]])->find();
+ //2 商品类型
+ if(empty($goods['type'])){
+ //场景验证
+ if(empty($class['examine'])){
+ //1 匹配数据
+ $room=search($roomList)->where([['warehouse','=',$infoVo['warehouse']],['goods','=',$infoVo['goods']],['attr','=',$infoVo['attr']]],true)->find();
+ (empty($room)||empty($infoVo['batch']))||$batch=search($batchList)->where([['room','=',$room['id']],['number','=',$infoVo['batch']],['time','=',$infoVo['mfd']]],true)->find();
+ //2 多单位处理
+ if($goods['unit']==-1){
+ //多单位|转存
+ $radix=unitRadix($infoVo['unit'],json_decode($goods['units'],true));
+ $info[$infoKey]['basic']=[
+ 'nums'=>math()->chain($infoVo['nums'])->mul($radix)->done(),
+ 'price'=>math()->chain($infoVo['price'])->div($radix)->round(4)->done()
+ ];
+ }else{
+ //常规单位|转存
+ $info[$infoKey]['basic']=[
+ 'nums'=>$infoVo['nums'],
+ 'price'=>$infoVo['price']
+ ];
+ }
+ //3 序列号
+ $serialData=json_decode($infoVo['serial']);
+ if(empty($serialData)){
+ $info[$infoKey]['serial']=[];
+ }else{
+ //序列号状态[不存在|未销售]
+ $serialCollect=search($serialList)->where([['goods','=',$infoVo['goods']],['number','in',$serialData]])->select();
+ foreach ($serialCollect as $serialCollectVo) {
+ if($serialCollectVo['state']==0){
+ if(empty($room) || $room['id']!=$serialCollectVo['room']){
+ return json(['state'=>'error','info'=>'审核单据[ '.$class['number'].' ]失败,原因:第'.($infoKey+1).'行序列号[ '.$serialCollectVo['number'].' ]与仓库不匹配!']);
+ exit;
+ }
+ if((empty($infoVo['batch'])&&!empty($serialCollectVo['batch']))||(!empty($infoVo['batch'])&&(empty($batch)||$batch['id']!=$serialCollectVo['batch']))){
+ return json(['state'=>'error','info'=>'审核单据[ '.$class['number'].' ]失败,原因:第'.($infoKey+1).'行序列号[ '.$serialCollectVo['number'].' ]与批次不匹配!']);
+ exit;
+ }
+ }else{
+ return json(['state'=>'error','info'=>'审核单据[ '.$class['number'].' ]失败,原因:第'.($infoKey+1).'行序列号[ '.$serialCollectVo['number'].' ]状态不正确!']);
+ exit;
+ }
+ }
+ $info[$infoKey]['serial']=$serialData;
+ }
+ //4 负库存验证
+ if($fun['overflow']==false){
+ //1 仓储验证
+ if(empty($room)){
+ return json(['state'=>'error','info'=>'审核单据[ '.$class['number'].' ]失败,原因:第'.($infoKey+1).'行仓储信息不存在!']);
+ exit;
+ }else{
+ if(bccomp($info[$infoKey]['basic']['nums'],$room['nums'])==1){
+ return json(['state'=>'error','info'=>'审核单据[ '.$class['number'].' ]失败,原因:第'.($infoKey+1).'行仓储库存不足!']);
+ exit;
+ }else{
+ $roomList[$room['rowKey']]['nums']=math()->chain($room['nums'])->sub($info[$infoKey]['basic']['nums'])->done();
+ }
+ }
+ //2 批次验证
+ if(!empty($infoVo['batch'])){
+ if(empty($batch)){
+ return json(['state'=>'error','info'=>'审核单据[ '.$class['number'].' ]失败,原因:第'.($infoKey+1).'行批次信息无效!']);
+ exit;
+ }else{
+ if(bccomp($info[$infoKey]['basic']['nums'],$batch['nums'])==1){
+ return json(['state'=>'error','info'=>'审核单据[ '.$class['number'].' ]失败,原因:第'.($infoKey+1).'行批次库存不足!']);
+ exit;
+ }else{
+ $batchList[$batch['rowKey']]['nums']=math()->chain($batch['nums'])->sub($info[$infoKey]['basic']['nums'])->done();
+ }
+ }
+ }
+ //3 序列号验证
+ if(!empty($serialData)){
+ $serialCount=search($serialList)->where([['room','=',$room['id']],['number','in',$serialData]])->count();
+ if($serialCount != count($serialData)){
+ return json(['state'=>'error','info'=>'审核单据[ '.$class['number'].' ]失败,原因:第'.($infoKey+1).'行存在无效序列号!']);
+ exit;
+ }
+ }
+ }
+ }else{
+ //1 验证序列号
+ $serialInfoCollect=Db::name('serial_info')->where([['type','=','extry'],['info','in',array_column($info,'id')]])->select()->toArray();
+ if(!empty($serialInfoCollect)){
+ //序列号状态[已销售]
+ $serialFind=Db::name('serial')->where([['id','in',array_column($serialInfoCollect,'pid')],['state','<>',1]])->find();
+ if(!empty($serialFind)){
+ return json(['state'=>'error','info'=>'反审核单据[ '.$class['number'].' ]失败,原因:第'.($infoKey+1).'行序列号[ '.$serialFind['number'].' ]状态不正确!']);
+ exit;
+ }
+ }
+ }
+ }
+ }
+ //4 数据处理
+ Db::startTrans();
+ try {
+ //场景验证
+ if(empty($class['examine'])){
+ //审核
+ //1 构造数据
+ $store=['room'=>[],'roomInfo'=>[],'batch'=>[],'batchInfo'=>[],'serial'=>[],'serialInfo'=>[],'serve'=>[],'serveInfo'=>[]];
+ foreach ($info as $infoKey=>$infoVo){
+ //判断商品类型
+ $goods=search($goodsList)->where([['id','=',$infoVo['goods']]])->find();
+ if(empty($goods['type'])){
+ //常规商品
+ //1 仓储
+ $store['room'][]=['warehouse'=>$infoVo['warehouse'],'goods'=>$infoVo['goods'],'attr'=>$infoVo['attr'],'nums'=>$infoVo['basic']['nums']];
+ //2 仓储详情
+ $store['roomInfo'][]=['pid'=>null,'type'=>'extry','class'=>$class['id'],'info'=>$infoVo['id'],'time'=>$class['time'],'direction'=>0,'price'=>$infoVo['basic']['price'],'nums'=>$infoVo['basic']['nums']];
+ //3 批次号
+ if(empty($infoVo['batch'])){
+ $store['batch'][]=[];
+ $store['batchInfo'][]=[];
+ }else{
+ $store['batch'][]=['room'=>null,'warehouse'=>$infoVo['warehouse'],'goods'=>$infoVo['goods'],'number'=>$infoVo['batch'],'time'=>$infoVo['mfd'],'nums'=>$infoVo['basic']['nums']];
+ $store['batchInfo'][]=['pid'=>null,'type'=>'extry','class'=>$class['id'],'info'=>$infoVo['id'],'direction'=>0,'nums'=>$infoVo['basic']['nums']];
+ }
+ //4 序列号
+ if(empty($infoVo['serial'])){
+ $store['serial'][]=[];
+ $store['serialInfo'][]=[];
+ }else{
+ $serial=[];
+ $serialInfo=[];
+ foreach ($infoVo['serial'] as $serialVo) {
+ $serial[]=['room'=>null,'warehouse'=>$infoVo['warehouse'],'batch'=>null,'goods'=>$infoVo['goods'],'number'=>$serialVo,'state'=>1];
+ $serialInfo[]=['pid'=>null,'type'=>'extry','class'=>$class['id'],'info'=>$infoVo['id']];
+ }
+ $store['serial'][]=$serial;
+ $store['serialInfo'][]=$serialInfo;
+ }
+ }else{
+ //5 服务商品
+ $store['serve'][]=['goods'=>$infoVo['goods'],'attr'=>$infoVo['attr'],'nums'=>$infoVo['nums']];
+ $store['serveInfo'][]=['pid'=>null,'type'=>'extry','class'=>$class['id'],'info'=>$infoVo['id'],'time'=>$class['time'],'price'=>$infoVo['price'],'nums'=>$infoVo['nums']];
+ }
+ }
+ //2 仓储
+ if(!empty($store['room'])){
+ //1 构造数据
+ $roomInsert=[];
+ foreach ($store['room'] as $roomVo) {
+ $roomFind=search($roomList)->where([['warehouse','=',$roomVo['warehouse']],['goods','=',$roomVo['goods']],['attr','=',$roomVo['attr']]])->find();
+ if(empty($roomFind)){
+ $roomVo['nums']=0;
+ $roomInsert[]=$roomVo;
+ }
+ }
+ //2 创建数据|去重
+ empty($roomInsert)||Db::name('room')->insertAll(array_unique($roomInsert,SORT_REGULAR));
+ //3 匹配主键|构造更新
+ $roomDuplicate=[];
+ $room=Db::name('room')->whereOr($roomWhereOrSql)->select()->toArray();
+ foreach ($store['room'] as $roomKey=>$roomVo) {
+ $roomFind=search($room)->where([['warehouse','=',$roomVo['warehouse']],['goods','=',$roomVo['goods']],['attr','=',$roomVo['attr']]])->find();
+ $store['room'][$roomKey]['id']=$roomFind['id'];
+ $roomDuplicate[]=['id'=>$roomFind['id'],'nums'=>$roomVo['nums']];
+ }
+ //4 更新数据
+ Db::name('room')->duplicate(['nums'=>Db::raw('nums - VALUES(`nums`)')])->insertAll($roomDuplicate);
+ }
+ //3 仓储详情
+ if(!empty($store['roomInfo'])){
+ //1 填充数据
+ foreach ($store['roomInfo'] as $roomInfoKey=>$roomInfoVo) {
+ $store['roomInfo'][$roomInfoKey]['pid']=$store['room'][$roomInfoKey]['id'];
+ }
+ //2 创建数据
+ Db::name('room_info')->insertAll($store['roomInfo']);
+ }
+ //4 批次号
+ if(!empty($store['batch'])){
+ //1 构造数据
+ $batchData=[];
+ foreach ($store['batch'] as $batchKey=>$batchVo) {
+ if(!empty($batchVo)){
+ $store['batch'][$batchKey]['room']=$store['room'][$batchKey]['id'];
+ $batchData[]=$store['batch'][$batchKey];
+ }
+ }
+ //2 排除数据|[[],[],[]]
+ if(!empty($batchData)){
+ //1 构造数据
+ $batchInsert=[];
+ foreach ($batchData as $batchDataKey=>$batchDataVo) {
+ $batchFind=search($batchList)->where([['room','=',$batchDataVo['room']],['number','=',$batchDataVo['number']],['time','=',$batchDataVo['time']]])->find();
+ if(empty($batchFind)){
+ $batchDataVo['nums']=0;
+ $batchInsert[]=$batchDataVo;
+ }
+ }
+ //2 创建数据|去重
+ empty($batchInsert)||Db::name('batch')->insertAll(array_unique($batchInsert,SORT_REGULAR));
+ //3 匹配主键|构造更新
+ $batchDuplicate=[];
+ $batch=Db::name('batch')->where([['number','in',$batchGather]])->select()->toArray();
+ foreach ($store['batch'] as $batchKey=>$batchVo) {
+ if(!empty($batchVo)){
+ $batchFind=search($batch)->where([['room','=',$batchVo['room']],['number','=',$batchVo['number']],['time','=',$batchVo['time']]])->find();
+ $store['batch'][$batchKey]['id']=$batchFind['id'];
+ $batchDuplicate[]=['id'=>$batchFind['id'],'nums'=>$batchVo['nums']];
+ }
+ }
+ //4 更新数据
+ Db::name('batch')->duplicate(['nums'=>Db::raw('nums - VALUES(`nums`)')])->insertAll($batchDuplicate);
+ }
+ }
+ //5 批次号详情
+ if(!empty($store['batchInfo'])){
+ //1 构造数据
+ $batchInfoInstall=[];
+ foreach ($store['batchInfo'] as $batchInfoKey=>$batchInfoVo) {
+ if(!empty($batchInfoVo)){
+ $batchInfoVo['pid']=$store['batch'][$batchInfoKey]['id'];
+ $batchInfoInstall[]=$batchInfoVo;
+ }
+ }
+ //2 排除数据|[[],[],[]]
+ if(!empty($batchInfoInstall)){
+ //创建数据
+ Db::name('batch_info')->insertAll($batchInfoInstall);
+ }
+ }
+ //6 序列号
+ if(!empty($store['serial'])){
+ //1 构造数据
+ $serialData=[];
+ foreach ($store['serial'] as $serialKey=>$item) {
+ if(!empty($item)){
+ foreach ($item as $itemKey=>$itemVo) {
+ $store['serial'][$serialKey][$itemKey]['room']=$store['room'][$serialKey]['id'];
+ $store['serial'][$serialKey][$itemKey]['batch']=empty($store['batch'][$serialKey])?0:$store['batch'][$serialKey]['id'];
+ $serialData[]=$store['serial'][$serialKey][$itemKey];
+ }
+ }
+ }
+ //2 排除数据|[[],[],[]]
+ if(!empty($serialData)){
+ //1 构造数据
+ $serialInsert=[];
+ foreach ($serialData as $serialDataKey=>$serialDataVo) {
+ $serialFind=search($serialList)->where([['room','=',$serialDataVo['room']],['batch','=',$serialDataVo['batch']],['number','=',$serialDataVo['number']]])->find();
+ if(empty($serialFind)){
+ $serialInsert[]=$serialDataVo;
+ }
+ }
+ //2 创建数据
+ empty($serialInsert)||Db::name('serial')->insertAll($serialInsert);
+ //3 匹配主键|构造更新
+ $serialDuplicate=[];
+ $serial=Db::name('serial')->where([['number','in',$serialGather]])->select()->toArray();
+ foreach ($store['serial'] as $serialKey=>$item) {
+ if(!empty($item)){
+ foreach ($item as $itemKey=>$itemVo) {
+ $serialFind=search($serial)->where([['room','=',$itemVo['room']],['batch','=',$itemVo['batch']],['number','=',$itemVo['number']]])->find();
+ $store['serial'][$serialKey][$itemKey]['id']=$serialFind['id'];
+ $serialFind['state']==0&&$serialDuplicate[]=$serialFind['id'];
+ }
+ }
+ }
+ //4 更新数据|状态变更
+ empty($serialDuplicate)||Db::name('serial')->where([['id','in',$serialDuplicate]])->update(['state'=>1]);
+ }
+ }
+ //7 序列号详情
+ if(!empty($store['serialInfo'])){
+ //1 构造数据
+ $serialInfoInstall=[];
+ foreach ($store['serialInfo'] as $serialInfoKey=>$item) {
+ if(!empty($item)){
+ foreach ($item as $itemKey=>$itemVo) {
+ $itemVo['pid']=$store['serial'][$serialInfoKey][$itemKey]['id'];
+ $serialInfoInstall[]=$itemVo;
+ }
+ }
+ }
+ //2 排除数据|[[],[],[]]
+ if(!empty($serialInfoInstall)){
+ //创建数据
+ Db::name('serial_info')->insertAll($serialInfoInstall);
+ }
+ }
+ //8 服务商品
+ if(!empty($store['serve'])){
+ //1 匹配数据|去重
+ $serveWhereOrSql=array_unique(array_map(function($item){
+ return [['goods','=',$item['goods']],['attr','=',$item['attr']]];
+ },$store['serve']),SORT_REGULAR);
+ $serve=Db::name('serve')->whereOr($serveWhereOrSql)->select()->toArray();
+ //2 构造数据
+ $serveInsert=[];
+ foreach ($store['serve'] as $serveVo) {
+ $serveFind=search($serve)->where([['goods','=',$serveVo['goods']],['attr','=',$serveVo['attr']]])->find();
+ if(empty($serveFind)){
+ $serveVo['nums']=0;
+ $serveInsert[]=$serveVo;
+ }
+ }
+ //3 创建数据|去重
+ empty($serveInsert)||Db::name('serve')->insertAll(array_unique($serveInsert,SORT_REGULAR));
+ //4 匹配主键|构造更新
+ $serveDuplicate=[];
+ $serve=Db::name('serve')->whereOr($serveWhereOrSql)->select()->toArray();
+ foreach ($store['serve'] as $serveKey=>$serveVo) {
+ $serveFind=search($serve)->where([['goods','=',$serveVo['goods']],['attr','=',$serveVo['attr']]])->find();
+ $store['serve'][$serveKey]['id']=$serveFind['id'];
+ $serveDuplicate[]=['id'=>$serveFind['id'],'nums'=>$serveVo['nums']];
+ }
+ //5 更新数据
+ Db::name('serve')->duplicate(['nums'=>Db::raw('nums + VALUES(`nums`)')])->insertAll($serveDuplicate);
+ }
+ //9 服务商品详情
+ if(!empty($store['serveInfo'])){
+ //1 填充数据
+ foreach ($store['serveInfo'] as $serveInfoKey=>$serveInfoVo) {
+ $store['serveInfo'][$serveInfoKey]['pid']=$store['serve'][$serveInfoKey]['id'];
+ }
+ //2 创建数据
+ Db::name('serve_info')->insertAll($store['serveInfo']);
+ }
+ //10 更新单据
+ Db::name('extry')->where([['id','=',$class['id']]])->update(['examine'=>1]);
+ //11 单据记录
+ Db::name('record')->insert(['type'=>'extry','source'=>$class['id'],'time'=>time(),'user'=>getUserID(),'info'=>'审核单据']);
+ //12 收发记录
+ $summary=new Summary;
+ $summary->note('extry',$class['id'],true);
+ //13 记录操作
+ pushLog('审核其它出库单[ '.$class['number'].' ]');//单据日志
+ }else{
+ //反审核
+ //1 匹配数据
+ $listSql=[['type','=','extry'],['info','in',array_column($info,'id')]];
+ $roomInfoList=Db::name('room_info')->where($listSql)->select()->toArray();
+ $batchInfoList=Db::name('batch_info')->where($listSql)->select()->toArray();
+ $serialInfoList=Db::name('serial_info')->where($listSql)->select()->toArray();
+ $serveInfoList=Db::name('serve_info')->where($listSql)->select()->toArray();
+ //1 仓储
+ $roomDuplicate=[];
+ foreach ($roomInfoList as $roomInfoVo) {
+ $roomDuplicate[]=['id'=>$roomInfoVo['pid'],'nums'=>$roomInfoVo['nums']];
+ }
+ //2.1 更新仓储
+ Db::name('room')->duplicate(['nums'=>Db::raw('nums + VALUES(`nums`)')])->insertAll($roomDuplicate);
+ //2.2 删除仓储详情
+ Db::name('room_info')->where([['id','in',array_column($roomInfoList,'id')]])->delete();
+ //2.3 仓储|冗余
+ $roomPk=array_unique(array_column($roomInfoList,'pid'));
+ $roomInfoData=Db::name('room_info')->where([['pid','in',$roomPk]])->select()->toArray();
+ $roomDiff=array_diff($roomPk,array_unique(array_column($roomInfoData,'pid')));
+ empty($roomDiff)||Db::name('room')->where([['id','in',$roomDiff]])->delete();
+ //3 批次号
+ if(!empty($batchInfoList)){
+ //1 构造数据
+ $batchInfoDuplicate=array_map(function($item){
+ return ['id'=>$item['pid'],'nums'=>$item['nums']];
+ },$batchInfoList);
+ //2 更新批次号
+ Db::name('batch')->duplicate(['nums'=>Db::raw('nums + VALUES(`nums`)')])->insertAll($batchInfoDuplicate);
+ //3 删除批次号详情
+ Db::name('batch_info')->where([['id','in',array_column($batchInfoList,'id')]])->delete();
+ //4 批次号|冗余
+ $batchPk=array_unique(array_column($batchInfoList,'pid'));
+ $batchInfoData=Db::name('batch_info')->where([['pid','in',$batchPk]])->select()->toArray();
+ $batchDiff=array_diff($batchPk,array_unique(array_column($batchInfoData,'pid')));
+ empty($batchDiff)||Db::name('batch')->where([['id','in',$batchDiff]])->delete();
+ }
+ //4 序列号
+ if(!empty($serialInfoList)){
+ //1 更新序列号
+ Db::name('serial')->where([['id','in',array_column($serialInfoList,'pid')]])->update(['state'=>0]);
+ //2 删除序列号详情
+ Db::name('serial_info')->where([['id','in',array_column($serialInfoList,'id')]])->delete();
+ //3 序列号|冗余
+ $serialPk=array_unique(array_column($serialInfoList,'pid'));
+ $serialInfoData=Db::name('serial_info')->where([['pid','in',$serialPk]])->select()->toArray();
+ $serialDiff=array_diff($serialPk,array_unique(array_column($serialInfoData,'pid')));
+ empty($serialDiff)||Db::name('serial')->where([['id','in',$serialDiff]])->delete();
+ }
+ //5 服务
+ if(!empty($serveInfoList)){
+ //1 构造数据
+ $serveInfoDuplicate=array_map(function($item){
+ return ['id'=>$item['pid'],'nums'=>$item['nums']];
+ },$serveInfoList);
+ //2 更新服务
+ Db::name('serve')->duplicate(['nums'=>Db::raw('nums - VALUES(`nums`)')])->insertAll($serveInfoDuplicate);
+ //3 删除服务详情
+ Db::name('serve_info')->where([['id','in',array_column($serveInfoList,'id')]])->delete();
+ //4 服务|冗余
+ $servePk=array_unique(array_column($serveInfoList,'pid'));
+ $serveInfoData=Db::name('serve_info')->where([['pid','in',$servePk]])->select()->toArray();
+ $serveDiff=array_diff($servePk,array_unique(array_column($serveInfoData,'pid')));
+ empty($serveDiff)||Db::name('serve')->where([['id','in',$serveDiff]])->delete();
+ }
+ //6 更新单据
+ Db::name('extry')->where([['id','=',$class['id']]])->update(['examine'=>0]);
+ //7 单据记录
+ Db::name('record')->insert(['type'=>'extry','source'=>$class['id'],'time'=>time(),'user'=>getUserID(),'info'=>'反审核单据']);
+ //8 收发记录
+ $summary=new Summary;
+ $summary->note('extry',$class['id'],false);
+ //9 记录操作
+ pushLog('反审核其它出库单[ '.$class['number'].' ]');//单据日志
+ }
+
+ Db::commit();
+ } catch (\Exception $e) {
+ Db::rollback();
+ return json(['state'=>'error','info'=>'内部错误,操作已撤销!']);
+ exit;
+ }
+ }
+ $result=['state'=>'success'];
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //上传
+ public function upload(){
+ $file = request()->file('file');
+ //获取上传文件
+ if (empty($file)) {
+ $result = ['state' => 'error','info' => '传入数据不完整!'];
+ } else {
+ //文件限制5MB
+ try{
+ validate(['file'=>['fileSize'=>5*1024*1024,'fileExt'=>'png,gif,jpg,jpeg,txt,doc,docx,rtf,xls,xlsx,ppt,pptx,pdf,zip,rar']])->check(['file'=>$file]);
+ $fileInfo=Filesystem::disk('upload')->putFile('extry', $file, 'uniqid');
+ $filePath=request()->domain().'/static/upload/'.$fileInfo;
+ $result=['state'=>'success','info'=>$filePath];
+ }catch(ValidateException $e) {
+ $result = ['state' => 'error','info' => $e->getMessage()];
+ }
+ }
+ return json($result);
+ }
+ //导入
+ public function import(){
+ delOverdueFile('static.upload.xlsx');//删除过期文件
+ $file=request()->file('file');//获取上传文件
+ if(empty($file)){
+ $result=['state'=>'error','info'=>'传入数据不完整!'];
+ }else{
+ $fun=getSys('fun');
+ try{
+ validate(['file'=>['fileSize'=>2*1024*1024,'fileExt'=>'xlsx']])->check(['file'=>$file]);
+ $fileInfo = Filesystem::disk('upload')->putFile('xlsx', $file, 'uniqid');
+ $filePath = pathChange('static.upload').$fileInfo;
+ $data=getXlsx($filePath);
+ unset($data[1]);//删除标题行
+ unset($data[2]);//删除列名行
+ //初始化CLASS
+ //单据类型匹配
+ if(in_array($data[3]['C'],['其它出库单','盘亏单'])){
+ $type=$data[3]['C']=="其它出库单"?0:1;
+ }else{
+ throw new ValidateException('单据类型[ '.$data[3]['C'].' ]未匹配!');
+ }
+ //关联人员匹配
+ if(empty($data[3]['E'])){
+ $people=['id'=>0];
+ }else{
+ $people=Db::name('people')->where([['name','=',$data[3]['E']]])->find();
+ if(empty($people)){
+ throw new ValidateException('关联人员[ '.$data[3]['E'].' ]未匹配!');
+ }
+ }
+ $class=[
+ 'frame'=>userInfo(getUserID(),'frame'),
+ 'time'=>$data[3]['A'],
+ 'number'=>$data[3]['B'],
+ 'type'=>$type,
+ 'total'=>0,
+ 'people'=>$people['id'],
+ 'logistics'=>["key"=>"auto","name"=>"自动识别","number"=>$data[3]['F']],
+ 'file'=>[],
+ 'data'=>$data[3]['G'],
+ 'more'=>[],
+ 'examine'=>0,
+ 'cse'=>0,
+ 'check'=>0,
+ 'user'=>getUserID()
+ ];
+ $this->validate($class,'app\validate\Extry');//数据合法性验证
+ //初始化INFO
+ $info=[];
+ $goods=Goods::with(['attr'])->where([['name','in',array_column($data,'H')]])->select()->toArray();
+ $warehouse=Db::name('warehouse')->where([['name','in',array_column($data,'K')]])->select()->toArray();
+ foreach ($data as $dataKey=>$dataVo) {
+ $record=[
+ 'goods'=>$dataVo['H'],
+ 'attr'=>$dataVo['I'],
+ 'unit'=>$dataVo['J'],
+ 'warehouse'=>$dataVo['K'],
+ 'batch'=>$dataVo['L'],
+ 'mfd'=>$dataVo['M'],
+ 'price'=>$dataVo['N'],
+ 'nums'=>$dataVo['O'],
+ 'serial'=>explode(',',$dataVo['P']),
+ 'total'=>0,
+ 'data'=>$dataVo['R']
+ ];
+ //商品匹配
+ $goodsFind=search($goods)->where([['name','=',$record['goods']]])->find();
+ if(empty($goodsFind)){
+ throw new ValidateException('模板文件第'.$dataKey.'行商品名称[ '.$record['goods'].' ]未匹配!');
+ }else{
+ $record['goods']=$goodsFind['id'];
+ }
+ //辅助属性匹配
+ if(empty($goodsFind['attr'])){
+ $record['attr']='';
+ }else{
+ if(empty($record['attr'])){
+ throw new ValidateException('模板文件第'.$dataKey.'行辅助属性不可为空!');
+ }else{
+ $attrFind=search($goodsFind['attr'])->where([['name','=',$record['attr']]])->find();
+ if(empty($attrFind)){
+ throw new ValidateException('模板文件第'.$dataKey.'行辅助属性[ '.$record['attr'].' ]未匹配!');
+ }
+ }
+ }
+ //单位匹配
+ if($goodsFind['unit']==-1){
+ if(empty($record['unit'])){
+ throw new ValidateException('模板文件第'.$dataKey.'行单位不可为空!');
+ }else{
+ $unitFind=search($goodsFind['units'])->where([['name','=',$record['unit']]])->find();
+ if(empty($unitFind) && $goodsFind['units'][0]['source']!=$record['unit']){
+ throw new ValidateException('模板文件第'.$dataKey.'行单位[ '.$record['unit'].' ]未匹配!');
+ }
+ }
+ }else{
+ $record['unit']=$goodsFind['unit'];
+ }
+ //仓库匹配
+ if(empty($goodsFind['type'])){
+ //常规产品
+ $warehouseFind=search($warehouse)->where([['name','=',$record['warehouse']]])->find();
+ if(empty($warehouseFind)){
+ throw new ValidateException('模板文件第'.$dataKey.'行仓库[ '.$record['warehouse'].' ]未匹配!');
+ }else{
+ $record['warehouse']=$warehouseFind['id'];
+ }
+ }else{
+ //服务产品
+ $record['warehouse']=null;
+ }
+ //批次号匹配
+ if(empty($goodsFind['batch'])){
+ $record['batch']='';
+ }else{
+ if(empty($record['batch'])){
+ throw new ValidateException('模板文件第'.$dataKey.'行批次号不可为空!');
+ }
+ }
+ //生产日期匹配
+ if(empty($goodsFind['validity'])){
+ $record['mfd']='';
+ }else{
+ if(empty($record['mfd'])){
+ throw new ValidateException('模板文件第'.$dataKey.'行生产日期不可为空!');
+ }
+ }
+ //成本匹配
+ if(!preg_match("/^\d+(\.\d{0,".$fun['digit']['money']."})?$/",$record['price'])){
+ throw new ValidateException('模板文件第'.$dataKey.'行成本不正确!');
+ }
+ //数量匹配
+ if(!preg_match("/^\d+(\.\d{0,".$fun['digit']['nums']."})?$/",$record['nums'])){
+ throw new ValidateException('模板文件第'.$dataKey.'行数量不正确!');
+ }
+ //序列号匹配
+ if(empty($goodsFind['serial'])){
+ $record['serial']=[];
+ }else{
+ if(count($record['serial'])==1 && empty($record['serial'][0])){
+ throw new ValidateException('模板文件第'.$dataKey.'行序列号不可为空!');
+ }else{
+ if(count($record['serial'])!=$record['nums']){
+ throw new ValidateException('模板文件第'.$dataKey.'行序列号个数与数量不符!');
+ }
+ }
+ }
+ try{
+ $this->validate($record,'app\validate\ExtryInfo');//数据合法性验证
+ $record['total']=math()->chain($record['price'])->mul($record['nums'])->round($fun['digit']['money'])->done();
+ //转存数据
+ $class['total']=math()->chain($class['total'])->add($record['total'])->done();//累加单据成本
+ $info[]=$record;
+ } catch (ValidateException $e) {
+ return json(['state'=>'error','info'=>'模板文件第'.$dataKey.'行'.$e->getMessage()]);//返回错误信息
+ exit;
+ }
+ }
+ //序列号重复验证
+ $serials=[];
+ foreach ($info as $infoVo) {
+ $serials = array_merge($serials,$infoVo['serial']);
+ }
+ if(count($serials)!=count(array_unique($serials))){
+ throw new ValidateException('商品信息中存在重复序列号!');
+ }
+ Db::startTrans();
+ try {
+ //新增CLASS
+ $classData=Extrys::create($class);
+ //新增INFO
+ foreach ($info as $infoKey=>$infoVo) {
+ $info[$infoKey]['pid']=$classData['id'];
+ }
+ $model = new ExtryInfo;
+ $model->saveAll($info);
+ Db::name('record')->insert(['type'=>'extry','source'=>$classData['id'],'time'=>time(),'user'=>getUserID(),'info'=>'导入单据']);
+ pushLog('导入其它出库单[ '.$classData['number'].' ]');//日志
+
+ Db::commit();
+ $result=['state'=>'success'];
+ } catch (\Exception $e) {
+ Db::rollback();
+ $result=['state'=>'error','info'=>'内部错误,操作已撤销!'];
+ }
+ }catch(ValidateException $e) {
+ $result=['state'=>'error','info'=>$e->getMessage()];//返回错误信息
+ }
+ }
+ return json($result);
+ }
+ //导出
+ public function exports(){
+ $input=input('get.');
+ if(existFull($input,['scene','parm']) && is_array($input['parm'])){
+ pushLog('导出其它出库单列表');//日志
+ $source=Extrys::with(['frameData','peopleData','userData','recordData','customerData'])->where([['id','in',$input['parm']]])->append(['extension'])->order(['id'=>'desc'])->select()->toArray();//查询CLASS数据
+ if($input['scene']=='simple'){
+ //简易报表
+ //开始构造导出数据
+ $excel=[];//初始化导出数据
+ //标题数据
+ $excel[]=['type'=>'title','info'=>'其它出库单列表'];
+ //表格数据
+ $field=[
+ 'frameData|name'=>'所属组织',
+ 'customerData|name'=>'客户',
+ 'extension|type'=>'单据类型',
+ 'time'=>'单据时间',
+ 'number'=>'单据编号',
+ 'total'=>'单据成本',
+ 'cost'=>'单据费用',
+ 'peopleData|name'=>'关联人员',
+ 'extension|examine'=>'审核状态',
+ 'extension|cse'=>'费用状态',
+ 'extension|check'=>'核对状态',
+ 'userData|name'=>'制单人',
+ 'data'=>'备注信息'
+ ];
+ $thead=array_values($field);//表格标题
+ $tbody=[];//表格内容
+ //构造表内数据
+ foreach ($source as $sourceVo) {
+ $rowData=[];
+ foreach (array_keys($field) as $fieldVo) {
+ $rowData[]=arraySeek($sourceVo,$fieldVo);//多键名数据赋值
+ }
+ $tbody[]=$rowData;//加入行数据
+ }
+ $excel[]=['type'=>'table','info'=>['thead'=>$thead,'tbody'=>$tbody]];//表格数据
+ //统计数据
+ $excel[]=['type'=>'node','info'=>[
+ '总数:'.count($source),
+ '总单据成本:'.mathArraySum(array_column($source,'total')),
+ '总单据费用:'.mathArraySum(array_column($source,'cost'))
+ ]];
+ //导出execl
+ buildExcel('其它出库单列表',$excel);
+ }else{
+ //详细报表
+ $files=[];//初始化文件列表
+ foreach ($source as $sourceVo) {
+ //开始构造导出数据
+ $excel=[];//初始化导出数据
+ //标题数据
+ $excel[]=['type'=>'title','info'=>'其它出库单'];
+ //节点数据
+ $excel[]=['type'=>'node','info'=>[
+ '客户:'.$sourceVo['customerData']['name'],
+ '单据日期:'.$sourceVo['time'],
+ '单据编号:'.$sourceVo['number']]
+ ];
+ //表格数据
+ $field=[
+ 'goodsData|name'=>'商品名称',
+ 'goodsData|spec'=>'规格型号',
+ 'attr'=>'辅助属性',
+ 'unit'=>'单位',
+ 'warehouseData|name'=>'仓库',
+ 'batch'=>'批次号',
+ 'mfd'=>'生产日期',
+ 'price'=>'成本',
+ 'nums'=>'数量',
+ 'extension|serial'=>'序列号',
+ 'total'=>'总成本',
+ 'data'=>'备注信息'
+ ];
+ //构造表内数据
+ $info=ExtryInfo::with(['goodsData','warehouseData'])->where([['pid','=',$sourceVo['id']]])->order(['id'=>'asc'])->append(['extension'])->select()->toArray();
+ //批次号匹配
+ if(empty(search($info)->where([['goodsData|batch','=',true]])->find())){
+ unset($field['batch']);
+ }
+ //生产日期匹配
+ if(empty(search($info)->where([['goodsData|validity','=',true]])->find())){
+ unset($field['mfd']);
+ }
+ //序列号匹配
+ if(empty(search($info)->where([['goodsData|serial','=',true]])->find())){
+ unset($field['extension|serial']);
+ }
+ $thead=array_values($field);//表格标题
+ $tbody=[];//表格内容
+ foreach ($info as $infoVo) {
+ $rowData=[];
+ foreach (array_keys($field) as $fieldVo) {
+ $rowData[]=arraySeek($infoVo,$fieldVo);//多键名数据赋值
+ }
+ $tbody[]=$rowData;//加入行数据
+ }
+ $excel[]=['type'=>'table','info'=>['thead'=>$thead,'tbody'=>$tbody]];//表格数据
+ //节点数据
+ $excel[]=['type'=>'node','info'=>[
+ '单据类型:'.$sourceVo['extension']['type'],
+ '单据成本:'.$sourceVo['total'],
+ '单据费用:'.$sourceVo['cost'],
+ '关联人员:'.arraySeek($sourceVo,'peopleData|name'),
+ '物流信息:'.$sourceVo['extension']['logistics'],
+ '备注信息:'.$sourceVo['data']]
+ ];
+ //生成execl
+ $files[]=buildExcel($sourceVo['number'],$excel,false);
+
+ }
+ buildZip('其它出库单_'.time(),$files);
+ }
+ }else{
+ return json(['state'=>'error','info'=>'传入数据不完整!']);
+ }
+ }
+}
\ No newline at end of file
diff --git a/serve/app/controller/Field.php b/serve/app/controller/Field.php
new file mode 100644
index 0000000..d8455d6
--- /dev/null
+++ b/serve/app/controller/Field.php
@@ -0,0 +1,98 @@
+count();//获取总条数
+ $info = Fields::where($sql)->page($input['page'],$input['limit'])->append(['extension'])->order(['id'=>'desc'])->select();//查询分页数据
+ $result=[
+ 'state'=>'success',
+ 'count'=>$count,
+ 'info'=>$info
+ ];//返回数据
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //新增|更新
+ public function save(){
+ $input=input('post.');
+ if(isset($input['id'])){
+ //验证数据
+ try {
+ empty($input['id'])?$this->validate($input,'app\validate\Field'):$this->validate($input,'app\validate\Field.update');
+ } catch (ValidateException $e) {
+ return json(['state'=>'error','info'=>$e->getError()]);
+ exit;
+ }
+
+ //处理数据
+ Db::startTrans();
+ try {
+ if(empty($input['id'])){
+ //创建数据
+ Fields::create($input);
+ pushLog('新增表单字段[ '.$input['name'].' ]');//日志
+ }else{
+ //更新数据
+ Fields::update($input);
+ pushLog('更新表单字段[ '.$input['name'].' ]');//日志
+ }
+
+ Db::commit();
+ $result=['state'=>'success'];
+ } catch (\Exception $e) {
+ Db::rollback();
+ $result=['state'=>'error','info'=>'内部错误,操作已撤销!'];
+ }
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //获取
+ public function get(){
+ $input=input('post.');
+ if(existFull($input,['id'])){
+ $result=[
+ 'state'=>'success',
+ 'info'=>Fields::where([['id','=',$input['id']]])->find()
+ ];
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //删除
+ public function del(){
+ $input=input('post.');
+ if(existFull($input,['parm']) && is_array($input['parm'])){
+ $data=Db::name('field')->where([['id','in',$input['parm']]])->order(['id'=>'desc'])->select()->toArray();
+ Db::startTrans();
+ try {
+ Db::name('field')->where([['id','in',$input['parm']]])->delete();
+ Db::name('log')->insert(['time'=>time(),'user'=>getUserID(),'info'=>'删除表单字段[ '.implode(' | ',array_column($data,'name')).' ]']);
+
+ Db::commit();
+ $result=['state'=>'success'];
+ } catch (\Exception $e) {
+ Db::rollback();
+ $result=['state'=>'error','info'=>'内部错误,操作已撤销!'];
+ }
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+}
diff --git a/serve/app/controller/Frame.php b/serve/app/controller/Frame.php
new file mode 100644
index 0000000..b81eb1d
--- /dev/null
+++ b/serve/app/controller/Frame.php
@@ -0,0 +1,129 @@
+'asc'])->select());
+ return json(['state'=>'success','info'=>$frame]);
+ }
+ //新增|更新
+ public function save(){
+ $input=input('post.');
+ if(isset($input['id'])){
+ //验证数据
+ try {
+ if(empty($input['id'])){
+ $this->validate($input,'app\validate\Frame');
+ }else{
+ $this->validate($input,'app\validate\Frame.update');
+ //所属不可等于或包含当前
+ if(in_array($input['pid'],findTreeArr('frame',$input['id'],'id'))){
+ throw new ValidateException('所属组织选择不正确!');
+ }
+ }
+ } catch (ValidateException $e) {
+ return json(['state'=>'error','info'=>$e->getError()]);
+ exit;
+ }
+
+ //处理数据
+ Db::startTrans();
+ try {
+ if(empty($input['id'])){
+ //创建数据
+ Frames::create($input);
+ pushLog('新增组织机构[ '.$input['name'].' ]');//日志
+ }else{
+ //更新数据
+ Frames::update($input);
+ pushLog('更新组织机构[ '.$input['name'].' ]');//日志
+ }
+
+ Db::commit();
+ $result=['state'=>'success'];
+ } catch (\Exception $e) {
+ Db::rollback();
+ $result=['state'=>'error','info'=>'内部错误,操作已撤销!'];
+ }
+ }else {
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //获取
+ public function get(){
+ $input=input('post.');
+ if(existFull($input,['id'])){
+ $result=[
+ 'state'=>'success',
+ 'info'=>Frames::where([['id','=',$input['id']]])->find()
+ ];
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //删除
+ public function del(){
+ $input=input('post.');
+ if(existFull($input,['id'])){
+ $subFind=Db::name('frame')->where([['pid','=',$input['id']]])->find();
+ if(empty($subFind)){
+ //关联判断
+ $exist=moreTableFind([
+ ['table'=>'account','where'=>[['frame','=',$input['id']]]],
+ ['table'=>'allot','where'=>[['frame','=',$input['id']]]],
+ ['table'=>'barter','where'=>[['frame','=',$input['id']]]],
+ ['table'=>'bill','where'=>[['frame','=',$input['id']]]],
+ ['table'=>'bor','where'=>[['frame','=',$input['id']]]],
+ ['table'=>'bre','where'=>[['frame','=',$input['id']]]],
+ ['table'=>'buy','where'=>[['frame','=',$input['id']]]],
+ ['table'=>'customer','where'=>[['frame','=',$input['id']]]],
+ ['table'=>'deploy','where'=>[['frame','=',$input['id']]]],
+ ['table'=>'entry','where'=>[['frame','=',$input['id']]]],
+ ['table'=>'extry','where'=>[['frame','=',$input['id']]]],
+ ['table'=>'ice','where'=>[['frame','=',$input['id']]]],
+ ['table'=>'imy','where'=>[['frame','=',$input['id']]]],
+ ['table'=>'oce','where'=>[['frame','=',$input['id']]]],
+ ['table'=>'omy','where'=>[['frame','=',$input['id']]]],
+ ['table'=>'people','where'=>[['frame','=',$input['id']]]],
+ ['table'=>'sell','where'=>[['frame','=',$input['id']]]],
+ ['table'=>'sor','where'=>[['frame','=',$input['id']]]],
+ ['table'=>'sre','where'=>[['frame','=',$input['id']]]],
+ ['table'=>'supplier','where'=>[['frame','=',$input['id']]]],
+ ['table'=>'swap','where'=>[['frame','=',$input['id']]]],
+ ['table'=>'user','where'=>[['frame','=',$input['id']]]],
+ ['table'=>'warehouse','where'=>[['frame','=',$input['id']]]],
+ ]);
+ if(empty($exist)){
+ //逻辑处理
+ $find=Db::name('frame')->where([['id','=',$input['id']]])->find();
+ Db::startTrans();
+ try {
+ Db::name('frame')->where([['id','=',$input['id']]])->delete();
+ pushLog('删除组织机构[ '.$find['name'].' ]');//日志
+
+ Db::commit();
+ $result=['state'=>'success'];
+ } catch (\Exception $e) {
+ Db::rollback();
+ $result=['state'=>'error','info'=>'内部错误,操作已撤销!'];
+ }
+ }else{
+ $result=['state'=>'error','info'=>'存在数据关联,删除失败!'];
+ }
+ }else{
+ $result=['state'=>'error','info'=>'存在子数据,删除失败!'];
+ }
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+
+}
diff --git a/serve/app/controller/Goods.php b/serve/app/controller/Goods.php
new file mode 100644
index 0000000..9afc56a
--- /dev/null
+++ b/serve/app/controller/Goods.php
@@ -0,0 +1,395 @@
+'name|py'],'fullLike'],
+ ['number','fullLike'],
+ ['spec','fullLike'],
+ ['brand','fullEq'],
+ ['code','fullLike'],
+ ['type','fullDec1'],
+ ['data','fullLike']
+ ]);//构造SQL
+ //商品分类树结构查询
+ if(existFull($input,['category'])){
+ $sql[]=['category','in',findTreeArr('category',$input['category'],'id')];
+ }
+ $count = Goodss::where($sql)->count();//获取总条数
+ $info = Goodss::with(['categoryData'])->where($sql)->page($input['page'],$input['limit'])->append(['extension'])->order(['id'=>'desc'])->select();//查询分页数据
+ $result=[
+ 'state'=>'success',
+ 'count'=>$count,
+ 'info'=>$info
+ ];//返回数据
+ return json($result);
+ }
+ //新增|更新
+ public function save(){
+ $input=input('post.');
+ if(isset($input['id'])){
+
+ try {
+ $input['py']=zhToPy($input['name']);//首拼信息
+ empty($input['id'])?$this->validate($input,'app\validate\Goods'):$this->validate($input,'app\validate\Goods.update');
+
+ //关联判断
+ if(!empty($input['id'])){
+ $exist=moreTableFind([
+ ['table'=>'bor_info','where'=>[['goods','=',$input['id']]]],
+ ['table'=>'buy_info','where'=>[['goods','=',$input['id']]]],
+ ['table'=>'bre_info','where'=>[['goods','=',$input['id']]]],
+ ['table'=>'sor_info','where'=>[['goods','=',$input['id']]]],
+ ['table'=>'sell_info','where'=>[['goods','=',$input['id']]]],
+ ['table'=>'sre_info','where'=>[['goods','=',$input['id']]]],
+ ['table'=>'extry_info','where'=>[['goods','=',$input['id']]]],
+ ['table'=>'entry_info','where'=>[['goods','=',$input['id']]]],
+ ['table'=>'swap_info','where'=>[['goods','=',$input['id']]]]
+ ]);
+ if(!empty($exist)){
+ $goods=Db::name('goods')->where([['id','=',$input['id']]])->find();
+ if($input['unit'] != $goods['unit']){
+ throw new ValidateException('[ 单位 ] 存在数据关联,操作已撤销!');
+ }else if($input['type'] != $goods['type']){
+ throw new ValidateException('[ 类型 ] 存在数据关联,操作已撤销!');
+ }else if($input['serial'] != $goods['serial']){
+ throw new ValidateException('[ 序列号 ] 存在数据关联,操作已撤销!');
+ }else if($input['batch'] != $goods['batch']){
+ throw new ValidateException('[ 批次 ] 存在数据关联,操作已撤销!');
+ }else if($input['validity'] != $goods['validity']){
+ throw new ValidateException('[ 有效期 ] 存在数据关联,操作已撤销!');
+ }else{
+ $attr=Db::name('attr')->where([['pid','=',$input['id']]])->select()->toArray();
+ $column=[array_column($attr,'name'),array_column($input['attr'],'name')];
+ $diff=array_diff($column[0],$column[1]);
+ if(!empty($diff)){
+ throw new ValidateException('[ 辅助属性 ] 存在数据关联,操作已撤销!');
+ }
+ }
+ }
+ }
+ } catch (ValidateException $e) {
+ return json(['state'=>'error','info'=>$e->getError()]);
+ exit;
+ }
+
+ //验证ATTR
+ if(empty($input['attr'])){
+ //验证辅助属性
+ foreach ($input['attr'] as $attrKey=>$attrVo) {
+ try {
+ $this->validate($attrVo,'app\validate\Attr');
+ } catch (ValidateException $e) {
+ return json(['state'=>'error','info'=>'辅助属性第'.($attrKey+1).'条'.$e->getError()]);
+ exit;
+ }
+ }
+ }
+
+ //处理数据
+ Db::startTrans();
+ try {
+ //GOODS数据
+ if(empty($input['id'])){
+ //创建数据
+ $createInfo=Goodss::create($input);
+ $input['id']=$createInfo['id'];//转存主键
+ pushLog('新增商品[ '.$input['name'].' ]');//日志
+ }else{
+ //更新数据
+ Goodss::update($input);
+ pushLog('更新商品[ '.$input['name'].' ]');//日志
+ }
+
+ //ATTR数据
+ Attr::where([['pid','=',$input['id']]])->delete();
+ if(!empty($input['attr'])){
+ foreach ($input['attr'] as $attrKey=>$attrVo) {
+ unset($input['attr'][$attrKey]['id']);
+ $input['attr'][$attrKey]['pid']=$input['id'];
+ }
+ $attr = new Attr;
+ $attr->saveAll($input['attr']);
+ }
+
+ Db::commit();
+ $result=['state'=>'success'];
+ } catch (\Exception $e) {
+ Db::rollback();
+ $result=['state'=>'error','info'=>'内部错误,操作已撤销!'];
+ }
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //获取
+ public function get(){
+ $input=input('post.');
+ if(existFull($input,['id'])){
+ $result=[
+ 'state'=>'success',
+ 'info'=>Goodss::with(['attr'])->where([['id','=',$input['id']]])->find()
+ ];
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //删除
+ public function del(){
+ $input=input('post.');
+ if(existFull($input,['parm']) && is_array($input['parm'])){
+ //关联判断
+ $exist=moreTableFind([
+ ['table'=>'sor_info','where'=>[['goods','in',$input['parm']]]],
+ ['table'=>'sell_info','where'=>[['goods','in',$input['parm']]]],
+ ['table'=>'sre_info','where'=>[['goods','in',$input['parm']]]],
+ ['table'=>'bor_info','where'=>[['goods','in',$input['parm']]]],
+ ['table'=>'buy_info','where'=>[['goods','in',$input['parm']]]],
+ ['table'=>'bre_info','where'=>[['goods','in',$input['parm']]]],
+ ['table'=>'extry_info','where'=>[['goods','in',$input['parm']]]],
+ ['table'=>'entry_info','where'=>[['goods','in',$input['parm']]]],
+ ['table'=>'swap_info','where'=>[['goods','in',$input['parm']]]],
+ ]);
+ if(empty($exist)){
+ //逻辑处理
+ $data=Db::name('goods')->where([['id','in',$input['parm']]])->order(['id'=>'desc'])->select()->toArray();
+ Db::startTrans();
+ try {
+ Db::name('goods')->where([['id','in',$input['parm']]])->delete();
+ Db::name('attr')->where([['pid','in',$input['parm']]])->delete();
+ Db::name('log')->insert(['time'=>time(),'user'=>getUserID(),'info'=>'删除商品[ '.implode(' | ',array_column($data,'name')).' ]']);
+
+ Db::commit();
+ $result=['state'=>'success'];
+ } catch (\Exception $e) {
+ Db::rollback();
+ $result=['state'=>'error','info'=>'内部错误,操作已撤销!'];
+ }
+ }else{
+ $result=['state'=>'error','info'=>'存在数据关联,删除失败!'];
+ }
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //上传
+ public function upload(){
+ $file=request()->file('file');//获取上传文件
+ if (empty($file)){
+ $result=['state'=>'error','info'=>'传入数据不完整!'];
+ }else{
+ try{
+ validate(['file'=>['fileSize'=>2*1024*1024,'fileExt'=>'png,gif,jpg,jpeg']])->check(['file'=>$file]);
+ $fileInfo=Filesystem::disk('upload')->putFile('goods', $file, 'uniqid');
+ $filePath=request()->domain().'/static/upload/'.$fileInfo;
+ $result=['state'=>'success','info'=>$filePath];
+ }catch(ValidateException $e) {
+ return json(['state'=>'error','info'=>$e->getMessage()]);
+ }
+ }
+ return json($result);
+ }
+ //导入
+ public function import(){
+ delOverdueFile('static.upload.xlsx');//删除过期文件
+ $file=request()->file('file');//获取上传文件
+ if(empty($file)){
+ $result=['state'=>'error','info'=>'传入数据不完整!'];
+ }else{
+ try{
+ validate(['file'=>['fileSize'=>2*1024*1024,'fileExt'=>'xlsx']])->check(['file'=>$file]);
+ $fileInfo = Filesystem::disk('upload')->putFile('xlsx', $file, 'uniqid');
+ $filePath = pathChange('static.upload').$fileInfo;
+ $data=getXlsx($filePath);
+ unset($data[1]);//删除标题行
+ $sql=[];//初始化SQL
+ foreach ($data as $dataKey=>$dataVo) {
+ $record=[
+ 'name'=>$dataVo['A'],
+ 'py'=>zhToPy($dataVo['A']),
+ 'number'=>$dataVo['B'],
+ 'spec'=>$dataVo['C'],
+ 'category'=>$dataVo['D'],
+ 'brand'=>$dataVo['E'],
+ 'unit'=>$dataVo['F'],
+ 'buy'=>$dataVo['G'],
+ 'sell'=>$dataVo['H'],
+ 'retail'=>$dataVo['I'],
+ 'integral'=>$dataVo['J'],
+ 'code'=>$dataVo['K'],
+ 'location'=>$dataVo['L'],
+ 'stock'=>$dataVo['M'],
+ 'type'=>$dataVo['N']=='常规商品'?0:1,
+ 'data'=>$dataVo['O'],
+ 'alias'=>'',
+ 'imgs'=>[],
+ 'details'=>'',
+ 'units'=>[],
+ 'strategy'=>[],
+ 'serial'=>0,
+ 'batch'=>0,
+ 'protect'=>0,
+ 'threshold'=>0,
+ 'more'=>[]
+ ];
+ try {
+ //数据合法性验证
+ $this->validate($record,'app\validate\Goods.imports');
+ } catch (ValidateException $e) {
+ return json(['state'=>'error','info'=>'模板文件第[ '.$dataKey.' ]行'.$e->getError()]);
+ exit;
+ }
+ $sql[]=$record;//加入SQL
+ }
+ //判断名称重复
+ $nameColumn=array_column($sql,'name');
+ $nameUnique=array_unique($nameColumn);
+ $nameDiff=array_diff_assoc($nameColumn,$nameUnique);
+ if(!empty($nameDiff)){
+ //返回错误信息
+ return json(['state'=>'error','info'=>'模板文件商品名称[ '.implode(' | ',$nameDiff).' ]重复!']);
+ }
+ //判断编号重复
+ $numberColumn=array_column($sql,'number');
+ $numberUnique=array_unique($numberColumn);
+ $numberDiff=array_diff_assoc($numberColumn,$numberUnique);
+ if(!empty($numberDiff)){
+ //返回错误信息
+ return json(['state'=>'error','info'=>'模板文件商品编号[ '.implode(' | ',$numberDiff).' ]重复!']);
+ }
+ //处理关联数据
+ foreach($sql as $sqlKey=>$sqlVo){
+ $sys=getSys(['unit','brand']);
+ //商品类别
+ if(empty($sqlVo['category'])){
+ return json(['state'=>'error','info'=>'模板文件第[ '.$sqlKey.' ]行商品类别不可为空!']);
+ }else{
+ $find=Db::name('category')->where([['name','=',$sqlVo['category']]])->find();
+ if(empty($find)){
+ $insert=Db::name('category')->insertGetId([
+ 'pid'=>0,
+ 'name'=>$sqlVo['category'],
+ "sort" => 99,
+ "data" => "自动创建|商品导入"
+ ]);
+ $sql[$sqlKey]['category']=$insert;
+ }else{
+ $sql[$sqlKey]['category']=$find['id'];
+ }
+ }
+ //商品品牌
+ if(!in_array($sqlVo['brand'],$sys['brand'])){
+ $sys['brand'][]=$sqlVo['brand'];
+ Sys::where([['name','=','brand']])->update(['info'=>json_encode($sys['brand'])]);
+ }
+ //商品单位
+ if($sqlVo['unit']=='多单位' || $sqlVo['unit']=='-1'){
+ return json(['state'=>'error','info'=>'模板文件第[ '.($sqlKey+1).' ]行商品单位[ 多单位 ]为保留字段!']);
+ }else{
+ if(!in_array($sqlVo['unit'],$sys['unit'])){
+ $sys['unit'][]=$sqlVo['unit'];
+ Sys::where([['name','=','unit']])->update(['info'=>json_encode($sys['unit'])]);
+ }
+ }
+ }
+ //新增数据
+ $goods = new Goodss;
+ $goods->saveAll($sql);
+ pushLog('批量导入[ '.count($sql).' ]条商品数据');//日志
+ $result=['state'=>'success','info'=>'成功导入'.count($sql).'行商品数据'];
+ }catch(ValidateException $e) {
+ $result=['state'=>'error','info'=>$e->getMessage()];//返回错误信息
+ }
+ }
+ return json($result);
+ }
+ //导出
+ public function exports(){
+ $input=input('get.');
+ if(existFull($input,['parm']) && is_array($input['parm'])){
+ $info=Goodss::with(['categoryData','attr'])->where([['id','in',$input['parm']]])->append(['extension'])->order(['id'=>'desc'])->select()->toArray();//查询数据
+ //字段数据二次处理
+ foreach ($info as $infoKey=>$infoVo) {
+ //图像赋值
+ if(empty($infoVo['imgs'])){
+ $info[$infoKey]['imgs']='';
+ }else{
+ $info[$infoKey]['imgs']=[
+ 'type'=>'img',
+ 'info'=>preg_replace("/(http|https):\/\/[^\/]*\//","",$infoVo['imgs'][0]['url'])
+ ];
+ }
+ //辅助属性赋值
+ if(empty($infoVo['attr'])){
+ $info[$infoKey]['attr']='';
+ }else{
+ $attrArr=[];
+ foreach ($infoVo['attr'] as $attrVo) {
+ $attrArr[]='属性名称:'.$attrVo['name'].' # 采购价格:'.$attrVo['buy'].' # 销售价格:'.$attrVo['sell'].' # 零售价格:'.$attrVo['retail'].' # 条形码:'.$attrVo['code'];
+ }
+ $info[$infoKey]['attr']=implode(chr(10),$attrArr);
+ }
+ //序列商品赋值
+ $info[$infoKey]['serial']=$infoVo['serial']?'是':'否';
+ //批次商品赋值
+ $info[$infoKey]['batch']=$infoVo['batch']?'是':'否';
+ }
+ $field=[
+ 'imgs'=>'商品图像',
+ 'name'=>'商品名称',
+ 'number'=>'商品编号',
+ 'spec'=>'规格型号',
+ 'categoryData|name'=>'商品类别',
+ 'brand'=>'商品品牌',
+ 'extension|unit'=>'商品单位',
+ 'buy'=>'采购价格',
+ 'sell'=>'销售价格',
+ 'retail'=>'零售价格',
+ 'integral'=>'兑换积分',
+ 'code'=>'商品条码',
+ 'location'=>'商品货位',
+ 'stock'=>'库存阈值',
+ 'extension|type'=>'商品类型',
+ 'attr'=>'辅助属性',
+ 'data'=>'备注信息',
+ 'alias'=>'零售名称',
+ 'serial'=>'序列商品',
+ 'batch'=>'批次商品',
+ 'protect'=>'保质期',
+ 'threshold'=>'预警阀值',
+ ];
+ //开始构造导出数据
+ $excel=[];//初始化导出数据
+ //标题数据
+ $excel[]=['type'=>'title','info'=>'商品信息'];
+ //表格数据
+ $thead=array_values($field);//表格标题
+ $tbody=[];//表格内容
+ //构造表内数据
+ foreach ($info as $infoVo) {
+ $rowData=[];
+ foreach (array_keys($field) as $fieldVo) {
+ $rowData[]=arraySeek($infoVo,$fieldVo);//多键名数据赋值
+ }
+ $tbody[]=$rowData;//加入行数据
+ }
+ $excel[]=['type'=>'table','info'=>['thead'=>$thead,'tbody'=>$tbody]];//表格数据
+ //统计数据
+ $excel[]=['type'=>'node','info'=>['总数:'.count($info)]];
+ //导出execl
+ pushLog('导出商品信息');//日志
+ buildExcel('商品信息',$excel);
+ }else{
+ return json(['state'=>'error','info'=>'传入数据不完整!']);
+ }
+ }
+}
\ No newline at end of file
diff --git a/serve/app/controller/Ice.php b/serve/app/controller/Ice.php
new file mode 100644
index 0000000..1f9e520
--- /dev/null
+++ b/serve/app/controller/Ice.php
@@ -0,0 +1,481 @@
+'time'],'startTime'],
+ [['endTime'=>'time'],'endTime'],
+ ['account','fullEq'],
+ ['people','fullEq'],
+ ['user','fullEq'],
+ ['examine','fullDec1'],
+ ['nucleus','fullDec1'],
+ ['data','fullLike']
+ ]);//构造SQL
+ $sql=frameScope($sql);//组织数据
+ $sql=sqlAuth('ice',$sql);//数据鉴权
+ $count = Ices::where($sql)->count();//获取总条数
+ $info = Ices::with(['frameData','customerData','accountData','peopleData','userData','billData','recordData'])->where($sql)->append(['extension'])->page($input['page'],$input['limit'])->order(['id'=>'desc'])->select()->toArray();//查询分页数据
+ $result=[
+ 'state'=>'success',
+ 'count'=>$count,
+ 'info'=>$info
+ ];//返回数据
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //新增|更新
+ public function save(){
+ $input=input('post.');
+ if(existFull($input,['class','info']) && isset($input['class']['id'])){
+ //构造|验证CLASS
+ try {
+ $class=$input['class'];
+ $class['frame']=userInfo(getUserID(),'frame');
+ $class['user']=getUserID();
+ $class['examine']=0;
+ $class['nucleus']=0;
+ empty($class['id'])?$this->validate($class,'app\validate\Ice'):$this->validate($class,'app\validate\Ice.update');
+ $period=getPeriod();
+ if(strtotime($class['time'])<=$period){
+ throw new ValidateException('单据日期与结账日期冲突!');
+ }
+ } catch (ValidateException $e) {
+ return json(['state'=>'error','info'=>$e->getError()]);
+ exit;
+ }
+
+ //验证INFO
+ foreach ($input['info'] as $infoKey=>$infoVo) {
+ try {
+ $this->validate($infoVo,'app\validate\IceInfo');
+ } catch (ValidateException $e) {
+ return json(['state'=>'error','info'=>'数据表格第'.($infoKey+1).'条'.$e->getError()]);
+ exit;
+ }
+ }
+
+ //处理数据
+ Db::startTrans();
+ try {
+ //CLASS数据
+ if(empty($class['id'])){
+ //创建数据
+ $createInfo=Ices::create($class);
+ $class['id']=$createInfo['id'];//转存主键
+ Db::name('record')->insert(['type'=>'ice','source'=>$class['id'],'time'=>time(),'user'=>getUserID(),'info'=>'新增单据']);
+ pushLog('新增其它收入单[ '.$class['number'].' ]');//日志
+ }else{
+ //更新数据
+ $updateInfo=Ices::update($class);
+ Db::name('record')->insert(['type'=>'ice','source'=>$class['id'],'time'=>time(),'user'=>getUserID(),'info'=>'更新单据']);
+ pushLog('更新其它收入单[ '.$class['number'].' ]');//日志
+ }
+
+ //INFO数据
+ IceInfo::where([['pid','=',$class['id']]])->delete();
+ foreach ($input['info'] as $infoKey=>$infoVo) {
+ $input['info'][$infoKey]['pid']=$class['id'];
+ }
+ $model = new IceInfo;
+ $model->saveAll($input['info']);
+
+ Db::commit();
+ $result=['state'=>'success','info'=>$class['id']];
+ } catch (\Exception $e) {
+ Db::rollback();
+ $result=['state'=>'error','info'=>'内部错误,操作已撤销!'];
+ }
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //获取
+ public function get(){
+ $input=input('post.');
+ if(existFull($input,['parm'])){
+ $class=Ices::where([['id','=',$input['parm']]])->find();
+ $info=IceInfo::with(['ietData'])->where([['pid','=',$input['parm']]])->order(['id'=>'asc'])->select();
+ $result=['state'=>'success','info'=>[
+ 'class'=>$class,
+ 'info'=>$info,
+ ]];
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //删除
+ public function del(){
+ $input=input('post.');
+ if(existFull($input,['parm']) && is_array($input['parm'])){
+ $data=Db::name('ice')->where([['id','in',$input['parm']]])->order(['id'=>'desc'])->select()->toArray();
+ $search=search($data)->where([['examine','=','1']])->find();
+ if(empty($search)){
+ Db::startTrans();
+ try {
+ Db::name('ice')->where([['id','in',$input['parm']]])->delete();
+ Db::name('ice_info')->where([['pid','in',$input['parm']]])->delete();
+ Db::name('record')->where([['type','=','ice'],['source','in',$input['parm']]])->delete();
+ Db::name('log')->insert(['time'=>time(),'user'=>getUserID(),'info'=>'删除其它收入单[ '.implode(' | ',array_column($data,'number')).' ]']);
+
+ Db::commit();
+ $result=['state'=>'success'];
+ } catch (\Exception $e) {
+ Db::rollback();
+ $result=['state'=>'error','info'=>'内部错误,操作已撤销!'];
+ }
+ }else{
+ $result=['state'=>'error','info'=>'单据['.$search['number'].']已审核,不可删除!'];
+ }
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //审核|反审核
+ public function examine(){
+ $input=input('post.');
+ if(existFull($input,['parm']) && is_array($input['parm'])){
+ //1 基础数据
+ $period=getPeriod();
+ $classList=Db::name('ice')->where([['id','in',$input['parm']]])->order(['id'=>'desc'])->select()->toArray();
+ //2 综合处理
+ foreach ($input['parm'] as $parmVo) {
+ //1 匹配数据
+ $class=search($classList)->where([['id','=',$parmVo]])->find();
+ //2 CLASS验证
+ if($class['time']<=$period){
+ return json(['state'=>'error','info'=>'操作单据[ '.$class['number'].' ]失败,原因:单据日期与结账日期冲突!']);
+ exit;
+ }
+ if(!empty($class['examine'])){
+ //核销单
+ $bill=Db::name('bill_info')->where([['mold','=','ice'],['source','=',$class['id']]])->find();
+ if(!empty($bill)){
+ return json(['state'=>'error','info'=>'反审核单据[ '.$class['number'].' ]失败,原因:该单据存在关联核销单!']);
+ exit;
+ }
+ }
+ //3 数据处理
+ Db::startTrans();
+ try {
+ //场景验证
+ if(empty($class['examine'])){
+ //审核
+ //1 资金|核销
+ if(!empty($class['money'])){
+ //1 更新资金账户
+ Db::name('account')->where([['id','=',$class['account']]])->inc('balance',$class['money'])->update();
+ //2 创建资金详情
+ Db::name('account_info')->insert([
+ 'pid'=>$class['account'],
+ 'type'=>'ice',
+ 'class'=>$class['id'],
+ 'time'=>$class['time'],
+ 'direction'=>1,
+ 'money'=>$class['money']
+ ]);
+ //3 创建核销记录
+ Db::name('ice_bill')->insert([
+ 'pid'=>$class['id'],
+ 'type'=>'ice',
+ 'source'=>$class['id'],
+ 'time'=>$class['time'],
+ 'money'=>$class['money']
+ ]);
+ }
+ //2 客户|应收款余额
+ if(!empty($class['customer'])){
+ $balance=math()->chain($class['actual'])->sub($class['money'])->done();
+ if(!empty($balance)){
+ Db::name('customer')->where([['id','=',$class['customer']]])->dec('balance',$balance)->update();
+ }
+ }
+ //3 更新单据
+ $nucleus=$class['money']==$class['actual']?2:($class['money']==0?0:1);
+ Db::name('ice')->where([['id','=',$class['id']]])->update(['examine'=>1,'nucleus'=>$nucleus]);
+ //4 单据记录
+ Db::name('record')->insert(['type'=>'ice','source'=>$class['id'],'time'=>time(),'user'=>getUserID(),'info'=>'审核单据']);
+ //5 记录操作
+ pushLog('审核其它收入单[ '.$class['number'].' ]');//单据日志
+ }else{
+ //反审核
+ //1 资金|核销
+ if(!empty($class['money'])){
+ //1 更新资金账户
+ Db::name('account')->where([['id','=',$class['account']]])->dec('balance',$class['money'])->update();
+ //2 删除资金详情
+ Db::name('account_info')->where([['type','=','ice'],['class','=',$class['id']]])->delete();
+ //3 删除核销记录
+ Db::name('ice_bill')->where([['pid','=',$class['id']]])->delete();
+ }
+ //2 客户|应收款余额
+ if(!empty($class['customer'])){
+ $balance=math()->chain($class['actual'])->sub($class['money'])->done();
+ if(!empty($balance)){
+ Db::name('customer')->where([['id','=',$class['customer']]])->inc('balance',$balance)->update();
+ }
+ }
+ //3 更新单据
+ Db::name('ice')->where([['id','=',$class['id']]])->update(['examine'=>0,'nucleus'=>0]);
+ //4 单据记录
+ Db::name('record')->insert(['type'=>'ice','source'=>$class['id'],'time'=>time(),'user'=>getUserID(),'info'=>'反审核单据']);
+ //5 记录操作
+ pushLog('反审核其它收入单[ '.$class['number'].' ]');//单据日志
+ }
+
+ Db::commit();
+ } catch (\Exception $e) {
+ Db::rollback();
+ return json(['state'=>'error','info'=>'内部错误,操作已撤销!']);
+ exit;
+ }
+ }
+ $result=['state'=>'success'];
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //上传
+ public function upload(){
+ $file = request()->file('file');
+ //获取上传文件
+ if (empty($file)) {
+ $result = ['state' => 'error','info' => '传入数据不完整!'];
+ } else {
+ //文件限制5MB
+ try{
+ validate(['file'=>['fileSize'=>5*1024*1024,'fileExt'=>'png,gif,jpg,jpeg,txt,doc,docx,rtf,xls,xlsx,ppt,pptx,pdf,zip,rar']])->check(['file'=>$file]);
+ $fileInfo=Filesystem::disk('upload')->putFile('ice', $file, 'uniqid');
+ $filePath=request()->domain().'/static/upload/'.$fileInfo;
+ $result=['state'=>'success','info'=>$filePath];
+ }catch(ValidateException $e) {
+ $result = ['state' => 'error','info' => $e->getMessage()];
+ }
+ }
+ return json($result);
+ }
+ //导入
+ public function import(){
+ delOverdueFile('static.upload.xlsx');//删除过期文件
+ $file=request()->file('file');//获取上传文件
+ if(empty($file)){
+ $result=['state'=>'error','info'=>'传入数据不完整!'];
+ }else{
+ $fun=getSys('fun');
+ try{
+ validate(['file'=>['fileSize'=>2*1024*1024,'fileExt'=>'xlsx']])->check(['file'=>$file]);
+ $fileInfo = Filesystem::disk('upload')->putFile('xlsx', $file, 'uniqid');
+ $filePath = pathChange('static.upload').$fileInfo;
+ $data=getXlsx($filePath);
+ unset($data[1]);//删除标题行
+ unset($data[2]);//删除列名行
+ //初始化CLASS
+ //客户匹配
+ if(empty($data[3]['A'])){
+ $customer=['id'=>0];
+ }else{
+ $customer=Db::name('customer')->where([['name','=',$data[3]['A']]])->find();
+ if(empty($customer)){
+ throw new ValidateException('客户[ '.$data[3]['A'].' ]未匹配!');
+ }
+ }
+ //结算账户匹配
+ $account=Db::name('account')->where([['name','=',$data[3]['E']]])->find();
+ if(empty($account)){
+ throw new ValidateException('资金账户[ '.$data[3]['E'].' ]未匹配!');
+ }
+ //关联人员匹配
+ if(empty($data[3]['F'])){
+ $people=['id'=>0];
+ }else{
+ $people=Db::name('people')->where([['name','=',$data[3]['F']]])->find();
+ if(empty($people)){
+ throw new ValidateException('关联人员[ '.$data[3]['F'].' ]未匹配!');
+ }
+ }
+ $class=[
+ 'frame'=>userInfo(getUserID(),'frame'),
+ 'customer'=>$customer['id'],
+ 'time'=>$data[3]['B'],
+ 'number'=>$data[3]['C'],
+ 'total'=>0,
+ 'account'=>$account['id'],
+ 'people'=>$people['id'],
+ 'file'=>[],
+ 'data'=>$data[3]['G'],
+ 'more'=>[],
+ 'examine'=>0,
+ 'nucleus'=>0,
+ 'user'=>getUserID()
+ ];
+ $this->validate($class,'app\validate\Ice');//数据合法性验证
+ //初始化INFO
+ $info=[];
+ $iet=Db::name('iet')->where([['name','in',array_column($data,'H')],['type','=',0]])->select()->toArray();
+ foreach ($data as $dataKey=>$dataVo) {
+ $record=[
+ 'iet'=>$dataVo['H'],
+ 'money'=>$dataVo['I'],
+ 'data'=>$dataVo['J']
+ ];
+ //收入类别匹配
+ $ietFind=search($iet)->where([['name','=',$record['iet']]])->find();
+ if(empty($ietFind)){
+ throw new ValidateException('模板文件第'.$dataKey.'行收入类别[ '.$record['iet'].' ]未匹配!');
+ }else{
+ $record['iet']=$ietFind['id'];
+ }
+ //结算金额匹配
+ if(!preg_match("/^(\-)?\d+(\.\d{0,".$fun['digit']['money']."})?$/",$record['money'])){
+ throw new ValidateException('模板文件第'.$dataKey.'行结算金额不正确!');
+ }
+ try{
+ $this->validate($record,'app\validate\IceInfo');//数据合法性验证
+ //转存数据
+ $class['total']=math()->chain($class['total'])->add($record['money'])->done();//累加单据金额
+ $info[]=$record;
+ } catch (ValidateException $e) {
+ return json(['state'=>'error','info'=>'模板文件第'.$dataKey.'行'.$e->getMessage()]);//返回错误信息
+ exit;
+ }
+ }
+ Db::startTrans();
+ try {
+ //新增CLASS
+ $classData=Ices::create($class);
+ //新增INFO
+ foreach ($info as $infoKey=>$infoVo) {
+ $info[$infoKey]['pid']=$classData['id'];
+ }
+ $model = new IceInfo;
+ $model->saveAll($info);
+ Db::name('record')->insert(['type'=>'ice','source'=>$classData['id'],'time'=>time(),'user'=>getUserID(),'info'=>'导入单据']);
+ pushLog('导入其它收入单[ '.$classData['number'].' ]');//日志
+
+ Db::commit();
+ $result=['state'=>'success'];
+ } catch (\Exception $e) {
+ Db::rollback();
+ $result=['state'=>'error','info'=>'内部错误,操作已撤销!'];
+ }
+ }catch(ValidateException $e) {
+ $result=['state'=>'error','info'=>$e->getMessage()];//返回错误信息
+ }
+ }
+ return json($result);
+ }
+ //导出
+ public function exports(){
+ $input=input('get.');
+ if(existFull($input,['scene','parm']) && is_array($input['parm'])){
+ pushLog('导出其它收入单列表');//日志
+ $source=Ices::with(['frameData','customerData','accountData','peopleData','userData'])->where([['id','in',$input['parm']]])->append(['extension'])->order(['id'=>'desc'])->select()->toArray();//查询CLASS数据
+ if($input['scene']=='simple'){
+ //简易报表
+ //开始构造导出数据
+ $excel=[];//初始化导出数据
+ //标题数据
+ $excel[]=['type'=>'title','info'=>'其它收入单列表'];
+ //表格数据
+ $field=[
+ 'frameData|name'=>'所属组织',
+ 'customerData|name'=>'客户',
+ 'time'=>'单据时间',
+ 'number'=>'单据编号',
+ 'total'=>'单据金额',
+ 'actual'=>'实际金额',
+ 'money'=>'单据收款',
+ 'extension|amount'=>'核销金额',
+ 'accountData|name'=>'结算账户',
+ 'peopleData|name'=>'关联人员',
+ 'extension|examine'=>'审核状态',
+ 'extension|nucleus'=>'核销状态',
+ 'userData|name'=>'制单人',
+ 'data'=>'备注信息'
+ ];
+ $thead=array_values($field);//表格标题
+ $tbody=[];//表格内容
+ //构造表内数据
+ foreach ($source as $sourceVo) {
+ $rowData=[];
+ foreach (array_keys($field) as $fieldVo) {
+ $rowData[]=arraySeek($sourceVo,$fieldVo);//多键名数据赋值
+ }
+ $tbody[]=$rowData;//加入行数据
+ }
+ $excel[]=['type'=>'table','info'=>['thead'=>$thead,'tbody'=>$tbody]];//表格数据
+ //统计数据
+ $excel[]=['type'=>'node','info'=>[
+ '总数:'.count($source),
+ '总单据金额:'.mathArraySum(array_column($source,'total')),
+ '总实际金额:'.mathArraySum(array_column($source,'actual')),
+ '总单据付款:'.mathArraySum(array_column($source,'money')),
+ '总核销金额:'.mathArraySum(arrayColumns($source,['extension','amount']))
+ ]];
+ //导出execl
+ buildExcel('其它收入单列表',$excel);
+ }else{
+ //详细报表
+ $files=[];//初始化文件列表
+ foreach ($source as $sourceVo) {
+ //开始构造导出数据
+ $excel=[];//初始化导出数据
+ //标题数据
+ $excel[]=['type'=>'title','info'=>'其它收入单'];
+ //节点数据
+ $excel[]=['type'=>'node','info'=>[
+ '客户:'.$sourceVo['customerData']['name'],
+ '单据日期:'.$sourceVo['time'],
+ '单据编号:'.$sourceVo['number']]
+ ];
+ //表格数据
+ $field=[
+ 'ietData|name'=>'收入类别',
+ 'money'=>'结算金额',
+ 'data'=>'备注信息'
+ ];
+ //构造表内数据
+ $info=IceInfo::with(['ietData'])->where([['pid','=',$sourceVo['id']]])->order(['id'=>'asc'])->select()->toArray();
+ $thead=array_values($field);//表格标题
+ $tbody=[];//表格内容
+ foreach ($info as $infoVo) {
+ $rowData=[];
+ foreach (array_keys($field) as $fieldVo) {
+ $rowData[]=arraySeek($infoVo,$fieldVo);//多键名数据赋值
+ }
+ $tbody[]=$rowData;//加入行数据
+ }
+ $excel[]=['type'=>'table','info'=>['thead'=>$thead,'tbody'=>$tbody]];//表格数据
+ //节点数据
+ $excel[]=['type'=>'node','info'=>[
+ '单据金额:'.$sourceVo['total'],
+ '结算账户:'.arraySeek($sourceVo,'accountData|name'),
+ '核销金额:'.$sourceVo['extension']['amount'],
+ '关联人员:'.arraySeek($sourceVo,'peopleData|name'),
+ '备注信息:'.$sourceVo['data']]
+ ];
+ //生成execl
+ $files[]=buildExcel($sourceVo['number'],$excel,false);
+ }
+ buildZip('其它收入单_'.time(),$files);
+ }
+ }else{
+ return json(['state'=>'error','info'=>'传入数据不完整!']);
+ }
+ }
+}
\ No newline at end of file
diff --git a/serve/app/controller/Iet.php b/serve/app/controller/Iet.php
new file mode 100644
index 0000000..5607193
--- /dev/null
+++ b/serve/app/controller/Iet.php
@@ -0,0 +1,103 @@
+count();//获取总条数
+ $info = Iets::where($sql)->append(['extension'])->order(['sort'=>'asc', 'id'=>'desc'])->select();//查询分页数据
+ $result=[
+ 'state'=>'success',
+ 'count'=>$count,
+ 'info'=>$info
+ ];//返回数据
+ return json($result);
+ }
+ //新增|更新
+ public function save(){
+ $input=input('post.');
+ if(isset($input['id'])){
+ //构造|验证
+ try {
+ empty($input['id'])?$this->validate($input,'app\validate\Iet'):$this->validate($input,'app\validate\Iet.update');
+ } catch (ValidateException $e) {
+ return json(['state'=>'error','info'=>$e->getError()]);
+ exit;
+ }
+
+ //处理数据
+ Db::startTrans();
+ try {
+ if(empty($input['id'])){
+ //创建数据
+ Iets::create($input);
+ pushLog('新增收支类别[ '.$input['name'].' ]');//日志
+ }else{
+ //更新数据
+ Iets::update($input);
+ pushLog('更新收支类别[ '.$input['name'].' ]');//日志
+ }
+
+ Db::commit();
+ $result=['state'=>'success'];
+ } catch (\Exception $e) {
+ Db::rollback();
+ $result=['state'=>'error','info'=>'内部错误,操作已撤销!'];
+ }
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //获取
+ public function get(){
+ $input=input('post.');
+ if(existFull($input,['id'])){
+ $info=Iets::where([['id','=',$input['id']]])->find();
+ $result=['state'=>'success','info'=>$info];
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //删除
+ public function del(){
+ $input=input('post.');
+ if(existFull($input,['id'])){
+ //关联判断
+ $exist=moreTableFind([
+ ['table'=>'cost','where'=>[['iet','=',$input['id']]]],
+ ['table'=>'ice_info','where'=>[['iet','=',$input['id']]]],
+ ['table'=>'oce_info','where'=>[['iet','=',$input['id']]]],
+ ]);
+ if(empty($exist)){
+ //逻辑处理
+ $find=Db::name('iet')->where([['id','=',$input['id']]])->find();
+ Db::startTrans();
+ try {
+ Db::name('iet')->where([['id','=',$input['id']]])->delete();
+ pushLog('删除收支类别[ '.$find['name'].' ]');//日志
+
+ Db::commit();
+ $result=['state'=>'success'];
+ } catch (\Exception $e) {
+ Db::rollback();
+ $result=['state'=>'error','info'=>'内部错误,操作已撤销!'];
+ }
+ }else{
+ $result=['state'=>'error','info'=>'存在数据关联,删除失败!'];
+ }
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+}
\ No newline at end of file
diff --git a/serve/app/controller/Imy.php b/serve/app/controller/Imy.php
new file mode 100644
index 0000000..d4610b2
--- /dev/null
+++ b/serve/app/controller/Imy.php
@@ -0,0 +1,454 @@
+'time'],'startTime'],
+ [['endTime'=>'time'],'endTime'],
+ ['people','fullEq'],
+ ['user','fullEq'],
+ ['examine','fullDec1'],
+ ['nucleus','fullDec1'],
+ ['data','fullLike']
+ ]);//构造SQL
+ //结算账户扩展查询
+ if(existFull($input,['account'])){
+ $sql[]=['id','in',array_column(Db::name('imy_info')->where([['account','=',$input['account']]])->select()->toArray(),'pid')];
+ }
+ $sql=frameScope($sql);//组织数据
+ $sql=sqlAuth('imy',$sql);//数据鉴权
+ $count = Imys::where($sql)->count();//获取总条数
+ $info = Imys::with(['frameData','customerData','peopleData','userData','billData','recordData'])->where($sql)->append(['extension'])->page($input['page'],$input['limit'])->order(['id'=>'desc'])->select()->toArray();//查询分页数据
+ $result=[
+ 'state'=>'success',
+ 'count'=>$count,
+ 'info'=>$info
+ ];//返回数据
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //新增|更新
+ public function save(){
+ $input=input('post.');
+ if(existFull($input,['class','info']) && isset($input['class']['id'])){
+ //构造|验证CLASS
+ try {
+ $class=$input['class'];
+ $class['frame']=userInfo(getUserID(),'frame');
+ $class['user']=getUserID();
+ $class['examine']=0;
+ $class['nucleus']=0;
+ empty($class['id'])?$this->validate($class,'app\validate\Imy'):$this->validate($class,'app\validate\Imy.update');
+ $period=getPeriod();
+ if(strtotime($class['time'])<=$period){
+ throw new ValidateException('单据日期与结账日期冲突!');
+ }
+ } catch (ValidateException $e) {
+ return json(['state'=>'error','info'=>$e->getError()]);
+ exit;
+ }
+
+ //验证INFO
+ foreach ($input['info'] as $infoKey=>$infoVo) {
+ try {
+ $this->validate($infoVo,'app\validate\ImyInfo');
+ } catch (ValidateException $e) {
+ return json(['state'=>'error','info'=>'数据表格第'.($infoKey+1).'条'.$e->getError()]);
+ exit;
+ }
+ }
+
+ //处理数据
+ Db::startTrans();
+ try {
+ //CLASS数据
+ if(empty($class['id'])){
+ //创建数据
+ $createInfo=Imys::create($class);
+ $class['id']=$createInfo['id'];//转存主键
+ Db::name('record')->insert(['type'=>'imy','source'=>$class['id'],'time'=>time(),'user'=>getUserID(),'info'=>'新增单据']);
+ pushLog('新增收款单[ '.$class['number'].' ]');//日志
+ }else{
+ //更新数据
+ $updateInfo=Imys::update($class);
+ Db::name('record')->insert(['type'=>'imy','source'=>$class['id'],'time'=>time(),'user'=>getUserID(),'info'=>'更新单据']);
+ pushLog('更新收款单[ '.$class['number'].' ]');//日志
+ }
+
+ //INFO数据
+ ImyInfo::where([['pid','=',$class['id']]])->delete();
+ foreach ($input['info'] as $infoKey=>$infoVo) {
+ $input['info'][$infoKey]['pid']=$class['id'];
+ }
+ $model = new ImyInfo;
+ $model->saveAll($input['info']);
+
+ Db::commit();
+ $result=['state'=>'success','info'=>$class['id']];
+ } catch (\Exception $e) {
+ Db::rollback();
+ $result=['state'=>'error','info'=>'内部错误,操作已撤销!'];
+ }
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //获取
+ public function get(){
+ $input=input('post.');
+ if(existFull($input,['parm'])){
+ $class=Imys::where([['id','=',$input['parm']]])->find();
+ $info=ImyInfo::with(['accountData'])->where([['pid','=',$input['parm']]])->order(['id'=>'asc'])->select();
+ $result=['state'=>'success','info'=>[
+ 'class'=>$class,
+ 'info'=>$info,
+ ]];
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //删除
+ public function del(){
+ $input=input('post.');
+ if(existFull($input,['parm']) && is_array($input['parm'])){
+ $data=Db::name('imy')->where([['id','in',$input['parm']]])->order(['id'=>'desc'])->select()->toArray();
+ $search=search($data)->where([['examine','=','1']])->find();
+ if(empty($search)){
+ Db::startTrans();
+ try {
+ Db::name('imy')->where([['id','in',$input['parm']]])->delete();
+ Db::name('imy_info')->where([['pid','in',$input['parm']]])->delete();
+ Db::name('record')->where([['type','=','imy'],['source','in',$input['parm']]])->delete();
+ Db::name('log')->insert(['time'=>time(),'user'=>getUserID(),'info'=>'删除收款单[ '.implode(' | ',array_column($data,'number')).' ]']);
+
+ Db::commit();
+ $result=['state'=>'success'];
+ } catch (\Exception $e) {
+ Db::rollback();
+ $result=['state'=>'error','info'=>'内部错误,操作已撤销!'];
+ }
+ }else{
+ $result=['state'=>'error','info'=>'单据['.$search['number'].']已审核,不可删除!'];
+ }
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //审核|反审核
+ public function examine(){
+ $input=input('post.');
+ if(existFull($input,['parm']) && is_array($input['parm'])){
+ //1 基础数据
+ $period=getPeriod();
+ $classList=Db::name('imy')->where([['id','in',$input['parm']]])->order(['id'=>'desc'])->select()->toArray();
+ $infoList=Db::name('imy_info')->where([['pid','in',$input['parm']]])->order(['id'=>'asc'])->select()->toArray();
+ //2 综合处理
+ foreach ($input['parm'] as $parmVo) {
+ //1 匹配数据
+ $class=search($classList)->where([['id','=',$parmVo]])->find();
+ $info=search($infoList)->where([['pid','=',$parmVo]])->select();
+ //2 CLASS验证
+ if($class['time']<=$period){
+ return json(['state'=>'error','info'=>'操作单据[ '.$class['number'].' ]失败,原因:单据日期与结账日期冲突!']);
+ exit;
+ }
+ if(!empty($class['examine'])){
+ //核销单
+ $bill=Db::name('bill_info')->where([['mold','=','imy'],['source','=',$class['id']]])->find();
+ if(!empty($bill)){
+ return json(['state'=>'error','info'=>'反审核单据[ '.$class['number'].' ]失败,原因:该单据存在关联核销单!']);
+ exit;
+ }
+ }
+ //3 数据处理
+ Db::startTrans();
+ try {
+ //场景验证
+ if(empty($class['examine'])){
+ //审核
+ //1 构造数据
+ $store=['account'=>[],'accountInfo'=>[]];
+ foreach ($info as $infoKey=>$infoVo){
+ //1 资金账户
+ $store['account'][]=['id'=>$infoVo['account'],'balance'=>$infoVo['money']];
+ //2 资金账户详情
+ $store['accountInfo'][]=['pid'=>$infoVo['account'],'type'=>'imy','class'=>$class['id'],'time'=>$class['time'],'direction'=>1,'money'=>$infoVo['money']];
+ }
+ //2 资金账户
+ Db::name('account')->duplicate(['balance'=>Db::raw('balance + VALUES(`balance`)')])->insertAll($store['account']);
+ //3 资金账户
+ Db::name('account_info')->insertAll($store['accountInfo']);
+ //4 客户|应收款余额
+ Db::name('customer')->where([['id','=',$class['customer']]])->dec('balance',$class['total'])->update();
+ //5 更新单据
+ Db::name('imy')->where([['id','=',$class['id']]])->update(['examine'=>1]);
+ //6 单据记录
+ Db::name('record')->insert(['type'=>'imy','source'=>$class['id'],'time'=>time(),'user'=>getUserID(),'info'=>'审核单据']);
+ //7 记录操作
+ pushLog('审核收款单[ '.$class['number'].' ]');//单据日志
+ }else{
+ //反审核
+ //1 匹配数据
+ $listSql=[['type','=','imy'],['class','=',$class['id']]];
+ $accountInfoList=Db::name('account_info')->where($listSql)->select()->toArray();
+ //2 资金账户
+ $accountDuplicate=[];
+ foreach ($accountInfoList as $accountInfoVo) {
+ $accountDuplicate[]=['id'=>$accountInfoVo['pid'],'balance'=>$accountInfoVo['money']];
+ }
+ //2.1 更新资金
+ Db::name('account')->duplicate(['balance'=>Db::raw('balance - VALUES(`balance`)')])->insertAll($accountDuplicate);
+ //2.2 删除资金详情
+ Db::name('account_info')->where([['id','in',array_column($accountInfoList,'id')]])->delete();
+ //3 客户|应收款余额
+ Db::name('customer')->where([['id','=',$class['customer']]])->inc('balance',$class['total'])->update();
+ //4 更新单据
+ Db::name('imy')->where([['id','=',$class['id']]])->update(['examine'=>0]);
+ //5 单据记录
+ Db::name('record')->insert(['type'=>'imy','source'=>$class['id'],'time'=>time(),'user'=>getUserID(),'info'=>'反审核单据']);
+ //6 记录操作
+ pushLog('反审核收款单[ '.$class['number'].' ]');//单据日志
+ }
+
+ Db::commit();
+ } catch (\Exception $e) {
+ Db::rollback();
+ return json(['state'=>'error','info'=>'内部错误,操作已撤销!']);
+ exit;
+ }
+ }
+ $result=['state'=>'success'];
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //上传
+ public function upload(){
+ $file = request()->file('file');
+ //获取上传文件
+ if (empty($file)) {
+ $result = ['state' => 'error','info' => '传入数据不完整!'];
+ } else {
+ //文件限制5MB
+ try{
+ validate(['file'=>['fileSize'=>5*1024*1024,'fileExt'=>'png,gif,jpg,jpeg,txt,doc,docx,rtf,xls,xlsx,ppt,pptx,pdf,zip,rar']])->check(['file'=>$file]);
+ $fileInfo=Filesystem::disk('upload')->putFile('imy', $file, 'uniqid');
+ $filePath=request()->domain().'/static/upload/'.$fileInfo;
+ $result=['state'=>'success','info'=>$filePath];
+ }catch(ValidateException $e) {
+ $result = ['state' => 'error','info' => $e->getMessage()];
+ }
+ }
+ return json($result);
+ }
+ //导入
+ public function import(){
+ delOverdueFile('static.upload.xlsx');//删除过期文件
+ $file=request()->file('file');//获取上传文件
+ if(empty($file)){
+ $result=['state'=>'error','info'=>'传入数据不完整!'];
+ }else{
+ $fun=getSys('fun');
+ try{
+ validate(['file'=>['fileSize'=>2*1024*1024,'fileExt'=>'xlsx']])->check(['file'=>$file]);
+ $fileInfo = Filesystem::disk('upload')->putFile('xlsx', $file, 'uniqid');
+ $filePath = pathChange('static.upload').$fileInfo;
+ $data=getXlsx($filePath);
+ unset($data[1]);//删除标题行
+ unset($data[2]);//删除列名行
+ //初始化CLASS
+ //客户匹配
+ $customer=Db::name('customer')->where([['name','=',$data[3]['A']]])->find();
+ if(empty($customer)){
+ throw new ValidateException('客户[ '.$data[3]['A'].' ]未匹配!');
+ }
+ //关联人员匹配
+ if(empty($data[3]['E'])){
+ $people=['id'=>0];
+ }else{
+ $people=Db::name('people')->where([['name','=',$data[3]['E']]])->find();
+ if(empty($people)){
+ throw new ValidateException('关联人员[ '.$data[3]['E'].' ]未匹配!');
+ }
+ }
+ $class=[
+ 'frame'=>userInfo(getUserID(),'frame'),
+ 'customer'=>$customer['id'],
+ 'time'=>$data[3]['B'],
+ 'number'=>$data[3]['C'],
+ 'total'=>0,
+ 'people'=>$people['id'],
+ 'file'=>[],
+ 'data'=>$data[3]['F'],
+ 'more'=>[],
+ 'examine'=>0,
+ 'nucleus'=>0,
+ 'user'=>getUserID()
+ ];
+ $this->validate($class,'app\validate\Imy');//数据合法性验证
+ //初始化INFO
+ $info=[];
+ $account=Db::name('account')->where([['name','in',array_column($data,'G')]])->select()->toArray();
+ foreach ($data as $dataKey=>$dataVo) {
+ $record=[
+ 'account'=>$dataVo['G'],
+ 'money'=>$dataVo['H'],
+ 'settle'=>$dataVo['I'],
+ 'data'=>$dataVo['J']
+ ];
+ //结算账户匹配
+ $accountFind=search($account)->where([['name','=',$record['account']]])->find();
+ if(empty($accountFind)){
+ throw new ValidateException('模板文件第'.$dataKey.'行结算账户[ '.$record['account'].' ]未匹配!');
+ }else{
+ $record['account']=$accountFind['id'];
+ }
+ //结算金额匹配
+ if(!preg_match("/^(\-)?\d+(\.\d{0,".$fun['digit']['money']."})?$/",$record['money'])){
+ throw new ValidateException('模板文件第'.$dataKey.'行结算金额不正确!');
+ }
+ try{
+ $this->validate($record,'app\validate\ImyInfo');//数据合法性验证
+ //转存数据
+ $class['total']=math()->chain($class['total'])->add($record['money'])->done();//累加单据金额
+ $info[]=$record;
+ } catch (ValidateException $e) {
+ return json(['state'=>'error','info'=>'模板文件第'.$dataKey.'行'.$e->getMessage()]);//返回错误信息
+ exit;
+ }
+ }
+ Db::startTrans();
+ try {
+ //新增CLASS
+ $classData=Imys::create($class);
+ //新增INFO
+ foreach ($info as $infoKey=>$infoVo) {
+ $info[$infoKey]['pid']=$classData['id'];
+ }
+ $model = new ImyInfo;
+ $model->saveAll($info);
+ Db::name('record')->insert(['type'=>'imy','source'=>$classData['id'],'time'=>time(),'user'=>getUserID(),'info'=>'导入单据']);
+ pushLog('导入收款单[ '.$classData['number'].' ]');//日志
+
+ Db::commit();
+ $result=['state'=>'success'];
+ } catch (\Exception $e) {
+ Db::rollback();
+ $result=['state'=>'error','info'=>'内部错误,操作已撤销!'];
+ }
+ }catch(ValidateException $e) {
+ $result=['state'=>'error','info'=>$e->getMessage()];//返回错误信息
+ }
+ }
+ return json($result);
+ }
+ //导出
+ public function exports(){
+ $input=input('get.');
+ if(existFull($input,['scene','parm']) && is_array($input['parm'])){
+ pushLog('导出收款单列表');//日志
+ $source=Imys::with(['frameData','customerData','peopleData','userData'])->where([['id','in',$input['parm']]])->append(['extension'])->order(['id'=>'desc'])->select()->toArray();//查询CLASS数据
+ if($input['scene']=='simple'){
+ //简易报表
+ //开始构造导出数据
+ $excel=[];//初始化导出数据
+ //标题数据
+ $excel[]=['type'=>'title','info'=>'收款单列表'];
+ //表格数据
+ $field=[
+ 'frameData|name'=>'所属组织',
+ 'customerData|name'=>'客户',
+ 'time'=>'单据时间',
+ 'number'=>'单据编号',
+ 'total'=>'单据金额',
+ 'extension|amount'=>'核销金额',
+ 'peopleData|name'=>'关联人员',
+ 'extension|examine'=>'审核状态',
+ 'extension|nucleus'=>'核销状态',
+ 'userData|name'=>'制单人',
+ 'data'=>'备注信息'
+ ];
+ $thead=array_values($field);//表格标题
+ $tbody=[];//表格内容
+ //构造表内数据
+ foreach ($source as $sourceVo) {
+ $rowData=[];
+ foreach (array_keys($field) as $fieldVo) {
+ $rowData[]=arraySeek($sourceVo,$fieldVo);//多键名数据赋值
+ }
+ $tbody[]=$rowData;//加入行数据
+ }
+ $excel[]=['type'=>'table','info'=>['thead'=>$thead,'tbody'=>$tbody]];//表格数据
+ //统计数据
+ $excel[]=['type'=>'node','info'=>[
+ '总数:'.count($source),
+ '总单据金额:'.mathArraySum(array_column($source,'total')),
+ '总核销金额:'.mathArraySum(arrayColumns($source,['extension','amount']))
+ ]];
+ //导出execl
+ buildExcel('收款单列表',$excel);
+ }else{
+ //详细报表
+ $files=[];//初始化文件列表
+ foreach ($source as $sourceVo) {
+ //开始构造导出数据
+ $excel=[];//初始化导出数据
+ //标题数据
+ $excel[]=['type'=>'title','info'=>'收款单'];
+ //节点数据
+ $excel[]=['type'=>'node','info'=>[
+ '客户:'.$sourceVo['customerData']['name'],
+ '单据日期:'.$sourceVo['time'],
+ '单据编号:'.$sourceVo['number']]
+ ];
+ //表格数据
+ $field=[
+ 'accountData|name'=>'结算账户',
+ 'money'=>'结算金额',
+ 'settle'=>'结算号',
+ 'data'=>'备注信息'
+ ];
+ //构造表内数据
+ $info=ImyInfo::with(['accountData'])->where([['pid','=',$sourceVo['id']]])->order(['id'=>'asc'])->select()->toArray();
+ $thead=array_values($field);//表格标题
+ $tbody=[];//表格内容
+ foreach ($info as $infoVo) {
+ $rowData=[];
+ foreach (array_keys($field) as $fieldVo) {
+ $rowData[]=arraySeek($infoVo,$fieldVo);//多键名数据赋值
+ }
+ $tbody[]=$rowData;//加入行数据
+ }
+ $excel[]=['type'=>'table','info'=>['thead'=>$thead,'tbody'=>$tbody]];//表格数据
+ //节点数据
+ $excel[]=['type'=>'node','info'=>[
+ '单据金额:'.$sourceVo['total'],
+ '核销金额:'.$sourceVo['extension']['amount'],
+ '关联人员:'.arraySeek($sourceVo,'peopleData|name'),
+ '备注信息:'.$sourceVo['data']]
+ ];
+ //生成execl
+ $files[]=buildExcel($sourceVo['number'],$excel,false);
+ }
+ buildZip('收款单_'.time(),$files);
+ }
+ }else{
+ return json(['state'=>'error','info'=>'传入数据不完整!']);
+ }
+ }
+}
\ No newline at end of file
diff --git a/serve/app/controller/Index.php b/serve/app/controller/Index.php
new file mode 100644
index 0000000..acbfda2
--- /dev/null
+++ b/serve/app/controller/Index.php
@@ -0,0 +1,9 @@
+where(empty($input['warehouse'])?sqlAuth('warehouse',[]):[['id','in',$input['warehouse']]])->order(['id'=>'desc'])->select()->toArray();
+ //构造表头|集合
+ $column=[];
+ foreach ($warehouse as $warehouseVo) {
+ $column[]=['id'=>$warehouseVo['id'],'key'=>'stock_'.$warehouseVo['id'],'name'=>$warehouseVo['name']];
+ }
+ //匹配商品
+ $sql=fastSql($input,[
+ [['name'=>'name|py'],'fullLike'],
+ ['number','fullLike'],
+ ['spec','fullLike'],
+ ['brand','fullEq'],
+ ['code','fullLike'],
+ ['data','fullLike']
+ ]);//构造SQL
+ //商品类型
+ $sql[]=['type','=',0];
+ //辅助属性扩展查询
+ $sqlOr=existFull($input,['code'])?[['id','in',array_column(Db::name('attr')->where([['code','=',$input['code']]])->select()->toArray(),'pid')]]:[];
+ //商品分类树结构查询
+ existFull($input,['category'])&&$sql[]=['category','in',findTreeArr('category',$input['category'],'id')];
+ //获取总条数
+ $count = Goods::where($sql)->whereOr($sqlOr)->count();
+ //查询分页数据
+ $info = Goods::with(['categoryData','attr'])->where($sql)->whereOr($sqlOr)->order(['id'=>'desc'])->page($input['page'],$input['limit'])->append(['extension'])->select()->toArray();
+ //唯一标识|属性处理
+ foreach ($info as $infoKey=>$infoVo) {
+ $info[$infoKey]['key']=$infoVo['id'];
+ foreach ($infoVo['attr'] as $attrKey=>$attrVo) {
+ $info[$infoKey]['attr'][$attrKey]['key']=$infoVo['id'].'.'.$attrVo['id'];
+ //属性处理
+ if(existFull($input,['code']) && !in_array($input['code'],[$infoVo['code'],$attrVo['code']])){
+ unset($info[$infoKey]['attr'][$attrKey]);
+ }
+ }
+ //重建索引
+ $info[$infoKey]['attr']=array_values($info[$infoKey]['attr']);
+ }
+ //查询库存数据
+ $room=Db::name('room')->where([['warehouse','in',array_column($warehouse,'id')],['goods','in',array_column($info,'id')]])->select()->toArray();
+ //库存集合[w:仓库|g:商品|a:属性]
+ $gather=['g'=>[],'wg'=>[],'ga'=>[],'wga'=>[]];
+ foreach ($room as $roomVo) {
+ //商品
+ $g=md5_16($roomVo['goods']);
+ $gather['g'][$g]=math()->chain($gather['g'][$g]??0)->add($roomVo['nums'])->done();
+ //仓库|商品
+ $wg=md5_16($roomVo['warehouse'].'&'.$roomVo['goods']);
+ $gather['wg'][$wg]=math()->chain($gather['wg'][$wg]??0)->add($roomVo['nums'])->done();
+ //判断属性
+ if(!empty($roomVo['attr'])){
+ //商品|属性
+ $ga=md5_16($roomVo['goods'].'&'.$roomVo['attr']);
+ $gather['ga'][$ga]=math()->chain($gather['ga'][$ga]??0)->add($roomVo['nums'])->done();
+ //仓库|商品|属性
+ $wga=md5_16($roomVo['warehouse'].'&'.$roomVo['goods'].'&'.$roomVo['attr']);
+ $gather['wga'][$wga]=math()->chain($gather['wga'][$wga]??0)->add($roomVo['nums'])->done();
+ }
+ }
+ //数量匹配|库存处理|结构处理
+ foreach ($info as $infoKey=>$infoVo) {
+ //商品
+ $g=md5_16($infoVo['id']);
+ $info[$infoKey]['summary']=isset($gather['g'][$g])?($infoVo['unit']=='-1'?unitSwitch($gather['g'][$g],$infoVo['units']):$gather['g'][$g]):0;
+ //仓库|商品
+ $record=[];
+ //单位数据
+ if($infoVo['unit']=='-1'){
+ $enter=[];
+ $unit=array_reverse(array_merge([['name'=>$infoVo['units'][0]['source']]],$infoVo['units']));
+ foreach ($unit as $unitVo) {
+ $enter[]=['name'=>$unitVo['name'],'nums'=>''];
+ }
+ }else{
+ $enter='';
+ }
+ foreach ($column as $columnVo) {
+ $wg=md5_16($columnVo['id'].'&'.$infoVo['id']);
+ $record['stock_'.$columnVo['id']]=[
+ 'warehouse'=>$columnVo['id'],
+ 'basis'=>$gather['wg'][$wg]??0,
+ 'basisAlias'=>isset($gather['wg'][$wg])?($infoVo['unit']=='-1'?unitSwitch($gather['wg'][$wg],$infoVo['units']):$gather['wg'][$wg]):0,
+ 'enter'=>$enter,
+ 'diff'=>0,
+ 'diffAlias'=>''
+ ];
+ }
+ $info[$infoKey]['record']=$record;
+ //匹配辅助属性
+ foreach ($infoVo['attr'] as $attrKey=>$attrVo) {
+ //商品|属性
+ $ga=md5_16($infoVo['id'].'&'.$attrVo['name']);
+ $info[$infoKey]['attr'][$attrKey]['summary']=isset($gather['ga'][$ga])?($infoVo['unit']=='-1'?unitSwitch($gather['ga'][$ga],$infoVo['units']):$gather['ga'][$ga]):0;
+ //仓库|商品|属性
+ $record=[];
+ foreach ($column as $columnVo) {
+ $wga=md5_16($columnVo['id'].'&'.$infoVo['id'].'&'.$attrVo['name']);
+ $record['stock_'.$columnVo['id']]=[
+ 'warehouse'=>$columnVo['id'],
+ 'basis'=>$gather['wga'][$wga]??0,
+ 'basisAlias'=>isset($gather['wga'][$wga])?($infoVo['unit']=='-1'?unitSwitch($gather['wga'][$wga],$infoVo['units']):$gather['wga'][$wga]):0,
+ 'enter'=>$enter,
+ 'diff'=>0,
+ 'diffAlias'=>''
+ ];
+ }
+ $info[$infoKey]['attr'][$attrKey]['record']=$record;
+ }
+ }
+ $result=[
+ 'state'=>'success',
+ 'count'=>$count,
+ 'info'=>$info,
+ 'column'=>$column
+ ];//返回数据
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //导出
+ public function exports(){
+ $input=input('get.');
+ pushLog('导出库存盘点单');//日志
+ //匹配商品
+ $sql=fastSql($input,[
+ [['name'=>'name|py'],'fullLike'],
+ ['number','fullLike'],
+ ['spec','fullLike'],
+ ['brand','fullEq'],
+ ['code','fullLike'],
+ ['data','fullLike']
+ ]);//构造SQL
+ //商品类型
+ $sql[]=['type','=',0];
+ //辅助属性扩展查询
+ $sqlOr=existFull($input,['code'])?[['id','in',array_column(Db::name('attr')->where([['code','=',$input['code']]])->select()->toArray(),'pid')]]:[];
+ //商品分类树结构查询
+ existFull($input,['category'])&&$sql[]=['category','in',findTreeArr('category',$input['category'],'id')];
+ //查询分页数据
+ $info = Goods::with(['categoryData','attr'])->where($sql)->whereOr($sqlOr)->order(['id'=>'desc'])->append(['extension'])->select()->toArray();
+ //属性处理
+ foreach ($info as $infoKey=>$infoVo) {
+ foreach ($infoVo['attr'] as $attrKey=>$attrVo) {
+ //属性处理
+ if(existFull($input,['code']) && !in_array($input['code'],[$infoVo['code'],$attrVo['code']])){
+ unset($info[$infoKey]['attr'][$attrKey]);
+ }
+ }
+ //重建索引
+ $info[$infoKey]['attr']=array_values($info[$infoKey]['attr']);
+ }
+ //结构重组
+ $source=[];
+ foreach ($info as $infoVo) {
+ $infoVo['enter']='';
+ $source[]=$infoVo;
+ if(!empty($infoVo['attr'])){
+ foreach ($infoVo['attr'] as $attrVo) {
+ $attrVo['name']='|- '.$attrVo['name'];
+ $attrVo['enter']='';
+ $source[]=$attrVo;
+ }
+ }
+ }
+ //开始构造导出数据
+ $excel=[];//初始化导出数据
+ //标题数据
+ $excel[]=['type'=>'title','info'=>'库存盘点单'];
+ //表格数据
+ $field=['name'=>'商品名称','enter'=>'盘点数','number'=>'商品编号','spec'=>'规格型号','categoryData|name'=>'商品分类','brand'=>'商品品牌','extension|unit'=>'商品单位','code'=>'商品条码','data'=>'商品备注'];
+ $thead=array_values($field);//表格标题
+ $tbody=[];//表格内容
+ //构造表内数据
+ foreach ($source as $sourceVo) {
+ $rowData=[];
+ foreach (array_keys($field) as $fieldVo) {
+ $rowData[]=arraySeek($sourceVo,$fieldVo);//多键名数据赋值
+ }
+ $tbody[]=$rowData;//加入行数据
+ }
+ $excel[]=['type'=>'table','info'=>['thead'=>$thead,'tbody'=>$tbody]];//表格数据
+ //导出execl
+ buildExcel('库存盘点单',$excel);
+ }
+ //生成盘盈单
+ public function buildEntry(){
+ $input=input('post.');
+ if(existFull($input,['info'])){
+ $class=['total'=>0,'type'=>1];
+ $fun=getSys('fun');
+ $list=[
+ 'goods'=>Goods::where([['id','in',array_unique(array_column($input['info'],'goods'))]])->select()->toArray(),
+ 'warehouse'=>Warehouse::where([['id','in',array_unique(array_column($input['info'],'warehouse'))]])->select()->toArray(),
+ ];
+ foreach ($input['info'] as $infoVo) {
+ $record=[];
+ $goods=search($list['goods'])->where([['id','=',$infoVo['goods']]])->find();
+ $warehouse=search($list['warehouse'])->where([['id','=',$infoVo['warehouse']]])->find();
+ $record['goods']=$infoVo['goods'];
+ $record['goodsData']=$goods;
+ $record['attr']=$infoVo['attr'];
+ $record['unit']=$infoVo['unit'];
+ $record['warehouse']=$infoVo['warehouse'];
+ $record['warehouseData']=$warehouse;
+ $record['batch']='';
+ $record['mfd']='';
+ $record['price']=$goods['buy'];
+ $record['nums']=$infoVo['nums'];
+ $record['serial']=[];
+ $record['total']=math()->chain($record['price'])->mul($record['nums'])->round($fun['digit']['money'])->done();
+ $record['data']='';
+ //转存数据
+ $info[]=$record;
+ $class['total']=math()->chain($class['total'])->add($record['total'])->done();//累加单据成本
+ }
+ $result=['state'=>'success','info'=>['class'=>$class,'info'=>$info]];
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //生成盘亏单
+ public function buildExtry(){
+ $input=input('post.');
+ if(existFull($input,['info']) && is_array($input['info'])){
+ $class=['total'=>0,'type'=>1];
+ $fun=getSys('fun');
+ $list=[
+ 'goods'=>Goods::where([['id','in',array_unique(array_column($input['info'],'goods'))]])->select()->toArray(),
+ 'warehouse'=>Warehouse::where([['id','in',array_unique(array_column($input['info'],'warehouse'))]])->select()->toArray(),
+ ];
+ foreach ($input['info'] as $infoVo) {
+ $record=[];
+ $goods=search($list['goods'])->where([['id','=',$infoVo['goods']]])->find();
+ $warehouse=search($list['warehouse'])->where([['id','=',$infoVo['warehouse']]])->find();
+ $record['goods']=$infoVo['goods'];
+ $record['goodsData']=$goods;
+ $record['attr']=$infoVo['attr'];
+ $record['unit']=$infoVo['unit'];
+ $record['warehouse']=$infoVo['warehouse'];
+ $record['warehouseData']=$warehouse;
+ $record['batch']='';
+ $record['mfd']='';
+ $record['price']=$goods['buy'];
+ $record['nums']=abs($infoVo['nums']);
+ $record['serial']=[];
+ $record['total']=math()->chain($record['price'])->mul($record['nums'])->round($fun['digit']['money'])->done();
+ $record['data']='';
+ //转存数据
+ $info[]=$record;
+ $class['total']=math()->chain($class['total'])->add($record['total'])->done();//累加单据成本
+ }
+ $result=['state'=>'success','info'=>['class'=>$class,'info'=>$info]];
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+}
\ No newline at end of file
diff --git a/serve/app/controller/Invoice.php b/serve/app/controller/Invoice.php
new file mode 100644
index 0000000..3ae2c58
--- /dev/null
+++ b/serve/app/controller/Invoice.php
@@ -0,0 +1,420 @@
+'class.number'],'fullLike'],
+ ['invoice','fullIn'],
+ [['startTime'=>'class.time'],'startTime'],
+ [['endTime'=>'class.time'],'endTime'],
+ ]);
+ $base[]=['examine','=',1];
+ $base[]=['invoice','<>',3];
+ $base=frameScope($base);
+ //匹配语句
+ $sql=[];
+ foreach ($input['mold'] as $mold) {
+ if(in_array($mold,['buy','bre'])){
+ $sql[$mold]=array_merge($base,fastSql($input,[['supplier','fullEq']]));
+ }else{
+ $sql[$mold]=array_merge($base,fastSql($input,[['customer','fullEq']]));
+ }
+ $sql[$mold]=sqlAuth($mold,$sql[$mold]);//数据鉴权
+ }
+ //构造查询
+ $union=[];
+ foreach ($input['mold'] as $mold) {
+ $union[]=Db::name($mold)->alias('class')->where($sql[$mold])->leftJoin(['is_invoice'=>'invoice'],'class.id=invoice.class and invoice.type="'.$mold.'"')->fieldRaw('"'.$mold.'" as mold,class.id,class.time,sum(invoice.money) as iat')->group('class.id')->buildSql();
+ }
+ $union=implode(' UNION ALL ',$union);
+ $count=DB::query('SELECT COUNT(*) as count FROM ('.$union.') as nodcloud')[0]["count"];
+ $record=DB::query('SELECT * FROM ('.$union.') as nodcloud ORDER BY `time` DESC LIMIT '.pageCalc($input['page'],$input['limit'],'str'));
+ //匹配数据
+ $list=[];
+ foreach ($input['mold'] as $mold) {
+ $gather=search($record)->where([['mold','=',$mold]])->select();
+ $db="app\\model\\".ucfirst($mold);
+ if(in_array($mold,['buy','bre'])){
+ $list[$mold]=$db::with(['frameData','supplierData'])->where([['id','in',array_column($gather,'id')]])->append(['extension'])->select()->toArray();
+ }else{
+ $list[$mold]=$db::with(['frameData','customerData'])->where([['id','in',array_column($gather,'id')]])->append(['extension'])->select()->toArray();
+ }
+ }
+ $data=[];
+ foreach ($record as $recordVo) {
+ $mold=$recordVo['mold'];
+ $row=search($list[$mold])->where([['id','=',$recordVo['id']]])->find();
+ $row['mold']=$mold;
+ $row['name']=['buy'=>'采购单','bre'=>'采购退货单','sell'=>'销售单','sre'=>'销售退货单'][$mold];
+ $row['current']=in_array($mold,['buy','bre'])?$row['supplierData']:$row['customerData'];
+ $row['iat']=floatval($recordVo['iat']);
+ $row['ani']=math()->chain($row['actual'])->sub($row['iat'])->done();
+ $row['money']="";
+ $data[]=$row;
+ }
+ $result=[
+ 'state'=>'success',
+ 'count'=>$count,
+ 'info'=>$data
+ ];//返回数据
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //开具发票
+ public function save(){
+ $input=input('post.');
+ if(existFull($input,['data'])&& is_array($input['data'])){
+ //验证数据
+ foreach ($input['data'] as $key=>$vo) {
+ try {
+ $this->validate($vo,'app\validate\Invoice');
+ } catch (ValidateException $e) {
+ return json(['state'=>'error','info'=>'选中数据第'.($key+1).'条'.$e->getError()]);
+ exit;
+ }
+ }
+ //单据匹配
+ $gather=[];
+ $tab=['buy','bre','sell','sre'];
+ foreach ($input['data'] as $vo) {
+ in_array($vo['type'],$tab)&&$gather[$vo['type']][]=$vo['class'];
+ }
+ $union=[];
+ foreach ($gather as $mold=>$vo) {
+ $union[]=Db::name($mold)->alias('class')->where([['class.id','in',$vo]])->leftJoin(['is_invoice'=>'invoice'],'class.id=invoice.class and invoice.type="'.$mold.'"')->fieldRaw('"'.$mold.'" as mold,class.id,class.actual as actual, sum(invoice.money) as iat')->group('class.id')->buildSql();
+ }
+ $union=implode(' UNION ALL ',$union);
+ $record=DB::query('SELECT * FROM ('.$union.') as nodcloud');
+ //验证数据
+ foreach ($input['data'] as $key=>$vo) {
+ $find=search($record)->where([['mold','=',$vo['type']],['id','=',$vo['class']]])->find();
+ $ani=math()->chain($find['actual'])->sub($find['iat'])->done();
+ if(bccomp($vo['money'],$ani)==1){
+ return json(['state'=>'error','info'=>'选中数据第'.($key+1).'条发票金额超出未开票金额!']);
+ exit;
+ }else{
+ $input['data'][$key]['ani']=$ani;
+ }
+ }
+ //处理数据
+ Db::startTrans();
+ try {
+ $bill=[];
+ foreach ($input['data'] as $key=>$vo) {
+ //发票状态
+ $bill[$vo['type']]['class'][]=[
+ 'id'=>$vo['class'],
+ 'invoice'=>bccomp($vo['money'],$vo['ani'])==0?2:1
+ ];
+ //发票记录
+ $bill[$vo['type']]['record'][]=['type'=>$vo['type'],'source'=>$vo['class'],'time'=>time(),'user'=>getUserID(),'info'=>'开具发票[ '.floatval($vo['money']).' ]'];
+ unset($input['data'][$key]['iat']);
+ }
+ //更新单据状态
+ foreach ($bill as $mold=>$vo) {
+ Db::name($mold)->duplicate(['invoice'=>Db::raw('VALUES(`invoice`)')])->insertAll($vo['class']);
+ Db::name('record')->insertAll($vo['record']);
+ }
+ //添加发票记录
+ $model = new \app\model\Invoice;
+ $model->saveAll($input['data']);
+ pushLog('开具购销发票');//日志
+
+ Db::commit();
+ $result=['state'=>'success'];
+ } catch (\Exception $e) {
+ Db::rollback();
+ $result=['state'=>'error','info'=>'内部错误,操作已撤销!'];
+ }
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //上传
+ public function upload(){
+ $file = request()->file('file');
+ //获取上传文件
+ if (empty($file)) {
+ $result = ['state' => 'error','info' => '传入数据不完整!'];
+ } else {
+ //文件限制5MB
+ try{
+ validate(['file'=>['fileSize'=>5*1024*1024,'fileExt'=>'png,gif,jpg,jpeg,txt,doc,docx,rtf,xls,xlsx,ppt,pptx,pdf,zip,rar']])->check(['file'=>$file]);
+ $fileInfo=Filesystem::disk('upload')->putFile('bor', $file, 'uniqid');
+ $filePath=request()->domain().'/static/upload/'.$fileInfo;
+ $result=['state'=>'success','info'=>$filePath];
+ }catch(ValidateException $e) {
+ $result = ['state'=>'error','info'=>$e->getMessage()];
+ }
+ }
+ return json($result);
+ }
+ //购销发票-导出
+ public function exports(){
+ $input=input('get.');
+ if(existFull($input,['parm']) && is_array($input['parm'])){
+ pushLog('导出购销发票');//日志
+ $parm=[];
+ $tab=['buy','bre','sell','sre'];
+ foreach($input['parm'] as $vo){
+ if(in_array($vo['mold'],$tab)){
+ $parm[$vo['mold']][]=$vo['id'];
+ }
+ }
+ //匹配数据
+ $list=[];
+ foreach ($parm as $mold=>$vo) {
+ $db="app\\model\\".ucfirst($mold);
+ if(in_array($mold,['buy','bre'])){
+ $list[$mold]=$db::with(['frameData','supplierData'])->alias('class')->where([['class.id','in',$vo]])->leftJoin(['is_invoice'=>'invoice'],'class.id=invoice.class and invoice.type="'.$mold.'"')->fieldRaw('class.*,sum(invoice.money) as iat')->group('class.id')->append(['extension'])->select()->toArray();
+ }else{
+ $list[$mold]=$db::with(['frameData','customerData'])->alias('class')->where([['class.id','in',$vo]])->leftJoin(['is_invoice'=>'invoice'],'class.id=invoice.class and invoice.type="'.$mold.'"')->fieldRaw('class.*,sum(invoice.money) as iat')->group('class.id')->append(['extension'])->select()->toArray();
+ }
+ }
+ $data=[];
+ foreach ($input['parm'] as $vo) {
+ $mold=$vo['mold'];
+ $row=search($list[$mold])->where([['id','=',$vo['id']]])->find();
+ $row['name']=['buy'=>'采购单','bre'=>'采购退货单','sell'=>'销售单','sre'=>'销售退货单'][$mold];
+ $row['current']=in_array($mold,['buy','bre'])?$row['supplierData']:$row['customerData'];
+ $row['iat']=floatval($row['iat']);
+ $row['ani']=math()->chain($row['actual'])->sub($row['iat'])->done();
+ $data[]=$row;
+ }
+ $source=$data;
+ //开始构造导出数据
+ $excel=[];//初始化导出数据
+ //标题数据
+ $excel[]=['type'=>'title','info'=>'购销发票'];
+ //表格数据
+ $field=[
+ 'name'=>'单据类型',
+ 'frameData|name'=>'所属组织',
+ 'current|name'=>'往来单位',
+ 'time'=>'单据时间',
+ 'number'=>'单据编号',
+ 'extension|invoice'=>'发票状态',
+ 'actual'=>'单据金额',
+ 'iat'=>'已开票金额',
+ 'ani'=>'未开票金额'
+ ];
+ $thead=array_values($field);//表格标题
+ $tbody=[];//表格内容
+ //构造表内数据
+ foreach ($source as $sourceVo) {
+ $rowData=[];
+ foreach (array_keys($field) as $fieldVo) {
+ $rowData[]=arraySeek($sourceVo,$fieldVo);//多键名数据赋值
+ }
+ $tbody[]=$rowData;//加入行数据
+ }
+ $excel[]=['type'=>'table','info'=>['thead'=>$thead,'tbody'=>$tbody]];//表格数据
+ $excel[]=['type'=>'node','info'=>[
+ '总数:'.count($source),
+ '单据总金额:'.mathArraySum(array_column($source,'actual')),
+ '已开票总金额:'.mathArraySum(array_column($source,'iat')),
+ '未开票总金额:'.mathArraySum(array_column($source,'ani'))
+ ]];
+ //导出execl
+ buildExcel('购销发票',$excel);
+ }else{
+ return json(['state'=>'error','info'=>'传入参数不完整!']);
+ }
+ }
+ //报表数据
+ public function form(){
+ $input=input('post.');
+ $sheet=['buy','bre','sell','sre'];
+ existFull($input,['mold'])||$input['mold']=$sheet;
+ if(existFull($input,['page','limit']) && arrayInArray($input['mold'],$sheet)){
+ $sql=[];
+ //构造SQL|INVOICE
+ $sql['invoice']=fastSql($input,[
+ [['mold'=>'type'],'fullIn'],
+ [['inr'=>'number'],'fullLike'],
+ ['title','fullLike'],
+ ]);
+
+ //构造SQL|CLASS|基础语句
+ $sql['base']=fastSql($input,[
+ ['number','fullLike'],
+ [['startTime'=>'time'],'startTime'],
+ [['endTime'=>'time'],'endTime'],
+ ]);
+ $sql['base']=frameScope($sql['base']);
+ //数据表
+ foreach ($input['mold'] as $t) {
+ if(in_array($t,['buy','bre'])){
+ $sql[$t]=array_merge($sql['base'],[['id','=',Db::raw('invoice.class')]],fastSql($input,[['supplier','fullEq']]));
+ }else{
+ $sql[$t]=array_merge($sql['base'],[['id','=',Db::raw('invoice.class')]],fastSql($input,[['customer','fullEq']]));
+ }
+ $sql[$t]=sqlAuth($t,$sql[$t]);//数据鉴权
+ }
+ //多源匹配
+ $union=[];
+ foreach ($input['mold'] as $t) {
+ //匹配类型|减少查询
+ if(in_array($t,$input['mold'])){
+ $union[]=Db::name($t)->where([
+ ['invoice.type','=',$t],
+ ])->where(empty($sql[$t])?[]:[$sql[$t]])->limit(1)->buildSql();
+ }
+ }
+ //合并子查询
+ $union=implode(' UNION ALL ',$union);
+ $count=Invoices::alias('invoice')->where($sql['invoice'])->whereExists($union)->count();
+ $info=Invoices::with(['sourceData'=>['frameData']])->alias('invoice')->where($sql['invoice'])->whereExists($union)->page($input['page'],$input['limit'])->order(['id'=>'desc'])->select()->toArray();
+
+ //匹配供应商|客户
+ $current=[
+ 'supplier'=>Db::name('supplier')->where([['id','in',arrayColumns(search($info)->where([['type','in',['buy','bre']]])->select(),['sourceData','supplier'])]])->select()->toArray(),
+ 'customer'=>Db::name('customer')->where([['id','in',arrayColumns(search($info)->where([['type','in',['sell','sre']]])->select(),['sourceData','customer'])]])->select()->toArray(),
+ ];
+ $data=[];
+ foreach ($info as $infoVo) {
+ $row=$infoVo;
+ $mold=$infoVo['type'];
+ $row['name']=['buy'=>'采购单','bre'=>'采购退货单','sell'=>'销售单','sre'=>'销售退货单'][$mold];
+ if(in_array($mold,['buy','bre'])){
+ $row['current']=search($current['supplier'])->where([['id','=',$row['sourceData']['supplier']]])->find();
+ }else{
+ $row['current']=search($current['customer'])->where([['id','=',$row['sourceData']['customer']]])->find();
+ }
+ $data[]=$row;
+ }
+ $result=[
+ 'state'=>'success',
+ 'count'=>$count,
+ 'info'=>$data
+ ];//返回数据
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //删除
+ public function del(){
+ $input=input('post.');
+ if(existFull($input,['parm']) && is_array($input['parm'])){
+ $data=Db::name('invoice')->where([['id','in',$input['parm']]])->order(['id'=>'desc'])->select()->toArray();
+ Db::startTrans();
+ try {
+ $gather=[];
+ $record=[];
+ //匹配数据
+ foreach ($data as $key=>$vo) {
+ $gather[$vo['type']][]=$vo['class'];
+ $record[]=['type'=>$vo['type'],'source'=>$vo['class'],'time'=>time(),'user'=>getUserID(),'info'=>'删除发票[ '.floatval($vo['money']).' ]'];
+ }
+ //插入单据记录
+ Db::name('record')->insertAll($record);
+ //删除发票记录
+ Db::name('invoice')->where([['id','in',$input['parm']]])->delete();
+ //匹配发票记录
+ $union=[];
+ foreach ($gather as $mold=>$vo) {
+ $union[]=Db::name($mold)->alias('class')->where([['class.id','in',$vo]])->leftJoin(['is_invoice'=>'invoice'],'class.id=invoice.class and invoice.type="'.$mold.'"')->fieldRaw('"'.$mold.'" as mold,class.id,count(invoice.id) as length')->group('class.id')->buildSql();
+ }
+ $union=implode(' UNION ALL ',$union);
+ $list=Db::query('SELECT * FROM ('.$union.') as nodcloud');
+ //更新单据状态
+ $bill=[];
+ foreach($list as $vo){
+ $bill[$vo['mold']][]=['id'=>$vo['id'],'invoice'=>empty($vo['length'])?0:1];
+ }
+ foreach($bill as $mold=>$vo){
+ Db::name($mold)->duplicate(['invoice'=>Db::raw('VALUES(`invoice`)')])->insertAll($vo);
+
+ }
+ pushLog('删除购销发票');//日志
+
+ Db::commit();
+ $result=['state'=>'success'];
+ } catch (\Exception $e) {
+ Db::rollback();
+ $result=['state'=>'error','info'=>'内部错误,操作已撤销!'];
+ }
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //购销发票报表-导出
+ public function formExports(){
+ $input=input('get.');
+ if(existFull($input,['parm']) && is_array($input['parm'])){
+ pushLog('导出购销发票报表');//日志
+ $info=Invoices::with(['sourceData'=>['frameData']])->where([['id','in',$input['parm']]])->order(['id'=>'desc'])->select()->toArray();
+ //匹配供应商|客户
+ $current=[
+ 'supplier'=>Db::name('supplier')->where([['id','in',arrayColumns(search($info)->where([['type','in',['buy','bre']]])->select(),['sourceData','supplier'])]])->select()->toArray(),
+ 'customer'=>Db::name('customer')->where([['id','in',arrayColumns(search($info)->where([['type','in',['sell','sre']]])->select(),['sourceData','customer'])]])->select()->toArray(),
+ ];
+ $data=[];
+ foreach ($info as $infoVo) {
+ $row=$infoVo;
+ $mold=$infoVo['type'];
+ $row['name']=['buy'=>'采购单','bre'=>'采购退货单','sell'=>'销售单','sre'=>'销售退货单'][$mold];
+ if(in_array($mold,['buy','bre'])){
+ $row['current']=search($current['supplier'])->where([['id','=',$row['sourceData']['supplier']]])->find();
+ }else{
+ $row['current']=search($current['customer'])->where([['id','=',$row['sourceData']['customer']]])->find();
+ }
+ $data[]=$row;
+ }
+ $source=$data;
+ //开始构造导出数据
+ $excel=[];//初始化导出数据
+ //标题数据
+ $excel[]=['type'=>'title','info'=>'购销发票报表'];
+ //表格数据
+ $field=[
+ 'name'=>'单据类型',
+ 'sourceData|frameData|name'=>'所属组织',
+ 'current|name'=>'往来单位',
+ 'sourceData|time'=>'单据时间',
+ 'sourceData|number'=>'单据编号',
+ 'sourceData|actual'=>'单据金额',
+ 'time'=>'开票时间',
+ 'number'=>'发票号码',
+ 'title'=>'发票抬头',
+ 'money'=>'发票金额',
+ 'data'=>'备注信息'
+ ];
+ $thead=array_values($field);//表格标题
+ $tbody=[];//表格内容
+ //构造表内数据
+ foreach ($source as $sourceVo) {
+ $rowData=[];
+ foreach (array_keys($field) as $fieldVo) {
+ $rowData[]=arraySeek($sourceVo,$fieldVo);//多键名数据赋值
+ }
+ $tbody[]=$rowData;//加入行数据
+ }
+ $excel[]=['type'=>'table','info'=>['thead'=>$thead,'tbody'=>$tbody]];//表格数据
+ $excel[]=['type'=>'node','info'=>[
+ '总数:'.count($source),
+ '单据总金额:'.mathArraySum(arrayColumns($source,['sourceData','actual'])),
+ '发票总金额:'.mathArraySum(array_column($source,'money'))
+ ]];
+ //导出execl
+ buildExcel('购销发票报表',$excel);
+ }else{
+ return json(['state'=>'error','info'=>'传入参数不完整!']);
+ }
+ }
+}
diff --git a/serve/app/controller/Log.php b/serve/app/controller/Log.php
new file mode 100644
index 0000000..bf68e65
--- /dev/null
+++ b/serve/app/controller/Log.php
@@ -0,0 +1,45 @@
+'time'],'startTime'],
+ [['endTime'=>'time'],'endTime']
+ ]);//构造SQL
+ $sql=sqlAuth('log',$sql);
+ $count = Logs::where($sql)->count();//获取总条数
+ $info = Logs::with(['userData'])->where($sql)->page($input['page'],$input['limit'])->order(['id'=>'desc'])->select();//查询分页数据
+ $result=[
+ 'state'=>'success',
+ 'count'=>$count,
+ 'info'=>$info
+ ];//返回数据
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //清空
+ public function empty(){
+ Db::startTrans();
+ try {
+ Db::query("truncate table is_log");
+ pushLog('清空操作日志');//日志
+
+ Db::commit();
+ $result=['state'=>'success'];
+ } catch (\Exception $e) {
+ Db::rollback();
+ $result=['state'=>'error','info'=>'内部错误,操作已撤销!'];
+ }
+ return json($result);
+ }
+}
diff --git a/serve/app/controller/Main.php b/serve/app/controller/Main.php
new file mode 100644
index 0000000..3c892da
--- /dev/null
+++ b/serve/app/controller/Main.php
@@ -0,0 +1,186 @@
+where(sqlAuth($t,$rowWhere))->fieldRaw('GROUP_CONCAT(`id`) as id,sum(actual) as actual')->select()->toArray()[0];
+ }elseif($t=='imy'){
+ $group[$v][$t]=Db::name($t)->where(sqlAuth($t,$rowWhere))->fieldRaw('sum(total) as total')->select()->toArray()[0];
+ }else{
+ $group[$v][$t]=Db::name($t)->where(sqlAuth($t,$rowWhere))->fieldRaw('sum(actual) as actual')->select()->toArray()[0];
+ }
+ }
+ }
+
+ $lattice['sve']=[
+ 'today'=>empty($group['today']['sell']['actual'])?0:floatval($group['today']['sell']['actual']),
+ 'yesterday'=>empty($group['yesterday']['sell']['actual'])?0:$group['yesterday']['sell']['actual'],
+ ];
+ $lattice['nos']=[
+ 'today'=>[
+ 'sell'=>empty($group['today']['sell']['id'])?[]:explode(',',$group['today']['sell']['id'])
+ ],
+ 'yesterday'=>[
+ 'sell'=>empty($group['yesterday']['sell']['id'])?[]:explode(',',$group['yesterday']['sell']['id'])
+ ]
+ ];
+ $lattice['spt']=[
+ 'today'=>Db::name('summary')->whereOr([
+ [['type','=','sell'],['class','in',$lattice['nos']['today']['sell']]]
+ ])->fieldRaw('sum(bct) as bct')->select()->toArray()[0]['bct'],
+ 'yesterday'=>Db::name('summary')->whereOr([
+ [['type','=','sell'],['class','in',$lattice['nos']['yesterday']['sell']]]
+ ])->fieldRaw('sum(bct) as bct')->select()->toArray()[0]['bct']
+ ];
+ $lattice['spt']=[
+ 'today'=>math()->chain($lattice['sve']['today'])->sub($lattice['spt']['today'])->done(),
+ 'yesterday'=>math()->chain($lattice['sve']['yesterday'])->sub($lattice['spt']['yesterday'])->done()
+ ];
+ $lattice['nos']=[
+ 'today'=>count(array_merge($lattice['nos']['today']['sell'])),
+ 'yesterday'=>count(array_merge($lattice['nos']['yesterday']['sell'])),
+ ];
+ $lattice['fund']=[
+ 'today'=>math()->chain($lattice['sve']['today'])->add($group['today']['imy']['total'])->add($group['today']['ice']['actual'])->done(),
+ 'yesterday'=>math()->chain($lattice['sve']['yesterday'])->add($group['yesterday']['imy']['total'])->add($group['yesterday']['ice']['actual'])->done(),
+ ];
+ $lattice['sve']['yesterday']=empty($lattice['sve']['yesterday'])?(empty($lattice['sve']['today'])?'0':'100'):math()->chain($lattice['sve']['today'])->div($lattice['sve']['yesterday'])->mul(100)->round(2)->done();
+ $lattice['spt']['yesterday']=empty($lattice['spt']['yesterday'])?(empty($lattice['spt']['today'])?'0':'100'):math()->chain($lattice['spt']['today'])->div($lattice['spt']['yesterday'])->mul(100)->round(2)->done();
+ $lattice['nos']['yesterday']=empty($lattice['nos']['yesterday'])?(empty($lattice['nos']['today'])?'0':'100'):math()->chain($lattice['nos']['today'])->div($lattice['nos']['yesterday'])->mul(100)->round(2)->done();
+ $lattice['fund']['yesterday']=empty($lattice['fund']['yesterday'])?(empty($lattice['fund']['today'])?'0':'100'):math()->chain($lattice['fund']['today'])->div($lattice['fund']['yesterday'])->mul(100)->round(2)->done();
+
+
+
+ //汇总信息
+ $list=[
+ 'room'=>Db::name('room')->field(['id','nums'])->where(sqlAuth('room',[]))->select()->toArray(),
+ 'customer'=>Db::name('customer')->field(['id','balance'])->where(sqlAuth('customer',frameScope([])))->select()->toArray(),
+ 'supplier'=>Db::name('supplier')->field(['id','balance'])->where(sqlAuth('supplier',frameScope([])))->select()->toArray()
+ ];
+ $summary=[];
+ $summary['goods']=Db::name('goods')->count();
+ $summary['customer']=count($list['customer']);
+ $summary['supplier']=count($list['supplier']);
+ $summary['room']=mathArraySum(array_column($list['room'],'nums'));
+ $summary['rwg'] = Db::name('room')->alias('room')->where([['id','in',array_column($list['room'],'id')]])->whereExists(
+ Db::name('goods')->where([['id','=',Db::raw('room.goods')],['room.nums','<=',Db::raw('stock')]])->buildSql(false)
+ )->count();
+ $summary['bwg'] = Db::name('batch')->alias('batch')->where(sqlAuth('batch',[]))->whereExists(
+ Db::name('goods')->where([['id','=',Db::raw('batch.goods')]])->whereRaw('batch.time + (threshold * 86400) < :time',['time'=>strtotime(date('Y-m-d',time()))])->buildSql(false)
+ )->count();
+
+ //资产数据
+ $assets['account']=Db::name('account')->fieldRaw('(sum(initial)+sum(balance)) as money')->where(sqlAuth('account',frameScope([])))->select()[0]['money'];
+ $sy=Db::name('summary')->fieldRaw('direction,sum(bct) as bct')->where(sqlAuth('summary'))->group(['direction'])->order('direction')->select()->toArray();
+ $assets['rsy']=empty($sy)?0:(count($sy)==2?math()->chain($sy[1]['bct'])->sub($sy[0]['bct'])->done():($sy[0]['direction']==0?-$sy[0]['bct']:$sy[0]['bct']));
+ $assets['cas']=mathArraySum(array_column($list['customer'],'balance'));
+ $assets['sas']=mathArraySum(array_column($list['supplier'],'balance'));
+ $assets['all']=math()->chain($assets['account'])->add($assets['rsy'])->add($assets['cas'])->sub($assets['sas'])->done();
+ //位数处理
+ foreach ($summary as $k=>$v){$summary[$k]=floatval($v);}
+ foreach ($assets as $k=>$v){$assets[$k]=floatval($v);}
+
+ //数据概括
+ $fun=getSys('fun');
+ $option=[];
+ $deploy=[
+ [
+ 'title'=>['text'=>'','left'=>'center'],
+ 'xAxis'=>['type'=>'category','boundaryGap'=>false,'data'=>[]],
+ 'grid'=>['top'=>'12%','left'=>'1%','right'=>'1%','bottom'=>'0%','containLabel'=>true],
+ 'yAxis'=>['type'=>'value'],
+ 'series'=>[['data'=>[],'type'=>'line','areaStyle'=>[]]],
+ 'tooltip'=>['trigger'=>'axis','axisPointer'=>['type'=>'cross']]
+ ],
+ [
+ 'title'=>['text'=>'库存数据','left'=>'center'],
+ 'tooltip'=>['trigger'=>'item'],
+ 'legend'=>['orient'=>'vertical','left'=>'left'],
+ 'series'=>[['type'=>'pie','radius'=>'60%','data'=>[]]]
+ ]
+ ];
+ $table=['buy'=>'采购单','bre'=>'采购退货单','sell'=>'销售单','sre'=>'销售退货单','imy'=>'收款单','omy'=>'付款单'];
+ $where=[['time','>=',time()-($fun['days']*86400)],['time','<=',time()],['examine','=',1]];
+ foreach($table as $k=>$v){
+ $bill=Db::name($k)->fieldRaw('time,sum('.(in_array($k,['imy','omy'])?'total':'actual').') as actual')->where(sqlAuth($k,$where))->group('time')->select()->toArray();
+ $xData=getOldDay($fun['days']);
+ $yData=[];
+ foreach($xData as $date){
+ $t=strtotime($date);
+ $find=search($bill)->where([['time','=',$t]])->find();
+ $yData[]=empty($find)?0:$find['actual'];
+ }
+ $replica=$deploy[0];
+ $replica['title']['text']=$v;
+ $replica['xAxis']['data']=$xData;
+ $replica['series'][0]['data']=$yData;
+ $option[]=$replica;
+ }
+ //库存分布
+ $pie=Db::name('room')->fieldRaw('warehouse,sum(nums) as nums')->where([['id','in',array_column($list['room'],'id')]])->group(['warehouse'])->select()->toArray();
+ $wlt=Db::name('warehouse')->where([['id','in',array_column($pie,'warehouse')]])->select();
+ $replica=$deploy[1];
+ foreach($pie as $v){
+ $w=search($wlt)->where([['id','=',$v['warehouse']]])->find();
+ $replica['series']['0']['data'][]=['value'=>$v['nums'],'name'=>$w['name']];
+ }
+ $option[]=$replica;
+
+ // 资金数据
+ $fund=[
+ 'xAxis'=>['type'=>'category','data'=>[]],
+ 'grid'=>['top'=>'6%','left'=>'1%','right'=>'1%','bottom'=>'0%','containLabel'=>true],
+ 'yAxis'=>['type'=>'value'],
+ 'series'=>[['data'=>[],'type'=>'bar','itemStyle'=>(object)[]]],
+ 'tooltip'=>['trigger'=>'axis','axisPointer'=>['type'=>'cross']]
+ ];
+ $fundData=Db::name('account')->fieldRaw('name,(initial+balance) as money')->where(sqlAuth('account',frameScope([])))->select()->toArray();
+ foreach ($fundData as $v) {
+ $fund['xAxis']['data'][]=$v['name'];
+ $fund['series'][0]['data'][]=$v['money'];
+ }
+ if(empty($fund['xAxis']['data'])){
+ $fund['xAxis']['data'][]='无数据';
+ $fund['series'][0]['data'][]=0;
+ }
+ //负载监测
+ $load=[];
+ $cacheMaxSize=256;
+ $load['cache']['size']=getDirSize(pathChange('runtime'));
+ $load['cache']['rate']=round($load['cache']['size']*100/$cacheMaxSize,2);
+ $mysqlMaxSize=256;
+ $load['mysql']['size']=getMysqlSize();
+ $load['mysql']['rate']=round($load['mysql']['size']*100/$mysqlMaxSize,2);
+
+ //运行环境
+ $run=[
+ 'os'=>PHP_OS,
+ 'soft'=>$_SERVER['SERVER_SOFTWARE'],
+ 'php'=>PHP_VERSION,
+ 'mysql'=>Db::query("select VERSION() as ver")[0]['ver'],
+ 'protocol'=>$_SERVER['SERVER_PROTOCOL']
+ ];
+ return json([
+ 'state'=>'success',
+ 'info'=>[
+ 'lattice'=>$lattice,
+ 'summary'=>$summary,
+ 'option'=>$option,
+ 'assets'=>$assets,
+ 'fund'=>$fund,
+ 'load'=>$load,
+ 'run'=>$run
+ ]
+ ]);
+ }
+}
diff --git a/serve/app/controller/Menu.php b/serve/app/controller/Menu.php
new file mode 100644
index 0000000..a9833eb
--- /dev/null
+++ b/serve/app/controller/Menu.php
@@ -0,0 +1,102 @@
+'asc'])->append(['extension'])->select());
+ return json(['state'=>'success','info'=>$menu]);
+ }
+ //新增|更新
+ public function save(){
+ $input=input('post.');
+ if(isset($input['id'])){
+ //验证数据
+ try {
+ if(empty($input['id'])){
+ $this->validate($input,'app\validate\Menu');
+ }else{
+ $this->validate($input,'app\validate\Menu.update');
+ //所属不可等于或包含当前
+ if(in_array($input['pid'],findTreeArr('menu',$input['id'],'id'))){
+ throw new ValidateException('所属菜单选择不正确!');
+ }
+ }
+ } catch (ValidateException $e) {
+ return json(['state'=>'error','info'=>$e->getError()]);
+ exit;
+ }
+
+ //处理数据
+ Db::startTrans();
+ try {
+ if(empty($input['id'])){
+ //创建数据
+ Menus::create($input);
+ pushLog('新增菜单[ '.$input['name'].' ]');//日志
+ }else{
+ //更新数据
+ Menus::update($input);
+ pushLog('更新菜单[ '.$input['name'].' ]');//日志
+ }
+
+ //修改上级架构菜单地址|#group
+ if($input['type']!=1){
+ Menus::where([['id','=',$input['pid']]])->update(['resource'=>'#group']);
+ }
+
+ Db::commit();
+ $result=['state'=>'success'];
+ } catch (\Exception $e) {
+ Db::rollback();
+ $result=['state'=>'error','info'=>'内部错误,操作已撤销!'];
+ }
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //获取
+ public function get(){
+ $input=input('post.');
+ if(existFull($input,['id'])){
+ $result=[
+ 'state'=>'success',
+ 'info'=>Menus::where([['id','=',$input['id']]])->find()
+ ];
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //删除
+ public function del(){
+ $input=input('post.');
+ if(existFull($input,['id'])){
+ $subFind=Db::name('menu')->where([['pid','=',$input['id']]])->find();
+ if(empty($subFind)){
+ $find=Db::name('menu')->where([['id','=',$input['id']]])->find();
+ Db::startTrans();
+ try {
+ Db::name('menu')->where([['id','=',$input['id']]])->delete();
+ pushLog('删除菜单[ '.$find['name'].' ]');//日志
+
+ Db::commit();
+ $result=['state'=>'success'];
+ } catch (\Exception $e) {
+ Db::rollback();
+ $result=['state'=>'error','info'=>'内部错误,操作已撤销!'];
+ }
+ }else{
+ $result=['state'=>'error','info'=>'存在子数据,删除失败!'];
+ }
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+}
diff --git a/serve/app/controller/Mould.php b/serve/app/controller/Mould.php
new file mode 100644
index 0000000..7443543
--- /dev/null
+++ b/serve/app/controller/Mould.php
@@ -0,0 +1,200 @@
+count();//获取总条数
+ $info = Moulds::where($sql)->page($input['page'],$input['limit'])->order(['key'=>'asc','sort'=>'asc'])->select();//查询分页数据
+ $result=[
+ 'state'=>'success',
+ 'count'=>$count,
+ 'info'=>$info
+ ];//返回数据
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //新增|更新
+ public function save(){
+ $input=input('post.');
+ if(isset($input['id'])){
+ //验证数据
+ try {
+ empty($input['id'])?$this->validate($input,'app\validate\Mould'):$this->validate($input,'app\validate\Mould.update');
+ } catch (ValidateException $e) {
+ return json(['state'=>'error','info'=>$e->getError()]);
+ exit;
+ }
+
+ //处理数据
+ Db::startTrans();
+ try {
+ if(empty($input['id'])){
+ //创建数据
+ Moulds::create($input);
+ pushLog('新增模板[ '.$input['name'].' ]');//日志
+ }else{
+ //更新数据
+ Moulds::update($input);
+ pushLog('更新模板[ '.$input['name'].' ]');//日志
+ }
+
+ Db::commit();
+ $result=['state'=>'success'];
+ } catch (\Exception $e) {
+ Db::rollback();
+ $result=['state'=>'error','info'=>'内部错误,操作已撤销!'];
+ }
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //获取
+ public function get(){
+ $input=input('post.');
+ if(existFull($input,['id'])){
+ $result=[
+ 'state'=>'success',
+ 'info'=>Moulds::where([['id','=',$input['id']]])->find()
+ ];
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //复制
+ public function copy(){
+ $input=input('post.');
+ if(existFull($input,['id'])){
+ $find=Moulds::where([['id','=',$input['id']]])->find()->toArray();
+ pushLog('复制模板[ '.$find['name'].' ]');//日志
+ unset($find['id']);//移除主键
+ $find['name']=$find['name'].'|复制';
+ Moulds::create($find);
+ $result=['state'=>'success'];
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //删除
+ public function del(){
+ $input=input('post.');
+ if(existFull($input,['id'])){
+ $find=Db::name('mould')->where([['id','=',$input['id']]])->find();
+ Db::startTrans();
+ try {
+ Db::name('mould')->where([['id','=',$input['id']]])->delete();
+ pushLog('删除模板[ '.$find['name'].' ]');//日志
+
+ Db::commit();
+ $result=['state'=>'success'];
+ } catch (\Exception $e) {
+ Db::rollback();
+ $result=['state'=>'error','info'=>'内部错误,操作已撤销!'];
+ }
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //导入
+ public function import(){
+ delOverdueFile('static.upload.mould');//删除过期文件
+ $file=request()->file('file');//获取上传文件
+ if(empty($file)){
+ $result=['state'=>'error','info'=>'传入数据不完整!'];
+ }else{
+ try{
+ validate(['file'=>['fileSize'=>1024*1024,'fileExt'=>'md']])->check(['file'=>$file]);
+ $fileInfo = Filesystem::disk('upload')->putFile('mould', $file, 'uniqid');
+ $filePath = pathChange('static.upload').$fileInfo;
+ $json=json_decode(file_get_contents($filePath),true);
+ if(existFull($json,['name','key','source','code','data'])){
+ $createInfo=Moulds::create($json);
+ pushLog('导入模板[ '.$createInfo['name'].' ]');//日志
+ $result=['state'=>'success'];
+ }else{
+ $result=['state'=>'error','info'=>'模板文件参数不正确!'];
+ }
+ }catch(ValidateException $e) {
+ $result=['state'=>'error','info'=>$e->getMessage()];//返回错误信息
+ }
+ }
+ return json($result);
+ }
+ //导出
+ public function exports(){
+ delOverdueFile('static.file.mould');//删除过期文件
+ $input=input('get.');
+ if(existFull($input,['parm']) && is_array($input['parm'])){
+ pushLog('导出打印模板');//日志
+ $info=Moulds::where([['id','in',$input['parm']]])->order(['id'=>'desc'])->select()->toArray();//查询数据
+ $zipFile=[];
+ foreach ($info as $infoVo) {
+ unset($infoVo['id']);
+ $fileName = str_replace(['/','\\',':','*','"','<','>','|','?'],'_',$infoVo['name']);
+ $filePath = pathChange('static.file.mould').$fileName.'.md';
+ file_put_contents($filePath,json_encode($infoVo));
+ $zipFile[]=$filePath;
+ }
+ buildZip('模板文件',$zipFile);
+ }else{
+ return json(['state'=>'error','info'=>'传入数据不完整!']);
+ }
+ }
+
+ // --- 场景函数 ---
+
+ //获取|ID
+ public function find(){
+ $input=input('post.');
+ if(existFull($input,['id'])){
+ $mould=Moulds::where([['id','=',$input['id']]])->find();
+ $result=[
+ 'state'=>'success',
+ 'info'=>$mould
+ ];//返回数据
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //获取|KEY
+ public function select(){
+ $input=input('post.');
+ if(existFull($input,['key'])){
+ $moulds=Moulds::where([['key','in',$input['key']]])->order(['sort'=>'asc'])->select();
+ $result=[
+ 'state'=>'success',
+ 'info'=>$moulds
+ ];//返回数据
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //更新|模板编辑
+ public function update(){
+ $input=input('post.');
+ if(existFull($input,['id','code'])){
+ Moulds::where([['id','=',$input['id']]])->update(['code'=>$input['code']]);
+ $result=['state'=>'success',];
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+}
\ No newline at end of file
diff --git a/serve/app/controller/Mrt.php b/serve/app/controller/Mrt.php
new file mode 100644
index 0000000..6772553
--- /dev/null
+++ b/serve/app/controller/Mrt.php
@@ -0,0 +1,476 @@
+'time'],'startTime'],
+ [['endTime'=>'time'],'endTime'],
+ ['user','fullEq'],
+ ['people','fullEq']
+ ]);
+ $sql[]=['examine','=',1];
+ $sql=frameScope($sql);//组织数据
+ $sql=sqlAuth('sell',$sql);//数据鉴权[结构一致]
+ $union=[];
+ $tab=['sell','sre'];
+ foreach ($tab as $t) {
+ if(in_array($t,$input['mold'])){
+ $union[]=Db::name($t)->where($sql)->fieldRaw('"'.$t.'" as mold,id')->buildSql();
+ }
+ }
+ $union=implode(' UNION ALL ',$union);
+ $count=DB::query('SELECT COUNT(*) as count FROM ('.$union.') as nodcloud')[0]["count"];
+ $record=DB::query('SELECT * FROM ('.$union.') as nodcloud LIMIT '.pageCalc($input['page'],$input['limit'],'str'));
+ $bill=['class'=>[],'summary'=>[],'info'=>[],''=>[]];
+ foreach ($tab as $t) {
+ if(in_array($t,$input['mold'])){
+ $gather=search($record)->where([['mold','=',$t]])->select();
+ $db=['class'=>"app\\model\\".ucfirst($t),'info'=>"app\\model\\".ucfirst($t).'Info'];
+ $bill['class']=array_merge($bill['class'],$db['class']::with(['frameData','customerData','userData','peopleData'])->fieldRaw('*,"'.$t.'" as mold,time as t')->where([['id','in',array_column($gather,'id')]])->append(['extension'])->select()->toArray());
+ $bill['summary']=array_merge($bill['summary'],Db::name('summary')->where([['type','=',$t],['class','in',array_column($gather,'id')]])->field(['type','class','info','bct'])->select()->toArray());
+ //匹配明细
+ if(!empty($input['type'])){
+ $bill['info'][$t]=$db['info']::with(['goodsData'])->where([['pid','in',array_column($gather,'id')]])->select()->toArray();
+ }
+ }
+ }
+ arraySort($bill['class'],'t',SORT_ASC);
+ $data=[];
+ //匹配数据
+ foreach ($bill['class'] as $classVo) {
+ $row=$classVo;
+ $row['key']=$row['id'].'_'.$row['mold'];
+ $row['bill']=['sell'=>'销售单','sre'=>'销售退货单'][$row['mold']];
+ if($row['mold']=='sell'){
+ $row['discount']=math()->chain($row['total'])->sub($row['actual'])->done();
+ }else if($row['mold']=='sre'){
+ $row['total']=math()->chain($row['total'])->mul(-1)->done();
+ $row['actual']=math()->chain($row['actual'])->mul(-1)->done();
+ $row['money']=math()->chain($row['money'])->mul(-1)->done();
+ $row['discount']=math()->chain($row['total'])->sub($row['actual'])->done();
+ }
+ $summary=search($bill['summary'])->where([['type','=',$row['mold']],['class','=',$row['id']]])->select();
+ $row['act']=mathArraySum(array_column($summary,'bct'));
+ if($row['bill']=='销售退货单' || $row['bill']=='零售退货单'){
+ $row['act']=math()->chain($row['act'])->mul(-1)->done();
+ $row['gpt']=math()->chain($row['actual'])->sub($row['act'])->done();
+ $row['gpr']='-'.(empty($row['actual'])?(empty($row['gpt'])?'0':'-100'):math()->chain($row['gpt'])->div($row['actual'])->mul(100)->round(2)->done()).'%';
+ $row['npt']=math()->chain($row['gpt'])->sub($row['cost'])->done();
+ $row['npr']='-'.(empty($row['actual'])?(empty($row['npt'])?'0':'-100'):math()->chain($row['npt'])->div($row['actual'])->mul(100)->round(2)->done()).'%';
+ }else{
+ $row['gpt']=math()->chain($row['actual'])->sub($row['act'])->done();
+ $row['gpr']=(empty($row['actual'])?(empty($row['gpt'])?'0':'-100'):math()->chain($row['gpt'])->div($row['actual'])->mul(100)->round(2)->done()).'%';
+ $row['npt']=math()->chain($row['gpt'])->sub($row['cost'])->done();
+ $row['npr']=(empty($row['actual'])?(empty($row['npt'])?'0':'-100'):math()->chain($row['npt'])->div($row['actual'])->mul(100)->round(2)->done()).'%';
+ }
+
+
+
+
+ //匹配明细
+ $node=[];
+ if(!empty($input['type'])){
+ $list=search($bill['info'][$row['mold']])->where([['pid','=',$row['id']]])->select();
+ foreach ($list as $listVo) {
+ $detail=[
+ 'name'=>$listVo['goodsData']['name'],
+ 'attr'=>$listVo['attr'],
+ 'unit'=>$listVo['unit'],
+ 'price'=>$listVo['price'],
+ 'nums'=>$listVo['nums'],
+ 'dsc'=>$listVo['dsc'],
+ 'total'=>$listVo['total'],
+ 'tat'=>$listVo['tat'],
+ 'tpt'=>$listVo['tpt']
+ ];
+ $calc=[];
+ $calc['act']=empty($listVo['goodsData']['type'])?floatval(search($summary)->where([['info','=',$listVo['id']]])->find()['bct']):0;
+ $calc['gpt']=math()->chain($detail['tpt'])->sub($calc['act'])->done();
+ $calc['gpr']=(empty($detail['tpt'])?(empty($calc['gpt'])?'0':'-100'):math()->chain($calc['gpt'])->div($detail['tpt'])->mul(100)->round(2)->done()).'%';
+ $node[]=['key'=>$row['id'].'_'.$listVo['id'].'_'.$row['mold'],'detail'=>$detail,'act'=>$calc['act'],'gpt'=>$calc['gpt'],'gpr'=>$calc['gpr']];
+ }
+ }
+ $row['node']=$node;
+ $data[]=$row;
+ }
+ $result=[
+ 'state'=>'success',
+ 'count'=>$count,
+ 'info'=>$data
+ ];//返回数据
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //销售利润表-导出
+ public function mptExports(){
+ $input=input('get.');
+ $sheet=['sell','sre'];
+ existFull($input,['mold'])||$input['mold']=$sheet;
+ if(isset($input['type']) && is_array($input['mold']) && arrayInArray($input['mold'],$sheet)){
+ $sql=fastSql($input,[
+ ['customer','fullEq'],
+ ['number','fullLike'],
+ [['startTime'=>'time'],'startTime'],
+ [['endTime'=>'time'],'endTime'],
+ ['user','fullEq'],
+ ['people','fullEq']
+ ]);
+ $sql[]=['examine','=',1];
+ $sql=frameScope($sql);//组织数据
+ $sql=sqlAuth('sell',$sql);//数据鉴权[结构一致]
+ $union=[];
+ $tab=['sell','sre'];
+ foreach ($tab as $t) {
+ if(in_array($t,$input['mold'])){
+ $union[]=Db::name($t)->where($sql)->fieldRaw('"'.$t.'" as mold,id')->buildSql();
+ }
+ }
+ $union=implode(' UNION ALL ',$union);
+ $record=DB::query('SELECT * FROM ('.$union.') as nodcloud');
+ $bill=['class'=>[],'summary'=>[],'info'=>[],''=>[]];
+ foreach ($tab as $t) {
+ if(in_array($t,$input['mold'])){
+ $gather=search($record)->where([['mold','=',$t]])->select();
+ $db=['class'=>"app\\model\\".ucfirst($t),'info'=>"app\\model\\".ucfirst($t).'Info'];
+ $bill['class']=array_merge($bill['class'],$db['class']::with(['frameData','customerData','userData','peopleData'])->fieldRaw('*,"'.$t.'" as mold,time as t')->where([['id','in',array_column($gather,'id')]])->append(['extension'])->select()->toArray());
+ $bill['summary']=array_merge($bill['summary'],Db::name('summary')->where([['type','=',$t],['class','in',array_column($gather,'id')]])->field(['type','class','info','bct'])->select()->toArray());
+ //匹配明细
+ if(!empty($input['type'])){
+ $bill['info'][$t]=$db['info']::with(['goodsData'])->where([['pid','in',array_column($gather,'id')]])->select()->toArray();
+ }
+ }
+ }
+ arraySort($bill['class'],'t',SORT_ASC);
+ $data=[];
+ //匹配数据
+ foreach ($bill['class'] as $classVo) {
+ $row=$classVo;
+ $row['bill']=['sell'=>'销售单','sre'=>'销售退货单'][$row['mold']];
+ if($row['mold']=='sell'){
+ $row['discount']=math()->chain($row['total'])->sub($row['actual'])->done();
+ }else if($row['mold']=='sre'){
+ $row['total']=math()->chain($row['total'])->mul(-1)->done();
+ $row['actual']=math()->chain($row['actual'])->mul(-1)->done();
+ $row['money']=math()->chain($row['money'])->mul(-1)->done();
+ $row['discount']=math()->chain($row['total'])->sub($row['actual'])->done();
+ }
+ $summary=search($bill['summary'])->where([['type','=',$row['mold']],['class','=',$row['id']]])->select();
+ $row['act']=mathArraySum(array_column($summary,'bct'));
+ if($row['bill']=='销售退货单' || $row['bill']=='零售退货单'){
+ $row['act']=math()->chain($row['act'])->mul(-1)->done();
+ $row['gpt']=math()->chain($row['actual'])->sub($row['act'])->done();
+ $row['gpr']='-'.(empty($row['actual'])?(empty($row['gpt'])?'0':'-100'):math()->chain($row['gpt'])->div($row['actual'])->mul(100)->round(2)->done()).'%';
+ $row['npt']=math()->chain($row['gpt'])->sub($row['cost'])->done();
+ $row['npr']='-'.(empty($row['actual'])?(empty($row['npt'])?'0':'-100'):math()->chain($row['npt'])->div($row['actual'])->mul(100)->round(2)->done()).'%';
+ }else{
+ $row['gpt']=math()->chain($row['actual'])->sub($row['act'])->done();
+ $row['gpr']=(empty($row['actual'])?(empty($row['gpt'])?'0':'-100'):math()->chain($row['gpt'])->div($row['actual'])->mul(100)->round(2)->done()).'%';
+ $row['npt']=math()->chain($row['gpt'])->sub($row['cost'])->done();
+ $row['npr']=(empty($row['actual'])?(empty($row['npt'])?'0':'-100'):math()->chain($row['npt'])->div($row['actual'])->mul(100)->round(2)->done()).'%';
+ }
+ //匹配明细
+ $node=[];
+ if(!empty($input['type'])){
+ $list=search($bill['info'][$row['mold']])->where([['pid','=',$row['id']]])->select();
+ foreach ($list as $listVo) {
+ $detail=[
+ 'name'=>$listVo['goodsData']['name'],
+ 'attr'=>$listVo['attr'],
+ 'unit'=>$listVo['unit'],
+ 'price'=>$listVo['price'],
+ 'nums'=>$listVo['nums'],
+ 'dsc'=>$listVo['dsc'],
+ 'total'=>$listVo['total'],
+ 'tat'=>$listVo['tat'],
+ 'tpt'=>$listVo['tpt']
+ ];
+ $calc=[];
+ $calc['act']=empty($listVo['goodsData']['type'])?floatval(search($summary)->where([['info','=',$listVo['id']]])->find()['bct']):0;
+ $calc['gpt']=math()->chain($detail['tpt'])->sub($calc['act'])->done();
+ $calc['gpr']=(empty($detail['tpt'])?(empty($calc['gpt'])?'0':'-100'):math()->chain($calc['gpt'])->div($detail['tpt'])->mul(100)->round(2)->done()).'%';
+ $node[]=['detail'=>$detail,'act'=>$calc['act'],'gpt'=>$calc['gpt'],'gpr'=>$calc['gpr']];
+ }
+ }
+ $row['node']=$node;
+ $data[]=$row;
+ }
+ $source=[];
+ foreach ($data as $dataVo) {
+ $source[]=$dataVo;
+ if(!empty($dataVo['node'])){
+ foreach ($dataVo['node'] as $node) {
+ $source[]=$node;
+ }
+ }
+ }
+ //开始构造导出数据
+ $excel=[];//初始化导出数据
+ //标题数据
+ $excel[]=['type'=>'title','info'=>'销售利润表'];
+ //表格数据
+ $field=[
+ [
+ 'bill'=>'单据类型',
+ 'frameData|name'=>'所属组织',
+ 'customerData|name'=>'客户',
+ 'time'=>'单据时间',
+ 'number'=>'单据编号'
+ ],
+ [
+ 'detail|name'=>'商品名称',
+ 'detail|attr'=>'辅助属性',
+ 'detail|unit'=>'单位',
+ 'detail|price'=>'单价',
+ 'detail|nums'=>'数量',
+ 'detail|dsc'=>'折扣额',
+ 'detail|total'=>'金额',
+ 'detail|tat'=>'税额',
+ 'detail|tpt'=>'价税合计'
+ ],
+ [
+ 'total'=>'单据金额',
+ 'discount'=>'优惠金额',
+ 'actual'=>'实际金额',
+ 'act'=>'成本',
+ 'gpt'=>'毛利润',
+ 'gpr'=>'毛利率',
+ 'cost'=>'单据费用',
+ 'npt'=>'净利润',
+ 'npr'=>'净利率',
+ 'extension|amount'=>'核销金额',
+ 'extension|nucleus'=>'核销状态',
+ 'userData|name'=>'制单人',
+ 'peopleData|name'=>'关联人员',
+ 'data'=>'备注信息'
+ ]
+ ];
+ $field=empty($input['type'])?array_merge($field[0],$field[2]):array_merge($field[0],$field[1],$field[2]);
+ $thead=array_values($field);//表格标题
+ $tbody=[];//表格内容
+ //构造表内数据
+ foreach ($source as $sourceVo) {
+ $rowData=[];
+ foreach (array_keys($field) as $fieldVo) {
+ $rowData[]=arraySeek($sourceVo,$fieldVo);//多键名数据赋值
+ }
+ $tbody[]=$rowData;//加入行数据
+ }
+ $excel[]=['type'=>'table','info'=>['thead'=>$thead,'tbody'=>$tbody]];//表格数据
+ //汇总数据
+ $excel[]=['type'=>'node','info'=>[
+ '总数:'.count($source),
+ ]];
+ //导出execl
+ buildExcel('销售利润表',$excel);
+ }else{
+ return json(['state'=>'error','info'=>'传入参数不完整!']);
+ }
+ }
+ //销售排行表
+ public function mot(){
+ $input=input('post.');
+ if(existFull($input,['page','limit'])){
+ $sql=fastSql($input,[
+ [['name'=>'name|py'],'fullLike'],
+ ['number','fullLike']
+ ]);
+ $goods=Db::name('goods')->where($sql)->select()->toArray();
+ //数据匹配
+ $existsSql=fastSql($input,[
+ [['startTime'=>'time'],'startTime'],
+ [['endTime'=>'time'],'endTime']
+ ]);
+ $existsSql[]=['goods','in',array_column($goods,'id')];
+ $existsSql[]=['examine','=',1];
+ $existsSql=frameScope($existsSql);
+ $existsSql=sqlAuth('sell',$existsSql);//结构一致
+ //多源匹配
+ $union=[];
+ $tab=['sell','sre'];
+ foreach ($tab as $t) {
+ $union[0][]=Db::name($t.'_info')->alias('info')->join(['is_'.$t=>'class'],'info.pid=class.id')->where($existsSql)->fieldRaw('goods,attr,sum(nums) as nums')->group(['goods,attr'])->buildSql();
+ }
+ $union_0=implode(' UNION ALL ',$union[0]);
+ $count=DB::query('select count(*) as count from ( SELECT count(*) FROM ('.$union_0.') as f GROUP BY goods,attr ) as nodcloud')[0]["count"];
+ $record=DB::query('SELECT * FROM ('.$union_0.') as nodcloud GROUP BY goods,attr ORDER BY `nums` DESC LIMIT '.pageCalc($input['page'],$input['limit'],'str'));
+ //构造条件|减少查询
+ foreach ($existsSql as $k=>$v) {
+ if($v[0]=='goods'){
+ $existsSql[$k][2]=array_column($record,'goods');
+ break;
+ }
+ }
+ foreach ($tab as $t) {
+ $union[1][]=Db::name($t.'_info')->alias('info')->join(['is_'.$t=>'class'],'info.pid=class.id')->where($existsSql)->fieldRaw('"'.$t.'" as mold,goods,attr,group_concat(info.id) as id,sum(dsc) as dsc,'.($t=='barter'?'0 as tat,sum(info.total) as tpt':'sum(tat) as tat,sum(tpt) as tpt'))->group(['goods,attr'])->buildSql();
+ }
+ $union_1=implode(' UNION ALL ',$union[1]);
+ $list=DB::query('SELECT * FROM ('.$union_1.') as nodcloud');
+ //获取数据
+ $summary=[];
+ foreach ($tab as $t) {
+ $gather=explode(',',implode(',',array_column(search($list)->where([['mold','=',$t]])->select(),'id')));
+ $summary[$t]=Db::name('summary')->where([['type','=',$t],['info','in',$gather]])->select()->toArray();
+ }
+ $data=[];
+ //统计数据
+ foreach ($record as $vo) {
+ $row=[];
+ $g=search($goods)->where([['id','=',$vo['goods']]])->find();
+ $row['goodsData']=$g;
+ $row['attr']=$vo['attr'];
+ $row['unit']=$g['unit']==-1?'多单位':$g['unit'];
+ $base=[['goods','=',$vo['goods']],['attr','=',$vo['attr']]];
+ $gather=[];
+ foreach ($tab as $t) {
+ $b=search($list)->where(array_merge($base,[['mold','=',$t]]))->find();
+ $s=search($summary[$t])->where(array_merge($base,[['type','=',$t]]))->select();
+ $gather['nums'][$t]=mathArraySum(array_column($s,'nums'));
+ $gather['dsc'][$t]=empty($b)?0:$b['dsc'];
+ $gather['tat'][$t]=empty($b)?0:$b['tat'];
+ $gather['tpt'][$t]=empty($b)?0:$b['tpt'];
+ $gather['bct'][$t]=mathArraySum(array_column($s,'bct'));
+ }
+ $nums=math()->chain($gather['nums']['sell'])->sub($gather['nums']['sre'])->done();
+ $row['nums']=$g['unit']==-1?unitSwitch($nums,json_decode($g['units'],true)):$nums;
+ $row['dsc']=math()->chain($gather['dsc']['sell'])->sub($gather['dsc']['sre'])->done();
+ $row['tat']=math()->chain($gather['tat']['sell'])->sub($gather['tat']['sre'])->done();
+ $row['tpt']=math()->chain($gather['tpt']['sell'])->sub($gather['tpt']['sre'])->done();
+ $row['bct']=math()->chain($gather['bct']['sell'])->sub($gather['bct']['sre'])->done();
+ $row['uct']=empty($nums)?0:math()->chain($row['bct'])->div($nums)->round(2)->abs()->done();
+ $total=math()->chain($row['tpt'])->sub($row['tat'])->done();
+ $row['gpt']=math()->chain($total)->sub($row['bct'])->done();
+ $row['gpr']=(empty($total)?(empty($row['gpt'])?'0':'-100'):math()->chain($row['gpt'])->div($total)->mul(100)->round(2)->done()).'%';
+ $data[]=$row;
+ }
+ $result=[
+ 'state'=>'success',
+ 'count'=>$count,
+ 'info'=>$data
+ ];//返回数据
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //销售排行表-导出
+ public function motExports(){
+ $input=input('get.');
+ pushLog('导出销售排行表');//日志
+ $sql=fastSql($input,[
+ [['name'=>'name|py'],'fullLike'],
+ ['number','fullLike']
+ ]);
+ $goods=Db::name('goods')->where($sql)->select()->toArray();
+ //数据匹配
+ $existsSql=fastSql($input,[
+ [['startTime'=>'time'],'startTime'],
+ [['endTime'=>'time'],'endTime']
+ ]);
+ $existsSql[]=['goods','in',array_column($goods,'id')];
+ $existsSql[]=['examine','=',1];
+ $existsSql=frameScope($existsSql);
+ $existsSql=sqlAuth('buy',$existsSql);//结构一致
+ //多源匹配
+ $union=[];
+ $tab=['sell','sre'];
+ foreach ($tab as $t) {
+ $union[0][]=Db::name($t.'_info')->alias('info')->join(['is_'.$t=>'class'],'info.pid=class.id')->where($existsSql)->fieldRaw('goods,attr,sum(nums) as nums')->group(['goods,attr'])->buildSql();
+ }
+ $union_0=implode(' UNION ALL ',$union[0]);
+ $count=DB::query('select count(*) as count from ( SELECT count(*) FROM ('.$union_0.') as f GROUP BY goods,attr ) as nodcloud')[0]["count"];
+ $record=DB::query('SELECT * FROM ('.$union_0.') as nodcloud GROUP BY goods,attr ORDER BY `nums` DESC');
+ //匹配数据
+ foreach ($tab as $t) {
+ $union[1][]=Db::name($t.'_info')->alias('info')->join(['is_'.$t=>'class'],'info.pid=class.id')->where($existsSql)->fieldRaw('"'.$t.'" as mold,goods,attr,group_concat(info.id) as id,sum(dsc) as dsc,'.($t=='barter'?'0 as tat,sum(info.total) as tpt':'sum(tat) as tat,sum(tpt) as tpt'))->group(['goods,attr'])->buildSql();
+ }
+ $union_1=implode(' UNION ALL ',$union[1]);
+ $list=DB::query('SELECT * FROM ('.$union_1.') as nodcloud');
+ //获取数据
+ $summary=[];
+ foreach ($tab as $t) {
+ $gather=explode(',',implode(',',array_column(search($list)->where([['mold','=',$t]])->select(),'id')));
+ $summary[$t]=Db::name('summary')->where([['type','=',$t],['info','in',$gather]])->select()->toArray();
+ }
+ $data=[];
+ //统计数据
+ foreach ($record as $vo) {
+ $row=[];
+ $g=search($goods)->where([['id','=',$vo['goods']]])->find();
+ $row['goodsData']=$g;
+ $row['attr']=$vo['attr'];
+ $row['unit']=$g['unit']==-1?'多单位':$g['unit'];
+ $base=[['goods','=',$vo['goods']],['attr','=',$vo['attr']]];
+ $gather=[];
+ foreach ($tab as $t) {
+ $b=search($list)->where(array_merge($base,[['mold','=',$t]]))->find();
+ $s=search($summary[$t])->where(array_merge($base,[['type','=',$t]]))->select();
+ $gather['nums'][$t]=mathArraySum(array_column($s,'nums'));
+ $gather['dsc'][$t]=empty($b)?0:$b['dsc'];
+ $gather['tat'][$t]=empty($b)?0:$b['tat'];
+ $gather['tpt'][$t]=empty($b)?0:$b['tpt'];
+ $gather['bct'][$t]=mathArraySum(array_column($s,'bct'));
+ }
+ $nums=math()->chain($gather['nums']['sell'])->sub($gather['nums']['sre'])->done();
+ $row['nums']=$g['unit']==-1?unitSwitch($nums,json_decode($g['units'],true)):$nums;
+ $row['dsc']=math()->chain($gather['dsc']['sell'])->sub($gather['dsc']['sre'])->done();
+ $row['tat']=math()->chain($gather['tat']['sell'])->sub($gather['tat']['sre'])->done();
+ $row['tpt']=math()->chain($gather['tpt']['sell'])->sub($gather['tpt']['sre'])->done();
+ $row['bct']=math()->chain($gather['bct']['sell'])->sub($gather['bct']['sre'])->done();
+ $row['uct']=empty($nums)?0:math()->chain($row['bct'])->div($nums)->round(2)->abs()->done();
+ $total=math()->chain($row['tpt'])->sub($row['tat'])->done();
+ $row['gpt']=math()->chain($total)->sub($row['bct'])->done();
+ $row['gpr']=(empty($total)?(empty($row['gpt'])?'0':'-100'):math()->chain($row['gpt'])->div($total)->mul(100)->round(2)->done()).'%';
+ $data[]=$row;
+ }
+ $source=$data;
+ //开始构造导出数据
+ $excel=[];//初始化导出数据
+ //标题数据
+ $excel[]=['type'=>'title','info'=>'销售排行表'];
+ //表格数据
+ $field=[
+ 'goodsData|name'=>'商品名称',
+ 'attr'=>'辅助属性',
+ 'goodsData|number'=>'商品编号',
+ 'goodsData|spec'=>'规格型号',
+ 'unit'=>'单位',
+ 'nums'=>'数量',
+ 'dsc'=>'折扣额',
+ 'tat'=>'税额',
+ 'tpt'=>'价税合计',
+ 'uct'=>'成本',
+ 'bct'=>'总成本',
+ 'gpt'=>'毛利润',
+ 'gpr'=>'毛利率'
+ ];
+ $thead=array_values($field);//表格标题
+ $tbody=[];//表格内容
+ //构造表内数据
+ foreach ($source as $sourceVo) {
+ $rowData=[];
+ foreach (array_keys($field) as $fieldVo) {
+ $rowData[]=arraySeek($sourceVo,$fieldVo);//多键名数据赋值
+ }
+ $tbody[]=$rowData;//加入行数据
+ }
+ $excel[]=['type'=>'table','info'=>['thead'=>$thead,'tbody'=>$tbody]];//表格数据
+ //汇总数据
+ $excel[]=['type'=>'node','info'=>[
+ '总数:'.count($source)
+ ]];
+ //导出execl
+ buildExcel('销售排行表',$excel);
+ }
+}
diff --git a/serve/app/controller/Oce.php b/serve/app/controller/Oce.php
new file mode 100644
index 0000000..e3c2ccb
--- /dev/null
+++ b/serve/app/controller/Oce.php
@@ -0,0 +1,569 @@
+'time'],'startTime'],
+ [['endTime'=>'time'],'endTime'],
+ ['account','fullEq'],
+ ['people','fullEq'],
+ ['user','fullEq'],
+ ['examine','fullDec1'],
+ ['nucleus','fullDec1'],
+ ['data','fullLike']
+ ]);//构造SQL
+ $sql=frameScope($sql);//组织数据
+ $sql=sqlAuth('oce',$sql);//数据鉴权
+ $count = Oces::where($sql)->count();//获取总条数
+ $info = Oces::with(['frameData','supplierData','accountData','peopleData','userData','billData','recordData'])->where($sql)->append(['extension'])->page($input['page'],$input['limit'])->order(['id'=>'desc'])->select()->toArray();//查询分页数据
+ $result=[
+ 'state'=>'success',
+ 'count'=>$count,
+ 'info'=>$info
+ ];//返回数据
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //新增|更新
+ public function save(){
+ $input=input('post.');
+ if(existFull($input,['class','info']) && isset($input['class']['id'])){
+ //构造|验证CLASS
+ try {
+ $class=$input['class'];
+ $class['frame']=userInfo(getUserID(),'frame');
+ $class['user']=getUserID();
+ $class['examine']=0;
+ $class['nucleus']=0;
+ empty($class['id'])?$this->validate($class,'app\validate\Oce'):$this->validate($class,'app\validate\Oce.update');
+ $period=getPeriod();
+ if(strtotime($class['time'])<=$period){
+ throw new ValidateException('单据日期与结账日期冲突!');
+ }
+ } catch (ValidateException $e) {
+ return json(['state'=>'error','info'=>$e->getError()]);
+ exit;
+ }
+
+ //验证INFO
+ foreach ($input['info'] as $infoKey=>$infoVo) {
+ try {
+ $this->validate($infoVo,'app\validate\OceInfo');
+ } catch (ValidateException $e) {
+ return json(['state'=>'error','info'=>'数据表格第'.($infoKey+1).'条'.$e->getError()]);
+ exit;
+ }
+ }
+
+ //处理数据
+ Db::startTrans();
+ try {
+ //CLASS数据
+ if(empty($class['id'])){
+ //创建数据
+ $createInfo=Oces::create($class);
+ $class['id']=$createInfo['id'];//转存主键
+ Db::name('record')->insert(['type'=>'oce','source'=>$class['id'],'time'=>time(),'user'=>getUserID(),'info'=>'新增单据']);
+ pushLog('新增其它支出单[ '.$class['number'].' ]');//日志
+ }else{
+ //更新数据
+ $updateInfo=Oces::update($class);
+ Db::name('record')->insert(['type'=>'oce','source'=>$class['id'],'time'=>time(),'user'=>getUserID(),'info'=>'更新单据']);
+ pushLog('更新其它支出单[ '.$class['number'].' ]');//日志
+ }
+
+ //INFO数据
+ OceInfo::where([['pid','=',$class['id']]])->delete();
+ foreach ($input['info'] as $infoKey=>$infoVo) {
+ $input['info'][$infoKey]['pid']=$class['id'];
+ }
+ $model = new OceInfo;
+ $model->saveAll($input['info']);
+
+ Db::commit();
+ $result=['state'=>'success','info'=>$class['id']];
+ } catch (\Exception $e) {
+ Db::rollback();
+ $result=['state'=>'error','info'=>'内部错误,操作已撤销!'];
+ }
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //获取
+ public function get(){
+ $input=input('post.');
+ if(existFull($input,['parm'])){
+ $class=Oces::where([['id','=',$input['parm']]])->find();
+ $info=OceInfo::with(['ietData'])->where([['pid','=',$input['parm']]])->order(['id'=>'asc'])->select();
+ $result=['state'=>'success','info'=>[
+ 'class'=>$class,
+ 'info'=>$info,
+ ]];
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //删除
+ public function del(){
+ $input=input('post.');
+ if(existFull($input,['parm']) && is_array($input['parm'])){
+ $data=Db::name('oce')->where([['id','in',$input['parm']]])->order(['id'=>'desc'])->select()->toArray();
+ $search=search($data)->where([['examine','=','1']])->find();
+ if(empty($search)){
+ Db::startTrans();
+ try {
+ Db::name('oce')->where([['id','in',$input['parm']]])->delete();
+ Db::name('oce_info')->where([['pid','in',$input['parm']]])->delete();
+ Db::name('record')->where([['type','=','oce'],['source','in',$input['parm']]])->delete();
+ Db::name('log')->insert(['time'=>time(),'user'=>getUserID(),'info'=>'删除其它支出单[ '.implode(' | ',array_column($data,'number')).' ]']);
+
+ Db::commit();
+ $result=['state'=>'success'];
+ } catch (\Exception $e) {
+ Db::rollback();
+ $result=['state'=>'error','info'=>'内部错误,操作已撤销!'];
+ }
+ }else{
+ $result=['state'=>'error','info'=>'单据['.$search['number'].']已审核,不可删除!'];
+ }
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //审核|反审核
+ public function examine(){
+ $input=input('post.');
+ if(existFull($input,['parm']) && is_array($input['parm'])){
+ //1 基础数据
+ $period=getPeriod();
+ $classList=Db::name('oce')->where([['id','in',$input['parm']]])->order(['id'=>'desc'])->select()->toArray();
+ $infoList=Db::name('oce_info')->where([['pid','in',$input['parm']]])->order(['id'=>'asc'])->select()->toArray();
+ //2 综合处理
+ foreach ($input['parm'] as $parmVo) {
+ //1 匹配数据
+ $class=search($classList)->where([['id','=',$parmVo]])->find();
+ $info=search($infoList)->where([['pid','=',$parmVo]])->select();
+ //2 CLASS验证
+ if($class['time']<=$period){
+ return json(['state'=>'error','info'=>'操作单据[ '.$class['number'].' ]失败,原因:单据日期与结账日期冲突!']);
+ exit;
+ }
+ //3 综合匹配
+ $sourceSum=mathArraySum(array_column($info,'source'));
+ if(!empty($sourceSum)){
+ //2.1 匹配费用
+ $costList=Db::name('cost')->where([['id','in',array_column($info,'source')]])->select()->toArray();
+ //2.1 构造数据
+ $costGather=array_map(function($row){
+ return [['type','=',$row['type']],['class','=',$row['class']]];
+ },$costList);
+ }
+ //4 数据验证
+ if(empty($class['examine'])){
+ if(!empty($sourceSum)){
+ // 关联验证
+ foreach ($info as $infoKey=>$infoVo) {
+ $cost=search($costList)->where([['id','=',$infoVo['source']]])->find();
+ if(!empty($cost)){
+ if(bccomp(math()->chain($cost['settle'])->add($infoVo['money'])->done(),$cost['money'])==1){
+ return json(['state'=>'error','info'=>'审核单据[ '.$class['number'].' ]失败,原因:第'.($infoKey+1).'行结算金额超出可结算费用!']);
+ exit;
+ }
+ }
+ }
+ }
+ }else{
+ //核销单
+ $bill=Db::name('bill_info')->where([['mold','=','oce'],['source','=',$class['id']]])->find();
+ if(!empty($bill)){
+ return json(['state'=>'error','info'=>'反审核单据[ '.$class['number'].' ]失败,原因:该单据存在关联核销单!']);
+ exit;
+ }
+ }
+ //5 数据处理
+ Db::startTrans();
+ try {
+ //场景验证
+ if(empty($class['examine'])){
+ //审核
+ //1 关联单据
+ $store=['cost'=>[],'costInfo'=>[]];
+ foreach ($info as $infoKey=>$infoVo){
+ if(!empty($infoVo['source'])){
+ //关联费用
+ $store['cost'][]=['id'=>$infoVo['source'],'settle'=>$infoVo['money']];
+ //关联费用记录
+ $store['costInfo'][]=['pid'=>$infoVo['source'],'oce'=>$class['id'],'time'=>$class['time'],'money'=>$infoVo['money']];
+ }
+ }
+ //1.1 处理数据
+ if(!empty($store['cost'])){
+ //1 更新详情
+ Db::name('cost')->duplicate(['settle'=>Db::raw('settle + VALUES(`settle`)')])->insertAll($store['cost']);
+ //2 更新状态
+ Db::name('cost')->where([['id','in',array_column($store['cost'],'id')]])->update(['state'=>Db::raw('CASE WHEN settle = money THEN 2 ELSE 1 END')]);
+ //3 插入记录
+ Db::name('cost_info')->insertAll($store['costInfo']);
+ //4 更新单据
+ $costGroup=Db::name('cost')->whereOr($costGather)->fieldRaw('type,class,group_concat(state) as states')->group(['type','class'])->select()->toArray();
+ //4.1 组装数据
+ $bill=[];
+ foreach ($costGroup as $costGroupVo) {
+ $states=explode(',',$costGroupVo['states']);
+ $bill[$costGroupVo['type']][]=['id'=>$costGroupVo['class'],'cse'=>mathArraySum($states)==count($states)*2?2:1];
+ }
+ //4.2 更新状态
+ foreach($bill as $billKey => $billVo){
+ Db::name($billKey)->duplicate(['cse'=>Db::raw('VALUES(`cse`)')])->insertAll($billVo);
+ }
+ }
+ //2 资金|核销
+ if(!empty($class['money'])){
+ //1 更新资金账户
+ Db::name('account')->where([['id','=',$class['account']]])->dec('balance',$class['money'])->update();
+ //2 创建资金详情
+ Db::name('account_info')->insert([
+ 'pid'=>$class['account'],
+ 'type'=>'oce',
+ 'class'=>$class['id'],
+ 'time'=>$class['time'],
+ 'direction'=>0,
+ 'money'=>$class['money']
+ ]);
+ //3 创建核销记录
+ Db::name('oce_bill')->insert([
+ 'pid'=>$class['id'],
+ 'type'=>'oce',
+ 'source'=>$class['id'],
+ 'time'=>$class['time'],
+ 'money'=>$class['money']
+ ]);
+ }
+ //3 供应商|应付款余额
+ if(!empty($class['supplier'])){
+ $balance=math()->chain($class['actual'])->sub($class['money'])->done();
+ if(!empty($balance)){
+ Db::name('supplier')->where([['id','=',$class['supplier']]])->inc('balance',$balance)->update();
+ }
+ }
+ //4 更新单据
+ $nucleus=$class['money']==$class['actual']?2:($class['money']==0?0:1);
+ Db::name('oce')->where([['id','=',$class['id']]])->update(['examine'=>1,'nucleus'=>$nucleus]);
+ //5 单据记录
+ Db::name('record')->insert(['type'=>'oce','source'=>$class['id'],'time'=>time(),'user'=>getUserID(),'info'=>'审核单据']);
+ //6 记录操作
+ pushLog('审核其它支出单[ '.$class['number'].' ]');//单据日志
+ }else{
+ //反审核
+ //1 关联单据
+ $store=['cost'=>[],'costInfo'=>[]];
+ foreach ($info as $infoKey=>$infoVo){
+ if(!empty($infoVo['source'])){
+ //关联费用
+ $store['cost'][]=['id'=>$infoVo['source'],'settle'=>$infoVo['money']];
+ //关联费用记录
+ $store['costInfo'][]=[['pid','=',$infoVo['source']],['oce','=',$class['id']]];
+ }
+ }
+ //1.1 处理数据
+ if(!empty($store['cost'])){
+ //1 更新详情
+ Db::name('cost')->duplicate(['settle'=>Db::raw('settle - VALUES(`settle`)')])->insertAll($store['cost']);
+ //2 更新状态
+ Db::name('cost')->where([['id','in',array_column($store['cost'],'id')]])->update(['state'=>Db::raw('CASE WHEN settle = 0 THEN 0 ELSE 1 END')]);
+ //3 删除记录
+ Db::name('cost_info')->whereOr($store['costInfo'])->delete();
+ //4 更新单据
+ $costGroup=Db::name('cost')->whereOr($costGather)->fieldRaw('type,class,group_concat(state) as states')->group(['type','class'])->select()->toArray();
+ //4.1 组装数据
+ $bill=[];
+ foreach ($costGroup as $costGroupVo) {
+ $states=explode(',',$costGroupVo['states']);
+ $bill[$costGroupVo['type']][]=['id'=>$costGroupVo['class'],'cse'=>empty(mathArraySum($states))?0:1];
+ }
+ //4.2 更新状态
+ foreach($bill as $billKey => $billVo){
+ Db::name($billKey)->duplicate(['cse'=>Db::raw('VALUES(`cse`)')])->insertAll($billVo);
+ }
+ }
+ //2 资金|核销
+ if(!empty($class['money'])){
+ //1 更新资金账户
+ Db::name('account')->where([['id','=',$class['account']]])->inc('balance',$class['money'])->update();
+ //2 删除资金详情
+ Db::name('account_info')->where([['type','=','oce'],['class','=',$class['id']]])->delete();
+ //3 删除核销记录
+ Db::name('oce_bill')->where([['pid','=',$class['id']]])->delete();
+ }
+ //3 供应商|应付款余额
+ if(!empty($class['supplier'])){
+ $balance=math()->chain($class['actual'])->sub($class['money'])->done();
+ if(!empty($balance)){
+ Db::name('supplier')->where([['id','=',$class['supplier']]])->dec('balance',$balance)->update();
+ }
+ }
+ //4 更新单据
+ Db::name('oce')->where([['id','=',$class['id']]])->update(['examine'=>0,'nucleus'=>0]);
+ //5 单据记录
+ Db::name('record')->insert(['type'=>'oce','source'=>$class['id'],'time'=>time(),'user'=>getUserID(),'info'=>'反审核单据']);
+ //6 记录操作
+ pushLog('反审核其它支出单[ '.$class['number'].' ]');//单据日志
+ }
+
+ Db::commit();
+ } catch (\Exception $e) {
+ Db::rollback();
+ return json(['state'=>'error','info'=>'内部错误,操作已撤销!']);
+ exit;
+ }
+ }
+ $result=['state'=>'success'];
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //上传
+ public function upload(){
+ $file = request()->file('file');
+ //获取上传文件
+ if (empty($file)) {
+ $result = ['state' => 'error','info' => '传入数据不完整!'];
+ } else {
+ //文件限制5MB
+ try{
+ validate(['file'=>['fileSize'=>5*1024*1024,'fileExt'=>'png,gif,jpg,jpeg,txt,doc,docx,rtf,xls,xlsx,ppt,pptx,pdf,zip,rar']])->check(['file'=>$file]);
+ $fileInfo=Filesystem::disk('upload')->putFile('oce', $file, 'uniqid');
+ $filePath=request()->domain().'/static/upload/'.$fileInfo;
+ $result=['state'=>'success','info'=>$filePath];
+ }catch(ValidateException $e) {
+ $result = ['state' => 'error','info' => $e->getMessage()];
+ }
+ }
+ return json($result);
+ }
+ //导入
+ public function import(){
+ delOverdueFile('static.upload.xlsx');//删除过期文件
+ $file=request()->file('file');//获取上传文件
+ if(empty($file)){
+ $result=['state'=>'error','info'=>'传入数据不完整!'];
+ }else{
+ $fun=getSys('fun');
+ try{
+ validate(['file'=>['fileSize'=>2*1024*1024,'fileExt'=>'xlsx']])->check(['file'=>$file]);
+ $fileInfo = Filesystem::disk('upload')->putFile('xlsx', $file, 'uniqid');
+ $filePath = pathChange('static.upload').$fileInfo;
+ $data=getXlsx($filePath);
+ unset($data[1]);//删除标题行
+ unset($data[2]);//删除列名行
+ //初始化CLASS
+ //供应商匹配
+ if(empty($data[3]['A'])){
+ $supplier=['id'=>0];
+ }else{
+ $supplier=Db::name('supplier')->where([['name','=',$data[3]['A']]])->find();
+ if(empty($supplier)){
+ throw new ValidateException('供应商[ '.$data[3]['A'].' ]未匹配!');
+ }
+ }
+ //结算账户匹配
+ $account=Db::name('account')->where([['name','=',$data[3]['E']]])->find();
+ if(empty($account)){
+ throw new ValidateException('资金账户[ '.$data[3]['E'].' ]未匹配!');
+ }
+ //关联人员匹配
+ if(empty($data[3]['F'])){
+ $people=['id'=>0];
+ }else{
+ $people=Db::name('people')->where([['name','=',$data[3]['F']]])->find();
+ if(empty($people)){
+ throw new ValidateException('关联人员[ '.$data[3]['F'].' ]未匹配!');
+ }
+ }
+ $class=[
+ 'frame'=>userInfo(getUserID(),'frame'),
+ 'supplier'=>$supplier['id'],
+ 'time'=>$data[3]['B'],
+ 'number'=>$data[3]['C'],
+ 'total'=>0,
+ 'account'=>$account['id'],
+ 'people'=>$people['id'],
+ 'file'=>[],
+ 'data'=>$data[3]['G'],
+ 'more'=>[],
+ 'examine'=>0,
+ 'nucleus'=>0,
+ 'user'=>getUserID()
+ ];
+ $this->validate($class,'app\validate\Oce');//数据合法性验证
+ //初始化INFO
+ $info=[];
+ $iet=Db::name('iet')->where([['name','in',array_column($data,'H')],['type','=',1]])->select()->toArray();
+ foreach ($data as $dataKey=>$dataVo) {
+ $record=[
+ 'iet'=>$dataVo['H'],
+ 'money'=>$dataVo['I'],
+ 'data'=>$dataVo['J']
+ ];
+ //支出类别匹配
+ $ietFind=search($iet)->where([['name','=',$record['iet']]])->find();
+ if(empty($ietFind)){
+ throw new ValidateException('模板文件第'.$dataKey.'行支出类别[ '.$record['iet'].' ]未匹配!');
+ }else{
+ $record['iet']=$ietFind['id'];
+ }
+ //结算金额匹配
+ if(!preg_match("/^(\-)?\d+(\.\d{0,".$fun['digit']['money']."})?$/",$record['money'])){
+ throw new ValidateException('模板文件第'.$dataKey.'行结算金额不正确!');
+ }
+ try{
+ $this->validate($record,'app\validate\OceInfo');//数据合法性验证
+ //转存数据
+ $class['total']=math()->chain($class['total'])->add($record['money'])->done();//累加单据金额
+ $info[]=$record;
+ } catch (ValidateException $e) {
+ return json(['state'=>'error','info'=>'模板文件第'.$dataKey.'行'.$e->getMessage()]);//返回错误信息
+ exit;
+ }
+ }
+ Db::startTrans();
+ try {
+ //新增CLASS
+ $classData=Oces::create($class);
+ //新增INFO
+ foreach ($info as $infoKey=>$infoVo) {
+ $info[$infoKey]['pid']=$classData['id'];
+ }
+ $model = new OceInfo;
+ $model->saveAll($info);
+ Db::name('record')->insert(['type'=>'oce','source'=>$classData['id'],'time'=>time(),'user'=>getUserID(),'info'=>'导入单据']);
+ pushLog('导入其它支出单[ '.$classData['number'].' ]');//日志
+
+ Db::commit();
+ $result=['state'=>'success'];
+ } catch (\Exception $e) {
+ Db::rollback();
+ $result=['state'=>'error','info'=>'内部错误,操作已撤销!'];
+ }
+ }catch(ValidateException $e) {
+ $result=['state'=>'error','info'=>$e->getMessage()];//返回错误信息
+ }
+ }
+ return json($result);
+ }
+ //导出
+ public function exports(){
+ $input=input('get.');
+ if(existFull($input,['scene','parm']) && is_array($input['parm'])){
+ pushLog('导出其它支出单列表');//日志
+ $source=Oces::with(['frameData','supplierData','accountData','peopleData','userData'])->where([['id','in',$input['parm']]])->append(['extension'])->order(['id'=>'desc'])->select()->toArray();//查询CLASS数据
+ if($input['scene']=='simple'){
+ //简易报表
+ //开始构造导出数据
+ $excel=[];//初始化导出数据
+ //标题数据
+ $excel[]=['type'=>'title','info'=>'其它支出单列表'];
+ //表格数据
+ $field=[
+ 'frameData|name'=>'所属组织',
+ 'supplierData|name'=>'供应商',
+ 'time'=>'单据时间',
+ 'number'=>'单据编号',
+ 'total'=>'单据金额',
+ 'actual'=>'实际金额',
+ 'money'=>'单据收款',
+ 'extension|amount'=>'核销金额',
+ 'accountData|name'=>'结算账户',
+ 'peopleData|name'=>'关联人员',
+ 'extension|examine'=>'审核状态',
+ 'extension|nucleus'=>'核销状态',
+ 'userData|name'=>'制单人',
+ 'data'=>'备注信息'
+ ];
+ $thead=array_values($field);//表格标题
+ $tbody=[];//表格内容
+ //构造表内数据
+ foreach ($source as $sourceVo) {
+ $rowData=[];
+ foreach (array_keys($field) as $fieldVo) {
+ $rowData[]=arraySeek($sourceVo,$fieldVo);//多键名数据赋值
+ }
+ $tbody[]=$rowData;//加入行数据
+ }
+ $excel[]=['type'=>'table','info'=>['thead'=>$thead,'tbody'=>$tbody]];//表格数据
+ //统计数据
+ $excel[]=['type'=>'node','info'=>[
+ '总数:'.count($source),
+ '总单据金额:'.mathArraySum(array_column($source,'total')),
+ '总实际金额:'.mathArraySum(array_column($source,'actual')),
+ '总单据付款:'.mathArraySum(array_column($source,'money')),
+ '总核销金额:'.mathArraySum(arrayColumns($source,['extension','amount']))
+ ]];
+ //导出execl
+ buildExcel('其它支出单列表',$excel);
+ }else{
+ //详细报表
+ $files=[];//初始化文件列表
+ foreach ($source as $sourceVo) {
+ //开始构造导出数据
+ $excel=[];//初始化导出数据
+ //标题数据
+ $excel[]=['type'=>'title','info'=>'其它支出单'];
+ //节点数据
+ $excel[]=['type'=>'node','info'=>[
+ '供应商:'.$sourceVo['supplierData']['name'],
+ '单据日期:'.$sourceVo['time'],
+ '单据编号:'.$sourceVo['number']]
+ ];
+ //表格数据
+ $field=[
+ 'ietData|name'=>'支出类别',
+ 'money'=>'结算金额',
+ 'data'=>'备注信息'
+ ];
+ //构造表内数据
+ $info=OceInfo::with(['ietData'])->where([['pid','=',$sourceVo['id']]])->order(['id'=>'asc'])->select()->toArray();
+ $thead=array_values($field);//表格标题
+ $tbody=[];//表格内容
+ foreach ($info as $infoVo) {
+ $rowData=[];
+ foreach (array_keys($field) as $fieldVo) {
+ $rowData[]=arraySeek($infoVo,$fieldVo);//多键名数据赋值
+ }
+ $tbody[]=$rowData;//加入行数据
+ }
+ $excel[]=['type'=>'table','info'=>['thead'=>$thead,'tbody'=>$tbody]];//表格数据
+ //节点数据
+ $excel[]=['type'=>'node','info'=>[
+ '单据金额:'.$sourceVo['total'],
+ '结算账户:'.arraySeek($sourceVo,'accountData|name'),
+ '核销金额:'.$sourceVo['extension']['amount'],
+ '关联人员:'.arraySeek($sourceVo,'peopleData|name'),
+ '备注信息:'.$sourceVo['data']]
+ ];
+ //生成execl
+ $files[]=buildExcel($sourceVo['number'],$excel,false);
+ }
+ buildZip('其它支出单_'.time(),$files);
+ }
+ }else{
+ return json(['state'=>'error','info'=>'传入数据不完整!']);
+ }
+ }
+}
\ No newline at end of file
diff --git a/serve/app/controller/Often.php b/serve/app/controller/Often.php
new file mode 100644
index 0000000..ff3df6d
--- /dev/null
+++ b/serve/app/controller/Often.php
@@ -0,0 +1,45 @@
+where($sql)->select();//查询分页数据
+ $result=[
+ 'state'=>'success',
+ 'info'=>$info
+ ];//返回数据
+ return json($result);
+ }
+ //新增|更新
+ public function save(){
+ $input=input('post.');
+ if(isset($input['parm'])){
+ $userID=getUserID();
+ //处理数据
+ Db::startTrans();
+ try {
+ Db::name('often')->where([['user','=',$userID]])->delete();
+
+ $insert=[];
+ foreach ($input['parm'] as $v) {
+ $insert[]=['user'=>$userID,'name'=>$v['name'],'key'=>$v['key']];
+ }
+ empty($insert)||Db::name('often')->insertAll($insert);
+
+ Db::commit();
+ $result=['state'=>'success'];
+ } catch (\Exception $e) {
+ Db::rollback();
+ $result=['state'=>'error','info'=>'内部错误,操作已撤销!'];
+ }
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+}
\ No newline at end of file
diff --git a/serve/app/controller/Omy.php b/serve/app/controller/Omy.php
new file mode 100644
index 0000000..98fddfb
--- /dev/null
+++ b/serve/app/controller/Omy.php
@@ -0,0 +1,454 @@
+'time'],'startTime'],
+ [['endTime'=>'time'],'endTime'],
+ ['people','fullEq'],
+ ['user','fullEq'],
+ ['examine','fullDec1'],
+ ['nucleus','fullDec1'],
+ ['data','fullLike']
+ ]);//构造SQL
+ //结算账户扩展查询
+ if(existFull($input,['account'])){
+ $sql[]=['id','in',array_column(Db::name('omy_info')->where([['account','=',$input['account']]])->select()->toArray(),'pid')];
+ }
+ $sql=frameScope($sql);//组织数据
+ $sql=sqlAuth('omy',$sql);//数据鉴权
+ $count = Omys::where($sql)->count();//获取总条数
+ $info = Omys::with(['frameData','supplierData','peopleData','userData','billData','recordData'])->where($sql)->append(['extension'])->page($input['page'],$input['limit'])->order(['id'=>'desc'])->select()->toArray();//查询分页数据
+ $result=[
+ 'state'=>'success',
+ 'count'=>$count,
+ 'info'=>$info
+ ];//返回数据
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //新增|更新
+ public function save(){
+ $input=input('post.');
+ if(existFull($input,['class','info']) && isset($input['class']['id'])){
+ //构造|验证CLASS
+ try {
+ $class=$input['class'];
+ $class['frame']=userInfo(getUserID(),'frame');
+ $class['user']=getUserID();
+ $class['examine']=0;
+ $class['nucleus']=0;
+ empty($class['id'])?$this->validate($class,'app\validate\Omy'):$this->validate($class,'app\validate\Omy.update');
+ $period=getPeriod();
+ if(strtotime($class['time'])<=$period){
+ throw new ValidateException('单据日期与结账日期冲突!');
+ }
+ } catch (ValidateException $e) {
+ return json(['state'=>'error','info'=>$e->getError()]);
+ exit;
+ }
+
+ //验证INFO
+ foreach ($input['info'] as $infoKey=>$infoVo) {
+ try {
+ $this->validate($infoVo,'app\validate\OmyInfo');
+ } catch (ValidateException $e) {
+ return json(['state'=>'error','info'=>'数据表格第'.($infoKey+1).'条'.$e->getError()]);
+ exit;
+ }
+ }
+
+ //处理数据
+ Db::startTrans();
+ try {
+ //CLASS数据
+ if(empty($class['id'])){
+ //创建数据
+ $createInfo=Omys::create($class);
+ $class['id']=$createInfo['id'];//转存主键
+ Db::name('record')->insert(['type'=>'omy','source'=>$class['id'],'time'=>time(),'user'=>getUserID(),'info'=>'新增单据']);
+ pushLog('新增付款单[ '.$class['number'].' ]');//日志
+ }else{
+ //更新数据
+ $updateInfo=Omys::update($class);
+ Db::name('record')->insert(['type'=>'omy','source'=>$class['id'],'time'=>time(),'user'=>getUserID(),'info'=>'更新单据']);
+ pushLog('更新付款单[ '.$class['number'].' ]');//日志
+ }
+
+ //INFO数据
+ OmyInfo::where([['pid','=',$class['id']]])->delete();
+ foreach ($input['info'] as $infoKey=>$infoVo) {
+ $input['info'][$infoKey]['pid']=$class['id'];
+ }
+ $model = new OmyInfo;
+ $model->saveAll($input['info']);
+
+ Db::commit();
+ $result=['state'=>'success','info'=>$class['id']];
+ } catch (\Exception $e) {
+ Db::rollback();
+ $result=['state'=>'error','info'=>'内部错误,操作已撤销!'];
+ }
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //获取
+ public function get(){
+ $input=input('post.');
+ if(existFull($input,['parm'])){
+ $class=Omys::where([['id','=',$input['parm']]])->find();
+ $info=OmyInfo::with(['accountData'])->where([['pid','=',$input['parm']]])->order(['id'=>'asc'])->select();
+ $result=['state'=>'success','info'=>[
+ 'class'=>$class,
+ 'info'=>$info,
+ ]];
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //删除
+ public function del(){
+ $input=input('post.');
+ if(existFull($input,['parm']) && is_array($input['parm'])){
+ $data=Db::name('omy')->where([['id','in',$input['parm']]])->order(['id'=>'desc'])->select()->toArray();
+ $search=search($data)->where([['examine','=','1']])->find();
+ if(empty($search)){
+ Db::startTrans();
+ try {
+ Db::name('omy')->where([['id','in',$input['parm']]])->delete();
+ Db::name('omy_info')->where([['pid','in',$input['parm']]])->delete();
+ Db::name('record')->where([['type','=','omy'],['source','in',$input['parm']]])->delete();
+ Db::name('log')->insert(['time'=>time(),'user'=>getUserID(),'info'=>'删除付款单[ '.implode(' | ',array_column($data,'number')).' ]']);
+
+ Db::commit();
+ $result=['state'=>'success'];
+ } catch (\Exception $e) {
+ Db::rollback();
+ $result=['state'=>'error','info'=>'内部错误,操作已撤销!'];
+ }
+ }else{
+ $result=['state'=>'error','info'=>'单据['.$search['number'].']已审核,不可删除!'];
+ }
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //审核|反审核
+ public function examine(){
+ $input=input('post.');
+ if(existFull($input,['parm']) && is_array($input['parm'])){
+ //1 基础数据
+ $period=getPeriod();
+ $classList=Db::name('omy')->where([['id','in',$input['parm']]])->order(['id'=>'desc'])->select()->toArray();
+ $infoList=Db::name('omy_info')->where([['pid','in',$input['parm']]])->order(['id'=>'asc'])->select()->toArray();
+ //2 综合处理
+ foreach ($input['parm'] as $parmVo) {
+ //1 匹配数据
+ $class=search($classList)->where([['id','=',$parmVo]])->find();
+ $info=search($infoList)->where([['pid','=',$parmVo]])->select();
+ //2 CLASS验证
+ if($class['time']<=$period){
+ return json(['state'=>'error','info'=>'操作单据[ '.$class['number'].' ]失败,原因:单据日期与结账日期冲突!']);
+ exit;
+ }
+ if(!empty($class['examine'])){
+ //核销单
+ $bill=Db::name('bill_info')->where([['mold','=','omy'],['source','=',$class['id']]])->find();
+ if(!empty($bill)){
+ return json(['state'=>'error','info'=>'反审核单据[ '.$class['number'].' ]失败,原因:该单据存在关联核销单!']);
+ exit;
+ }
+ }
+ //3 数据处理
+ Db::startTrans();
+ try {
+ //场景验证
+ if(empty($class['examine'])){
+ //审核
+ //1 构造数据
+ $store=['account'=>[],'accountInfo'=>[]];
+ foreach ($info as $infoKey=>$infoVo){
+ //1 资金账户
+ $store['account'][]=['id'=>$infoVo['account'],'balance'=>$infoVo['money']];
+ //2 资金账户详情
+ $store['accountInfo'][]=['pid'=>$infoVo['account'],'type'=>'omy','class'=>$class['id'],'time'=>$class['time'],'direction'=>0,'money'=>$infoVo['money']];
+ }
+ //2 资金账户
+ Db::name('account')->duplicate(['balance'=>Db::raw('balance - VALUES(`balance`)')])->insertAll($store['account']);
+ //3 资金账户
+ Db::name('account_info')->insertAll($store['accountInfo']);
+ //4 供应商|应付款余额
+ Db::name('supplier')->where([['id','=',$class['supplier']]])->dec('balance',$class['total'])->update();
+ //5 更新单据
+ Db::name('omy')->where([['id','=',$class['id']]])->update(['examine'=>1]);
+ //6 单据记录
+ Db::name('record')->insert(['type'=>'omy','source'=>$class['id'],'time'=>time(),'user'=>getUserID(),'info'=>'审核单据']);
+ //7 记录操作
+ pushLog('审核付款单[ '.$class['number'].' ]');//单据日志
+ }else{
+ //反审核
+ //1 匹配数据
+ $listSql=[['type','=','omy'],['class','=',$class['id']]];
+ $accountInfoList=Db::name('account_info')->where($listSql)->select()->toArray();
+ //2 资金账户
+ $accountDuplicate=[];
+ foreach ($accountInfoList as $accountInfoVo) {
+ $accountDuplicate[]=['id'=>$accountInfoVo['pid'],'balance'=>$accountInfoVo['money']];
+ }
+ //2.1 更新资金
+ Db::name('account')->duplicate(['balance'=>Db::raw('balance + VALUES(`balance`)')])->insertAll($accountDuplicate);
+ //2.2 删除资金详情
+ Db::name('account_info')->where([['id','in',array_column($accountInfoList,'id')]])->delete();
+ //3 供应商|应付款余额
+ Db::name('supplier')->where([['id','=',$class['supplier']]])->inc('balance',$class['total'])->update();
+ //4 更新单据
+ Db::name('omy')->where([['id','=',$class['id']]])->update(['examine'=>0]);
+ //5 单据记录
+ Db::name('record')->insert(['type'=>'omy','source'=>$class['id'],'time'=>time(),'user'=>getUserID(),'info'=>'反审核单据']);
+ //6 记录操作
+ pushLog('反审核付款单[ '.$class['number'].' ]');//单据日志
+ }
+
+ Db::commit();
+ } catch (\Exception $e) {
+ Db::rollback();
+ return json(['state'=>'error','info'=>'内部错误,操作已撤销!']);
+ exit;
+ }
+ }
+ $result=['state'=>'success'];
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //上传
+ public function upload(){
+ $file = request()->file('file');
+ //获取上传文件
+ if (empty($file)) {
+ $result = ['state' => 'error','info' => '传入数据不完整!'];
+ } else {
+ //文件限制5MB
+ try{
+ validate(['file'=>['fileSize'=>5*1024*1024,'fileExt'=>'png,gif,jpg,jpeg,txt,doc,docx,rtf,xls,xlsx,ppt,pptx,pdf,zip,rar']])->check(['file'=>$file]);
+ $fileInfo=Filesystem::disk('upload')->putFile('omy', $file, 'uniqid');
+ $filePath=request()->domain().'/static/upload/'.$fileInfo;
+ $result=['state'=>'success','info'=>$filePath];
+ }catch(ValidateException $e) {
+ $result = ['state' => 'error','info' => $e->getMessage()];
+ }
+ }
+ return json($result);
+ }
+ //导入
+ public function import(){
+ delOverdueFile('static.upload.xlsx');//删除过期文件
+ $file=request()->file('file');//获取上传文件
+ if(empty($file)){
+ $result=['state'=>'error','info'=>'传入数据不完整!'];
+ }else{
+ $fun=getSys('fun');
+ try{
+ validate(['file'=>['fileSize'=>2*1024*1024,'fileExt'=>'xlsx']])->check(['file'=>$file]);
+ $fileInfo = Filesystem::disk('upload')->putFile('xlsx', $file, 'uniqid');
+ $filePath = pathChange('static.upload').$fileInfo;
+ $data=getXlsx($filePath);
+ unset($data[1]);//删除标题行
+ unset($data[2]);//删除列名行
+ //初始化CLASS
+ //供应商匹配
+ $supplier=Db::name('supplier')->where([['name','=',$data[3]['A']]])->find();
+ if(empty($supplier)){
+ throw new ValidateException('供应商[ '.$data[3]['A'].' ]未匹配!');
+ }
+ //关联人员匹配
+ if(empty($data[3]['E'])){
+ $people=['id'=>0];
+ }else{
+ $people=Db::name('people')->where([['name','=',$data[3]['E']]])->find();
+ if(empty($people)){
+ throw new ValidateException('关联人员[ '.$data[3]['E'].' ]未匹配!');
+ }
+ }
+ $class=[
+ 'frame'=>userInfo(getUserID(),'frame'),
+ 'supplier'=>$supplier['id'],
+ 'time'=>$data[3]['B'],
+ 'number'=>$data[3]['C'],
+ 'total'=>0,
+ 'people'=>$people['id'],
+ 'file'=>[],
+ 'data'=>$data[3]['F'],
+ 'more'=>[],
+ 'examine'=>0,
+ 'nucleus'=>0,
+ 'user'=>getUserID()
+ ];
+ $this->validate($class,'app\validate\Omy');//数据合法性验证
+ //初始化INFO
+ $info=[];
+ $account=Db::name('account')->where([['name','in',array_column($data,'G')]])->select()->toArray();
+ foreach ($data as $dataKey=>$dataVo) {
+ $record=[
+ 'account'=>$dataVo['G'],
+ 'money'=>$dataVo['H'],
+ 'settle'=>$dataVo['I'],
+ 'data'=>$dataVo['J']
+ ];
+ //结算账户匹配
+ $accountFind=search($account)->where([['name','=',$record['account']]])->find();
+ if(empty($accountFind)){
+ throw new ValidateException('模板文件第'.$dataKey.'行结算账户[ '.$record['account'].' ]未匹配!');
+ }else{
+ $record['account']=$accountFind['id'];
+ }
+ //结算金额匹配
+ if(!preg_match("/^(\-)?\d+(\.\d{0,".$fun['digit']['money']."})?$/",$record['money'])){
+ throw new ValidateException('模板文件第'.$dataKey.'行结算金额不正确!');
+ }
+ try{
+ $this->validate($record,'app\validate\OmyInfo');//数据合法性验证
+ //转存数据
+ $class['total']=math()->chain($class['total'])->add($record['money'])->done();//累加单据金额
+ $info[]=$record;
+ } catch (ValidateException $e) {
+ return json(['state'=>'error','info'=>'模板文件第'.$dataKey.'行'.$e->getMessage()]);//返回错误信息
+ exit;
+ }
+ }
+ Db::startTrans();
+ try {
+ //新增CLASS
+ $classData=Omys::create($class);
+ //新增INFO
+ foreach ($info as $infoKey=>$infoVo) {
+ $info[$infoKey]['pid']=$classData['id'];
+ }
+ $model = new OmyInfo;
+ $model->saveAll($info);
+ Db::name('record')->insert(['type'=>'omy','source'=>$classData['id'],'time'=>time(),'user'=>getUserID(),'info'=>'导入单据']);
+ pushLog('导入付款单[ '.$classData['number'].' ]');//日志
+
+ Db::commit();
+ $result=['state'=>'success'];
+ } catch (\Exception $e) {
+ Db::rollback();
+ $result=['state'=>'error','info'=>'内部错误,操作已撤销!'];
+ }
+ }catch(ValidateException $e) {
+ $result=['state'=>'error','info'=>$e->getMessage()];//返回错误信息
+ }
+ }
+ return json($result);
+ }
+ //导出
+ public function exports(){
+ $input=input('get.');
+ if(existFull($input,['scene','parm']) && is_array($input['parm'])){
+ pushLog('导出付款单列表');//日志
+ $source=Omys::with(['frameData','supplierData','peopleData','userData'])->where([['id','in',$input['parm']]])->append(['extension'])->order(['id'=>'desc'])->select()->toArray();//查询CLASS数据
+ if($input['scene']=='simple'){
+ //简易报表
+ //开始构造导出数据
+ $excel=[];//初始化导出数据
+ //标题数据
+ $excel[]=['type'=>'title','info'=>'付款单列表'];
+ //表格数据
+ $field=[
+ 'frameData|name'=>'所属组织',
+ 'supplierData|name'=>'供应商',
+ 'time'=>'单据时间',
+ 'number'=>'单据编号',
+ 'total'=>'单据金额',
+ 'extension|amount'=>'核销金额',
+ 'peopleData|name'=>'关联人员',
+ 'extension|examine'=>'审核状态',
+ 'extension|nucleus'=>'核销状态',
+ 'userData|name'=>'制单人',
+ 'data'=>'备注信息'
+ ];
+ $thead=array_values($field);//表格标题
+ $tbody=[];//表格内容
+ //构造表内数据
+ foreach ($source as $sourceVo) {
+ $rowData=[];
+ foreach (array_keys($field) as $fieldVo) {
+ $rowData[]=arraySeek($sourceVo,$fieldVo);//多键名数据赋值
+ }
+ $tbody[]=$rowData;//加入行数据
+ }
+ $excel[]=['type'=>'table','info'=>['thead'=>$thead,'tbody'=>$tbody]];//表格数据
+ //统计数据
+ $excel[]=['type'=>'node','info'=>[
+ '总数:'.count($source),
+ '总单据金额:'.mathArraySum(array_column($source,'total')),
+ '总核销金额:'.mathArraySum(arrayColumns($source,['extension','amount']))
+ ]];
+ //导出execl
+ buildExcel('付款单列表',$excel);
+ }else{
+ //详细报表
+ $files=[];//初始化文件列表
+ foreach ($source as $sourceVo) {
+ //开始构造导出数据
+ $excel=[];//初始化导出数据
+ //标题数据
+ $excel[]=['type'=>'title','info'=>'付款单'];
+ //节点数据
+ $excel[]=['type'=>'node','info'=>[
+ '供应商:'.$sourceVo['supplierData']['name'],
+ '单据日期:'.$sourceVo['time'],
+ '单据编号:'.$sourceVo['number']]
+ ];
+ //表格数据
+ $field=[
+ 'accountData|name'=>'结算账户',
+ 'money'=>'结算金额',
+ 'settle'=>'结算号',
+ 'data'=>'备注信息'
+ ];
+ //构造表内数据
+ $info=OmyInfo::with(['accountData'])->where([['pid','=',$sourceVo['id']]])->order(['id'=>'asc'])->select()->toArray();
+ $thead=array_values($field);//表格标题
+ $tbody=[];//表格内容
+ foreach ($info as $infoVo) {
+ $rowData=[];
+ foreach (array_keys($field) as $fieldVo) {
+ $rowData[]=arraySeek($infoVo,$fieldVo);//多键名数据赋值
+ }
+ $tbody[]=$rowData;//加入行数据
+ }
+ $excel[]=['type'=>'table','info'=>['thead'=>$thead,'tbody'=>$tbody]];//表格数据
+ //节点数据
+ $excel[]=['type'=>'node','info'=>[
+ '单据金额:'.$sourceVo['total'],
+ '核销金额:'.$sourceVo['extension']['amount'],
+ '关联人员:'.arraySeek($sourceVo,'peopleData|name'),
+ '备注信息:'.$sourceVo['data']]
+ ];
+ //生成execl
+ $files[]=buildExcel($sourceVo['number'],$excel,false);
+ }
+ buildZip('付款单_'.time(),$files);
+ }
+ }else{
+ return json(['state'=>'error','info'=>'传入数据不完整!']);
+ }
+ }
+}
\ No newline at end of file
diff --git a/serve/app/controller/People.php b/serve/app/controller/People.php
new file mode 100644
index 0000000..0a5d686
--- /dev/null
+++ b/serve/app/controller/People.php
@@ -0,0 +1,235 @@
+'name|py'],'fullLike'],
+ ['number','fullLike'],
+ ['sex','fullDec1'],
+ ['tel','fullLike'],
+ ['add','fullLike'],
+ ['card','fullLike'],
+ ['data','fullLike']
+ ]);//构造SQL
+ $sql=frameScope($sql);//组织数据
+ $sql=sqlAuth('people',$sql);//数据鉴权
+ $count = Peoples::where($sql)->count();//获取总条数
+ $info = Peoples::with(['frameData'])->append(['extension'])->where($sql)->page($input['page'],$input['limit'])->order(['id'=>'desc'])->select();//查询分页数据
+ $result=[
+ 'state'=>'success',
+ 'count'=>$count,
+ 'info'=>$info
+ ];//返回数据
+ return json($result);
+ }
+ //新增|更新
+ public function save(){
+ $input=input('post.');
+ if(isset($input['id'])){
+ //构造|验证
+ try {
+ $input['py']=zhToPy($input['name']);//首拼信息
+ empty($input['id'])?$this->validate($input,'app\validate\People'):$this->validate($input,'app\validate\People.update');
+ } catch (ValidateException $e) {
+ return json(['state'=>'error','info'=>$e->getError()]);
+ exit;
+ }
+
+ //处理数据
+ Db::startTrans();
+ try {
+ if(empty($input['id'])){
+ //创建数据
+ Peoples::create($input);
+ pushLog('新增人员[ '.$input['name'].' ]');//日志
+ }else{
+ //更新数据
+ Peoples::update($input);
+ pushLog('更新人员[ '.$input['name'].' ]');//日志
+ }
+
+ Db::commit();
+ $result=['state'=>'success'];
+ } catch (\Exception $e) {
+ Db::rollback();
+ $result=['state'=>'error','info'=>'内部错误,操作已撤销!'];
+ }
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //获取
+ public function get(){
+ $input=input('post.');
+ if(existFull($input,['id'])){
+ $result=[
+ 'state'=>'success',
+ 'info'=>Peoples::where([['id','=',$input['id']]])->find()
+ ];
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //删除
+ public function del(){
+ $input=input('post.');
+ if(existFull($input,['parm']) && is_array($input['parm'])){
+ //关联判断
+ $exist=moreTableFind([
+ ['table'=>'allot','where'=>[['people','in',$input['parm']]]],
+ ['table'=>'barter','where'=>[['people','in',$input['parm']]]],
+ ['table'=>'bill','where'=>[['people','in',$input['parm']]]],
+ ['table'=>'bor','where'=>[['people','in',$input['parm']]]],
+ ['table'=>'bre','where'=>[['people','in',$input['parm']]]],
+ ['table'=>'buy','where'=>[['people','in',$input['parm']]]],
+ ['table'=>'entry','where'=>[['people','in',$input['parm']]]],
+ ['table'=>'extry','where'=>[['people','in',$input['parm']]]],
+ ['table'=>'ice','where'=>[['people','in',$input['parm']]]],
+ ['table'=>'oce','where'=>[['people','in',$input['parm']]]],
+ ['table'=>'imy','where'=>[['people','in',$input['parm']]]],
+ ['table'=>'omy','where'=>[['people','in',$input['parm']]]],
+ ['table'=>'sell','where'=>[['people','in',$input['parm']]]],
+ ['table'=>'sor','where'=>[['people','in',$input['parm']]]],
+ ['table'=>'sre','where'=>[['people','in',$input['parm']]]],
+ ['table'=>'swap','where'=>[['people','in',$input['parm']]]]
+ ]);
+ if(empty($exist)){
+ //逻辑处理
+ $data=Db::name('people')->where([['id','in',$input['parm']]])->order(['id'=>'desc'])->select()->toArray();
+ Db::startTrans();
+ try {
+ Db::name('people')->where([['id','in',$input['parm']]])->delete();
+ Db::name('log')->insert(['time'=>time(),'user'=>getUserID(),'info'=>'删除人员[ '.implode(' | ',array_column($data,'name')).' ]']);
+
+ Db::commit();
+ $result=['state'=>'success'];
+ } catch (\Exception $e) {
+ Db::rollback();
+ $result=['state'=>'error','info'=>'内部错误,操作已撤销!'];
+ }
+ }else{
+ $result=['state'=>'error','info'=>'存在数据关联,删除失败!'];
+ }
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //导入
+ public function import(){
+ delOverdueFile('static.upload.xlsx');//删除过期文件
+ $file=request()->file('file');//获取上传文件
+ if(empty($file)){
+ $result=['state'=>'error','info'=>'传入数据不完整!'];
+ }else{
+ try{
+ validate(['file'=>['fileSize'=>2*1024*1024,'fileExt'=>'xlsx']])->check(['file'=>$file]);
+ $fileInfo = Filesystem::disk('upload')->putFile('xlsx', $file, 'uniqid');
+ $filePath = pathChange('static.upload').$fileInfo;
+ $data=getXlsx($filePath);
+ unset($data[1]);//删除列名行
+ $sql=[];//初始化SQL
+ $frame=Db::name('frame')->where([['name','in',array_column($data,'C')]])->select()->toArray();
+ foreach ($data as $dataKey=>$dataVo) {
+ $record=[
+ 'name'=>$dataVo['A'],
+ 'py'=>zhToPy($dataVo['A']),
+ 'number'=>$dataVo['B'],
+ 'frame'=>$dataVo['C'],
+ 'sex'=>$dataVo['D'],
+ 'tel'=>$dataVo['E'],
+ 'add'=>$dataVo['F'],
+ 'card'=>$dataVo['G'],
+ 'data'=>$dataVo['H'],
+ 'more'=>[]
+ ];
+ //所属组织匹配
+ $frameFind=search($frame)->where([['name','=',$record['frame']]])->find();
+ if(empty($frameFind)){
+ throw new ValidateException('模板文件第'.$dataKey.'行所属组织[ '.$record['frame'].' ]未匹配!');
+ }else{
+ $record['frame']=$frameFind['id'];
+ }
+ //人员性别匹配
+ if(in_array($record['sex'],['男','女'])){
+ $record['sex']=$record['sex']=='男'?1:0;
+ }else{
+ throw new ValidateException('模板文件第'.$dataKey.'行人员性别[ '.$record['sex'].' ]未匹配!');
+ }
+ try {
+ //数据合法性验证
+ $this->validate($record,'app\validate\People');
+ $sql[]=$record;//加入SQL
+ } catch (ValidateException $e) {
+ return json(['state'=>'error','info'=>'模板文件第[ '.$dataKey.' ]行'.$e->getError()]);
+ exit;
+ }
+ }
+ //判断编号重复
+ $column=array_column($sql,'number');
+ $unique=array_unique($column);
+ $diff=array_diff_assoc($column,$unique);
+ if(!empty($diff)){
+ //返回错误信息
+ return json(['state'=>'error','info'=>'模板文件人员编号[ '.implode(' | ',$diff).' ]重复!']);
+ }
+ //新增数据
+ $customer = new Peoples;
+ $customer->saveAll($sql);
+ pushLog('批量导入[ '.count($sql).' ]条人员数据');//日志
+ $result=['state'=>'success','info'=>'成功导入'.count($sql).'行人员数据'];
+ }catch(ValidateException $e) {
+ $result=['state'=>'error','info'=>$e->getMessage()];//返回错误信息
+ }
+ }
+ return json($result);
+ }
+ //导出
+ public function exports(){
+ $input=input('get.');
+ if(existFull($input,['parm']) && is_array($input['parm'])){
+ $info=Peoples::with(['frameData'])->append(['extension'])->where([['id','in',$input['parm']]])->order(['id'=>'desc'])->select()->toArray();//查询数据
+ $field=[
+ 'name'=>'人员名称',
+ 'number'=>'人员编号',
+ 'frameData|name'=>'所属组织',
+ 'extension|sex'=>'人员性别',
+ 'tel'=>'联系电话',
+ 'add'=>'联系地址',
+ 'card'=>'身份证号',
+ 'data'=>'备注信息'
+ ];
+ //开始构造导出数据
+ $excel=[];//初始化导出数据
+ //标题数据
+ $excel[]=['type'=>'title','info'=>'人员信息'];
+ //表格数据
+ $thead=array_values($field);//表格标题
+ $tbody=[];//表格内容
+ //构造表内数据
+ foreach ($info as $infoVo) {
+ $rowData=[];
+ foreach (array_keys($field) as $fieldVo) {
+ $rowData[]=arraySeek($infoVo,$fieldVo);//多键名数据赋值
+ }
+ $tbody[]=$rowData;//加入行数据
+ }
+ $excel[]=['type'=>'table','info'=>['thead'=>$thead,'tbody'=>$tbody]];//表格数据
+ //统计数据
+ $excel[]=['type'=>'node','info'=>['总数:'.count($info)]];
+ //导出execl
+ pushLog('导出人员信息');//日志
+ buildExcel('人员信息',$excel);
+ }else{
+ return json(['state'=>'error','info'=>'传入数据不完整!']);
+ }
+ }
+}
\ No newline at end of file
diff --git a/serve/app/controller/Period.php b/serve/app/controller/Period.php
new file mode 100644
index 0000000..8e98daf
--- /dev/null
+++ b/serve/app/controller/Period.php
@@ -0,0 +1,51 @@
+count();//获取总条数
+ $info = Periods::with(['userData'])->page($input['page'],$input['limit'])->order(['id'=>'desc'])->select();//查询分页数据
+ $result=[
+ 'state'=>'success',
+ 'count'=>$count,
+ 'info'=>$info
+ ];//返回数据
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //结账
+ public function save(){
+ $input=input('post.');
+ if(existFull($input,['date']) && strtotime($input['date'])){
+ $period=getPeriod();
+ $date=strtotime($input['date']);
+ if($date>$period){
+ $data=['date'=>$date,'time'=>time(),'user'=>getUserID()];
+ Db::name('period')->insert($data);
+ pushLog('结账操作');//日志
+
+ $result=['state'=>'success'];
+ }else{
+ $result=['state'=>'error','info'=>'结账周期不正确!'];
+ }
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //反结账
+ public function back(){
+ $period=getPeriod();
+ $row=db('period')->where([['date','=',$period]])->delete();
+ pushLog('反结账操作');//日志
+ return json(['state'=>'success']);
+ }
+}
diff --git a/serve/app/controller/Role.php b/serve/app/controller/Role.php
new file mode 100644
index 0000000..874138b
--- /dev/null
+++ b/serve/app/controller/Role.php
@@ -0,0 +1,103 @@
+count();//获取总条数
+ $info = Roles::where($sql)->page($input['page'],$input['limit'])->order(['id'=>'desc'])->select();//查询分页数据
+ $result=[
+ 'state'=>'success',
+ 'count'=>$count,
+ 'info'=>$info
+ ];//返回数据
+ return json($result);
+ }
+ //新增|更新
+ public function save(){
+ $input=input('post.');
+ if(isset($input['id'])){
+ //验证数据
+ try {
+ empty($input['id'])?$this->validate($input,'app\validate\Role'):$this->validate($input,'app\validate\Role.update');
+ } catch (ValidateException $e) {
+ return json(['state'=>'error','info'=>$e->getError()]);
+ exit;
+ }
+
+ //处理数据
+ Db::startTrans();
+ try {
+ if(empty($input['id'])){
+ //创建数据
+ Roles::create($input);
+ pushLog('新增用户角色[ '.$input['name'].' ]');//日志
+ }else{
+ //更新数据
+ Roles::update($input);
+ pushLog('更新用户角色[ '.$input['name'].' ]');//日志
+ }
+
+ Db::commit();
+ $result=['state'=>'success'];
+ } catch (\Exception $e) {
+ Db::rollback();
+ $result=['state'=>'error','info'=>'内部错误,操作已撤销!'];
+ }
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //获取
+ public function get(){
+ $input=input('post.');
+ if(existFull($input,['id'])){
+ $result=[
+ 'state'=>'success',
+ 'info'=>Roles::where([['id','=',$input['id']]])->find()
+ ];
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //删除
+ public function del(){
+ $input=input('post.');
+ if(existFull($input,['id'])){
+ //关联判断
+ $exist=moreTableFind([
+ ['table'=>'user','where'=>[['role','=',$input['id']]]],
+ ]);
+ //判断数据是否存在
+ if(!$exist){
+ $find=Db::name('role')->where([['id','=',$input['id']]])->find();
+ Db::startTrans();
+ try {
+ Db::name('role')->where([['id','=',$input['id']]])->delete();
+ pushLog('删除用户角色[ '.$find['name'].' ]');//日志
+
+ Db::commit();
+ $result=['state'=>'success'];
+ } catch (\Exception $e) {
+ Db::rollback();
+ $result=['state'=>'error','info'=>'内部错误,操作已撤销!'];
+ }
+ }else{
+ $result=['state'=>'error','info'=>'存在数据关联,删除失败!'];
+ }
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+}
\ No newline at end of file
diff --git a/serve/app/controller/Sell.php b/serve/app/controller/Sell.php
new file mode 100644
index 0000000..b574fe6
--- /dev/null
+++ b/serve/app/controller/Sell.php
@@ -0,0 +1,1298 @@
+'time'],'startTime'],
+ [['endTime'=>'time'],'endTime'],
+ ['examine','fullDec1'],
+ ['nucleus','fullDec1'],
+ ['cse','fullDec1'],
+ ['invoice','fullDec1'],
+ ['check','fullDec1'],
+ ['data','fullLike']
+ ]);//构造SQL
+ //商品信息扩展查询
+ if(existFull($input,['goods'])){
+ $goods=array_column(Db::name('goods')->where([['name|py','like','%'.$input['goods'].'%']])->select()->toArray(),'id');
+ $sql[]=['id','in',array_column(Db::name('sell_info')->where([['goods','in',$goods]])->select()->toArray(),'pid')];
+ }
+ $sql=frameScope($sql);//组织数据
+ $sql=sqlAuth('sell',$sql);//数据鉴权
+ $count = Sells::where($sql)->count();//获取总条数
+ $info = Sells::with(['frameData','customerData','peopleData','userData','billData','costData','invoiceData','recordData'])->where($sql)->append(['extension'])->page($input['page'],$input['limit'])->order(['id'=>'desc'])->select()->toArray();//查询分页数据
+ //关联单据
+ if(!empty($info)){
+ $sor=Db::name('sor')->where([['id','in',array_column($info,'source')]])->select()->toArray();
+ $sre=Db::name('sre')->where([['source','in',array_column($info,'id')]])->select()->toArray();
+ foreach ($info as $infoKey=>$infoVo) {
+ //销售订单
+ $sorData=array_map(function($item){
+ return ['type'=>'销售订单','time'=>date('Y-m-d',$item['time']),'number'=>$item['number'],'sort'=>$item['time'],'sort'=>$item['time'],'types'=>'sor','id'=>$item['id']];
+ },search($sor)->where([['id','=',$infoVo['source']]])->select());
+ //销售退货单
+ $sreData=array_map(function($item){
+ return ['type'=>'销售退货单','time'=>date('Y-m-d',$item['time']),'number'=>$item['number'],'sort'=>$item['time'],'sort'=>$item['time'],'types'=>'sre','id'=>$item['id']];
+ },search($sre)->where([['source','=',$infoVo['id']]])->select());
+ //合并排序
+ $merge=array_merge($sorData,$sreData);
+ array_multisort(array_column($merge,'sort'),SORT_DESC,$merge);
+ $info[$infoKey]['relation']=$merge;
+ }
+ }
+ $result=[
+ 'state'=>'success',
+ 'count'=>$count,
+ 'info'=>$info
+ ];//返回数据
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //新增|更新
+ public function save(){
+ $input=input('post.');
+ if(existFull($input,['class','info']) && isset($input['class']['id'])){
+ //构造|验证CLASS
+ try {
+ $class=$input['class'];
+ $class['frame']=userInfo(getUserID(),'frame');
+ $class['user']=getUserID();
+ $class['cse']=empty($class['cost'])?3:0;
+ $class['invoice']=empty($class['actual'])?3:0;
+ $class['examine']=0;
+ $class['nucleus']=0;
+ empty($class['id'])?$this->validate($class,'app\validate\Sell'):$this->validate($class,'app\validate\Sell.update');
+ $period=getPeriod();
+ if(strtotime($class['time'])<=$period){
+ throw new ValidateException('单据日期与结账日期冲突!');
+ }
+ } catch (ValidateException $e) {
+ return json(['state'=>'error','info'=>$e->getError()]);
+ exit;
+ }
+
+ //验证INFO
+ foreach ($input['info'] as $infoKey=>$infoVo) {
+ try {
+ $this->validate($infoVo,'app\validate\SellInfo');
+ } catch (ValidateException $e) {
+ return json(['state'=>'error','info'=>'商品信息第'.($infoKey+1).'条'.$e->getError()]);
+ exit;
+ }
+ }
+
+ //验证Cost
+ foreach ($input['cost'] as $costKey=>$costVo) {
+ try {
+ $this->validate($costVo,'app\validate\Cost');
+ } catch (ValidateException $e) {
+ return json(['state'=>'error','info'=>'单据费用第'.($infoKey+1).'条'.$e->getError()]);
+ exit;
+ }
+ }
+
+ //处理数据
+ Db::startTrans();
+ try {
+ //CLASS数据
+ if(empty($class['id'])){
+ //创建数据
+ $createInfo=Sells::create($class);
+ $class['id']=$createInfo['id'];//转存主键
+ Db::name('record')->insert(['type'=>'sell','source'=>$class['id'],'time'=>time(),'user'=>getUserID(),'info'=>'新增单据']);
+ pushLog('新增销售单[ '.$class['number'].' ]');//日志
+ }else{
+ //更新数据
+ $updateInfo=Sells::update($class);
+ Db::name('record')->insert(['type'=>'sell','source'=>$class['id'],'time'=>time(),'user'=>getUserID(),'info'=>'更新单据']);
+ pushLog('更新销售单[ '.$class['number'].' ]');//日志
+ }
+
+ //INFO数据
+ SellInfo::where([['pid','=',$class['id']]])->delete();
+ foreach ($input['info'] as $infoKey=>$infoVo) {
+ $input['info'][$infoKey]['pid']=$class['id'];
+ $input['info'][$infoKey]['retreat']=0;//初始|退货数量
+ }
+ $model = new SellInfo;
+ $model->saveAll($input['info']);
+
+ //COST数据
+ Cost::where([['type','=','sell'],['class','=',$class['id']]])->delete();
+ foreach ($input['cost'] as $costKey=>$costVo) {
+ unset($input['cost'][$costKey]['id']);
+ $input['cost'][$costKey]['type']='sell';
+ $input['cost'][$costKey]['class']=$class['id'];
+ $input['cost'][$costKey]['time']=$class['time'];
+ $input['cost'][$costKey]['settle']=0;
+ $input['cost'][$costKey]['state']=0;
+ }
+ $model = new Cost;
+ $model->saveAll($input['cost']);
+
+ Db::commit();
+ $result=['state'=>'success','info'=>$class['id']];
+ } catch (\Exception $e) {
+ Db::rollback();
+ $result=['state'=>'error','info'=>'内部错误,操作已撤销!'];
+ }
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //获取
+ public function get(){
+ $input=input('post.');
+ if(existFull($input,['parm'])){
+ $class=Sells::where([['id','=',$input['parm']]])->find();
+ $info=SellInfo::with(['goodsData','warehouseData'])->where([['pid','=',$input['parm']]])->order(['id'=>'asc'])->select();
+ $cost=Cost::where([['type','=','sell'],['class','=',$input['parm']]])->order(['id'=>'asc'])->select();
+ $result=['state'=>'success','info'=>[
+ 'class'=>$class,
+ 'info'=>$info,
+ 'cost'=>$cost,
+ ]];
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //删除
+ public function del(){
+ $input=input('post.');
+ if(existFull($input,['parm']) && is_array($input['parm'])){
+ //关联验证
+ $exist=moreTableFind([['table'=>'sre','where'=>[['source','in',$input['parm']]]]]);
+ if($exist){
+ $result=['state'=>'error','info'=>'存在数据关联,删除失败!'];
+ }else{
+ $data=Db::name('sell')->where([['id','in',$input['parm']]])->order(['id'=>'desc'])->select()->toArray();
+ $search=search($data)->where([['examine','=','1']])->find();
+ if(empty($search)){
+ Db::startTrans();
+ try {
+ Db::name('sell')->where([['id','in',$input['parm']]])->delete();
+ Db::name('sell_info')->where([['pid','in',$input['parm']]])->delete();
+ Db::name('cost')->where([['type','=','sell'],['class','in',$input['parm']]])->delete();
+ Db::name('record')->where([['type','=','sell'],['source','in',$input['parm']]])->delete();
+ Db::name('log')->insert(['time'=>time(),'user'=>getUserID(),'info'=>'删除销售单[ '.implode(' | ',array_column($data,'number')).' ]']);
+
+ Db::commit();
+ $result=['state'=>'success'];
+ } catch (\Exception $e) {
+ Db::rollback();
+ $result=['state'=>'error','info'=>'内部错误,操作已撤销!'];
+ }
+ }else{
+ $result=['state'=>'error','info'=>'单据['.$search['number'].']已审核,不可删除!'];
+ }
+ }
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //核对|反核对
+ public function check(){
+ $input=input('post.');
+ if(existFull($input,['parm']) && is_array($input['parm'])){
+ $period=getPeriod();
+ $classList=Db::name('sell')->where([['id','in',$input['parm']]])->order(['id'=>'desc'])->select()->toArray();
+ foreach ($input['parm'] as $parmVo) {
+ $class=search($classList)->where([['id','=',$parmVo]])->find();
+ if($class['time']<=$period){
+ return json(['state'=>'error','info'=>'操作单据失败,原因:单据日期与结账日期冲突!']);
+ exit;
+ }
+ if(empty($class['check'])){
+ Db::name('sell')->where([['id','=',$class['id']]])->update(['check'=>1]);
+ //1 单据记录
+ Db::name('record')->insert(['type'=>'sell','source'=>$class['id'],'time'=>time(),'user'=>getUserID(),'info'=>'核对单据']);
+ //2 记录操作
+ pushLog('核对销售单[ '.$class['number'].' ]');//单据日志
+ }else{
+ Db::name('sell')->where([['id','=',$class['id']]])->update(['check'=>0]);
+ //1 单据记录
+ Db::name('record')->insert(['type'=>'sell','source'=>$class['id'],'time'=>time(),'user'=>getUserID(),'info'=>'反核对单据']);
+ //2 记录操作
+ pushLog('反核对销售单[ '.$class['number'].' ]');//单据日志
+ }
+ }
+ $result=['state'=>'success'];
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //审核|反审核
+ public function examine(){
+ $input=input('post.');
+ if(existFull($input,['parm']) && is_array($input['parm'])){
+ //1 基础数据
+ $fun=getSys('fun');
+ $period=getPeriod();
+ $classList=Db::name('sell')->where([['id','in',$input['parm']]])->order(['id'=>'desc'])->select()->toArray();
+ $infoList=Db::name('sell_info')->where([['pid','in',$input['parm']]])->order(['id'=>'asc'])->select()->toArray();
+ //2 综合处理
+ foreach ($input['parm'] as $parmVo) {
+ //1 匹配数据
+ $class=search($classList)->where([['id','=',$parmVo]])->find();
+ $info=search($infoList)->where([['pid','=',$parmVo]])->select();
+ //1.1 商品数据
+ $goodsList=Db::name('goods')->where([['id','in',array_unique(array_column($info,'goods'))]])->select()->toArray();
+ //1.2 综合匹配
+ if(empty($class['examine'])){
+ //1 关联单据
+ empty($class['source'])||$sorInfoList=Db::name('sor_info')->where([['id','in',array_column($info,'source')]])->select()->toArray();
+ //2 构造数据
+ $batchGather=[];
+ $serialGather=[];
+ $roomWhereOrSql=[];
+ foreach ($info as $infoVo) {
+ //1 批次号
+ empty($infoVo['batch'])||$batchGather[]=$infoVo['batch'];
+ //2 序列号
+ $serialGather=array_merge($serialGather,json_decode($infoVo['serial']));
+ //3 仓储条件
+ empty($infoVo['warehouse'])||$roomWhereOrSql[]=[['warehouse','=',$infoVo['warehouse']],['goods','=',$infoVo['goods']],['attr','=',$infoVo['attr']]];
+ }
+ //3 匹配数据
+ empty($batchGather)||$batchList=Db::name('batch')->where([['number','in',$batchGather]])->select()->toArray();
+ empty($serialGather)||$serialList=Db::name('serial')->where([['number','in',$serialGather],['state','<>',2]])->select()->toArray();
+ if(!empty($roomWhereOrSql)){
+ //1 去重转存
+ $roomWhereOrSql=array_unique($roomWhereOrSql,SORT_REGULAR);
+ //2 仓储匹配
+ $roomList=Db::name('room')->whereOr($roomWhereOrSql)->select()->toArray();
+ }
+ }
+ //2 CLASS验证
+ if($class['time']<=$period){
+ return json(['state'=>'error','info'=>'操作单据[ '.$class['number'].' ]失败,原因:单据日期与结账日期冲突!']);
+ exit;
+ }
+ if(empty($class['examine'])){
+ //销售订单
+ if(!empty($class['source'])){
+ $sor=Db::name('sor')->where([['id','=',$class['source']]])->find();
+ if(in_array($sor['state'],[2,3])){
+ return json(['state'=>'error','info'=>'反审核单据[ '.$class['number'].' ]失败,原因:关联订单状态不正确!']);
+ exit;
+ }
+ }
+ }else{
+ //1 销售订单
+ if(!empty($class['source'])){
+ $sor=Db::name('sor')->where([['id','=',$class['source']]])->find();
+ if(in_array($sor['state'],[0,3])){
+ return json(['state'=>'error','info'=>'反审核单据[ '.$class['number'].' ]失败,原因:关联订单状态不正确!']);
+ exit;
+ }
+ }
+ //2 销售退货单
+ $sre=Db::name('sre')->where([['source','=',$class['id']]])->find();
+ if(!empty($sre)){
+ return json(['state'=>'error','info'=>'反审核单据[ '.$class['number'].' ]失败,原因:该单据存在关联销售退货单!']);
+ exit;
+ }
+ //3 核销单
+ $bill=Db::name('bill_info')->where([['mold','=','sell'],['source','=',$class['id']]])->find();
+ if(!empty($bill)){
+ return json(['state'=>'error','info'=>'反审核单据[ '.$class['number'].' ]失败,原因:该单据存在关联核销单!']);
+ exit;
+ }
+ //4 单据费用
+ $cost=Db::name('cost')->alias('cost')->where([['type','=','sell'],['class','=',$class['id']]])->whereExists(function($query){
+ $query->name('oce_info')->where([['source','=',Db::raw('cost.id')]])->limit(1);
+ })->find();
+ if(!empty($cost)){
+ return json(['state'=>'error','info'=>'反审核单据[ '.$class['number'].' ]失败,原因:该单据存在关联其它支出单!']);
+ exit;
+ }
+ //5 单据发票
+ $invoice=Db::name('invoice')->where([['type','=','sell'],['class','=',$class['id']]])->find();
+ if(!empty($invoice)){
+ return json(['state'=>'error','info'=>'反审核单据[ '.$class['number'].' ]失败,原因:该单据存在关联单据发票!']);
+ exit;
+ }
+ }
+ //3 INFO验证|构造
+ foreach ($info as $infoKey=>$infoVo) {
+ //1 匹配商品
+ $goods=search($goodsList)->where([['id','=',$infoVo['goods']]])->find();
+ //2 商品类型
+ if(empty($goods['type'])){
+ //场景验证
+ if(empty($class['examine'])){
+ //1 匹配数据
+ $room=search($roomList)->where([['warehouse','=',$infoVo['warehouse']],['goods','=',$infoVo['goods']],['attr','=',$infoVo['attr']]],true)->find();
+ (empty($room)||empty($infoVo['batch']))||$batch=search($batchList)->where([['room','=',$room['id']],['number','=',$infoVo['batch']],['time','=',$infoVo['mfd']]],true)->find();
+ //2 关联单据
+ if(!empty($infoVo['source'])){
+ $sorInfo=search($sorInfoList)->where([['id','=',$infoVo['source']]])->find();
+ if(!empty($sorInfo)){
+ if($sorInfo['unit']!=$infoVo['unit']){
+ //单位匹配
+ return json(['state'=>'error','info'=>'审核单据[ '.$class['number'].' ]失败,原因:第'.($infoKey+1).'行单位与销售订单不匹配!']);
+ exit;
+ }elseif(bccomp(math()->chain($sorInfo['handle'])->add($infoVo['nums'])->done(),$sorInfo['nums'])==1){
+ //数量匹配
+ return json(['state'=>'error','info'=>'审核单据[ '.$class['number'].' ]失败,原因:第'.($infoKey+1).'行超出销售订单可出库数量!']);
+ exit;
+ }
+ }
+
+ }
+ //3 多单位处理
+ if($goods['unit']==-1){
+ //多单位|转存
+ $radix=unitRadix($infoVo['unit'],json_decode($goods['units'],true));
+ $info[$infoKey]['basic']=[
+ 'nums'=>math()->chain($infoVo['nums'])->mul($radix)->done(),
+ 'price'=>math()->chain($infoVo['price'])->div($radix)->round(4)->done()
+ ];
+ }else{
+ //常规单位|转存
+ $info[$infoKey]['basic']=[
+ 'nums'=>$infoVo['nums'],
+ 'price'=>$infoVo['price']
+ ];
+ }
+ //4 序列号
+ $serialData=json_decode($infoVo['serial']);
+ if(empty($serialData)){
+ $info[$infoKey]['serial']=[];
+ }else{
+ //序列号状态[不存在|未销售]
+ $serialCollect=search($serialList)->where([['goods','=',$infoVo['goods']],['number','in',$serialData]])->select();
+ foreach ($serialCollect as $serialCollectVo) {
+ if($serialCollectVo['state']==0){
+ if(empty($room) || $room['id']!=$serialCollectVo['room']){
+ return json(['state'=>'error','info'=>'审核单据[ '.$class['number'].' ]失败,原因:第'.($infoKey+1).'行序列号[ '.$serialCollectVo['number'].' ]与仓库不匹配!']);
+ exit;
+ }
+ if((empty($infoVo['batch'])&&!empty($serialCollectVo['batch']))||(!empty($infoVo['batch'])&&(empty($batch)||$batch['id']!=$serialCollectVo['batch']))){
+ return json(['state'=>'error','info'=>'审核单据[ '.$class['number'].' ]失败,原因:第'.($infoKey+1).'行序列号[ '.$serialCollectVo['number'].' ]与批次不匹配!']);
+ exit;
+ }
+ }else{
+ return json(['state'=>'error','info'=>'审核单据[ '.$class['number'].' ]失败,原因:第'.($infoKey+1).'行序列号[ '.$serialCollectVo['number'].' ]状态不正确!']);
+ exit;
+ }
+ }
+ $info[$infoKey]['serial']=$serialData;
+ }
+ //5 负库存验证
+ if($fun['overflow']==false){
+ //1 仓储验证
+ if(empty($room)){
+ return json(['state'=>'error','info'=>'审核单据[ '.$class['number'].' ]失败,原因:第'.($infoKey+1).'行仓储信息不存在!']);
+ exit;
+ }else{
+ if(bccomp($info[$infoKey]['basic']['nums'],$room['nums'])==1){
+ return json(['state'=>'error','info'=>'审核单据[ '.$class['number'].' ]失败,原因:第'.($infoKey+1).'行仓储库存不足!']);
+ exit;
+ }else{
+ $roomList[$room['rowKey']]['nums']=math()->chain($room['nums'])->sub($info[$infoKey]['basic']['nums'])->done();
+ }
+ }
+ //2 批次验证
+ if(!empty($infoVo['batch'])){
+ if(empty($batch)){
+ return json(['state'=>'error','info'=>'审核单据[ '.$class['number'].' ]失败,原因:第'.($infoKey+1).'行批次信息无效!']);
+ exit;
+ }else{
+ if(bccomp($info[$infoKey]['basic']['nums'],$batch['nums'])==1){
+ return json(['state'=>'error','info'=>'审核单据[ '.$class['number'].' ]失败,原因:第'.($infoKey+1).'行批次库存不足!']);
+ exit;
+ }else{
+ $batchList[$batch['rowKey']]['nums']=math()->chain($batch['nums'])->sub($info[$infoKey]['basic']['nums'])->done();
+ }
+ }
+ }
+ //3 序列号验证
+ if(!empty($serialData)){
+ $serialCount=search($serialList)->where([['room','=',$room['id']],['number','in',$serialData]])->count();
+ if($serialCount != count($serialData)){
+ return json(['state'=>'error','info'=>'审核单据[ '.$class['number'].' ]失败,原因:第'.($infoKey+1).'行存在无效序列号!']);
+ exit;
+ }
+ }
+ }
+ }else{
+ //1 验证序列号
+ $serialInfoCollect=Db::name('serial_info')->where([['type','=','sell'],['info','in',array_column($info,'id')]])->select()->toArray();
+ if(!empty($serialInfoCollect)){
+ //序列号状态[已销售]
+ $serialFind=Db::name('serial')->where([['id','in',array_column($serialInfoCollect,'pid')],['state','<>',1]])->find();
+ if(!empty($serialFind)){
+ return json(['state'=>'error','info'=>'反审核单据[ '.$class['number'].' ]失败,原因:第'.($infoKey+1).'行序列号[ '.$serialFind['number'].' ]状态不正确!']);
+ exit;
+ }
+ }
+ }
+ }
+ }
+ //4 数据处理
+ Db::startTrans();
+ try {
+ //场景验证
+ if(empty($class['examine'])){
+ //审核
+ //1 构造数据
+ $store=['sorInfo'=>[],'room'=>[],'roomInfo'=>[],'batch'=>[],'batchInfo'=>[],'serial'=>[],'serialInfo'=>[],'serve'=>[],'serveInfo'=>[]];
+ foreach ($info as $infoKey=>$infoVo){
+ //1 关联单据
+ empty($infoVo['source'])||$store['sorInfo'][]=['id'=>$infoVo['source'],'handle'=>$infoVo['nums']];
+ //2 判断商品类型
+ $goods=search($goodsList)->where([['id','=',$infoVo['goods']]])->find();
+ if(empty($goods['type'])){
+ //常规商品
+ //1 仓储
+ $store['room'][]=['warehouse'=>$infoVo['warehouse'],'goods'=>$infoVo['goods'],'attr'=>$infoVo['attr'],'nums'=>$infoVo['basic']['nums']];
+ //2 仓储详情
+ $store['roomInfo'][]=['pid'=>null,'type'=>'sell','class'=>$class['id'],'info'=>$infoVo['id'],'time'=>$class['time'],'direction'=>0,'price'=>$infoVo['basic']['price'],'nums'=>$infoVo['basic']['nums']];
+ //3 批次号
+ if(empty($infoVo['batch'])){
+ $store['batch'][]=[];
+ $store['batchInfo'][]=[];
+ }else{
+ $store['batch'][]=['room'=>null,'warehouse'=>$infoVo['warehouse'],'goods'=>$infoVo['goods'],'number'=>$infoVo['batch'],'time'=>$infoVo['mfd'],'nums'=>$infoVo['basic']['nums']];
+ $store['batchInfo'][]=['pid'=>null,'type'=>'sell','class'=>$class['id'],'info'=>$infoVo['id'],'direction'=>0,'nums'=>$infoVo['basic']['nums']];
+ }
+ //4 序列号
+ if(empty($infoVo['serial'])){
+ $store['serial'][]=[];
+ $store['serialInfo'][]=[];
+ }else{
+ $serial=[];
+ $serialInfo=[];
+ foreach ($infoVo['serial'] as $serialVo) {
+ $serial[]=['room'=>null,'warehouse'=>$infoVo['warehouse'],'batch'=>null,'goods'=>$infoVo['goods'],'number'=>$serialVo,'state'=>1];
+ $serialInfo[]=['pid'=>null,'type'=>'sell','class'=>$class['id'],'info'=>$infoVo['id']];
+ }
+ $store['serial'][]=$serial;
+ $store['serialInfo'][]=$serialInfo;
+ }
+ }else{
+ //5 服务
+ $store['serve'][]=['goods'=>$infoVo['goods'],'attr'=>$infoVo['attr'],'nums'=>$infoVo['nums']];
+ $store['serveInfo'][]=['pid'=>null,'type'=>'sell','class'=>$class['id'],'info'=>$infoVo['id'],'time'=>$class['time'],'price'=>$infoVo['price'],'nums'=>$infoVo['nums']];
+ }
+ }
+ //2 关联单据
+ if(!empty($store['sorInfo'])){
+ //1 更新详情
+ Db::name('sor_info')->duplicate(['handle'=>Db::raw('handle + VALUES(`handle`)')])->insertAll($store['sorInfo']);
+ //2 更新CLASS
+ $sorInfo=Db::name('sor_info')->where([['pid','=',$class['source']]])->select()->toArray();
+ $state=mathArraySum(array_column($sorInfo,'nums'))==mathArraySum(array_column($sorInfo,'handle'))?2:1;
+ Db::name('sor')->where([['id','=',$class['source']]])->update(['state'=>$state]);
+ }
+ //3 仓储
+ if(!empty($store['room'])){
+ //1 构造数据
+ $roomInsert=[];
+ foreach ($store['room'] as $roomVo) {
+ $roomFind=search($roomList)->where([['warehouse','=',$roomVo['warehouse']],['goods','=',$roomVo['goods']],['attr','=',$roomVo['attr']]])->find();
+ if(empty($roomFind)){
+ $roomVo['nums']=0;
+ $roomInsert[]=$roomVo;
+ }
+ }
+ //2 创建数据|去重
+ empty($roomInsert)||Db::name('room')->insertAll(array_unique($roomInsert,SORT_REGULAR));
+ //3 匹配主键|构造更新
+ $roomDuplicate=[];
+ $room=Db::name('room')->whereOr($roomWhereOrSql)->select()->toArray();
+ foreach ($store['room'] as $roomKey=>$roomVo) {
+ $roomFind=search($room)->where([['warehouse','=',$roomVo['warehouse']],['goods','=',$roomVo['goods']],['attr','=',$roomVo['attr']]])->find();
+ $store['room'][$roomKey]['id']=$roomFind['id'];
+ $roomDuplicate[]=['id'=>$roomFind['id'],'nums'=>$roomVo['nums']];
+ }
+ //4 更新数据
+ Db::name('room')->duplicate(['nums'=>Db::raw('nums - VALUES(`nums`)')])->insertAll($roomDuplicate);
+ }
+ //4 仓储详情
+ if(!empty($store['roomInfo'])){
+ //1 填充数据
+ foreach ($store['roomInfo'] as $roomInfoKey=>$roomInfoVo) {
+ $store['roomInfo'][$roomInfoKey]['pid']=$store['room'][$roomInfoKey]['id'];
+ }
+ //2 创建数据
+ Db::name('room_info')->insertAll($store['roomInfo']);
+ }
+ //5 批次号
+ if(!empty($store['batch'])){
+ //1 构造数据
+ $batchData=[];
+ foreach ($store['batch'] as $batchKey=>$batchVo) {
+ if(!empty($batchVo)){
+ $store['batch'][$batchKey]['room']=$store['room'][$batchKey]['id'];
+ $batchData[]=$store['batch'][$batchKey];
+ }
+ }
+ //2 排除数据|[[],[],[]]
+ if(!empty($batchData)){
+ //1 构造数据
+ $batchInsert=[];
+ foreach ($batchData as $batchDataKey=>$batchDataVo) {
+ $batchFind=search($batchList)->where([['room','=',$batchDataVo['room']],['number','=',$batchDataVo['number']],['time','=',$batchDataVo['time']]])->find();
+ if(empty($batchFind)){
+ $batchDataVo['nums']=0;
+ $batchInsert[]=$batchDataVo;
+ }
+ }
+ //2 创建数据|去重
+ empty($batchInsert)||Db::name('batch')->insertAll(array_unique($batchInsert,SORT_REGULAR));
+ //3 匹配主键|构造更新
+ $batchDuplicate=[];
+ $batch=Db::name('batch')->where([['number','in',$batchGather]])->select()->toArray();
+ foreach ($store['batch'] as $batchKey=>$batchVo) {
+ if(!empty($batchVo)){
+ $batchFind=search($batch)->where([['room','=',$batchVo['room']],['number','=',$batchVo['number']],['time','=',$batchVo['time']]])->find();
+ $store['batch'][$batchKey]['id']=$batchFind['id'];
+ $batchDuplicate[]=['id'=>$batchFind['id'],'nums'=>$batchVo['nums']];
+ }
+ }
+ //4 更新数据
+ Db::name('batch')->duplicate(['nums'=>Db::raw('nums - VALUES(`nums`)')])->insertAll($batchDuplicate);
+ }
+ }
+ //6 批次号详情
+ if(!empty($store['batchInfo'])){
+ //1 构造数据
+ $batchInfoInstall=[];
+ foreach ($store['batchInfo'] as $batchInfoKey=>$batchInfoVo) {
+ if(!empty($batchInfoVo)){
+ $batchInfoVo['pid']=$store['batch'][$batchInfoKey]['id'];
+ $batchInfoInstall[]=$batchInfoVo;
+ }
+ }
+ //2 排除数据|[[],[],[]]
+ if(!empty($batchInfoInstall)){
+ //创建数据
+ Db::name('batch_info')->insertAll($batchInfoInstall);
+ }
+ }
+ //7 序列号
+ if(!empty($store['serial'])){
+ //1 构造数据
+ $serialData=[];
+ foreach ($store['serial'] as $serialKey=>$item) {
+ if(!empty($item)){
+ foreach ($item as $itemKey=>$itemVo) {
+ $store['serial'][$serialKey][$itemKey]['room']=$store['room'][$serialKey]['id'];
+ $store['serial'][$serialKey][$itemKey]['batch']=empty($store['batch'][$serialKey])?0:$store['batch'][$serialKey]['id'];
+ $serialData[]=$store['serial'][$serialKey][$itemKey];
+ }
+ }
+ }
+ //2 排除数据|[[],[],[]]
+ if(!empty($serialData)){
+ //1 构造数据
+ $serialInsert=[];
+ foreach ($serialData as $serialDataKey=>$serialDataVo) {
+ $serialFind=search($serialList)->where([['room','=',$serialDataVo['room']],['batch','=',$serialDataVo['batch']],['number','=',$serialDataVo['number']]])->find();
+ if(empty($serialFind)){
+ $serialInsert[]=$serialDataVo;
+ }
+ }
+ //2 创建数据
+ empty($serialInsert)||Db::name('serial')->insertAll($serialInsert);
+ //3 匹配主键|构造更新
+ $serialDuplicate=[];
+ $serial=Db::name('serial')->where([['number','in',$serialGather]])->select()->toArray();
+ foreach ($store['serial'] as $serialKey=>$item) {
+ if(!empty($item)){
+ foreach ($item as $itemKey=>$itemVo) {
+ $serialFind=search($serial)->where([['room','=',$itemVo['room']],['batch','=',$itemVo['batch']],['number','=',$itemVo['number']]])->find();
+ $store['serial'][$serialKey][$itemKey]['id']=$serialFind['id'];
+ $serialFind['state']==0&&$serialDuplicate[]=$serialFind['id'];
+ }
+ }
+ }
+ //4 更新数据|状态变更
+ empty($serialDuplicate)||Db::name('serial')->where([['id','in',$serialDuplicate]])->update(['state'=>1]);
+ }
+ }
+ //8 序列号详情
+ if(!empty($store['serialInfo'])){
+ //1 构造数据
+ $serialInfoInstall=[];
+ foreach ($store['serialInfo'] as $serialInfoKey=>$item) {
+ if(!empty($item)){
+ foreach ($item as $itemKey=>$itemVo) {
+ $itemVo['pid']=$store['serial'][$serialInfoKey][$itemKey]['id'];
+ $serialInfoInstall[]=$itemVo;
+ }
+ }
+ }
+ //2 排除数据|[[],[],[]]
+ if(!empty($serialInfoInstall)){
+ //创建数据
+ Db::name('serial_info')->insertAll($serialInfoInstall);
+ }
+ }
+ //9 服务商品
+ if(!empty($store['serve'])){
+ //1 匹配数据|去重
+ $serveWhereOrSql=array_unique(array_map(function($item){
+ return [['goods','=',$item['goods']],['attr','=',$item['attr']]];
+ },$store['serve']),SORT_REGULAR);
+ $serve=Db::name('serve')->whereOr($serveWhereOrSql)->select()->toArray();
+ //2 构造数据
+ $serveInsert=[];
+ foreach ($store['serve'] as $serveVo) {
+ $serveFind=search($serve)->where([['goods','=',$serveVo['goods']],['attr','=',$serveVo['attr']]])->find();
+ if(empty($serveFind)){
+ $serveVo['nums']=0;
+ $serveInsert[]=$serveVo;
+ }
+ }
+ //3 创建数据|去重
+ empty($serveInsert)||Db::name('serve')->insertAll(array_unique($serveInsert,SORT_REGULAR));
+ //4 匹配主键|构造更新
+ $serveDuplicate=[];
+ $serve=Db::name('serve')->whereOr($serveWhereOrSql)->select()->toArray();
+ foreach ($store['serve'] as $serveKey=>$serveVo) {
+ $serveFind=search($serve)->where([['goods','=',$serveVo['goods']],['attr','=',$serveVo['attr']]])->find();
+ $store['serve'][$serveKey]['id']=$serveFind['id'];
+ $serveDuplicate[]=['id'=>$serveFind['id'],'nums'=>$serveVo['nums']];
+ }
+ //5 更新数据
+ Db::name('serve')->duplicate(['nums'=>Db::raw('nums + VALUES(`nums`)')])->insertAll($serveDuplicate);
+ }
+ //10 服务商品详情
+ if(!empty($store['serveInfo'])){
+ //1 填充数据
+ foreach ($store['serveInfo'] as $serveInfoKey=>$serveInfoVo) {
+ $store['serveInfo'][$serveInfoKey]['pid']=$store['serve'][$serveInfoKey]['id'];
+ }
+ //2 创建数据
+ Db::name('serve_info')->insertAll($store['serveInfo']);
+ }
+ //11 资金|核销
+ if(!empty($class['money'])){
+ //1 更新资金账户
+ Db::name('account')->where([['id','=',$class['account']]])->inc('balance',$class['money'])->update();
+ //2 创建资金详情
+ Db::name('account_info')->insert([
+ 'pid'=>$class['account'],
+ 'type'=>'sell',
+ 'class'=>$class['id'],
+ 'time'=>$class['time'],
+ 'direction'=>1,
+ 'money'=>$class['money']
+ ]);
+ //3 创建核销记录
+ Db::name('sell_bill')->insert([
+ 'pid'=>$class['id'],
+ 'type'=>'sell',
+ 'source'=>$class['id'],
+ 'time'=>$class['time'],
+ 'money'=>$class['money']
+ ]);
+ }
+ //12 客户|应收款余额
+ $balance=math()->chain($class['actual'])->sub($class['money'])->done();
+ if(!empty($balance)){
+ Db::name('customer')->where([['id','=',$class['customer']]])->inc('balance',$balance)->update();
+ }
+ //13 更新单据
+ $nucleus=$class['money']==$class['actual']?2:($class['money']==0?0:1);
+ Db::name('sell')->where([['id','=',$class['id']]])->update(['examine'=>1,'nucleus'=>$nucleus]);
+ //14 单据记录
+ Db::name('record')->insert(['type'=>'sell','source'=>$class['id'],'time'=>time(),'user'=>getUserID(),'info'=>'审核单据']);
+ //15 收发记录
+ $summary=new Summary;
+ $summary->note('sell',$class['id'],true);
+ //16 记录操作
+ pushLog('审核销售单[ '.$class['number'].' ]');//单据日志
+ }else{
+ //反审核
+ //1 匹配数据
+ $listSql=[['type','=','sell'],['info','in',array_column($info,'id')]];
+ $roomInfoList=Db::name('room_info')->where($listSql)->select()->toArray();
+ $batchInfoList=Db::name('batch_info')->where($listSql)->select()->toArray();
+ $serialInfoList=Db::name('serial_info')->where($listSql)->select()->toArray();
+ $serveInfoList=Db::name('serve_info')->where($listSql)->select()->toArray();
+ //2 关联单据
+ if(!empty($class['source'])){
+ //1 更新详情
+ $sorInfoDuplicate=[];
+ foreach ($info as $infoVo) {
+ empty($infoVo['source'])||$sorInfoDuplicate[]=['id'=>$infoVo['source'],'handle'=>$infoVo['nums']];
+ }
+ empty($sorInfoDuplicate)||Db::name('sor_info')->duplicate(['handle'=>Db::raw('handle - VALUES(`handle`)')])->insertAll($sorInfoDuplicate);
+ //2 更新CALSS
+ $sorInfo=Db::name('sor_info')->where([['pid','=',$class['source']]])->select()->toArray();
+ $state=empty(mathArraySum(array_column($sorInfo,'handle')))?0:1;
+ Db::name('sor')->where([['id','=',$class['source']]])->update(['state'=>$state]);
+ }
+ //3 仓储
+ $roomDuplicate=[];
+ foreach ($roomInfoList as $roomInfoVo) {
+ $roomDuplicate[]=['id'=>$roomInfoVo['pid'],'nums'=>$roomInfoVo['nums']];
+ }
+ //3.1 更新仓储
+ Db::name('room')->duplicate(['nums'=>Db::raw('nums + VALUES(`nums`)')])->insertAll($roomDuplicate);
+ //3.2 删除仓储详情
+ Db::name('room_info')->where([['id','in',array_column($roomInfoList,'id')]])->delete();
+ //3.3 仓储|冗余
+ $roomPk=array_unique(array_column($roomInfoList,'pid'));
+ $roomInfoData=Db::name('room_info')->where([['pid','in',$roomPk]])->select()->toArray();
+ $roomDiff=array_diff($roomPk,array_unique(array_column($roomInfoData,'pid')));
+ empty($roomDiff)||Db::name('room')->where([['id','in',$roomDiff]])->delete();
+ //4 批次号
+ if(!empty($batchInfoList)){
+ //1 构造数据
+ $batchInfoDuplicate=array_map(function($item){
+ return ['id'=>$item['pid'],'nums'=>$item['nums']];
+ },$batchInfoList);
+ //2 更新批次号
+ Db::name('batch')->duplicate(['nums'=>Db::raw('nums + VALUES(`nums`)')])->insertAll($batchInfoDuplicate);
+ //3 删除批次号详情
+ Db::name('batch_info')->where([['id','in',array_column($batchInfoList,'id')]])->delete();
+ //4 批次号|冗余
+ $batchPk=array_unique(array_column($batchInfoList,'pid'));
+ $batchInfoData=Db::name('batch_info')->where([['pid','in',$batchPk]])->select()->toArray();
+ $batchDiff=array_diff($batchPk,array_unique(array_column($batchInfoData,'pid')));
+ empty($batchDiff)||Db::name('batch')->where([['id','in',$batchDiff]])->delete();
+ }
+ //5 序列号
+ if(!empty($serialInfoList)){
+ //1 更新序列号
+ Db::name('serial')->where([['id','in',array_column($serialInfoList,'pid')]])->update(['state'=>0]);
+ //2 删除序列号详情
+ Db::name('serial_info')->where([['id','in',array_column($serialInfoList,'id')]])->delete();
+ //3 序列号|冗余
+ $serialPk=array_unique(array_column($serialInfoList,'pid'));
+ $serialInfoData=Db::name('serial_info')->where([['pid','in',$serialPk]])->select()->toArray();
+ $serialDiff=array_diff($serialPk,array_unique(array_column($serialInfoData,'pid')));
+ empty($serialDiff)||Db::name('serial')->where([['id','in',$serialDiff]])->delete();
+ }
+ //6 服务
+ if(!empty($serveInfoList)){
+ //1 构造数据
+ $serveInfoDuplicate=array_map(function($item){
+ return ['id'=>$item['pid'],'nums'=>$item['nums']];
+ },$serveInfoList);
+ //2 更新服务
+ Db::name('serve')->duplicate(['nums'=>Db::raw('nums - VALUES(`nums`)')])->insertAll($serveInfoDuplicate);
+ //3 删除服务详情
+ Db::name('serve_info')->where([['id','in',array_column($serveInfoList,'id')]])->delete();
+ //4 服务|冗余
+ $servePk=array_unique(array_column($serveInfoList,'pid'));
+ $serveInfoData=Db::name('serve_info')->where([['pid','in',$servePk]])->select()->toArray();
+ $serveDiff=array_diff($servePk,array_unique(array_column($serveInfoData,'pid')));
+ empty($serveDiff)||Db::name('serve')->where([['id','in',$serveDiff]])->delete();
+ }
+ //7 资金|核销
+ if(!empty($class['money'])){
+ //1 更新资金账户
+ Db::name('account')->where([['id','=',$class['account']]])->dec('balance',$class['money'])->update();
+ //2 删除资金详情
+ Db::name('account_info')->where([['type','=','sell'],['class','=',$class['id']]])->delete();
+ //3 删除核销记录
+ Db::name('sell_bill')->where([['pid','=',$class['id']]])->delete();
+ }
+ //8 客户|应收款余额
+ $balance=math()->chain($class['actual'])->sub($class['money'])->done();
+ if(!empty($balance)){
+ Db::name('customer')->where([['id','=',$class['customer']]])->dec('balance',$balance)->update();
+ }
+ //9 更新单据
+ Db::name('sell')->where([['id','=',$class['id']]])->update(['examine'=>0,'nucleus'=>0]);
+ //10 单据记录
+ Db::name('record')->insert(['type'=>'sell','source'=>$class['id'],'time'=>time(),'user'=>getUserID(),'info'=>'反审核单据']);
+ //11 收发记录
+ $summary=new Summary;
+ $summary->note('sell',$class['id'],false);
+ //12 记录操作
+ pushLog('反审核销售单[ '.$class['number'].' ]');//单据日志
+ }
+
+ Db::commit();
+ } catch (\Exception $e) {
+ Db::rollback();
+ return json(['state'=>'error','info'=>'内部错误,操作已撤销!']);
+ exit;
+ }
+ }
+ $result=['state'=>'success'];
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //上传
+ public function upload(){
+ $file = request()->file('file');
+ //获取上传文件
+ if (empty($file)) {
+ $result = ['state' => 'error','info' => '传入数据不完整!'];
+ } else {
+ //文件限制5MB
+ try{
+ validate(['file'=>['fileSize'=>5*1024*1024,'fileExt'=>'png,gif,jpg,jpeg,txt,doc,docx,rtf,xls,xlsx,ppt,pptx,pdf,zip,rar']])->check(['file'=>$file]);
+ $fileInfo=Filesystem::disk('upload')->putFile('sell', $file, 'uniqid');
+ $filePath=request()->domain().'/static/upload/'.$fileInfo;
+ $result=['state'=>'success','info'=>$filePath];
+ }catch(ValidateException $e) {
+ $result = ['state' => 'error','info' => $e->getMessage()];
+ }
+ }
+ return json($result);
+ }
+ //生成销售退货单
+ public function buildSre(){
+ $input=input('post.');
+ if(existFull($input,['id'])){
+ //源数据
+ $source=[
+ 'class'=>Sells::where([['id','=',$input['id']]])->find(),
+ 'info'=>SellInfo::with(['goodsData','warehouseData'])->where([['pid','=',$input['id']]])->order(['id'=>'asc'])->select()->toArray()
+ ];
+ //状态验证
+ if(mathArraySum(array_column($source['info'],'nums'))==mathArraySum(array_column($source['info'],'retreat'))){
+ $result=['state'=>'warning','info'=>'操作失败,无可生成的数据!'];
+ }else{
+ //CLASS数据
+ $class=[
+ 'source'=>$source['class']['id'],
+ 'customer'=>$source['class']['customer'],
+ 'total'=>0
+ ];
+ //INFO数据
+ $info=[];
+ $fun=getSys('fun');
+ foreach ($source['info'] as $infoVo) {
+ //判断入库状态
+ if(bccomp($infoVo['nums'],$infoVo['retreat'])==1){
+ $infoVo['source']=$infoVo['id'];
+ $infoVo['serial']=[];
+ //重算价格
+ $infoVo['nums']=math()->chain($infoVo['nums'])->sub($infoVo['retreat'])->done();
+ $storage=math()->chain($infoVo['price'])->mul($infoVo['nums'])->round($fun['digit']['money'])->done();
+ //折扣额|金额
+ if($infoVo['discount']==0){
+ $infoVo['total']=$storage;
+ }else{
+ $infoVo['dsc']=math()->chain($storage)->div(100)->mul($infoVo['discount'])->round($fun['digit']['money'])->done();
+ $infoVo['total']=math()->chain($storage)->sub($infoVo['dsc'])->done();
+ }
+ //税额|价税合计
+ if($infoVo['tax']==0){
+ $infoVo['tpt']=$infoVo['total'];
+ }else{
+ $infoVo['tat']=math()->chain($infoVo['total'])->div(100)->mul($infoVo['tax'])->round(2)->done();
+ $infoVo['tpt']=math()->chain($infoVo['total'])->add($infoVo['tat'])->done();
+ }
+ //转存数据
+ $info[]=$infoVo;
+ $class['total']=math()->chain($class['total'])->add($infoVo['tpt'])->done();//累加单据金额
+ }
+ }
+ $result=['state'=>'success','info'=>['class'=>$class,'info'=>$info]];
+ }
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //导入
+ public function import(){
+ delOverdueFile('static.upload.xlsx');//删除过期文件
+ $file=request()->file('file');//获取上传文件
+ if(empty($file)){
+ $result=['state'=>'error','info'=>'传入数据不完整!'];
+ }else{
+ $fun=getSys('fun');
+ try{
+ validate(['file'=>['fileSize'=>2*1024*1024,'fileExt'=>'xlsx']])->check(['file'=>$file]);
+ $fileInfo = Filesystem::disk('upload')->putFile('xlsx', $file, 'uniqid');
+ $filePath = pathChange('static.upload').$fileInfo;
+ $data=getXlsx($filePath);
+ unset($data[1]);//删除标题行
+ unset($data[2]);//删除列名行
+ //初始化CLASS
+ //客户匹配
+ $customer=Db::name('customer')->where([['name','=',$data[3]['A']]])->find();
+ if(empty($customer)){
+ throw new ValidateException('客户[ '.$data[3]['A'].' ]未匹配!');
+ }
+ //结算账户匹配
+ if(empty($data[3]['F'])){
+ $account=['id'=>0];
+ }else{
+ $account=Db::name('account')->where([['name','=',$data[3]['G']]])->find();
+ if(empty($account)){
+ throw new ValidateException('结算账户[ '.$data[3]['G'].' ]不正确!');
+ }
+ }
+ //关联人员匹配
+ if(empty($data[3]['H'])){
+ $people=['id'=>0];
+ }else{
+ $people=Db::name('people')->where([['name','=',$data[3]['H']]])->find();
+ if(empty($people)){
+ throw new ValidateException('关联人员[ '.$data[3]['H'].' ]未匹配!');
+ }
+ }
+ $class=[
+ 'source'=>0,
+ 'frame'=>userInfo(getUserID(),'frame'),
+ 'customer'=>$customer['id'],
+ 'time'=>$data[3]['B'],
+ 'number'=>$data[3]['C'],
+ 'total'=>0,
+ 'actual'=>$data[3]['E'],
+ 'money'=>$data[3]['F'],
+ 'account'=>$account['id'],
+ 'people'=>$people['id'],
+ 'logistics'=>["key"=>"auto","name"=>"自动识别","number"=>$data[3]['I']],
+ 'file'=>[],
+ 'data'=>$data[3]['J'],
+ 'more'=>[],
+ 'examine'=>0,
+ 'nucleus'=>0,
+ 'cse'=>0,
+ 'invoice'=>0,
+ 'check'=>0,
+ 'user'=>getUserID()
+ ];
+ $this->validate($class,'app\validate\Sell');//数据合法性验证
+ //初始化INFO
+ $info=[];
+ $goods=Goods::with(['attr'])->where([['name','in',array_column($data,'K')]])->select()->toArray();
+ $warehouse=Db::name('warehouse')->where([['name','in',array_column($data,'N')]])->select()->toArray();
+ foreach ($data as $dataKey=>$dataVo) {
+ $record=[
+ 'source'=>0,
+ 'goods'=>$dataVo['K'],
+ 'attr'=>$dataVo['L'],
+ 'unit'=>$dataVo['M'],
+ 'warehouse'=>$dataVo['N'],
+ 'batch'=>$dataVo['O'],
+ 'mfd'=>$dataVo['P'],
+ 'price'=>$dataVo['Q'],
+ 'nums'=>$dataVo['R'],
+ 'serial'=>explode(',',$dataVo['S']),
+ 'discount'=>$dataVo['T'],
+ 'dsc'=>0,
+ 'total'=>0,
+ 'tax'=>$dataVo['W'],
+ 'tat'=>0,
+ 'tpt'=>0,
+ 'data'=>$dataVo['Z'],
+ 'retreat'=>0,
+ ];
+ //商品匹配
+ $goodsFind=search($goods)->where([['name','=',$record['goods']]])->find();
+ if(empty($goodsFind)){
+ throw new ValidateException('模板文件第'.$dataKey.'行商品名称[ '.$record['goods'].' ]未匹配!');
+ }else{
+ $record['goods']=$goodsFind['id'];
+ }
+ //辅助属性匹配
+ if(empty($goodsFind['attr'])){
+ $record['attr']='';
+ }else{
+ if(empty($record['attr'])){
+ throw new ValidateException('模板文件第'.$dataKey.'行辅助属性不可为空!');
+ }else{
+ $attrFind=search($goodsFind['attr'])->where([['name','=',$record['attr']]])->find();
+ if(empty($attrFind)){
+ throw new ValidateException('模板文件第'.$dataKey.'行辅助属性[ '.$record['attr'].' ]未匹配!');
+ }
+ }
+ }
+ //单位匹配
+ if($goodsFind['unit']==-1){
+ if(empty($record['unit'])){
+ throw new ValidateException('模板文件第'.$dataKey.'行单位不可为空!');
+ }else{
+ $unitFind=search($goodsFind['units'])->where([['name','=',$record['unit']]])->find();
+ if(empty($unitFind) && $goodsFind['units'][0]['source']!=$record['unit']){
+ throw new ValidateException('模板文件第'.$dataKey.'行单位[ '.$record['unit'].' ]未匹配!');
+ }
+ }
+ }else{
+ $record['unit']=$goodsFind['unit'];
+ }
+ //仓库匹配
+ if(empty($goodsFind['type'])){
+ //常规产品
+ $warehouseFind=search($warehouse)->where([['name','=',$record['warehouse']]])->find();
+ if(empty($warehouseFind)){
+ throw new ValidateException('模板文件第'.$dataKey.'行仓库[ '.$record['warehouse'].' ]未匹配!');
+ }else{
+ $record['warehouse']=$warehouseFind['id'];
+ }
+ }else{
+ //服务产品
+ $record['warehouse']=null;
+ }
+ //批次号匹配
+ if(empty($goodsFind['batch'])){
+ $record['batch']='';
+ }else{
+ if(empty($record['batch'])){
+ throw new ValidateException('模板文件第'.$dataKey.'行批次号不可为空!');
+ }
+ }
+ //生产日期匹配
+ if(empty($goodsFind['validity'])){
+ $record['mfd']='';
+ }else{
+ if(empty($record['mfd'])){
+ throw new ValidateException('模板文件第'.$dataKey.'行生产日期不可为空!');
+ }
+ }
+ //单价匹配
+ if(!preg_match("/^\d+(\.\d{0,".$fun['digit']['money']."})?$/",$record['price'])){
+ throw new ValidateException('模板文件第'.$dataKey.'行单价不正确!');
+ }
+ //数量匹配
+ if(!preg_match("/^\d+(\.\d{0,".$fun['digit']['nums']."})?$/",$record['nums'])){
+ throw new ValidateException('模板文件第'.$dataKey.'行数量不正确!');
+ }
+ //序列号匹配
+ if(empty($goodsFind['serial'])){
+ $record['serial']=[];
+ }else{
+ if(count($record['serial'])==1 && empty($record['serial'][0])){
+ throw new ValidateException('模板文件第'.$dataKey.'行序列号不可为空!');
+ }else{
+ if(count($record['serial'])!=$record['nums']){
+ throw new ValidateException('模板文件第'.$dataKey.'行序列号个数与数量不符!');
+ }
+ }
+ }
+ try{
+ $this->validate($record,'app\validate\SellInfo');//数据合法性验证
+ $storage=math()->chain($record['price'])->mul($record['nums'])->round($fun['digit']['money'])->done();
+ //折扣额|金额
+ if($record['discount']==0){
+ $record['total']=$storage;
+ }else{
+ $record['dsc']=math()->chain($storage)->div(100)->mul($record['discount'])->round($fun['digit']['money'])->done();
+ $record['total']=math()->chain($storage)->sub($record['dsc'])->done();
+ }
+ //税额|价税合计
+ if($record['tax']==0){
+ $record['tpt']=$record['total'];
+ }else{
+ $record['tat']=math()->chain($record['total'])->div(100)->mul($record['tax'])->round(2)->done();
+ $record['tpt']=math()->chain($record['total'])->add($record['tat'])->done();
+ }
+ //转存数据
+ $class['total']=math()->chain($class['total'])->add($record['tpt'])->done();//累加单据金额
+ $info[]=$record;
+ } catch (ValidateException $e) {
+ return json(['state'=>'error','info'=>'模板文件第'.$dataKey.'行'.$e->getMessage()]);//返回错误信息
+ exit;
+ }
+ }
+ //序列号重复验证
+ $serials=[];
+ foreach ($info as $infoVo) {
+ $serials = array_merge($serials,$infoVo['serial']);
+ }
+ if(count($serials)!=count(array_unique($serials))){
+ throw new ValidateException('商品信息中存在重复序列号!');
+ }
+ //CLASS数据验证
+ if(bccomp($class['total'],$class['actual'])==-1){
+ throw new ValidateException('实际金额不可大于单据金额[ '.$class['total'].' ]!');
+ }else if(bccomp($class['actual'],$class['money'])==-1){
+ throw new ValidateException('实收金额不可大于实际金额[ '.floatval($class['actual']).' ]!');
+ }else{
+ Db::startTrans();
+ try {
+ //新增CLASS
+ $classData=Sells::create($class);
+ //新增INFO
+ foreach ($info as $infoKey=>$infoVo) {
+ $info[$infoKey]['pid']=$classData['id'];
+ }
+ $model = new SellInfo;
+ $model->saveAll($info);
+ Db::name('record')->insert(['type'=>'sell','source'=>$classData['id'],'time'=>time(),'user'=>getUserID(),'info'=>'导入单据']);
+ pushLog('导入销售单[ '.$classData['number'].' ]');//日志
+
+ Db::commit();
+ $result=['state'=>'success'];
+ } catch (\Exception $e) {
+ Db::rollback();
+ $result=['state'=>'error','info'=>'内部错误,操作已撤销!'];
+ }
+ }
+ }catch(ValidateException $e) {
+ $result=['state'=>'error','info'=>$e->getMessage()];//返回错误信息
+ }
+ }
+ return json($result);
+ }
+ //导出
+ public function exports(){
+ $input=input('get.');
+ if(existFull($input,['scene','parm']) && is_array($input['parm'])){
+ pushLog('导出销售单列表');//日志
+ $source=Sells::with(['frameData','customerData','accountData','peopleData','userData'])->where([['id','in',$input['parm']]])->append(['extension'])->order(['id'=>'desc'])->select()->toArray();//查询CLASS数据
+ if($input['scene']=='simple'){
+ //简易报表
+ //开始构造导出数据
+ $excel=[];//初始化导出数据
+ //标题数据
+ $excel[]=['type'=>'title','info'=>'销售单列表'];
+ //表格数据
+ $field=[
+ 'frameData|name'=>'所属组织',
+ 'customerData|name'=>'客户',
+ 'time'=>'单据时间',
+ 'number'=>'单据编号',
+ 'total'=>'单据金额',
+ 'actual'=>'实际金额',
+ 'money'=>'单据收款',
+ 'extension|amount'=>'核销金额',
+ 'cost'=>'单据费用',
+ 'peopleData|name'=>'关联人员',
+ 'extension|examine'=>'审核状态',
+ 'extension|nucleus'=>'核销状态',
+ 'extension|cse'=>'费用状态',
+ 'extension|invoice'=>'发票状态',
+ 'extension|check'=>'核对状态',
+ 'userData|name'=>'制单人',
+ 'data'=>'备注信息'
+ ];
+ $thead=array_values($field);//表格标题
+ $tbody=[];//表格内容
+ //构造表内数据
+ foreach ($source as $sourceVo) {
+ $rowData=[];
+ foreach (array_keys($field) as $fieldVo) {
+ $rowData[]=arraySeek($sourceVo,$fieldVo);//多键名数据赋值
+ }
+ $tbody[]=$rowData;//加入行数据
+ }
+ $excel[]=['type'=>'table','info'=>['thead'=>$thead,'tbody'=>$tbody]];//表格数据
+ //统计数据
+ $excel[]=['type'=>'node','info'=>[
+ '总数:'.count($source),
+ '总单据金额:'.mathArraySum(array_column($source,'total')),
+ '总实际金额:'.mathArraySum(array_column($source,'actual')),
+ '总单据收款:'.mathArraySum(array_column($source,'money')),
+ '总核销金额:'.mathArraySum(arrayColumns($source,['extension','amount'])),
+ '总单据费用:'.mathArraySum(array_column($source,'cost'))
+ ]];
+ //导出execl
+ buildExcel('销售单列表',$excel);
+ }else{
+ //详细报表
+ $files=[];//初始化文件列表
+ foreach ($source as $sourceVo) {
+ //开始构造导出数据
+ $excel=[];//初始化导出数据
+ //标题数据
+ $excel[]=['type'=>'title','info'=>'销售单'];
+ //节点数据
+ $excel[]=['type'=>'node','info'=>[
+ '客户:'.$sourceVo['customerData']['name'],
+ '单据日期:'.$sourceVo['time'],
+ '单据编号:'.$sourceVo['number']]
+ ];
+ //表格数据
+ $field=[
+ 'goodsData|name'=>'商品名称',
+ 'goodsData|spec'=>'规格型号',
+ 'attr'=>'辅助属性',
+ 'unit'=>'单位',
+ 'warehouseData|name'=>'仓库',
+ 'batch'=>'批次号',
+ 'mfd'=>'生产日期',
+ 'price'=>'单价',
+ 'nums'=>'数量',
+ 'extension|serial'=>'序列号',
+ 'retreat'=>'退货数量',
+ 'discount'=>'折扣率',
+ 'dsc'=>'折扣额',
+ 'total'=>'金额',
+ 'tax'=>'税率',
+ 'tat'=>'税额',
+ 'tpt'=>'价税合计',
+ 'data'=>'备注信息'
+ ];
+ //构造表内数据
+ $info=SellInfo::with(['goodsData','warehouseData'])->where([['pid','=',$sourceVo['id']]])->order(['id'=>'asc'])->append(['extension'])->select()->toArray();
+ //批次号匹配
+ if(empty(search($info)->where([['goodsData|batch','=',true]])->find())){
+ unset($field['batch']);
+ }
+ //生产日期匹配
+ if(empty(search($info)->where([['goodsData|validity','=',true]])->find())){
+ unset($field['mfd']);
+ }
+ //序列号匹配
+ if(empty(search($info)->where([['goodsData|serial','=',true]])->find())){
+ unset($field['extension|serial']);
+ }
+ //退货数量匹配
+ if(empty(search($info)->where([['retreat','<>',0]])->find())){
+ unset($field['retreat']);
+ }
+ //税金匹配
+ $fun=getSys('fun');
+ if(empty(search($info)->where([['tax','<>',0]])->find()) && !$fun['tax']){
+ unset($field['tax']);
+ unset($field['tat']);
+ unset($field['tpt']);
+ }
+ $thead=array_values($field);//表格标题
+ $tbody=[];//表格内容
+ foreach ($info as $infoVo) {
+ $rowData=[];
+ foreach (array_keys($field) as $fieldVo) {
+ $rowData[]=arraySeek($infoVo,$fieldVo);//多键名数据赋值
+ }
+ $tbody[]=$rowData;//加入行数据
+ }
+ $excel[]=['type'=>'table','info'=>['thead'=>$thead,'tbody'=>$tbody]];//表格数据
+ //节点数据
+ $excel[]=['type'=>'node','info'=>[
+ '单据金额:'.$sourceVo['total'],
+ '单据费用:'.$sourceVo['cost'],
+ '实际金额:'.$sourceVo['actual'],
+ '核销金额:'.$sourceVo['extension']['amount'],
+ '结算账户:'.arraySeek($sourceVo,'accountData|name'),
+ '发票信息:'.$sourceVo['invoice'],
+ '关联人员:'.arraySeek($sourceVo,'peopleData|name'),
+ '物流信息:'.$sourceVo['extension']['logistics'],
+ '备注信息:'.$sourceVo['data']]
+ ];
+ //生成execl
+ $files[]=buildExcel($sourceVo['number'],$excel,false);
+
+ }
+ buildZip('销售单_'.time(),$files);
+ }
+ }else{
+ return json(['state'=>'error','info'=>'传入数据不完整!']);
+ }
+ }
+}
\ No newline at end of file
diff --git a/serve/app/controller/Serial.php b/serve/app/controller/Serial.php
new file mode 100644
index 0000000..5995408
--- /dev/null
+++ b/serve/app/controller/Serial.php
@@ -0,0 +1,450 @@
+where(empty($input['warehouse'])?sqlAuth('warehouse',[]):[['id','in',$input['warehouse']]])->select()->toArray();
+ //匹配商品
+ $sql=fastSql($input,[
+ [['name'=>'name|py'],'fullLike'],
+ ['number','fullLike'],
+ ['spec','fullLike'],
+ ['brand','fullEq'],
+ ['code','fullLike']
+ ]);//构造SQL
+ //商品类型
+ $sql[]=['type','=',0];
+ //辅助属性扩展查询
+ $sqlOr=existFull($input,['code'])?[['id','in',array_column(Db::name('attr')->where([['code','=',$input['code']]])->select()->toArray(),'pid')]]:[];
+ //商品分类树结构查询
+ existFull($input,['category'])&&$sql[]=['category','in',findTreeArr('category',$input['category'],'id')];
+ //批次查询
+ $serialSql=fastSql($input,[
+ [['serial'=>'number'],'fullLike'],
+ ['state','fullDec1']
+ ]);//构造SQL
+ $serialSql[]=['warehouse','in',array_column($warehouse,'id')];
+ //查询操作
+ if(existFull($input,['batch'])){
+ $exists=Db::name('batch')->where([['number','like','%'.$input['batch'].'%'],['id','=',Db::raw('serial.batch')]])->buildSql(false);
+ $serial=Db::name('serial')->where($serialSql)->alias('serial')->whereExists($exists)->select()->toArray();
+ }else{
+ $serial=Db::name('serial')->where($serialSql)->select()->toArray();
+ }
+ //查询商品
+ $sql[]=['id','in',array_column($serial,'goods')];
+ //获取总条数
+ $count = Goods::where($sql)->whereOr($sqlOr)->count();
+ //查询分页数据
+ $info = Goods::with(['categoryData','attr'])->where($sql)->whereOr($sqlOr)->order(['id'=>'desc'])->page($input['page'],$input['limit'])->append(['extension'])->select()->toArray();
+ //唯一标识|属性处理
+ foreach ($info as $infoKey=>$infoVo) {
+ $info[$infoKey]['key']=$infoVo['id'];
+ foreach ($infoVo['attr'] as $attrKey=>$attrVo) {
+ $info[$infoKey]['attr'][$attrKey]['key']=$infoVo['id'].'.'.$attrVo['id'];
+ //属性处理
+ if(existFull($input,['code']) && !in_array($input['code'],[$infoVo['code'],$attrVo['code']])){
+ unset($info[$infoKey]['attr'][$attrKey]);
+ }
+ }
+ //重建索引
+ $info[$infoKey]['attr']=array_values($info[$infoKey]['attr']);
+ }
+ //库存集合[g:商品|a:属性]
+ $gather=['g'=>[],'ga'=>[]];
+ //二次匹配
+ $serial=search($serial)->where([['goods','in',array_column($info,'id')]])->select();
+ //查询库存数据-仓储
+ $room=Db::name('room')->where([['id','in',array_unique(array_column($serial,'room'))]])->select()->toArray();
+ //构造序列数据
+ foreach ($serial as $serialKey=>$serialVo) {
+ //商品
+ $g=md5_16($serialVo['goods']);
+ $gather['g'][$g]=math()->chain($gather['g'][$g]??0)->add(1)->done();
+ //判断属性
+ $find=search($room)->where([['id','=',$serialVo['room']]])->find();
+ if(empty($find['attr'])){
+ $serial[$serialKey]['attr']=null;
+ }else{
+ //商品|属性
+ $ga=md5_16($serialVo['goods'].'&'.$find['attr']);
+ $gather['ga'][$ga]=math()->chain($gather['ga'][$ga]??0)->add(1)->done();
+ $serial[$serialKey]['attr']=$find['attr'];
+ }
+ }
+ //匹配数据
+ $batch=Db::name('batch')->where([['id','in',array_unique(array_column($serial,'batch'))]])->select()->toArray();
+ foreach ($info as $infoKey=>$infoVo) {
+ //商品
+ $g=md5_16($infoVo['id']);
+ $info[$infoKey]['summary']=isset($gather['g'][$g])?$gather['g'][$g]:0;
+ if(empty($infoVo['attr'])){
+ $list=search($serial)->where([['goods','=',$infoVo['id']],['attr','=',null]])->select();
+ foreach ($list as $listVo) {
+ $row=[
+ 'key'=>md5_16($infoVo['id'].'&'.$listVo['id']),
+ 'serial'=>$listVo['id'],
+ 'name'=>$listVo['number'],
+ 'summary'=>1,
+ 'state'=>['未销售','已销售','已调拨','已退货'][$listVo['state']]
+ ];
+ //仓库信息
+ $warehouseFind=search($warehouse)->where([['id','=',$listVo['warehouse']]])->find();
+ $row['warehouse']=$warehouseFind['name'];
+ //批次信息
+ if(empty($listVo['batch'])){
+ $row['batch']='';
+ }else{
+ $batchFind=search($batch)->where([['id','=',$listVo['batch']]])->find();
+ $row['batch']=$batchFind['number'];
+ }
+ $info[$infoKey]['attr'][]=$row;
+ }
+ }else{
+ $list=search($serial)->where([['goods','=',$infoVo['id']],['attr','<>',null]])->select();
+ //匹配辅助属性
+ foreach ($infoVo['attr'] as $attrKey=>$attrVo) {
+ //商品|属性
+ $ga=md5_16($infoVo['id'].'&'.$attrVo['name']);
+ $info[$infoKey]['attr'][$attrKey]['summary']=isset($gather['ga'][$ga])?$gather['ga'][$ga]:0;
+ $select=search($list)->where([['attr','=',$attrVo['name']]])->select();
+ foreach ($select as $selectVo) {
+ $row=[
+ 'key'=>md5_16($infoVo['id'].'&'.$selectVo['id']),
+ 'serial'=>$selectVo['id'],
+ 'name'=>$selectVo['number'],
+ 'summary'=>1,
+ 'state'=>['未销售','已销售','已调拨','已退货'][$selectVo['state']]
+ ];
+ //仓库信息
+ $warehouseFind=search($warehouse)->where([['id','=',$selectVo['warehouse']]])->find();
+ $row['warehouse']=$warehouseFind['name'];
+ //批次信息
+ if(empty($selectVo['batch'])){
+ $row['batch']='';
+ }else{
+ $batchFind=search($batch)->where([['id','=',$selectVo['batch']]])->find();
+ $row['batch']=$batchFind['number'];
+ }
+ $info[$infoKey]['attr'][$attrKey]['attr'][]=$row;
+ }
+ if(empty($select))unset($info[$infoKey]['attr'][$attrKey]);
+ }
+ $info[$infoKey]['attr']=array_values($info[$infoKey]['attr']);
+ }
+ }
+ $result=[
+ 'state'=>'success',
+ 'count'=>$count,
+ 'info'=>$info
+ ];//返回数据
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+
+ //导出
+ public function exports(){
+ $input=input('get.');
+ existFull($input,['warehouse'])||$input['warehouse']=[];
+ if(isset($input['warehouse']) && is_array($input['warehouse'])){
+ pushLog('导出序列列表');//日志
+ //匹配仓库
+ $warehouse = Db::name('warehouse')->where(empty($input['warehouse'])?sqlAuth('warehouse',[]):[['id','in',$input['warehouse']]])->select()->toArray();
+ //匹配商品
+ $sql=fastSql($input,[
+ [['name'=>'name|py'],'fullLike'],
+ ['number','fullLike'],
+ ['spec','fullLike'],
+ ['brand','fullEq'],
+ ['code','fullLike']
+ ]);//构造SQL
+ //商品类型
+ $sql[]=['type','=',0];
+ //辅助属性扩展查询
+ $sqlOr=existFull($input,['code'])?[['id','in',array_column(Db::name('attr')->where([['code','=',$input['code']]])->select()->toArray(),'pid')]]:[];
+ //商品分类树结构查询
+ existFull($input,['category'])&&$sql[]=['category','in',findTreeArr('category',$input['category'],'id')];
+ //批次查询
+ $serialSql=fastSql($input,[
+ [['serial'=>'number'],'fullLike'],
+ ['state','fullDec1']
+ ]);//构造SQL
+ $serialSql[]=['warehouse','in',array_column($warehouse,'id')];
+ //查询操作
+ if(existFull($input,['batch'])){
+ $exists=Db::name('batch')->where([['number','like','%'.$input['batch'].'%'],['id','=',Db::raw('serial.batch')]])->buildSql(false);
+ $serial=Db::name('serial')->where($serialSql)->alias('serial')->whereExists($exists)->select()->toArray();
+ }else{
+ $serial=Db::name('serial')->where($serialSql)->select()->toArray();
+ }
+ //查询商品
+ $sql[]=['id','in',array_column($serial,'goods')];
+ //获取总条数
+ $count = Goods::where($sql)->whereOr($sqlOr)->count();
+ //查询分页数据
+ $info = Goods::with(['categoryData','attr'])->where($sql)->whereOr($sqlOr)->order(['id'=>'desc'])->append(['extension'])->select()->toArray();
+ //唯一标识|属性处理
+ foreach ($info as $infoKey=>$infoVo) {
+ foreach ($infoVo['attr'] as $attrKey=>$attrVo) {
+ //属性处理
+ if(existFull($input,['code']) && !in_array($input['code'],[$infoVo['code'],$attrVo['code']])){
+ unset($info[$infoKey]['attr'][$attrKey]);
+ }
+ }
+ //重建索引
+ $info[$infoKey]['attr']=array_values($info[$infoKey]['attr']);
+ }
+ //库存集合[g:商品|a:属性]
+ $gather=['g'=>[],'ga'=>[]];
+ //二次匹配
+ $serial=search($serial)->where([['goods','in',array_column($info,'id')]])->select();
+ //查询库存数据-仓储
+ $room=Db::name('room')->where([['id','in',array_unique(array_column($serial,'room'))]])->select()->toArray();
+ //构造序列数据
+ foreach ($serial as $serialKey=>$serialVo) {
+ //商品
+ $g=md5_16($serialVo['goods']);
+ $gather['g'][$g]=math()->chain($gather['g'][$g]??0)->add(1)->done();
+ //判断属性
+ $find=search($room)->where([['id','=',$serialVo['room']]])->find();
+ if(empty($find['attr'])){
+ $serial[$serialKey]['attr']=null;
+ }else{
+ //商品|属性
+ $ga=md5_16($serialVo['goods'].'&'.$find['attr']);
+ $gather['ga'][$ga]=math()->chain($gather['ga'][$ga]??0)->add(1)->done();
+ $serial[$serialKey]['attr']=$find['attr'];
+ }
+ }
+ //匹配数据
+ $batch=Db::name('batch')->where([['id','in',array_unique(array_column($serial,'batch'))]])->select()->toArray();
+ foreach ($info as $infoKey=>$infoVo) {
+ //商品
+ $g=md5_16($infoVo['id']);
+ $info[$infoKey]['summary']=isset($gather['g'][$g])?$gather['g'][$g]:0;
+ if(empty($infoVo['attr'])){
+ $list=search($serial)->where([['goods','=',$infoVo['id']],['attr','=',null]])->select();
+ foreach ($list as $listVo) {
+ $row=[
+ 'name'=>$listVo['number'],
+ 'summary'=>1,
+ 'state'=>['未销售','已销售','已调拨','已退货'][$listVo['state']]
+ ];
+ //仓库信息
+ $warehouseFind=search($warehouse)->where([['id','=',$listVo['warehouse']]])->find();
+ $row['warehouse']=$warehouseFind['name'];
+ //批次信息
+ if(empty($listVo['batch'])){
+ $row['batch']='';
+ }else{
+ $batchFind=search($batch)->where([['id','=',$listVo['batch']]])->find();
+ $row['batch']=$batchFind['number'];
+ }
+ $info[$infoKey]['attr'][]=$row;
+ }
+ }else{
+ $list=search($serial)->where([['goods','=',$infoVo['id']],['attr','<>',null]])->select();
+ //匹配辅助属性
+ foreach ($infoVo['attr'] as $attrKey=>$attrVo) {
+ //商品|属性
+ $ga=md5_16($infoVo['id'].'&'.$attrVo['name']);
+ $info[$infoKey]['attr'][$attrKey]['summary']=isset($gather['ga'][$ga])?$gather['ga'][$ga]:0;
+ $select=search($list)->where([['attr','=',$attrVo['name']]])->select();
+ foreach ($select as $selectVo) {
+ $row=[
+ 'name'=>$selectVo['number'],
+ 'summary'=>1,
+ 'state'=>['未销售','已销售','已调拨','已退货'][$selectVo['state']]
+ ];
+ //仓库信息
+ $warehouseFind=search($warehouse)->where([['id','=',$selectVo['warehouse']]])->find();
+ $row['warehouse']=$warehouseFind['name'];
+ //批次信息
+ if(empty($selectVo['batch'])){
+ $row['batch']='';
+ }else{
+ $batchFind=search($batch)->where([['id','=',$selectVo['batch']]])->find();
+ $row['batch']=$batchFind['number'];
+ }
+ $info[$infoKey]['attr'][$attrKey]['attr'][]=$row;
+ }
+ if(empty($select))unset($info[$infoKey]['attr'][$attrKey]);
+ }
+ $info[$infoKey]['attr']=array_values($info[$infoKey]['attr']);
+ }
+ }
+ //结构重组
+ $source=[];
+ foreach ($info as $infoVo) {
+ $source[]=$infoVo;
+ if(!empty($infoVo['attr'])){
+ foreach ($infoVo['attr'] as $attrVo) {
+ $attrVo['name']='|- '.$attrVo['name'];
+ $source[]=$attrVo;
+ if(existFull($attrVo,['attr'])){
+ foreach ($attrVo['attr'] as $subVo) {
+ $subVo['name']='|-- '.$subVo['name'];
+ $source[]=$subVo;
+ }
+ }
+ }
+ }
+ }
+ //开始构造导出数据
+ $excel=[];//初始化导出数据
+ //标题数据
+ $excel[]=['type'=>'title','info'=>'序列列表'];
+ //表格数据
+ $field=array_merge(['name'=>'商品名称','summary'=>'库存数量','state'=>'序列状态','warehouse'=>'所属仓库','batch'=>'所属批次','number'=>'商品编号','spec'=>'规格型号','categoryData|name'=>'商品分类','brand'=>'商品品牌','extension|unit'=>'商品单位','code'=>'商品条码','data'=>'商品备注']);
+ $thead=array_values($field);//表格标题
+ $tbody=[];//表格内容
+ //构造表内数据
+ foreach ($source as $sourceVo) {
+ $rowData=[];
+ foreach (array_keys($field) as $fieldVo) {
+ $rowData[]=arraySeek($sourceVo,$fieldVo);//多键名数据赋值
+ }
+ $tbody[]=$rowData;//加入行数据
+ }
+ $excel[]=['type'=>'table','info'=>['thead'=>$thead,'tbody'=>$tbody]];//表格数据
+ //导出execl
+ buildExcel('序列列表',$excel);
+ }else{
+ return json(['state'=>'error','info'=>'传入数据不完整!']);
+ }
+ }
+
+
+ //详情列表
+ public function detailRecord(){
+ $input=input('post.');
+ $sheet=['buy','bre','sell','sre','swapOut','swapEnter','entry','extry'];
+ existFull($input,['type'])||$input['type']=$sheet;
+ if(existFull($input,['page','limit','serial']) && is_arrays($input,['serial','type']) && arrayInArray($input['type'],$sheet)){
+ //构造SQL|serial
+ $sql=fastSql($input,[
+ [['serial'=>'id'],'fullIn']
+ ]);
+ //查询仓储数据
+ $serial=Db::name('serial')->where($sql)->field(['id'])->select()->toArray();
+ if(empty($serial)){
+ $count=0;
+ $info=[];
+ }else{
+ //构造SQL|SERIALINFO
+ $infoSql=fastSql($input,[['type','fullIn']]);
+ $infoSql[]=['pid','in',array_column($serial,'id')];
+ //子查询SQL
+ $existsSql=fastSql($input,[
+ ['number','fullLike'],
+ [['startTime'=>'time'],'startTime'],
+ [['endTime'=>'time'],'endTime']
+ ]);
+ $existsSql[]=['id','=',Db::raw('info.class')];
+ $existsSql=frameScope($existsSql);
+ //多源匹配
+ $union=[];
+ //数据关系表
+ $table=['buy'=>'buy','bre'=>'bre','sell'=>'sell','sre'=>'sre','swapOut'=>'swap','swapEnter'=>'swap','entry'=>'entry','extry'=>'extry'];
+ foreach ($table as $k=>$v) {
+ //匹配类型|减少查询
+ if(in_array($k,$input['type'])){
+ $union[]=Db::name($v)->where([['info.type','=',$k]])->where(array_merge($existsSql,sqlAuth($v,[])))->limit(1)->buildSql();
+ }
+ }
+ //合并子查询
+ $union=implode(' UNION ALL ',$union);
+ $count=SerialInfo::alias('info')->where($infoSql)->whereExists($union)->count();
+ $info=SerialInfo::with(['sourceData'=>['frameData']])->alias('info')->where($infoSql)->whereExists($union)->page($input['page'],$input['limit'])->order(['id'=>'desc'])->append(['extension'])->select()->toArray();
+ }
+ $result=[
+ 'state'=>'success',
+ 'count'=>$count,
+ 'info'=>$info
+ ];//返回数据
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //详情导出
+ public function detailExports(){
+ $input=input('get.');
+ $sheet=['buy','bre','sell','sre','swapOut','swapEnter','entry','extry'];
+ existFull($input,['serial'])||$input['serial']=[];
+ existFull($input,['type'])||$input['type']=$sheet;
+ if(existFull($input,['serial']) && is_arrays($input,['serial','type']) && arrayInArray($input['type'],$sheet)){
+ pushLog('导出序列详情');//日志
+ //构造SQL|serial
+ $sql=fastSql($input,[
+ [['serial'=>'id'],'fullIn']
+ ]);
+ //查询仓储数据
+ $serial=Db::name('serial')->where($sql)->field(['id','number'])->select()->toArray();
+ if(empty($serial)){
+ $source=[];
+ }else{
+ //构造SQL|SERIALINFO
+ $infoSql=fastSql($input,[['type','fullIn']]);
+ $infoSql[]=['pid','in',array_column($serial,'id')];
+ //子查询SQL
+ $existsSql=fastSql($input,[
+ ['number','fullLike'],
+ [['startTime'=>'time'],'startTime'],
+ [['endTime'=>'time'],'endTime']
+ ]);
+ $existsSql[]=['id','=',Db::raw('info.class')];
+ $existsSql=frameScope($existsSql);
+ //多源匹配
+ $union=[];
+ //数据关系表
+ $table=['buy'=>'buy','bre'=>'bre','sell'=>'sell','sre'=>'sre','swapOut'=>'swap','swapEnter'=>'swap','entry'=>'entry','extry'=>'extry'];
+ foreach ($table as $k=>$v) {
+ //匹配类型|减少查询
+ if(in_array($k,$input['type'])){
+ $union[]=Db::name($v)->where([['info.type','=',$k]])->where(array_merge($existsSql,sqlAuth($v,[])))->limit(1)->buildSql();
+ }
+ }
+ //合并子查询
+ $union=implode(' UNION ALL ',$union);
+ $source=SerialInfo::with(['sourceData'=>['frameData']])->alias('info')->where($infoSql)->whereExists($union)->order(['id'=>'desc'])->append(['extension'])->select()->toArray();
+ }
+ //开始构造导出数据
+ $excel=[];//初始化导出数据
+ //标题数据
+ $excel[]=['type'=>'title','info'=>'序列详情'];
+ //表格数据
+ $field=[
+ 'sourceData|frameData|name'=>'所属组织',
+ 'sourceData|time'=>'操作时间',
+ 'extension|type'=>'单据类型',
+ 'sourceData|number'=>'单据编号'
+ ];
+ $thead=array_values($field);//表格标题
+ $tbody=[];//表格内容
+ //构造表内数据
+ foreach ($source as $sourceVo) {
+ $rowData=[];
+ foreach (array_keys($field) as $fieldVo) {
+ $rowData[]=arraySeek($sourceVo,$fieldVo);//多键名数据赋值
+ }
+ $tbody[]=$rowData;//加入行数据
+ }
+ $excel[]=['type'=>'table','info'=>['thead'=>$thead,'tbody'=>$tbody]];//表格数据
+ //导出execl
+ buildExcel('序列详情',$excel);
+ }else{
+ return json(['state'=>'error','info'=>'传入数据不完整!']);
+ }
+ }
+}
\ No newline at end of file
diff --git a/serve/app/controller/Service.php b/serve/app/controller/Service.php
new file mode 100644
index 0000000..63cc844
--- /dev/null
+++ b/serve/app/controller/Service.php
@@ -0,0 +1,627 @@
+select()->toArray(),-1);
+ }else{
+ $frame=Db::name('frame')->where([['id','in',$userFrame]])->select()->toArray();
+ //追加子数据
+ foreach ($frame as $frameKey=>$frameVo) {
+ $frame[$frameKey]['sub']=[];
+ }
+ }
+ //获取用户权限菜单
+ $menu = $tree::hTree(getRootMemu());
+ //获取全局字段配置
+ $fields = getFields();
+ //获取用户权限数据
+ $root = getUserRoot();
+ //获取商品类别数据
+ $category = $tree::hTree(Db::name('category')->order(['sort'=>'asc'])->select()->toArray(),-1);
+ //获取仓库数据
+ $warehouse=Db::name('warehouse')->where(sqlAuth('warehouse',[]))->field(['id','name'])->order(['id'=>'desc'])->select();
+ //获取资金账户
+ $account=Db::name('account')->where(sqlAuth('account',[]))->field(['id','name'])->order(['id'=>'desc'])->select();
+ //获取收支类别
+ $ietList=Db::name('iet')->order(['sort'=>'asc'])->select()->toArray();
+ $iet=['in'=>search($ietList)->where([['type','=',0]])->select(),'out'=>search($ietList)->where([['type','=',1]])->select()];
+ //获取常用功能
+ $often = Db::name('often')->where([['user','=',getUserId()]])->field(['name','key'])->select();
+ //获取系统参数
+ $sys = getSys(['name','icp','notice','brand','unit','crCategory','crGrade','srCategory','fun','logistics']);
+ //返回数据
+ return json(['state' => 'success','info' => [
+ 'frame' => $frame,
+ 'menu' => $menu,
+ 'fields' => $fields,
+ 'root'=>$root,
+ 'category' => $category,
+ 'warehouse' => $warehouse,
+ 'account' => $account,
+ 'iet' => $iet,
+ 'often' => $often,
+ 'sys' => $sys
+ ]]);
+ }
+ //获取|组织数据
+ public function getFrame(){
+ $cache=cache(getToken());
+ $result = ['state' => 'success','info'=>isset($cache['frame'])?$cache['frame']:[]];
+ return json($result);
+ }
+ //保存|组织数据
+ public function saveFrame(){
+ $input=input('post.');
+ if(existFull($input,['parm']) || is_array($input['parm'])){
+ $token=getToken();
+ $cache=cache($token);
+ $cache['frame']=$input['parm'];
+ cache($token,$cache);
+ $result = ['state' => 'success'];
+ }else{
+ $result = ['state' => 'error','info' => '传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //获取|商品列表
+ public function goodsRecord(){
+ $input = input('post.');
+ if (existFull($input,['page','limit'])) {
+ $sql=fastSql($input,[
+ [['mate'=>'name|py|number|spec'],'fullLike'],
+ ['code','fullEq'],
+ ['brand','fullEq'],
+ ['type','fullDec1'],
+ ['data','fullLike']
+ ]);
+ //辅助属性扩展查询
+ $sqlOr=existFull($input,['code'])?[['id','in',array_column(Db::name('attr')->where([['code','=',$input['code']]])->select()->toArray(),'pid')]]:[];
+ //商品分类树结构查询
+ existFull($input,['category'])&&$sql[]=['category','in',findTreeArr('category',$input['category'],'id')];
+ //获取总条数
+ $count = Goods::where($sql)->whereOr($sqlOr)->count();
+ //查询分页数据
+ $info = Goods::with(['categoryData','attr'])->where($sql)->whereOr($sqlOr)->append(['extension'])->page($input['page'],$input['limit'])->order(['id'=>'desc'])->select()->toArray();
+ //唯一标识|属性处理
+ foreach ($info as $infoKey=>$infoVo) {
+ $info[$infoKey]['key']=$infoVo['id'];
+ foreach ($infoVo['attr'] as $attrKey=>$attrVo) {
+ $info[$infoKey]['attr'][$attrKey]['key']=$infoVo['id'].'.'.$attrVo['id'];
+ //属性处理
+ if(existFull($input,['code']) && !in_array($input['code'],[$infoVo['code'],$attrVo['code']])){
+ unset($info[$infoKey]['attr'][$attrKey]);
+ }
+ }
+ //重建索引
+ $info[$infoKey]['attr']=array_values($info[$infoKey]['attr']);
+ }
+ $result = [
+ 'state' => 'success',
+ 'count' => $count,
+ 'info' => $info
+ ];
+ //返回数据
+ } else {
+ $result = ['state' => 'error','info' => '传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //商品|扫码接口
+ public function goodsScan(){
+ $input = input('post.');
+ if (existFull($input,['code'])) {
+ $sql=[['code','=',$input['code']]];
+ $sqlOr=[['id','in',array_column(Db::name('attr')->where([['code','=',$input['code']]])->select()->toArray(),'pid')]];
+ //查询数据
+ $info = Goods::with(['attr'])->where($sql)->whereOr($sqlOr)->order(['id'=>'desc'])->select()->toArray();
+ //处理|辅助属性条形码
+ foreach ($info as $infoKey=>$infoVo) {
+ //匹配|有辅助属性|主条形码不同
+ if(!empty($infoVo['attr']) && $infoVo['code']!=$input['code']){
+ foreach ($infoVo['attr'] as $attrKey=>$attrVo) {
+ if($attrVo['code']!=$input['code']){
+ unset($info[$infoKey]['attr'][$attrKey]);
+ }
+ }
+ //重建索引
+ $info[$infoKey]['attr']=array_values($info[$infoKey]['attr']);
+ }
+ }
+ $result = [
+ 'state' => 'success',
+ 'info' => $info
+ ];
+ //返回数据
+ } else {
+ $result = ['state' => 'error','info' => '传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //获取|库存信息
+ public function goodsDepot(){
+ $input = input('post.');
+ if (existFull($input,['page','limit','goods']) && isset($input['attr'])){
+ //查询数据
+ $warehouseSql=sqlAuth('warehouse',[]);
+ $count=Db::name('warehouse')->where($warehouseSql)->count();
+ $warehouse=Db::name('warehouse')->where($warehouseSql)->page($input['page'],$input['limit'])->order(['id'=>'desc'])->select()->toArray();
+ //匹配数据
+ $room=Db::name('room')->where([['warehouse','in',array_column($warehouse,'id')],['goods','=',$input['goods']],['attr','=',$input['attr']]])->select()->toArray();
+ //构造数据
+ $info=[];
+ foreach ($warehouse as $warehouseVo) {
+ $item=['warehouse'=>$warehouseVo['id']];
+ $item['name']=$warehouseVo['name'];
+ //仓储查询
+ $roomFind=search($room)->where([['warehouse','=',$warehouseVo['id']]])->find();
+ //记录赋值
+ $item['nums']=empty($roomFind)?0:floatval($roomFind['nums']);
+ //记录转存
+ $info[]=$item;
+ }
+ //数据处理|单位转换
+ $goods=Db::name('goods')->where([['id','=',$input['goods']]])->find();
+ if($goods['unit']=='-1'){
+ foreach ($info as $infoKey=>$infoVo) {
+ $info[$infoKey]['nums']=unitSwitch($infoVo['nums'],json_decode($goods['units'],true));
+ }
+ }
+ //返回数据
+ $result = [
+ 'state' => 'success',
+ 'count' => $count,
+ 'info' => $info
+ ];
+ } else {
+ $result = ['state' => 'error','info' => '传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //商品|最近价格
+ public function recentPrice(){
+ $input = input('post.');
+ if(existFull($input,['model','source','goods']) && in_array($input['model'],['bor','buy','bre','sor','sell','sre']) && isset($input['attr']) && isset($input['unit'])){
+ $model=$input['model'];
+ //构造CLASS条件
+ $sql=[['examine','=',1]];
+ //场景匹配
+ in_array($model,['bor','buy','bre'])&&$sql[]=['supplier','=',$input['source']];//供应商
+ in_array($model,['sor','sell','sre'])&&$sql[]=['customer','=',$input['source']];//客户
+ //查询CLASS数据
+ $sql=sqlAuth($model,$sql);//数据鉴权
+ $class=Db::name($model)->where($sql)->field(['id'])->order(['id'=>'desc'])->select()->toArray();
+ if(empty($class)){
+ $result = ['state' => 'success','info' => 0];
+ }else{
+ //查询INFO数据
+ $parm=[
+ ['pid','in',array_column($class,'id')],
+ ['goods','=',$input['goods']],
+ ['attr','=',$input['attr']],
+ ['unit','=',$input['unit']]
+ ];
+ $info=Db::name($model.'_info')->where($parm)->order(['pid'=>'desc'])->find();
+ if(empty($info)){
+ $result = ['state' => 'success','info' => 0];
+ }else{
+ $result = ['state' => 'success','info' => floatval($info['price'])];
+ }
+ }
+ } else {
+ $result = ['state' => 'error','info' => '传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //商品序列号
+ public function getSerial(){
+ $input = input('post.');
+ if(existFull($input,['page','limit','warehouse','goods']) && isset($input['attr']) && isset($input['batch']) && isset($input['mfd']) && isset($input['state'])){
+ $room=Db::name('room')->where([['warehouse','=',$input['warehouse']],['goods','=',$input['goods']],['attr','=',$input['attr']]])->find();
+ if(empty($room)){
+ $result = ['state' => 'success','count' => 0,'info' => []];
+ }else{
+ if(empty($input['batch'])){
+ $batch=['id'=>0];
+ }else{
+ $batch=Db::name('batch')->where([['room','=',$room['id']],['number','=',$input['batch']],['time','=',empty($input['mfd'])?0:strtotime($input['mfd'])]])->find();
+ if(empty($batch)){
+ return json(['state' => 'success','count' => 0,'info' => []]);
+ exit;
+ }
+ }
+ $count=Serial::where([['room','=',$room['id']],['batch','=',$batch['id']],['state','=',$input['state']]])->count();
+ $info=Serial::where([['room','=',$room['id']],['batch','=',$batch['id']],['state','=',$input['state']]])->append(['extension'])->page($input['page'],$input['limit'])->order(['id'=>'asc'])->select();
+ $result = ['state' => 'success','count' => $count,'info' => $info];
+ }
+ }else{
+ $result = ['state' => 'error','info' => '传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //商品批次号
+ public function getBatch(){
+ $input = input('post.');
+ if(existFull($input,['page','limit','warehouse','goods']) && isset($input['attr'])){
+ //匹配仓储
+ $room=Db::name('room')->where([['warehouse','=',$input['warehouse']],['goods','=',$input['goods']],['attr','=',$input['attr']]])->find();
+ if(empty($room)){
+ $result = ['state' => 'success','count' => 0,'info' => []];
+ }else{
+ //匹配批次号
+ $sql=fastSql($input,[
+ ['number','fullLike'],
+ [['startTime'=>'time'],'startTime'],
+ [['endTime'=>'time'],'endTime']
+ ]);//构造SQL
+ $sql[]=['room','=',$room['id']];
+ $count=Batch::where($sql)->count();
+ $info=Batch::where($sql)->page($input['page'],$input['limit'])->order(['id'=>'asc'])->select()->toArray();
+ //数据处理|单位转换
+ $goods=Db::name('goods')->where([['id','=',$input['goods']]])->find();
+ if($goods['unit']=='-1'){
+ foreach ($info as $infoKey=>$infoVo) {
+ $info[$infoKey]['nums']=unitSwitch($infoVo['nums'],json_decode($goods['units'],true));
+ }
+ }
+ $result = ['state' => 'success','count' => $count,'info' => $info];
+ }
+ }else{
+ $result = ['state' => 'error','info' => '传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //单据列表
+ public function billRecord(){
+ $input = input('post.');
+ if (existFull($input,['page','limit','mold']) && in_array($input['mold'],['imy','omy','buy','bre','sell','sre','ice','oce'])) {
+ if(in_array($input['mold'],['omy','buy','bre','oce'])){
+ $sql=fastSql($input,[
+ ['supplier','fullEq'],
+ ['number','fullLike'],
+ [['startTime'=>'time'],'startTime'],
+ [['endTime'=>'time'],'endTime'],
+ ['user','fullEq'],
+ ['data','fullLike']
+ ]);
+ }else{
+ $sql=fastSql($input,[
+ ['customer','fullEq'],
+ ['number','fullLike'],
+ [['startTime'=>'time'],'startTime'],
+ [['endTime'=>'time'],'endTime'],
+ ['user','fullEq'],
+ ['data','fullLike']
+ ]);
+ }
+ $sql[]=['examine','=',1];
+ $sql[]=existFull($input,['nucleus'])?['nucleus','=',$input['nucleus']-1]:['nucleus','in',[0,1]];
+ $sql=sqlAuth($input['mold'],$sql);//数据鉴权
+ $table=['imy'=>'\app\model\Imy','omy'=>'\app\model\Omy','buy'=>'\app\model\Buy','bre'=>'\app\model\Bre','sell'=>'\app\model\Sell','sre'=>'\app\model\Sre','ice'=>'\app\model\Ice','oce'=>'\app\model\Oce'];
+ $count = $table[$input['mold']]::where($sql)->count();//获取总条数
+ $info = $table[$input['mold']]::with(['frameData','userData'])->where($sql)->append(['extension'])->page($input['page'],$input['limit'])->order(['id'=>'desc'])->select()->toArray();//查询分页数据
+ //数据处理
+ foreach ($info as $key=>$vo) {
+ in_array($input['mold'],['buy','bre','sell','sre','ice','oce'])&&$info[$key]['total']=$vo['actual'];
+ }
+ $result = [
+ 'state' => 'success',
+ 'count' => $count,
+ 'info' => $info
+ ];
+ //返回数据
+ } else {
+ $result = ['state' => 'error','info' => '传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //匹配|下拉接口
+ public function getScene() {
+ $input = input('post.');
+ if (existFull($input,['id','scene'])) {
+ $find=Db::name($input['scene'])->where([['id','=',$input['id']]])->find();
+ $result=['state' => 'success','info' => $find];
+ } else {
+ $result = ['state' => 'error','info' => '传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //用户角色|下拉接口
+ public function roleRecord() {
+ $input = input('post.');
+ if (existFull($input,['page','limit'])) {
+ //构造SQL
+ $sql = fastSql($input,[
+ [['query'=>'name|py'],'fullLike']
+ ]);
+ $count = Db::name('role')->where($sql)->count();
+ //获取总条数
+ $info = Db::name('role')->where($sql)->page($input['page'],$input['limit'])->order(['id'=>'desc'])->select()->toArray();
+ //查询分页数据
+ $result = [
+ 'state' => 'success',
+ 'count' => $count,
+ 'info' => $info
+ ];
+ //返回数据
+ } else {
+ $result = ['state' => 'error','info' => '传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //用户数据|下拉接口
+ public function userRecord() {
+ $input = input('post.');
+ if (existFull($input,['page','limit'])) {
+ //构造SQL
+ $sql = fastSql($input,[
+ [['query'=>'name|py'],'fullLike']
+ ]);
+ isset($input['noAuth']) || ($sql = sqlAuth('user',$sql));
+ //数据鉴权
+ $count = Db::name('user')->where($sql)->count();
+ //获取总条数
+ $info = Db::name('user')->where($sql)->page($input['page'],$input['limit'])->order(['id'=>'desc'])->select()->toArray();
+ //查询分页数据
+ $result = [
+ 'state' => 'success',
+ 'count' => $count,
+ 'info' => $info
+ ];
+ //返回数据
+ } else {
+ $result = ['state' => 'error','info' => '传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //人员数据|下拉接口
+ public function peopleRecord() {
+ $input = input('post.');
+ if (existFull($input,['page','limit'])) {
+ //构造SQL
+ $sql = fastSql($input,[
+ [['query'=>'name|py'],'fullLike']
+ ]);
+ isset($input['noAuth']) || ($sql = sqlAuth('people',$sql));
+ //数据鉴权
+ $count = Db::name('people')->where($sql)->count();
+ //获取总条数
+ $info = Db::name('people')->where($sql)->page($input['page'],$input['limit'])->order(['id'=>'desc'])->select()->toArray();
+ //查询分页数据
+ $result = [
+ 'state' => 'success',
+ 'count' => $count,
+ 'info' => $info
+ ];
+ //返回数据
+ } else {
+ $result = ['state' => 'error','info' => '传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //仓库数据|下拉接口
+ public function warehouseRecord() {
+ $input = input('post.');
+ if (existFull($input,['page','limit'])) {
+ //构造SQL
+ $sql = fastSql($input,[
+ [['query'=>'name|py'],'fullLike']
+ ]);
+ $sql = sqlAuth('warehouse',$sql);//数据鉴权
+ $count = Db::name('warehouse')->where($sql)->count();
+ //获取总条数
+ $info = Db::name('warehouse')->where($sql)->page($input['page'],$input['limit'])->order(['id'=>'desc'])->select()->toArray();
+ //查询分页数据
+ $result = [
+ 'state' => 'success',
+ 'count' => $count,
+ 'info' => $info
+ ];
+ //返回数据
+ } else {
+ $result = ['state' => 'error','info' => '传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //供应商数据|下拉接口
+ public function supplierRecord() {
+ $input = input('post.');
+ if (existFull($input,['page','limit'])) {
+ //构造SQL
+ $sql = fastSql($input,[
+ [['query'=>'name|py'],'fullLike']
+ ]);
+ $sql = sqlAuth('supplier',$sql);//数据鉴权
+ $count = Db::name('supplier')->where($sql)->count();
+ //获取总条数
+ $info = Db::name('supplier')->where($sql)->page($input['page'],$input['limit'])->order(['id'=>'desc'])->select()->toArray();
+ //查询分页数据
+ $result = [
+ 'state' => 'success',
+ 'count' => $count,
+ 'info' => $info
+ ];
+ //返回数据
+ } else {
+ $result = ['state' => 'error','info' => '传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //客户数据|下拉接口
+ public function customerRecord() {
+ $input = input('post.');
+ if (existFull($input,['page','limit'])) {
+ //构造SQL
+ $sql = fastSql($input,[
+ [['query'=>'name|py|contacts'],'fullLike']
+ ]);
+ $sql = sqlAuth('customer',$sql);//数据鉴权
+ $count = Db::name('customer')->where($sql)->count();
+ //获取总条数
+ $info = Db::name('customer')->where($sql)->page($input['page'],$input['limit'])->order(['id'=>'desc'])->select()->toArray();
+ //查询分页数据
+ $result = [
+ 'state' => 'success',
+ 'count' => $count,
+ 'info' => $info
+ ];
+ //返回数据
+ } else {
+ $result = ['state' => 'error','info' => '传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //资金账户|下拉接口
+ public function accountRecord() {
+ $input = input('post.');
+ if (existFull($input,['page','limit'])) {
+ //构造SQL
+ $sql = fastSql($input,[
+ [['query'=>'name'],'fullLike']
+ ]);
+ $sql = sqlAuth('account',$sql);//数据鉴权
+ $count = Db::name('account')->where($sql)->count();
+ //获取总条数
+ $info = Db::name('account')->where($sql)->page($input['page'],$input['limit'])->order(['id'=>'desc'])->select()->toArray();
+ //查询分页数据
+ $result = [
+ 'state' => 'success',
+ 'count' => $count,
+ 'info' => $info
+ ];
+ } else {
+ $result = ['state' => 'error','info' => '传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //收支类别|下拉接口
+ public function ietRecord() {
+ $input = input('post.');
+ if (existFull($input,['page','limit'])) {
+ //构造SQL
+ $sql = fastSql($input,[
+ [['query'=>'name'],'fullLike']
+ ]);
+ $count = Db::name('iet')->where($sql)->count();
+ //获取总条数
+ $info = Db::name('iet')->where($sql)->page($input['page'],$input['limit'])->order(['id'=>'desc'])->select()->toArray();
+ //查询分页数据
+ $result = [
+ 'state' => 'success',
+ 'count' => $count,
+ 'info' => $info
+ ];
+ } else {
+ $result = ['state' => 'error','info' => '传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //费用详情|数据接口
+ public function getCost() {
+ $input = input('post.');
+ if (existFull($input,['cost'])) {
+ $info=Cost::with(['sourceData','ietData'])->where([['id','=',$input['cost']]])->append(['extension'])->find()->toArray();
+ $info['uat']=math()->chain($info['money'])->sub($info['settle'])->done();
+ $result = ['state' => 'success','info' => $info];
+ } else {
+ $result = ['state' => 'error','info' => '传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //零售配置
+ public function getDeploy(){
+ $deploy=getFrameDeploy();
+ if(!empty($deploy)){
+ //安全处理-隐藏接口配置
+ $deploy['wechat']=[
+ 'enable'=>$deploy['wechat']['enable'],
+ 'account'=>$deploy['wechat']['account']
+ ];
+ $deploy['ali']=[
+ 'enable'=>$deploy['ali']['enable'],
+ 'account'=>$deploy['ali']['account']
+ ];
+ }
+ return json(['state'=>'success','info'=>$deploy]);
+ }
+ //扩展字段文件上传
+ public function fieldUpload() {
+ $file = request()->file('file');
+ //获取上传文件
+ if (empty($file)) {
+ $result = ['state' => 'error','info' => '传入数据不完整!'];
+ } else {
+ //文件限制5MB
+ try{
+ validate(['file'=>['fileSize'=>5*1024*1024,'fileExt'=>'png,gif,jpg,jpeg,txt,doc,docx,rtf,xls,xlsx,ppt,pptx,pdf,zip,rar']])->check(['file'=>$file]);
+ $fileInfo=Filesystem::disk('upload')->putFile('field', $file, 'uniqid');
+ $filePath=request()->domain().'/static/upload/'.$fileInfo;
+ $result=['state'=>'success','info'=>$filePath];
+ }catch(ValidateException $e) {
+ $result=['state' => 'error','info' => $e->getMessage()];
+ }
+ }
+ return json($result);
+ }
+ //编辑器图像上传
+ public function editorUpload(){
+ $files=request()->file('images');//获取上传文件
+ if(empty($files)){
+ $result=['state'=>'error','info'=>'传入数据不完整!'];
+ }else{
+ //文件限制2MB
+ foreach ($files as $file) {
+ try{
+ validate(['file'=>['fileSize'=>2*1024*1024,'fileExt'=>'png,gif,jpg,jpeg']])->check(['file'=>$file]);
+ }catch(ValidateException $e) {
+ return json(['state'=>'error','info'=>$e->getMessage()]);
+ exit;
+ }
+ }
+ foreach ($files as $file) {
+ $fileInfo=Filesystem::disk('upload')->putFile('editor', $file, 'uniqid');
+ $filePath=request()->domain().'/static/upload/'.$fileInfo;
+ $data[]=$filePath;
+ }
+ $result=['state'=>'success','info'=>$data];
+ }
+ return json($result);
+ }
+ //获取版本信息
+ public function getUpgrade(){
+ $ask = json_decode(curl('https://www.nodcloud.com/api/service/version',false,['product' => config('soft.product'),'edition' => config('soft.edition'),'version' => config('soft.version')],'GET'),true);
+ if(empty($ask)){
+ $resule = ['state' => 'success','info'=>['ver'=>config('soft.version'),'new'=>config('soft.version'),'url'=>'']];
+ }else{
+ if($ask['state']=='success'){
+ $resule = ['state' => 'success','info'=>['ver'=>config('soft.version'),'new'=>$ask['info']['version'],'url'=>$ask['info']['url']]];
+ }elseif($ask['state']=='warning'){
+ $resule = ['state' => 'error','info' => $ask['message']];
+ }else{
+ $resule = ['state' => 'error','info' => '版本服务系统异常!'];
+ }
+ }
+ return json($resule);
+ }
+ //清空缓存文件
+ public function clachCache(){
+ delCache();
+ delDir('runtime.log');
+ delDir('runtime.session');
+ return json(['state'=>'success']);
+ }
+ //退出
+ public function out(){
+ pushLog('退出登录');
+ cache(getToken(),NULL);
+ return json(['state' => 'success']);
+ }
+}
\ No newline at end of file
diff --git a/serve/app/controller/Sor.php b/serve/app/controller/Sor.php
new file mode 100644
index 0000000..0345170
--- /dev/null
+++ b/serve/app/controller/Sor.php
@@ -0,0 +1,692 @@
+'time'],'startTime'],
+ [['endTime'=>'time'],'endTime'],
+ [['startArrival'=>'arrival'],'startTime'],
+ [['endArrival'=>'arrival'],'endTime'],
+ ['user','fullEq'],
+ ['examine','fullDec1'],
+ ['state','fullDec1'],
+ ['data','fullLike']
+ ]);//构造SQL
+ //商品信息扩展查询
+ if(existFull($input,['goods'])){
+ $goods=array_column(Db::name('goods')->where([['name|py','like','%'.$input['goods'].'%']])->select()->toArray(),'id');
+ $sql[]=['id','in',array_column(Db::name('sor_info')->where([['goods','in',$goods]])->select()->toArray(),'pid')];
+ }
+ $sql=frameScope($sql);//组织数据
+ $sql=sqlAuth('sor',$sql);//数据鉴权
+ $count = Sors::where($sql)->count();//获取总条数
+ $info = Sors::with(['frameData','customerData','peopleData','userData','recordData'])->where($sql)->append(['extension'])->page($input['page'],$input['limit'])->order(['id'=>'desc'])->select()->toArray();//查询分页数据
+ //关联单据
+ if(!empty($info)){
+ $bor=Db::name('bor')->where([['source','in',array_column($info,'id')]])->select()->toArray();
+ $sell=Db::name('sell')->where([['source','in',array_column($info,'id')]])->select()->toArray();
+ foreach ($info as $infoKey=>$infoVo) {
+ //采购订单
+ $borData=array_map(function($item){
+ return ['type'=>'采购订单','time'=>date('Y-m-d',$item['time']),'number'=>$item['number'],'sort'=>$item['time'],'sort'=>$item['time'],'types'=>'bor','id'=>$item['id']];
+ },search($bor)->where([['source','=',$infoVo['id']]])->select());
+ //采购单
+ $sellData=array_map(function($item){
+ return ['type'=>'销售单','time'=>date('Y-m-d',$item['time']),'number'=>$item['number'],'sort'=>$item['time'],'sort'=>$item['time'],'types'=>'sell','id'=>$item['id']];
+ },search($sell)->where([['source','=',$infoVo['id']]])->select());
+ //合并排序
+ $merge=array_merge($borData,$sellData);
+ array_multisort(array_column($merge,'sort'),SORT_DESC,$merge);
+ $info[$infoKey]['relation']=$merge;
+ }
+ }
+ $result=[
+ 'state'=>'success',
+ 'count'=>$count,
+ 'info'=>$info
+ ];//返回数据
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //新增|更新
+ public function save(){
+ $input=input('post.');
+ if(existFull($input,['class','info']) && isset($input['class']['id'])){
+ //构造|验证CLASS
+ try {
+ $class=$input['class'];
+ $class['frame']=userInfo(getUserID(),'frame');
+ $class['user']=getUserID();
+ $class['examine']=0;
+ empty($class['id'])?$this->validate($class,'app\validate\Sor'):$this->validate($class,'app\validate\Sor.update');
+ $period=getPeriod();
+ if(strtotime($class['time'])<=$period){
+ throw new ValidateException('单据日期与结账日期冲突!');
+ }
+ } catch (ValidateException $e) {
+ return json(['state'=>'error','info'=>$e->getError()]);
+ exit;
+ }
+
+ //验证INFO
+ foreach ($input['info'] as $infoKey=>$infoVo) {
+ try {
+ $this->validate($infoVo,'app\validate\SorInfo');
+ } catch (ValidateException $e) {
+ return json(['state'=>'error','info'=>'商品信息第'.($infoKey+1).'条'.$e->getError()]);
+ exit;
+ }
+ }
+
+ //处理数据
+ Db::startTrans();
+ try {
+ //CLASS数据
+ if(empty($class['id'])){
+ //创建数据
+ $createInfo=Sors::create($class);
+ $class['id']=$createInfo['id'];//转存主键
+ Db::name('record')->insert(['type'=>'sor','source'=>$class['id'],'time'=>time(),'user'=>getUserID(),'info'=>'新增单据']);
+ pushLog('新增销售订单[ '.$class['number'].' ]');//日志
+ }else{
+ //更新数据
+ $updateInfo=Sors::update($class);
+ Db::name('record')->insert(['type'=>'sor','source'=>$class['id'],'time'=>time(),'user'=>getUserID(),'info'=>'更新单据']);
+ pushLog('更新销售订单[ '.$class['number'].' ]');//日志
+ }
+
+ //INFO数据
+ SorInfo::where([['pid','=',$class['id']]])->delete();
+ foreach ($input['info'] as $infoKey=>$infoVo) {
+ $input['info'][$infoKey]['pid']=$class['id'];
+ $input['info'][$infoKey]['handle']=0;//初始|出库数量
+ }
+ $model = new SorInfo;
+ $model->saveAll($input['info']);
+
+ Db::commit();
+ $result=['state'=>'success','info'=>$class['id']];
+ } catch (\Exception $e) {
+ Db::rollback();
+ $result=['state'=>'error','info'=>'内部错误,操作已撤销!'];
+ }
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //获取
+ public function get(){
+ $input=input('post.');
+ if(existFull($input,['parm'])){
+ $class=Sors::where([['id','=',$input['parm']]])->find();
+ $info=SorInfo::with(['goodsData','warehouseData'])->where([['pid','=',$input['parm']]])->order(['id'=>'asc'])->select();
+ $result=['state'=>'success','info'=>[
+ 'class'=>$class,
+ 'info'=>$info,
+ ]];
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //删除
+ public function del(){
+ $input=input('post.');
+ if(existFull($input,['parm']) && is_array($input['parm'])){
+ //关联验证
+ $exist=moreTableFind([
+ ['table'=>'bor','where'=>[['source','in',$input['parm']]]],
+ ['table'=>'sell','where'=>[['source','in',$input['parm']]]]
+ ]);
+ if($exist){
+ $result=['state'=>'error','info'=>'存在数据关联,删除失败!'];
+ }else{
+ $data=Db::name('sor')->where([['id','in',$input['parm']]])->order(['id'=>'desc'])->select()->toArray();
+ $search=search($data)->where([['examine','=','1']])->find();
+ if(empty($search)){
+ Db::startTrans();
+ try {
+ Db::name('sor')->where([['id','in',$input['parm']]])->delete();
+ Db::name('sor_info')->where([['pid','in',$input['parm']]])->delete();
+ Db::name('record')->where([['type','=','sor'],['source','in',$input['parm']]])->delete();
+ Db::name('log')->insert(['time'=>time(),'user'=>getUserID(),'info'=>'删除销售订单[ '.implode(' | ',array_column($data,'number')).' ]']);
+
+ Db::commit();
+ $result=['state'=>'success'];
+ } catch (\Exception $e) {
+ Db::rollback();
+ $result=['state'=>'error','info'=>'内部错误,操作已撤销!'];
+ }
+ }else{
+ $result=['state'=>'error','info'=>'单据['.$search['number'].']已审核,不可删除!'];
+ }
+ }
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //审核|反审核
+ public function examine(){
+ $input=input('post.');
+ if(existFull($input,['parm']) && is_array($input['parm'])){
+ //1 基础数据
+ $period=getPeriod();
+ $classList=Db::name('sor')->where([['id','in',$input['parm']]])->order(['id'=>'desc'])->select()->toArray();
+ //2 综合处理
+ foreach ($classList as $class) {
+ //1 CLASS验证
+ if($class['time']<=$period){
+ return json(['state'=>'error','info'=>'操作单据[ '.$class['number'].' ]失败,原因:单据日期与结账日期冲突!']);
+ exit;
+ }
+ if(!empty($class['examine'])){
+ //销售单
+ $sell=Db::name('sell')->where([['source','=',$class['id']]])->find();
+ if(!empty($sell)){
+ return json(['state'=>'error','info'=>'反审核单据[ '.$class['number'].' ]失败,原因:该订单存在关联销售单!']);
+ exit;
+ }
+ }
+ //2 数据处理
+ Db::startTrans();
+ try {
+ //场景判断
+ if(empty($class['examine'])){
+ //审核
+ Db::name('sor')->where([['id','=',$class['id']]])->update(['examine'=>1]);
+ Db::name('record')->insert(['type'=>'sor','source'=>$class['id'],'time'=>time(),'user'=>getUserID(),'info'=>'审核单据']);
+ pushLog('审核销售订单[ '.$class['number'].' ]');//日志
+ }else{
+ //反审核
+ Db::name('sor')->where([['id','=',$class['id']]])->update(['examine'=>0]);
+ Db::name('record')->insert(['type'=>'sor','source'=>$class['id'],'time'=>time(),'user'=>getUserID(),'info'=>'反审核单据']);
+ pushLog('反审核销售订单[ '.$class['number'].' ]');//日志
+ }
+
+ Db::commit();
+ } catch (\Exception $e) {
+ Db::rollback();
+ return json(['state'=>'error','info'=>'内部错误,操作已撤销!']);
+ exit;
+ }
+ }
+ $result=['state'=>'success'];
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //开启|关闭
+ public function update(){
+ $input=input('post.');
+ if(existFull($input,['id'])){
+ $period=getPeriod();
+ $class=Db::name('sor')->where([['id','=',$input['id']]])->find();
+ Db::startTrans();
+ if($class['time']<=$period){
+ return json(['state'=>'error','info'=>'操作单据失败,原因:单据日期与结账日期冲突!']);
+ exit;
+ }else{
+ try {
+ if($class['state']==3){
+ //开启
+ Db::name('sor')->where([['id','=',$class['id']]])->update(['state'=>1]);
+ Db::name('record')->insert(['type'=>'sor','source'=>$class['id'],'time'=>time(),'user'=>getUserID(),'info'=>'开启单据']);
+ pushLog('开启销售订单[ '.$class['number'].' ]');//日志
+ }else{
+ //关闭
+ Db::name('sor')->where([['id','=',$class['id']]])->update(['state'=>3]);
+ Db::name('record')->insert(['type'=>'sor','source'=>$class['id'],'time'=>time(),'user'=>getUserID(),'info'=>'关闭单据']);
+ pushLog('关闭销售订单[ '.$class['number'].' ]');//日志
+ }
+
+ Db::commit();
+ $result=['state'=>'success'];
+ } catch (\Exception $e) {
+ Db::rollback();
+ $result=['state'=>'error','info'=>'内部错误,操作已撤销!'];
+ }
+ }
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return empty($parm)?json($result):$result;
+ }
+ //生成销售单
+ public function buildSell(){
+ $input=input('post.');
+ if(existFull($input,['id'])){
+ //源数据
+ $source=[
+ 'class'=>Sors::where([['id','=',$input['id']]])->find(),
+ 'info'=>SorInfo::with(['goodsData','warehouseData'])->where([['pid','=',$input['id']]])->order(['id'=>'asc'])->select()->toArray()
+ ];
+ //状态验证
+ if($source['class']['state']!=2){
+ //CLASS数据
+ $class=[
+ 'source'=>$source['class']['id'],
+ 'customer'=>$source['class']['customer'],
+ 'total'=>0
+ ];
+ //INFO数据
+ $info=[];
+ $fun=getSys('fun');
+ foreach ($source['info'] as $infoVo) {
+ //判断入库状态
+ if(bccomp($infoVo['nums'],$infoVo['handle'])==1){
+ $infoVo['source']=$infoVo['id'];
+ $infoVo['serial']=[];
+ $infoVo['batch']='';
+ $infoVo['mfd']='';
+ $infoVo['retreat']=0;
+ //重算价格
+ $infoVo['nums']=math()->chain($infoVo['nums'])->sub($infoVo['handle'])->done();
+ $storage=math()->chain($infoVo['price'])->mul($infoVo['nums'])->round($fun['digit']['money'])->done();
+ //折扣额|金额
+ if($infoVo['discount']==0){
+ $infoVo['total']=$storage;
+ }else{
+ $infoVo['dsc']=math()->chain($storage)->div(100)->mul($infoVo['discount'])->round($fun['digit']['money'])->done();
+ $infoVo['total']=math()->chain($storage)->sub($infoVo['dsc'])->done();
+ }
+ //税额|价税合计
+ if($infoVo['tax']==0){
+ $infoVo['tpt']=$infoVo['total'];
+ }else{
+ $infoVo['tat']=math()->chain($infoVo['total'])->div(100)->mul($infoVo['tax'])->round(2)->done();
+ $infoVo['tpt']=math()->chain($infoVo['total'])->add($infoVo['tat'])->done();
+ }
+ //转存数据
+ $info[]=$infoVo;
+ $class['total']=math()->chain($class['total'])->add($infoVo['tpt'])->done();//累加单据金额
+ }
+ }
+ $result=['state'=>'success','info'=>['class'=>$class,'info'=>$info]];
+ }else{
+ $result=['state'=>'warning','info'=>'操作失败,订单状态为已出库!'];
+ }
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //生产采购订单
+ public function buildBor(){
+ $input=input('post.');
+ if(existFull($input,['id'])){
+ //源数据
+ $source=[
+ 'class'=>Sors::where([['id','=',$input['id']]])->find(),
+ 'info'=>SorInfo::with(['goodsData','warehouseData'])->where([['pid','=',$input['id']]])->order(['id'=>'asc'])->select()->toArray()
+ ];
+ //状态验证
+ if($source['class']['state']!=2){
+ //CLASS数据
+ $class=[
+ 'source'=>$source['class']['id'],
+ 'total'=>0
+ ];
+ //INFO数据
+ $info=[];
+ $fun=getSys('fun');
+ foreach ($source['info'] as $infoVo) {
+ //判断入库状态
+ if(bccomp($infoVo['nums'],$infoVo['handle'])==1){
+ $infoVo['handle']=0;
+ //重算价格
+ $infoVo['price']=$infoVo['goodsData']['buy'];
+ $infoVo['nums']=math()->chain($infoVo['nums'])->sub($infoVo['handle'])->done();
+ $storage=math()->chain($infoVo['price'])->mul($infoVo['nums'])->round($fun['digit']['money'])->done();
+ //折扣额|金额
+ if($infoVo['discount']==0){
+ $infoVo['total']=$storage;
+ }else{
+ $infoVo['dsc']=math()->chain($storage)->div(100)->mul($infoVo['discount'])->round($fun['digit']['money'])->done();
+ $infoVo['total']=math()->chain($storage)->sub($infoVo['dsc'])->done();
+ }
+ //税额|价税合计
+ if($infoVo['tax']==0){
+ $infoVo['tpt']=$infoVo['total'];
+ }else{
+ $infoVo['tat']=math()->chain($infoVo['total'])->div(100)->mul($infoVo['tax'])->round(2)->done();
+ $infoVo['tpt']=math()->chain($infoVo['total'])->add($infoVo['tat'])->done();
+ }
+ //转存数据
+ $info[]=$infoVo;
+ $class['total']=math()->chain($class['total'])->add($infoVo['tpt'])->done();//累加单据金额
+ }
+ }
+ $result=['state'=>'success','info'=>['class'=>$class,'info'=>$info]];
+ }else{
+ $result=['state'=>'warning','info'=>'操作失败,订单状态为已出库!'];
+ }
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //上传
+ public function upload(){
+ $file = request()->file('file');
+ //获取上传文件
+ if (empty($file)) {
+ $result = ['state' => 'error','info' => '传入数据不完整!'];
+ } else {
+ //文件限制5MB
+ try{
+ validate(['file'=>['fileSize'=>5*1024*1024,'fileExt'=>'png,gif,jpg,jpeg,txt,doc,docx,rtf,xls,xlsx,ppt,pptx,pdf,zip,rar']])->check(['file'=>$file]);
+ $fileInfo=Filesystem::disk('upload')->putFile('sor', $file, 'uniqid');
+ $filePath=request()->domain().'/static/upload/'.$fileInfo;
+ $result=['state'=>'success','info'=>$filePath];
+ }catch(ValidateException $e) {
+ $result = ['state'=>'error','info'=>$e->getMessage()];
+ }
+ }
+ return json($result);
+ }
+ //导入
+ public function import(){
+ delOverdueFile('static.upload.xlsx');//删除过期文件
+ $file=request()->file('file');//获取上传文件
+ if(empty($file)){
+ $result=['state'=>'error','info'=>'传入数据不完整!'];
+ }else{
+ $fun=getSys('fun');
+ try{
+ validate(['file'=>['fileSize'=>2*1024*1024,'fileExt'=>'xlsx']])->check(['file'=>$file]);
+ $fileInfo = Filesystem::disk('upload')->putFile('xlsx', $file, 'uniqid');
+ $filePath = pathChange('static.upload').$fileInfo;
+ $data=getXlsx($filePath);
+ unset($data[1]);//删除标题行
+ unset($data[2]);//删除列名行
+ //初始化CLASS
+ //客户匹配
+ $customer=Db::name('customer')->where([['name','=',$data[3]['A']]])->find();
+ if(empty($customer)){
+ throw new ValidateException('客户[ '.$data[3]['A'].' ]未匹配!');
+ }
+ //关联人员匹配
+ if(empty($data[3]['F'])){
+ $people=['id'=>0];
+ }else{
+ $people=Db::name('people')->where([['name','=',$data[3]['F']]])->find();
+ if(empty($people)){
+ throw new ValidateException('关联人员[ '.$data[3]['F'].' ]未匹配!');
+ }
+ }
+ $class=[
+ 'frame'=>userInfo(getUserID(),'frame'),
+ 'customer'=>$customer['id'],
+ 'time'=>$data[3]['B'],
+ 'number'=>$data[3]['C'],
+ 'total'=>0,
+ 'actual'=>$data[3]['E'],
+ 'people'=>$people['id'],
+ 'arrival'=>$data[3]['G'],
+ 'logistics'=>["key"=>"auto","name"=>"自动识别","number"=>$data[3]['H']],
+ 'file'=>[],
+ 'data'=>$data[3]['I'],
+ 'more'=>[],
+ 'examine'=>0,
+ 'state'=>0,
+ 'user'=>getUserID()
+ ];
+ $this->validate($class,'app\validate\Sor');//数据合法性验证
+ //初始化INFO
+ $info=[];
+ $goods=Goods::with(['attr'])->where([['name','in',array_column($data,'J')]])->select()->toArray();
+ $warehouse=Db::name('warehouse')->where([['name','in',array_column($data,'M')]])->select()->toArray();
+ foreach ($data as $dataKey=>$dataVo) {
+ $record=[
+ 'goods'=>$dataVo['J'],
+ 'attr'=>$dataVo['K'],
+ 'unit'=>$dataVo['L'],
+ 'warehouse'=>$dataVo['M'],
+ 'price'=>$dataVo['N'],
+ 'nums'=>$dataVo['O'],
+ 'discount'=>$dataVo['P'],
+ 'dsc'=>0,
+ 'total'=>0,
+ 'tax'=>$dataVo['S'],
+ 'tat'=>0,
+ 'tpt'=>0,
+ 'data'=>$dataVo['V'],
+ 'handle'=>0,
+ ];
+ //商品匹配
+ $goodsFind=search($goods)->where([['name','=',$record['goods']]])->find();
+ if(empty($goodsFind)){
+ throw new ValidateException('模板文件第'.$dataKey.'行商品名称[ '.$record['goods'].' ]未匹配!');
+ }else{
+ $record['goods']=$goodsFind['id'];
+ }
+ //辅助属性匹配
+ if(empty($goodsFind['attr'])){
+ $record['attr']='';
+ }else{
+ if(empty($record['attr'])){
+ throw new ValidateException('模板文件第'.$dataKey.'行辅助属性不可为空!');
+ }else{
+ $attrFind=search($goodsFind['attr'])->where([['name','=',$record['attr']]])->find();
+ if(empty($attrFind)){
+ throw new ValidateException('模板文件第'.$dataKey.'行辅助属性[ '.$record['attr'].' ]未匹配!');
+ }
+ }
+ }
+ //单位匹配
+ if($goodsFind['unit']==-1){
+ if(empty($record['unit'])){
+ throw new ValidateException('模板文件第'.$dataKey.'行单位不可为空!');
+ }else{
+ $unitFind=search($goodsFind['units'])->where([['name','=',$record['unit']]])->find();
+ if(empty($unitFind) && $goodsFind['units'][0]['source']!=$record['unit']){
+ throw new ValidateException('模板文件第'.$dataKey.'行单位[ '.$record['unit'].' ]未匹配!');
+ }
+ }
+ }else{
+ $record['unit']=$goodsFind['unit'];
+ }
+ //仓库匹配
+ if(empty($goodsFind['type'])){
+ //常规产品
+ $warehouseFind=search($warehouse)->where([['name','=',$record['warehouse']]])->find();
+ if(empty($warehouseFind)){
+ throw new ValidateException('模板文件第'.$dataKey.'行仓库[ '.$record['warehouse'].' ]未匹配!');
+ }else{
+ $record['warehouse']=$warehouseFind['id'];
+ }
+ }else{
+ //服务产品
+ $record['warehouse']=null;
+ }
+ //单价匹配
+ if(!preg_match("/^\d+(\.\d{0,".$fun['digit']['money']."})?$/",$record['price'])){
+ throw new ValidateException('模板文件第'.$dataKey.'行单价不正确!');
+ }
+ //数量匹配
+ if(!preg_match("/^\d+(\.\d{0,".$fun['digit']['nums']."})?$/",$record['nums'])){
+ throw new ValidateException('模板文件第'.$dataKey.'行数量不正确!');
+ }
+ try{
+ $this->validate($record,'app\validate\SorInfo');//数据合法性验证
+ $storage=math()->chain($record['price'])->mul($record['nums'])->round($fun['digit']['money'])->done();
+ //折扣额|金额
+ if($record['discount']==0){
+ $record['total']=$storage;
+ }else{
+ $record['dsc']=math()->chain($storage)->div(100)->mul($record['discount'])->round($fun['digit']['money'])->done();
+ $record['total']=math()->chain($storage)->sub($record['dsc'])->done();
+ }
+ //税额|价税合计
+ if($record['tax']==0){
+ $record['tpt']=$record['total'];
+ }else{
+
+ $record['tat']=math()->chain($record['total'])->div(100)->mul($record['tax'])->round(2)->done();
+ $record['tpt']=math()->chain($record['total'])->add($record['tat'])->done();
+ }
+ //转存数据
+ $class['total']=math()->chain($class['total'])->add($record['tpt'])->done();//累加单据金额
+ $info[]=$record;
+ } catch (ValidateException $e) {
+ return json(['state'=>'error','info'=>'模板文件第'.$dataKey.'行'.$e->getMessage()]);//返回错误信息
+ exit;
+ }
+ }
+ //CLASS数据验证
+ if(bccomp($class['total'],$class['actual'])==-1){
+ throw new ValidateException('实际金额不可大于单据金额[ '.$class['total'].' ]!');
+ }else{
+ Db::startTrans();
+ try {
+ //新增CLASS
+ $classData=Sors::create($class);
+ //新增INFO
+ foreach ($info as $infoKey=>$infoVo) {
+ $info[$infoKey]['pid']=$classData['id'];
+ }
+ $model = new SorInfo;
+ $model->saveAll($info);
+ Db::name('record')->insert(['type'=>'sor','source'=>$classData['id'],'time'=>time(),'user'=>getUserID(),'info'=>'导入单据']);
+ pushLog('导入销售订单[ '.$classData['number'].' ]');//日志
+
+ Db::commit();
+ $result=['state'=>'success'];
+ } catch (\Exception $e) {
+ Db::rollback();
+ $result=['state'=>'error','info'=>'内部错误,操作已撤销!'];
+ }
+ }
+ }catch(ValidateException $e) {
+ $result=['state'=>'error','info'=>$e->getMessage()];//返回错误信息
+ }
+ }
+ return json($result);
+ }
+ //导出
+ public function exports(){
+ $input=input('get.');
+ if(existFull($input,['scene','parm']) && is_array($input['parm'])){
+ pushLog('导出销售订单列表');//日志
+ $source=Sors::with(['frameData','customerData','peopleData','userData'])->where([['id','in',$input['parm']]])->append(['extension'])->order(['id'=>'desc'])->select()->toArray();//查询CLASS数据
+ if($input['scene']=='simple'){
+ //简易报表
+ //开始构造导出数据
+ $excel=[];//初始化导出数据
+ //标题数据
+ $excel[]=['type'=>'title','info'=>'销售订单列表'];
+ //表格数据
+ $field=[
+ 'frameData|name'=>'所属组织',
+ 'customerData|name'=>'客户',
+ 'time'=>'单据时间',
+ 'number'=>'单据编号',
+ 'total'=>'单据金额',
+ 'actual'=>'实际金额',
+ 'arrival'=>'到货日期',
+ 'peopleData|name'=>'关联人员',
+ 'extension|examine'=>'审核状态',
+ 'extension|state'=>'出库状态',
+ 'userData|name'=>'制单人',
+ 'data'=>'备注信息'
+ ];
+ $thead=array_values($field);//表格标题
+ $tbody=[];//表格内容
+ //构造表内数据
+ foreach ($source as $sourceVo) {
+ $rowData=[];
+ foreach (array_keys($field) as $fieldVo) {
+ $rowData[]=arraySeek($sourceVo,$fieldVo);//多键名数据赋值
+ }
+ $tbody[]=$rowData;//加入行数据
+ }
+ $excel[]=['type'=>'table','info'=>['thead'=>$thead,'tbody'=>$tbody]];//表格数据
+ //统计数据
+ $excel[]=['type'=>'node','info'=>['总数:'.count($source),'总单据金额:'.mathArraySum(array_column($source,'total')),'总实际金额:'.mathArraySum(array_column($source,'actual'))]];
+ //导出execl
+ buildExcel('销售订单列表',$excel);
+ }else{
+ //详细报表
+ $files=[];//初始化文件列表
+ foreach ($source as $sourceVo) {
+ //开始构造导出数据
+ $excel=[];//初始化导出数据
+ //标题数据
+ $excel[]=['type'=>'title','info'=>'销售订单'];
+ //节点数据
+ $excel[]=['type'=>'node','info'=>[
+ '客户:'.$sourceVo['customerData']['name'],
+ '单据日期:'.$sourceVo['time'],
+ '单据编号:'.$sourceVo['number']]
+ ];
+ //表格数据
+ $field=[
+ 'goodsData|name'=>'商品名称',
+ 'goodsData|spec'=>'规格型号',
+ 'attr'=>'辅助属性',
+ 'unit'=>'单位',
+ 'warehouseData|name'=>'仓库',
+ 'price'=>'单价',
+ 'nums'=>'数量',
+ 'handle'=>'出库数量',
+ 'discount'=>'折扣率',
+ 'dsc'=>'折扣额',
+ 'total'=>'金额',
+ 'tax'=>'税率',
+ 'tat'=>'税额',
+ 'tpt'=>'价税合计',
+ 'data'=>'备注信息'
+ ];
+ //构造表内数据
+ $info=SorInfo::with(['goodsData','warehouseData'])->where([['pid','=',$sourceVo['id']]])->order(['id'=>'asc'])->select()->toArray();
+ //税金匹配
+ $fun=getSys('fun');
+ if(empty(search($info)->where([['tax','<>',0]])->find()) && !$fun['tax']){
+ unset($field['tax']);
+ unset($field['tat']);
+ unset($field['tpt']);
+ }
+ $thead=array_values($field);//表格标题
+ $tbody=[];//表格内容
+ foreach ($info as $infoVo) {
+ $rowData=[];
+ foreach (array_keys($field) as $fieldVo) {
+ $rowData[]=arraySeek($infoVo,$fieldVo);//多键名数据赋值
+ }
+ $tbody[]=$rowData;//加入行数据
+ }
+ $excel[]=['type'=>'table','info'=>['thead'=>$thead,'tbody'=>$tbody]];//表格数据
+ //节点数据
+ $excel[]=['type'=>'node','info'=>[
+ '单据金额:'.$sourceVo['total'],
+ '实际金额:'.$sourceVo['actual'],
+ '关联人员:'.arraySeek($sourceVo,'peopleData|name'),
+ '到货日期:'.$sourceVo['arrival'],
+ '物流信息:'.$sourceVo['extension']['logistics'],
+ '备注信息:'.$sourceVo['data']]
+ ];
+ //生成execl
+ $files[]=buildExcel($sourceVo['number'],$excel,false);
+ }
+ buildZip('销售订单_'.time(),$files);
+ }
+ }else{
+ return json(['state'=>'error','info'=>'传入数据不完整!']);
+ }
+ }
+}
diff --git a/serve/app/controller/Sre.php b/serve/app/controller/Sre.php
new file mode 100644
index 0000000..2727e81
--- /dev/null
+++ b/serve/app/controller/Sre.php
@@ -0,0 +1,1175 @@
+'time'],'startTime'],
+ [['endTime'=>'time'],'endTime'],
+ ['examine','fullDec1'],
+ ['nucleus','fullDec1'],
+ ['cse','fullDec1'],
+ ['invoice','fullDec1'],
+ ['check','fullDec1'],
+ ['data','fullLike']
+ ]);//构造SQL
+ //商品信息扩展查询
+ if(existFull($input,['goods'])){
+ $goods=array_column(Db::name('goods')->where([['name|py','like','%'.$input['goods'].'%']])->select()->toArray(),'id');
+ $sql[]=['id','in',array_column(Db::name('sre_info')->where([['goods','in',$goods]])->select()->toArray(),'pid')];
+ }
+ $sql=frameScope($sql);//组织数据
+ $sql=sqlAuth('sre',$sql);//数据鉴权
+ $count = Sres::where($sql)->count();//获取总条数
+ $info = Sres::with(['frameData','customerData','peopleData','userData','billData','costData','invoiceData','recordData'])->where($sql)->append(['extension'])->page($input['page'],$input['limit'])->order(['id'=>'desc'])->select()->toArray();//查询分页数据
+ //关联单据
+ if(!empty($info)){
+ $sell=Db::name('sell')->where([['id','in',array_column($info,'source')]])->select()->toArray();
+ foreach ($info as $infoKey=>$infoVo) {
+ //销售单
+ $relation=array_map(function($item){
+ return ['type'=>'销售单','time'=>date('Y-m-d',$item['time']),'number'=>$item['number'],'sort'=>$item['time'],'sort'=>$item['time'],'sort'=>$item['time'],'types'=>'sell','id'=>$item['id']];
+ },search($sell)->where([['id','=',$infoVo['source']]])->select());
+ //数据排序
+ array_multisort(array_column($relation,'sort'),SORT_DESC,$relation);
+ $info[$infoKey]['relation']=$relation;
+ }
+ }
+ $result=[
+ 'state'=>'success',
+ 'count'=>$count,
+ 'info'=>$info
+ ];//返回数据
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //新增|更新
+ public function save(){
+ $input=input('post.');
+ if(existFull($input,['class','info']) && isset($input['class']['id'])){
+ //构造|验证CLASS
+ try {
+ $class=$input['class'];
+ $class['frame']=userInfo(getUserID(),'frame');
+ $class['user']=getUserID();
+ $class['cse']=empty($class['cost'])?3:0;
+ $class['invoice']=empty($class['actual'])?3:0;
+ $class['examine']=0;
+ $class['nucleus']=0;
+ empty($class['id'])?$this->validate($class,'app\validate\Sre'):$this->validate($class,'app\validate\Sre.update');
+ $period=getPeriod();
+ if(strtotime($class['time'])<=$period){
+ throw new ValidateException('单据日期与结账日期冲突!');
+ }
+ } catch (ValidateException $e) {
+ return json(['state'=>'error','info'=>$e->getError()]);
+ exit;
+ }
+
+ //验证INFO
+ foreach ($input['info'] as $infoKey=>$infoVo) {
+ try {
+ $this->validate($infoVo,'app\validate\SreInfo');
+ } catch (ValidateException $e) {
+ return json(['state'=>'error','info'=>'商品信息第'.($infoKey+1).'条'.$e->getError()]);
+ exit;
+ }
+ }
+
+ //验证Cost
+ foreach ($input['cost'] as $costKey=>$costVo) {
+ try {
+ $this->validate($costVo,'app\validate\Cost');
+ } catch (ValidateException $e) {
+ return json(['state'=>'error','info'=>'单据费用第'.($infoKey+1).'条'.$e->getError()]);
+ exit;
+ }
+ }
+
+ //处理数据
+ Db::startTrans();
+ try {
+ //CLASS数据
+ if(empty($class['id'])){
+ //创建数据
+ $createInfo=Sres::create($class);
+ $class['id']=$createInfo['id'];//转存主键
+ Db::name('record')->insert(['type'=>'sre','source'=>$class['id'],'time'=>time(),'user'=>getUserID(),'info'=>'新增单据']);
+ pushLog('新增销售退货单[ '.$class['number'].' ]');//日志
+ }else{
+ //更新数据
+ $updateInfo=Sres::update($class);
+ Db::name('record')->insert(['type'=>'sre','source'=>$class['id'],'time'=>time(),'user'=>getUserID(),'info'=>'更新单据']);
+ pushLog('更新销售退货单[ '.$class['number'].' ]');//日志
+ }
+
+ //INFO数据
+ SreInfo::where([['pid','=',$class['id']]])->delete();
+ foreach ($input['info'] as $infoKey=>$infoVo) {
+ $input['info'][$infoKey]['pid']=$class['id'];
+ }
+ $model = new SreInfo;
+ $model->saveAll($input['info']);
+
+ //COST数据
+ Cost::where([['type','=','sre'],['class','=',$class['id']]])->delete();
+ foreach ($input['cost'] as $costKey=>$costVo) {
+ unset($input['cost'][$costKey]['id']);
+ $input['cost'][$costKey]['type']='sre';
+ $input['cost'][$costKey]['class']=$class['id'];
+ $input['cost'][$costKey]['time']=$class['time'];
+ $input['cost'][$costKey]['settle']=0;
+ $input['cost'][$costKey]['state']=0;
+ }
+ $model = new Cost;
+ $model->saveAll($input['cost']);
+
+ Db::commit();
+ $result=['state'=>'success','info'=>$class['id']];
+ } catch (\Exception $e) {
+ Db::rollback();
+ $result=['state'=>'error','info'=>'内部错误,操作已撤销!'];
+ }
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //获取
+ public function get(){
+ $input=input('post.');
+ if(existFull($input,['parm'])){
+ $class=Sres::where([['id','=',$input['parm']]])->find();
+ $info=SreInfo::with(['goodsData','warehouseData'])->where([['pid','=',$input['parm']]])->order(['id'=>'asc'])->select();
+ $cost=Cost::where([['type','=','sre'],['class','=',$input['parm']]])->order(['id'=>'asc'])->select();
+ $result=['state'=>'success','info'=>[
+ 'class'=>$class,
+ 'info'=>$info,
+ 'cost'=>$cost,
+ ]];
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //删除
+ public function del(){
+ $input=input('post.');
+ if(existFull($input,['parm']) && is_array($input['parm'])){
+ $data=Db::name('sre')->where([['id','in',$input['parm']]])->order(['id'=>'desc'])->select()->toArray();
+ $search=search($data)->where([['examine','=','1']])->find();
+ if(empty($search)){
+ Db::startTrans();
+ try {
+ Db::name('sre')->where([['id','in',$input['parm']]])->delete();
+ Db::name('sre_info')->where([['pid','in',$input['parm']]])->delete();
+ Db::name('cost')->where([['type','=','sre'],['class','in',$input['parm']]])->delete();
+ Db::name('record')->where([['type','=','sre'],['source','in',$input['parm']]])->delete();
+ Db::name('log')->insert(['time'=>time(),'user'=>getUserID(),'info'=>'删除销售退货单[ '.implode(' | ',array_column($data,'number')).' ]']);
+
+ Db::commit();
+ $result=['state'=>'success'];
+ } catch (\Exception $e) {
+ Db::rollback();
+ $result=['state'=>'error','info'=>'内部错误,操作已撤销!'];
+ }
+ }else{
+ $result=['state'=>'error','info'=>'单据['.$search['number'].']已审核,不可删除!'];
+ }
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //核对|反核对
+ public function check(){
+ $input=input('post.');
+ if(existFull($input,['parm']) && is_array($input['parm'])){
+ $period=getPeriod();
+ $classList=Db::name('sre')->where([['id','in',$input['parm']]])->order(['id'=>'desc'])->select()->toArray();
+ foreach ($input['parm'] as $parmVo) {
+ $class=search($classList)->where([['id','=',$parmVo]])->find();
+ if($class['time']<=$period){
+ return json(['state'=>'error','info'=>'操作单据失败,原因:单据日期与结账日期冲突!']);
+ exit;
+ }
+ if(empty($class['check'])){
+ Db::name('sre')->where([['id','=',$class['id']]])->update(['check'=>1]);
+ //1 单据记录
+ Db::name('record')->insert(['type'=>'sre','source'=>$class['id'],'time'=>time(),'user'=>getUserID(),'info'=>'核对单据']);
+ //2 记录操作
+ pushLog('核对销售退货单[ '.$class['number'].' ]');//单据日志
+ }else{
+ Db::name('sre')->where([['id','=',$class['id']]])->update(['check'=>0]);
+ //1 单据记录
+ Db::name('record')->insert(['type'=>'sre','source'=>$class['id'],'time'=>time(),'user'=>getUserID(),'info'=>'反核对单据']);
+ //2 记录操作
+ pushLog('反核对销售退货单[ '.$class['number'].' ]');//单据日志
+ }
+ }
+ $result=['state'=>'success'];
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //审核|反审核
+ public function examine(){
+ $input=input('post.');
+ if(existFull($input,['parm']) && is_array($input['parm'])){
+ //1 基础数据
+ $period=getPeriod();
+ $classList=Db::name('sre')->where([['id','in',$input['parm']]])->order(['id'=>'desc'])->select()->toArray();
+ $infoList=Db::name('sre_info')->where([['pid','in',$input['parm']]])->order(['id'=>'asc'])->select()->toArray();
+ //2 综合处理
+ foreach ($input['parm'] as $parmVo) {
+ //1 匹配数据
+ $class=search($classList)->where([['id','=',$parmVo]])->find();
+ $info=search($infoList)->where([['pid','=',$parmVo]])->select();
+ //1.1 商品数据
+ $goodsList=Db::name('goods')->where([['id','in',array_unique(array_column($info,'goods'))]])->select()->toArray();
+ //1.2 综合匹配
+ if(empty($class['examine'])){
+ //1 关联单据
+ empty($class['source'])||$sellInfoList=Db::name('sell_info')->where([['id','in',array_column($info,'source')]])->select()->toArray();
+ //2 构造数据
+ $batchGather=[];
+ $serialGather=[];
+ $roomWhereOrSql=[];
+ foreach ($info as $infoVo) {
+ //1 批次号
+ empty($infoVo['batch'])||$batchGather[]=$infoVo['batch'];
+ //2 序列号
+ $serialGather=array_merge($serialGather,json_decode($infoVo['serial']));
+ //3 仓储条件
+ empty($infoVo['warehouse'])||$roomWhereOrSql[]=[['warehouse','=',$infoVo['warehouse']],['goods','=',$infoVo['goods']],['attr','=',$infoVo['attr']]];
+ }
+ //3 匹配数据
+ empty($batchGather)||$batchList=Db::name('batch')->where([['number','in',$batchGather]])->select()->toArray();
+ empty($serialGather)||$serialList=Db::name('serial')->where([['number','in',$serialGather]])->select()->toArray();
+ if(!empty($roomWhereOrSql)){
+ //1 去重转存
+ $roomWhereOrSql=array_unique($roomWhereOrSql,SORT_REGULAR);
+ //2 仓储匹配
+ $roomList=Db::name('room')->whereOr($roomWhereOrSql)->select()->toArray();
+ }
+ }
+ //2 CLASS验证
+ if($class['time']<=$period){
+ return json(['state'=>'error','info'=>'操作单据[ '.$class['number'].' ]失败,原因:单据日期与结账日期冲突!']);
+ exit;
+ }
+ if(!empty($class['examine'])){
+ //1 核销单
+ $bill=Db::name('bill_info')->where([['mold','=','sre'],['source','=',$class['id']]])->find();
+ if(!empty($bill)){
+ return json(['state'=>'error','info'=>'反审核单据[ '.$class['number'].' ]失败,原因:该单据存在关联核销单!']);
+ exit;
+ }
+ //2 单据费用
+ $cost=Db::name('cost')->alias('cost')->where([['type','=','sre'],['class','=',$class['id']]])->whereExists(function($query){
+ $query->name('oce_info')->where([['source','=',Db::raw('cost.id')]])->limit(1);
+ })->find();
+ if(!empty($cost)){
+ return json(['state'=>'error','info'=>'反审核单据[ '.$class['number'].' ]失败,原因:该单据存在关联其它支出单!']);
+ exit;
+ }
+ //3 单据发票
+ $invoice=Db::name('invoice')->where([['type','=','sre'],['class','=',$class['id']]])->find();
+ if(!empty($invoice)){
+ return json(['state'=>'error','info'=>'反审核单据[ '.$class['number'].' ]失败,原因:该单据存在关联单据发票!']);
+ exit;
+ }
+ }
+ //3 INFO验证|构造
+ foreach ($info as $infoKey=>$infoVo) {
+ //1 匹配商品
+ $goods=search($goodsList)->where([['id','=',$infoVo['goods']]])->find();
+ //2 商品类型
+ if(empty($goods['type'])){
+ //场景验证
+ if(empty($class['examine'])){
+ //1 关联单据
+ if(!empty($infoVo['source'])){
+ $sellInfo=search($sellInfoList)->where([['id','=',$infoVo['source']]])->find();
+ if(!empty($sellInfo)){
+ if($sellInfo['unit']!=$infoVo['unit']){
+ //单位匹配
+ return json(['state'=>'error','info'=>'审核单据[ '.$class['number'].' ]失败,原因:第'.($infoKey+1).'行单位与销售单不匹配!']);
+ exit;
+ }elseif(bccomp(math()->chain($sellInfo['retreat'])->add($infoVo['nums'])->done(),$sellInfo['nums'])==1){
+ //数量匹配
+ return json(['state'=>'error','info'=>'审核单据[ '.$class['number'].' ]失败,原因:第'.($infoKey+1).'行超出销售单可退货数量!']);
+ exit;
+ }
+ }
+
+ }
+ //2 多单位处理
+ if($goods['unit']==-1){
+ //多单位|转存
+ $radix=unitRadix($infoVo['unit'],json_decode($goods['units'],true));
+ $info[$infoKey]['basic']=[
+ 'nums'=>math()->chain($infoVo['nums'])->mul($radix)->done(),
+ 'price'=>math()->chain($infoVo['price'])->div($radix)->round(4)->done()
+ ];
+ }else{
+ //常规单位|转存
+ $info[$infoKey]['basic']=[
+ 'nums'=>$infoVo['nums'],
+ 'price'=>$infoVo['price']
+ ];
+ }
+ //3 序列号
+ $serialData=json_decode($infoVo['serial']);
+ if(empty($serialData)){
+ $info[$infoKey]['serial']=[];
+ }else{
+ //序列号状态[不存在|已销售]
+ $serialFind=search($serialList)->where([['goods','=',$infoVo['goods']],['number','in',$serialData],['state','<>',1]])->find();
+ if(empty($serialFind)){
+ $info[$infoKey]['serial']=$serialData;
+ }else{
+ return json(['state'=>'error','info'=>'审核单据[ '.$class['number'].' ]失败,原因:第'.($infoKey+1).'行序列号[ '.$serialFind['number'].' ]状态不正确!']);
+ exit;
+ }
+ }
+ }else{
+ //1 验证序列号
+ $serialInfoCollect=Db::name('serial_info')->where([['type','=','sre'],['info','in',array_column($info,'id')]])->select()->toArray();
+ if(!empty($serialInfoCollect)){
+ //序列号状态[未销售]
+ $serialFind=Db::name('serial')->where([['id','in',array_column($serialInfoCollect,'pid')],['state','<>',0]])->find();
+ if(!empty($serialFind)){
+ return json(['state'=>'error','info'=>'反审核单据[ '.$class['number'].' ]失败,原因:第'.($infoKey+1).'行序列号[ '.$serialFind['number'].' ]状态不正确!']);
+ exit;
+ }
+ }
+ }
+ }
+ }
+ //4 数据处理
+ Db::startTrans();
+ try {
+ //场景验证
+ if(empty($class['examine'])){
+ //审核
+ //1 构造数据
+ $store=['sellInfo'=>[],'room'=>[],'roomInfo'=>[],'batch'=>[],'batchInfo'=>[],'serial'=>[],'serialInfo'=>[],'serve'=>[],'serveInfo'=>[]];
+ foreach ($info as $infoKey=>$infoVo){
+ //1 关联单据
+ empty($infoVo['source'])||$store['sellInfo'][]=['id'=>$infoVo['source'],'retreat'=>$infoVo['nums']];
+ //2 判断商品类型
+ $goods=search($goodsList)->where([['id','=',$infoVo['goods']]])->find();
+ if(empty($goods['type'])){
+ //常规商品
+ //1 仓储
+ $store['room'][]=['warehouse'=>$infoVo['warehouse'],'goods'=>$infoVo['goods'],'attr'=>$infoVo['attr'],'nums'=>$infoVo['basic']['nums']];
+ //2 仓储详情
+ $store['roomInfo'][]=['pid'=>null,'type'=>'sre','class'=>$class['id'],'info'=>$infoVo['id'],'time'=>$class['time'],'direction'=>1,'price'=>$infoVo['basic']['price'],'nums'=>$infoVo['basic']['nums']];
+ //3 批次号
+ if(empty($infoVo['batch'])){
+ $store['batch'][]=[];
+ $store['batchInfo'][]=[];
+ }else{
+ $store['batch'][]=['room'=>null,'warehouse'=>$infoVo['warehouse'],'goods'=>$infoVo['goods'],'number'=>$infoVo['batch'],'time'=>$infoVo['mfd'],'nums'=>$infoVo['basic']['nums']];
+ $store['batchInfo'][]=['pid'=>null,'type'=>'sre','class'=>$class['id'],'info'=>$infoVo['id'],'direction'=>1,'nums'=>$infoVo['basic']['nums']];
+ }
+ //4 序列号
+ if(empty($infoVo['serial'])){
+ $store['serial'][]=[];
+ $store['serialInfo'][]=[];
+ }else{
+ $serial=[];
+ $serialInfo=[];
+ foreach ($infoVo['serial'] as $serialVo) {
+ $serial[]=['room'=>null,'warehouse'=>$infoVo['warehouse'],'batch'=>null,'goods'=>$infoVo['goods'],'number'=>$serialVo,'state'=>0];
+ $serialInfo[]=['pid'=>null,'type'=>'sre','class'=>$class['id'],'info'=>$infoVo['id']];
+ }
+ $store['serial'][]=$serial;
+ $store['serialInfo'][]=$serialInfo;
+ }
+ }else{
+ //5 服务商品
+ $store['serve'][]=['goods'=>$infoVo['goods'],'attr'=>$infoVo['attr'],'nums'=>$infoVo['nums']];
+ $store['serveInfo'][]=['pid'=>null,'type'=>'sre','class'=>$class['id'],'info'=>$infoVo['id'],'time'=>$class['time'],'price'=>$infoVo['price'],'nums'=>$infoVo['nums']];
+ }
+ }
+ //2 关联单据
+ if(!empty($store['sellInfo'])){
+ //更新详情
+ Db::name('sell_info')->duplicate(['retreat'=>Db::raw('retreat + VALUES(`retreat`)')])->insertAll($store['sellInfo']);
+ $sellInfo=Db::name('sell_info')->where([['id','in',array_column($store['sellInfo'],'id')]])->select()->toArray();
+ $sorInfoDuplicate=[];
+ foreach ($sellInfo as $sellVo){
+ $nums=search($store['sellInfo'])->where([['id','=',$sellVo['id']]])->find()['retreat'];
+ empty($sellVo['source'])||$sorInfoDuplicate[]=['id'=>$sellVo['source'],'handle'=>$nums];
+ }
+ if(!empty($sorInfoDuplicate)){
+ //更新详情
+ Db::name('sor_info')->duplicate(['handle'=>Db::raw('handle - VALUES(`handle`)')])->insertAll($sorInfoDuplicate);
+ //2 更新销售订单CLASS
+ $sorInfo=Db::name('sor_info')->where([['id','in',array_column($sellInfo,'source')]])->select()->toArray();
+ if(array_sum(array_column($sorInfo,'handle'))==0){
+ $state=0;
+ }else{
+ $state=mathArraySum(array_column($sorInfo,'nums'))==mathArraySum(array_column($sorInfo,'handle'))?2:1;
+ }
+ Db::name('sor')->where([['id','=',$sorInfo[0]['pid']]])->update(['state'=>$state]);
+ }
+
+ }
+ //3 仓储
+ if(!empty($store['room'])){
+ //1 构造数据
+ $roomInsert=[];
+ foreach ($store['room'] as $roomVo) {
+ $roomFind=search($roomList)->where([['warehouse','=',$roomVo['warehouse']],['goods','=',$roomVo['goods']],['attr','=',$roomVo['attr']]])->find();
+ if(empty($roomFind)){
+ $roomVo['nums']=0;
+ $roomInsert[]=$roomVo;
+ }
+ }
+ //2 创建数据|去重
+ empty($roomInsert)||Db::name('room')->insertAll(array_unique($roomInsert,SORT_REGULAR));
+ //3 匹配主键|构造更新
+ $roomDuplicate=[];
+ $room=Db::name('room')->whereOr($roomWhereOrSql)->select()->toArray();
+ foreach ($store['room'] as $roomKey=>$roomVo) {
+ $roomFind=search($room)->where([['warehouse','=',$roomVo['warehouse']],['goods','=',$roomVo['goods']],['attr','=',$roomVo['attr']]])->find();
+ $store['room'][$roomKey]['id']=$roomFind['id'];
+ $roomDuplicate[]=['id'=>$roomFind['id'],'nums'=>$roomVo['nums']];
+ }
+ //4 更新数据
+ Db::name('room')->duplicate(['nums'=>Db::raw('nums + VALUES(`nums`)')])->insertAll($roomDuplicate);
+ }
+ //4 仓储详情
+ if(!empty($store['roomInfo'])){
+ //1 填充数据
+ foreach ($store['roomInfo'] as $roomInfoKey=>$roomInfoVo) {
+ $store['roomInfo'][$roomInfoKey]['pid']=$store['room'][$roomInfoKey]['id'];
+ }
+ //2 创建数据
+ Db::name('room_info')->insertAll($store['roomInfo']);
+ }
+ //5 批次号
+ if(!empty($store['batch'])){
+ //1 构造数据
+ $batchData=[];
+ foreach ($store['batch'] as $batchKey=>$batchVo) {
+ if(!empty($batchVo)){
+ $store['batch'][$batchKey]['room']=$store['room'][$batchKey]['id'];
+ $batchData[]=$store['batch'][$batchKey];
+ }
+ }
+ //2 排除数据|[[],[],[]]
+ if(!empty($batchData)){
+ //1 构造数据
+ $batchInsert=[];
+ foreach ($batchData as $batchDataKey=>$batchDataVo) {
+ $batchFind=search($batchList)->where([['room','=',$batchDataVo['room']],['number','=',$batchDataVo['number']],['time','=',$batchDataVo['time']]])->find();
+ if(empty($batchFind)){
+ $batchDataVo['nums']=0;
+ $batchInsert[]=$batchDataVo;
+ }
+ }
+ //2 创建数据|去重
+ empty($batchInsert)||Db::name('batch')->insertAll(array_unique($batchInsert,SORT_REGULAR));
+ //3 匹配主键|构造更新
+ $batchDuplicate=[];
+ $batch=Db::name('batch')->where([['number','in',$batchGather]])->select()->toArray();
+ foreach ($store['batch'] as $batchKey=>$batchVo) {
+ if(!empty($batchVo)){
+ $batchFind=search($batch)->where([['room','=',$batchVo['room']],['number','=',$batchVo['number']],['time','=',$batchVo['time']]])->find();
+ $store['batch'][$batchKey]['id']=$batchFind['id'];
+ $batchDuplicate[]=['id'=>$batchFind['id'],'nums'=>$batchVo['nums']];
+ }
+ }
+ //4 更新数据
+ Db::name('batch')->duplicate(['nums'=>Db::raw('nums + VALUES(`nums`)')])->insertAll($batchDuplicate);
+ }
+ }
+ //6 批次号详情
+ if(!empty($store['batchInfo'])){
+ //1 构造数据
+ $batchInfoInstall=[];
+ foreach ($store['batchInfo'] as $batchInfoKey=>$batchInfoVo) {
+ if(!empty($batchInfoVo)){
+ $batchInfoVo['pid']=$store['batch'][$batchInfoKey]['id'];
+ $batchInfoInstall[]=$batchInfoVo;
+ }
+ }
+ //2 排除数据|[[],[],[]]
+ if(!empty($batchInfoInstall)){
+ //创建数据
+ Db::name('batch_info')->insertAll($batchInfoInstall);
+ }
+ }
+ //7 序列号
+ if(!empty($store['serial'])){
+ //1 构造数据
+ $serialData=[];
+ foreach ($store['serial'] as $serialKey=>$item) {
+ if(!empty($item)){
+ foreach ($item as $itemKey=>$itemVo) {
+ $store['serial'][$serialKey][$itemKey]['room']=$store['room'][$serialKey]['id'];
+ $store['serial'][$serialKey][$itemKey]['batch']=empty($store['batch'][$serialKey])?0:$store['batch'][$serialKey]['id'];
+ $serialData[]=$store['serial'][$serialKey][$itemKey];
+ }
+ }
+ }
+ //2 排除数据|[[],[],[]]
+ if(!empty($serialData)){
+ //1 构造数据
+ $serialInsert=[];
+ foreach ($serialData as $serialDataKey=>$serialDataVo) {
+ $serialFind=search($serialList)->where([['room','=',$serialDataVo['room']],['batch','=',$serialDataVo['batch']],['number','=',$serialDataVo['number']]])->find();
+ if(empty($serialFind)){
+ $serialInsert[]=$serialDataVo;
+ }
+ }
+ //2 创建数据
+ empty($serialInsert)||Db::name('serial')->insertAll($serialInsert);
+ //3 匹配主键|构造更新
+ $serialDuplicate=[];
+ $serial=Db::name('serial')->where([['number','in',$serialGather]])->select()->toArray();
+ foreach ($store['serial'] as $serialKey=>$item) {
+ if(!empty($item)){
+ foreach ($item as $itemKey=>$itemVo) {
+ $serialFind=search($serial)->where([['room','=',$itemVo['room']],['batch','=',$itemVo['batch']],['number','=',$itemVo['number']]])->find();
+ $store['serial'][$serialKey][$itemKey]['id']=$serialFind['id'];
+ $serialFind['state']==1&&$serialDuplicate[]=$serialFind['id'];
+ }
+ }
+ }
+ //4 更新数据|状态变更
+ empty($serialDuplicate)||Db::name('serial')->where([['id','in',$serialDuplicate]])->update(['state'=>0]);
+ }
+ }
+ //8 序列号详情
+ if(!empty($store['serialInfo'])){
+ //1 构造数据
+ $serialInfoInstall=[];
+ foreach ($store['serialInfo'] as $serialInfoKey=>$item) {
+ if(!empty($item)){
+ foreach ($item as $itemKey=>$itemVo) {
+ $itemVo['pid']=$store['serial'][$serialInfoKey][$itemKey]['id'];
+ $serialInfoInstall[]=$itemVo;
+ }
+ }
+ }
+ //2 排除数据|[[],[],[]]
+ if(!empty($serialInfoInstall)){
+ //创建数据
+ Db::name('serial_info')->insertAll($serialInfoInstall);
+ }
+ }
+ //9 服务商品
+ if(!empty($store['serve'])){
+ //1 匹配数据|去重
+ $serveWhereOrSql=array_unique(array_map(function($item){
+ return [['goods','=',$item['goods']],['attr','=',$item['attr']]];
+ },$store['serve']),SORT_REGULAR);
+ $serve=Db::name('serve')->whereOr($serveWhereOrSql)->select()->toArray();
+ //2 构造数据
+ $serveInsert=[];
+ foreach ($store['serve'] as $serveVo) {
+ $serveFind=search($serve)->where([['goods','=',$serveVo['goods']],['attr','=',$serveVo['attr']]])->find();
+ if(empty($serveFind)){
+ $serveVo['nums']=0;
+ $serveInsert[]=$serveVo;
+ }
+ }
+ //3 创建数据|去重
+ empty($serveInsert)||Db::name('serve')->insertAll(array_unique($serveInsert,SORT_REGULAR));
+ //4 匹配主键|构造更新
+ $serveDuplicate=[];
+ $serve=Db::name('serve')->whereOr($serveWhereOrSql)->select()->toArray();
+ foreach ($store['serve'] as $serveKey=>$serveVo) {
+ $serveFind=search($serve)->where([['goods','=',$serveVo['goods']],['attr','=',$serveVo['attr']]])->find();
+ $store['serve'][$serveKey]['id']=$serveFind['id'];
+ $serveDuplicate[]=['id'=>$serveFind['id'],'nums'=>$serveVo['nums']];
+ }
+ //5 更新数据
+ Db::name('serve')->duplicate(['nums'=>Db::raw('nums + VALUES(`nums`)')])->insertAll($serveDuplicate);
+ }
+ //10 服务商品详情
+ if(!empty($store['serveInfo'])){
+ //1 填充数据
+ foreach ($store['serveInfo'] as $serveInfoKey=>$serveInfoVo) {
+ $store['serveInfo'][$serveInfoKey]['pid']=$store['serve'][$serveInfoKey]['id'];
+ }
+ //2 创建数据
+ Db::name('serve_info')->insertAll($store['serveInfo']);
+ }
+ //11 资金|核销
+ if(!empty($class['money'])){
+ //1 更新资金账户
+ Db::name('account')->where([['id','=',$class['account']]])->dec('balance',$class['money'])->update();
+ //2 创建资金详情
+ Db::name('account_info')->insert([
+ 'pid'=>$class['account'],
+ 'type'=>'sre',
+ 'class'=>$class['id'],
+ 'time'=>$class['time'],
+ 'direction'=>0,
+ 'money'=>$class['money']
+ ]);
+ //3 创建核销记录
+ Db::name('sre_bill')->insert([
+ 'pid'=>$class['id'],
+ 'type'=>'sre',
+ 'source'=>$class['id'],
+ 'time'=>$class['time'],
+ 'money'=>$class['money']
+ ]);
+ }
+ //12 客户|应收款余额
+ $balance=math()->chain($class['actual'])->sub($class['money'])->done();
+ if(!empty($balance)){
+ Db::name('customer')->where([['id','=',$class['customer']]])->dec('balance',$balance)->update();
+ }
+ //13 更新单据
+ $nucleus=$class['money']==$class['actual']?2:($class['money']==0?0:1);
+ Db::name('sre')->where([['id','=',$class['id']]])->update(['examine'=>1,'nucleus'=>$nucleus]);
+ //14 单据记录
+ Db::name('record')->insert(['type'=>'sre','source'=>$class['id'],'time'=>time(),'user'=>getUserID(),'info'=>'审核单据']);
+ //15 收发记录
+ $summary=new Summary;
+ $summary->note('sre',$class['id'],true);
+ //16 记录操作
+ pushLog('审核销售退货单[ '.$class['number'].' ]');//单据日志
+ }else{
+ //反审核
+ //1 匹配数据
+ $listSql=[['type','=','sre'],['info','in',array_column($info,'id')]];
+ $roomInfoList=Db::name('room_info')->where($listSql)->select()->toArray();
+ $batchInfoList=Db::name('batch_info')->where($listSql)->select()->toArray();
+ $serialInfoList=Db::name('serial_info')->where($listSql)->select()->toArray();
+ $serveInfoList=Db::name('serve_info')->where($listSql)->select()->toArray();
+ //2 关联单据
+ if(!empty($class['source'])){
+ //更新详情
+ $sellInfoDuplicate=[];
+ foreach ($info as $infoVo) {
+ empty($infoVo['source'])||$sellInfoDuplicate[]=['id'=>$infoVo['source'],'retreat'=>$infoVo['nums']];
+ }
+ empty($sellInfoDuplicate)||Db::name('sell_info')->duplicate(['retreat'=>Db::raw('retreat - VALUES(`retreat`)')])->insertAll($sellInfoDuplicate);
+ //查询是否关联销售订单
+ $sellInfo=Db::name('sell_info')->where([['id','in',array_column($sellInfoDuplicate,'id')]])->select()->toArray();
+ $sorInfoDuplicate=[];
+ foreach ($sellInfo as $sellVo){
+ empty($sellVo['source'])||$sorInfoDuplicate[]=['id'=>$sellVo['source'],'handle'=>$infoVo['nums']];
+ }
+ if(!empty($sorInfoDuplicate)){
+ //更新详情
+ Db::name('sor_info')->duplicate(['handle'=>Db::raw('handle + VALUES(`handle`)')])->insertAll($sorInfoDuplicate);
+ //2 更新销售订单CLASS
+ $sorInfo=Db::name('sor_info')->where([['id','in',array_column($sellInfo,'source')]])->select()->toArray();
+ $state=mathArraySum(array_column($sorInfo,'nums'))==mathArraySum(array_column($sorInfo,'handle'))?2:1;
+ Db::name('sor')->where([['id','=',$sorInfo[0]['pid']]])->update(['state'=>$state]);
+ }
+
+ }
+ //3 仓储
+ $roomDuplicate=[];
+ foreach ($roomInfoList as $roomInfoVo) {
+ $roomDuplicate[]=['id'=>$roomInfoVo['pid'],'nums'=>$roomInfoVo['nums']];
+ }
+ //3.1 更新仓储
+ Db::name('room')->duplicate(['nums'=>Db::raw('nums - VALUES(`nums`)')])->insertAll($roomDuplicate);
+ //3.2 删除仓储详情
+ Db::name('room_info')->where([['id','in',array_column($roomInfoList,'id')]])->delete();
+ //3.3 仓储|冗余
+ $roomPk=array_unique(array_column($roomInfoList,'pid'));
+ $roomInfoData=Db::name('room_info')->where([['pid','in',$roomPk]])->select()->toArray();
+ $roomDiff=array_diff($roomPk,array_unique(array_column($roomInfoData,'pid')));
+ empty($roomDiff)||Db::name('room')->where([['id','in',$roomDiff]])->delete();
+ //4 批次号
+ if(!empty($batchInfoList)){
+ //1 构造数据
+ $batchInfoDuplicate=array_map(function($item){
+ return ['id'=>$item['pid'],'nums'=>$item['nums']];
+ },$batchInfoList);
+ //2 更新批次号
+ Db::name('batch')->duplicate(['nums'=>Db::raw('nums - VALUES(`nums`)')])->insertAll($batchInfoDuplicate);
+ //3 删除批次号详情
+ Db::name('batch_info')->where([['id','in',array_column($batchInfoList,'id')]])->delete();
+ //4 批次号|冗余
+ $batchPk=array_unique(array_column($batchInfoList,'pid'));
+ $batchInfoData=Db::name('batch_info')->where([['pid','in',$batchPk]])->select()->toArray();
+ $batchDiff=array_diff($batchPk,array_unique(array_column($batchInfoData,'pid')));
+ empty($batchDiff)||Db::name('batch')->where([['id','in',$batchDiff]])->delete();
+ }
+ //5 序列号
+ if(!empty($serialInfoList)){
+ //1 更新序列号
+ Db::name('serial')->where([['id','in',array_column($serialInfoList,'pid')]])->update(['state'=>1]);
+ //2 删除序列号详情
+ Db::name('serial_info')->where([['id','in',array_column($serialInfoList,'id')]])->delete();
+ //3 序列号|冗余
+ $serialPk=array_unique(array_column($serialInfoList,'pid'));
+ $serialInfoData=Db::name('serial_info')->where([['pid','in',$serialPk]])->select()->toArray();
+ $serialDiff=array_diff($serialPk,array_unique(array_column($serialInfoData,'pid')));
+ empty($serialDiff)||Db::name('serial')->where([['id','in',$serialDiff]])->delete();
+ }
+ //6 服务
+ if(!empty($serveInfoList)){
+ //1 构造数据
+ $serveInfoDuplicate=array_map(function($item){
+ return ['id'=>$item['pid'],'nums'=>$item['nums']];
+ },$serveInfoList);
+ //2 更新服务
+ Db::name('serve')->duplicate(['nums'=>Db::raw('nums - VALUES(`nums`)')])->insertAll($serveInfoDuplicate);
+ //3 删除服务详情
+ Db::name('serve_info')->where([['id','in',array_column($serveInfoList,'id')]])->delete();
+ //4 服务|冗余
+ $servePk=array_unique(array_column($serveInfoList,'pid'));
+ $serveInfoData=Db::name('serve_info')->where([['pid','in',$servePk]])->select()->toArray();
+ $serveDiff=array_diff($servePk,array_unique(array_column($serveInfoData,'pid')));
+ empty($serveDiff)||Db::name('serve')->where([['id','in',$serveDiff]])->delete();
+ }
+ //7 资金|核销
+ if(!empty($class['money'])){
+ //1 更新资金账户
+ Db::name('account')->where([['id','=',$class['account']]])->inc('balance',$class['money'])->update();
+ //2 删除资金详情
+ Db::name('account_info')->where([['type','=','sre'],['class','=',$class['id']]])->delete();
+ //3 删除核销记录
+ Db::name('sre_bill')->where([['pid','=',$class['id']]])->delete();
+ }
+ //8 客户|应收款余额
+ $balance=math()->chain($class['actual'])->sub($class['money'])->done();
+ if(!empty($balance)){
+ Db::name('customer')->where([['id','=',$class['customer']]])->inc('balance',$balance)->update();
+ }
+ //9 更新单据
+ Db::name('sre')->where([['id','=',$class['id']]])->update(['examine'=>0,'nucleus'=>0]);
+ //10 单据记录
+ Db::name('record')->insert(['type'=>'sre','source'=>$class['id'],'time'=>time(),'user'=>getUserID(),'info'=>'反审核单据']);
+ //11 收发记录
+ $summary=new Summary;
+ $summary->note('sre',$class['id'],false);
+ //12 记录操作
+ pushLog('反审核销售退货单[ '.$class['number'].' ]');//单据日志
+ }
+
+ Db::commit();
+ } catch (\Exception $e) {
+ Db::rollback();
+ return json(['state'=>'error','info'=>'内部错误,操作已撤销!']);
+ exit;
+ }
+ }
+ $result=['state'=>'success'];
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //上传
+ public function upload(){
+ $file = request()->file('file');
+ //获取上传文件
+ if (empty($file)) {
+ $result = ['state' => 'error','info' => '传入数据不完整!'];
+ } else {
+ //文件限制5MB
+ try{
+ validate(['file'=>['fileSize'=>5*1024*1024,'fileExt'=>'png,gif,jpg,jpeg,txt,doc,docx,rtf,xls,xlsx,ppt,pptx,pdf,zip,rar']])->check(['file'=>$file]);
+ $fileInfo=Filesystem::disk('upload')->putFile('sre', $file, 'uniqid');
+ $filePath=request()->domain().'/static/upload/'.$fileInfo;
+ $result=['state'=>'success','info'=>$filePath];
+ }catch(ValidateException $e) {
+ $result = ['state' => 'error','info' => $e->getMessage()];
+ }
+ }
+ return json($result);
+ }
+ //导入
+ public function import(){
+ delOverdueFile('static.upload.xlsx');//删除过期文件
+ $file=request()->file('file');//获取上传文件
+ if(empty($file)){
+ $result=['state'=>'error','info'=>'传入数据不完整!'];
+ }else{
+ $fun=getSys('fun');
+ try{
+ validate(['file'=>['fileSize'=>2*1024*1024,'fileExt'=>'xlsx']])->check(['file'=>$file]);
+ $fileInfo = Filesystem::disk('upload')->putFile('xlsx', $file, 'uniqid');
+ $filePath = pathChange('static.upload').$fileInfo;
+ $data=getXlsx($filePath);
+ unset($data[1]);//删除标题行
+ unset($data[2]);//删除列名行
+ //初始化CLASS
+ //客户匹配
+ $customer=Db::name('customer')->where([['name','=',$data[3]['A']]])->find();
+ if(empty($customer)){
+ throw new ValidateException('客户[ '.$data[3]['A'].' ]未匹配!');
+ }
+ //结算账户匹配
+ if(empty($data[3]['F'])){
+ $account=['id'=>0];
+ }else{
+ $account=Db::name('account')->where([['name','=',$data[3]['G']]])->find();
+ if(empty($account)){
+ throw new ValidateException('结算账户[ '.$data[3]['G'].' ]不正确!');
+ }
+ }
+ //关联人员匹配
+ if(empty($data[3]['H'])){
+ $people=['id'=>0];
+ }else{
+ $people=Db::name('people')->where([['name','=',$data[3]['H']]])->find();
+ if(empty($people)){
+ throw new ValidateException('关联人员[ '.$data[3]['H'].' ]未匹配!');
+ }
+ }
+ $class=[
+ 'source'=>0,
+ 'frame'=>userInfo(getUserID(),'frame'),
+ 'customer'=>$customer['id'],
+ 'time'=>$data[3]['B'],
+ 'number'=>$data[3]['C'],
+ 'total'=>0,
+ 'actual'=>$data[3]['E'],
+ 'money'=>$data[3]['F'],
+ 'account'=>$account['id'],
+ 'people'=>$people['id'],
+ 'logistics'=>["key"=>"auto","name"=>"自动识别","number"=>$data[3]['I']],
+ 'file'=>[],
+ 'data'=>$data[3]['J'],
+ 'more'=>[],
+ 'examine'=>0,
+ 'nucleus'=>0,
+ 'cse'=>0,
+ 'invoice'=>0,
+ 'check'=>0,
+ 'user'=>getUserID()
+ ];
+ $this->validate($class,'app\validate\Sre');//数据合法性验证
+ //初始化INFO
+ $info=[];
+ $goods=Goods::with(['attr'])->where([['name','in',array_column($data,'K')]])->select()->toArray();
+ $warehouse=Db::name('warehouse')->where([['name','in',array_column($data,'N')]])->select()->toArray();
+ foreach ($data as $dataKey=>$dataVo) {
+ $record=[
+ 'source'=>0,
+ 'goods'=>$dataVo['K'],
+ 'attr'=>$dataVo['L'],
+ 'unit'=>$dataVo['M'],
+ 'warehouse'=>$dataVo['N'],
+ 'batch'=>$dataVo['O'],
+ 'mfd'=>$dataVo['P'],
+ 'price'=>$dataVo['Q'],
+ 'nums'=>$dataVo['R'],
+ 'serial'=>explode(',',$dataVo['S']),
+ 'discount'=>$dataVo['T'],
+ 'dsc'=>0,
+ 'total'=>0,
+ 'tax'=>$dataVo['W'],
+ 'tat'=>0,
+ 'tpt'=>0,
+ 'data'=>$dataVo['Z'],
+ ];
+ //商品匹配
+ $goodsFind=search($goods)->where([['name','=',$record['goods']]])->find();
+ if(empty($goodsFind)){
+ throw new ValidateException('模板文件第'.$dataKey.'行商品名称[ '.$record['goods'].' ]未匹配!');
+ }else{
+ $record['goods']=$goodsFind['id'];
+ }
+ //辅助属性匹配
+ if(empty($goodsFind['attr'])){
+ $record['attr']='';
+ }else{
+ if(empty($record['attr'])){
+ throw new ValidateException('模板文件第'.$dataKey.'行辅助属性不可为空!');
+ }else{
+ $attrFind=search($goodsFind['attr'])->where([['name','=',$record['attr']]])->find();
+ if(empty($attrFind)){
+ throw new ValidateException('模板文件第'.$dataKey.'行辅助属性[ '.$record['attr'].' ]未匹配!');
+ }
+ }
+ }
+ //单位匹配
+ if($goodsFind['unit']==-1){
+ if(empty($record['unit'])){
+ throw new ValidateException('模板文件第'.$dataKey.'行单位不可为空!');
+ }else{
+ $unitFind=search($goodsFind['units'])->where([['name','=',$record['unit']]])->find();
+ if(empty($unitFind) && $goodsFind['units'][0]['source']!=$record['unit']){
+ throw new ValidateException('模板文件第'.$dataKey.'行单位[ '.$record['unit'].' ]未匹配!');
+ }
+ }
+ }else{
+ $record['unit']=$goodsFind['unit'];
+ }
+ //仓库匹配
+ if(empty($goodsFind['type'])){
+ //常规产品
+ $warehouseFind=search($warehouse)->where([['name','=',$record['warehouse']]])->find();
+ if(empty($warehouseFind)){
+ throw new ValidateException('模板文件第'.$dataKey.'行仓库[ '.$record['warehouse'].' ]未匹配!');
+ }else{
+ $record['warehouse']=$warehouseFind['id'];
+ }
+ }else{
+ //服务产品
+ $record['warehouse']=null;
+ }
+ //批次号匹配
+ if(empty($goodsFind['batch'])){
+ $record['batch']='';
+ }else{
+ if(empty($record['batch'])){
+ throw new ValidateException('模板文件第'.$dataKey.'行批次号不可为空!');
+ }
+ }
+ //生产日期匹配
+ if(empty($goodsFind['validity'])){
+ $record['mfd']='';
+ }else{
+ if(empty($record['mfd'])){
+ throw new ValidateException('模板文件第'.$dataKey.'行生产日期不可为空!');
+ }
+ }
+ //单价匹配
+ if(!preg_match("/^\d+(\.\d{0,".$fun['digit']['money']."})?$/",$record['price'])){
+ throw new ValidateException('模板文件第'.$dataKey.'行单价不正确!');
+ }
+ //数量匹配
+ if(!preg_match("/^\d+(\.\d{0,".$fun['digit']['nums']."})?$/",$record['nums'])){
+ throw new ValidateException('模板文件第'.$dataKey.'行数量不正确!');
+ }
+ //序列号匹配
+ if(empty($goodsFind['serial'])){
+ $record['serial']=[];
+ }else{
+ if(count($record['serial'])==1 && empty($record['serial'][0])){
+ throw new ValidateException('模板文件第'.$dataKey.'行序列号不可为空!');
+ }else{
+ if(count($record['serial'])!=$record['nums']){
+ throw new ValidateException('模板文件第'.$dataKey.'行序列号个数与数量不符!');
+ }
+ }
+ }
+ try{
+ $this->validate($record,'app\validate\SreInfo');//数据合法性验证
+ $storage=math()->chain($record['price'])->mul($record['nums'])->round($fun['digit']['money'])->done();
+ //折扣额|金额
+ if($record['discount']==0){
+ $record['total']=$storage;
+ }else{
+ $record['dsc']=math()->chain($storage)->div(100)->mul($record['discount'])->round($fun['digit']['money'])->done();
+ $record['total']=math()->chain($storage)->sub($record['dsc'])->done();
+ }
+ //税额|价税合计
+ if($record['tax']==0){
+ $record['tpt']=$record['total'];
+ }else{
+ $record['tat']=math()->chain($record['total'])->div(100)->mul($record['tax'])->round(2)->done();
+ $record['tpt']=math()->chain($record['total'])->add($record['tat'])->done();
+ }
+ //转存数据
+ $class['total']=math()->chain($class['total'])->add($record['tpt'])->done();//累加单据金额
+ $info[]=$record;
+ } catch (ValidateException $e) {
+ return json(['state'=>'error','info'=>'模板文件第'.$dataKey.'行'.$e->getMessage()]);//返回错误信息
+ exit;
+ }
+ }
+ //序列号重复验证
+ $serials=[];
+ foreach ($info as $infoVo) {
+ $serials = array_merge($serials,$infoVo['serial']);
+ }
+ if(count($serials)!=count(array_unique($serials))){
+ throw new ValidateException('商品信息中存在重复序列号!');
+ }
+ //CLASS数据验证
+ if(bccomp($class['total'],$class['actual'])==-1){
+ throw new ValidateException('实际金额不可大于单据金额[ '.$class['total'].' ]!');
+ }else if(bccomp($class['actual'],$class['money'])==-1){
+ throw new ValidateException('实付金额不可大于实际金额[ '.floatval($class['actual']).' ]!');
+ }else{
+ Db::startTrans();
+ try {
+ //新增CLASS
+ $classData=Sres::create($class);
+ //新增INFO
+ foreach ($info as $infoKey=>$infoVo) {
+ $info[$infoKey]['pid']=$classData['id'];
+ }
+ $model = new SreInfo;
+ $model->saveAll($info);
+ Db::name('record')->insert(['type'=>'sre','source'=>$classData['id'],'time'=>time(),'user'=>getUserID(),'info'=>'导入单据']);
+ pushLog('导入销售退货单[ '.$classData['number'].' ]');//日志
+
+ Db::commit();
+ $result=['state'=>'success'];
+ } catch (\Exception $e) {
+ Db::rollback();
+ $result=['state'=>'error','info'=>'内部错误,操作已撤销!'];
+ }
+ }
+ }catch(ValidateException $e) {
+ $result=['state'=>'error','info'=>$e->getMessage()];//返回错误信息
+ }
+ }
+ return json($result);
+ }
+ //导出
+ public function exports(){
+ $input=input('get.');
+ if(existFull($input,['scene','parm']) && is_array($input['parm'])){
+ pushLog('导出销售退货单列表');//日志
+ $source=Sres::with(['frameData','customerData','accountData','peopleData','userData'])->where([['id','in',$input['parm']]])->append(['extension'])->order(['id'=>'desc'])->select()->toArray();//查询CLASS数据
+ if($input['scene']=='simple'){
+ //简易报表
+ //开始构造导出数据
+ $excel=[];//初始化导出数据
+ //标题数据
+ $excel[]=['type'=>'title','info'=>'销售退货单列表'];
+ //表格数据
+ $field=[
+ 'frameData|name'=>'所属组织',
+ 'customerData|name'=>'客户',
+ 'time'=>'单据时间',
+ 'number'=>'单据编号',
+ 'total'=>'单据金额',
+ 'actual'=>'实际金额',
+ 'money'=>'单据付款',
+ 'extension|amount'=>'核销金额',
+ 'cost'=>'单据费用',
+ 'peopleData|name'=>'关联人员',
+ 'extension|examine'=>'审核状态',
+ 'extension|nucleus'=>'核销状态',
+ 'extension|cse'=>'费用状态',
+ 'extension|invoice'=>'发票状态',
+ 'extension|check'=>'核对状态',
+ 'userData|name'=>'制单人',
+ 'data'=>'备注信息'
+ ];
+ $thead=array_values($field);//表格标题
+ $tbody=[];//表格内容
+ //构造表内数据
+ foreach ($source as $sourceVo) {
+ $rowData=[];
+ foreach (array_keys($field) as $fieldVo) {
+ $rowData[]=arraySeek($sourceVo,$fieldVo);//多键名数据赋值
+ }
+ $tbody[]=$rowData;//加入行数据
+ }
+ $excel[]=['type'=>'table','info'=>['thead'=>$thead,'tbody'=>$tbody]];//表格数据
+ //统计数据
+ $excel[]=['type'=>'node','info'=>[
+ '总数:'.count($source),
+ '总单据金额:'.mathArraySum(array_column($source,'total')),
+ '总实际金额:'.mathArraySum(array_column($source,'actual')),
+ '总单据付款:'.mathArraySum(array_column($source,'money')),
+ '总核销金额:'.mathArraySum(arrayColumns($source,['extension','amount'])),
+ '总单据费用:'.mathArraySum(array_column($source,'cost'))
+ ]];
+ //导出execl
+ buildExcel('销售退货单列表',$excel);
+ }else{
+ //详细报表
+ $files=[];//初始化文件列表
+ foreach ($source as $sourceVo) {
+ //开始构造导出数据
+ $excel=[];//初始化导出数据
+ //标题数据
+ $excel[]=['type'=>'title','info'=>'销售退货单'];
+ //节点数据
+ $excel[]=['type'=>'node','info'=>[
+ '客户:'.$sourceVo['customerData']['name'],
+ '单据日期:'.$sourceVo['time'],
+ '单据编号:'.$sourceVo['number']]
+ ];
+ //表格数据
+ $field=[
+ 'goodsData|name'=>'商品名称',
+ 'goodsData|spec'=>'规格型号',
+ 'attr'=>'辅助属性',
+ 'unit'=>'单位',
+ 'warehouseData|name'=>'仓库',
+ 'batch'=>'批次号',
+ 'mfd'=>'生产日期',
+ 'price'=>'单价',
+ 'nums'=>'数量',
+ 'extension|serial'=>'序列号',
+ 'discount'=>'折扣率',
+ 'dsc'=>'折扣额',
+ 'total'=>'金额',
+ 'tax'=>'税率',
+ 'tat'=>'税额',
+ 'tpt'=>'价税合计',
+ 'data'=>'备注信息'
+ ];
+ //构造表内数据
+ $info=SreInfo::with(['goodsData','warehouseData'])->where([['pid','=',$sourceVo['id']]])->order(['id'=>'asc'])->append(['extension'])->select()->toArray();
+ //批次号匹配
+ if(empty(search($info)->where([['goodsData|batch','=',true]])->find())){
+ unset($field['batch']);
+ }
+ //生产日期匹配
+ if(empty(search($info)->where([['goodsData|validity','=',true]])->find())){
+ unset($field['mfd']);
+ }
+ //序列号匹配
+ if(empty(search($info)->where([['goodsData|serial','=',true]])->find())){
+ unset($field['extension|serial']);
+ }
+ //税金匹配
+ $fun=getSys('fun');
+ if(empty(search($info)->where([['tax','<>',0]])->find()) && !$fun['tax']){
+ unset($field['tax']);
+ unset($field['tat']);
+ unset($field['tpt']);
+ }
+ $thead=array_values($field);//表格标题
+ $tbody=[];//表格内容
+ foreach ($info as $infoVo) {
+ $rowData=[];
+ foreach (array_keys($field) as $fieldVo) {
+ $rowData[]=arraySeek($infoVo,$fieldVo);//多键名数据赋值
+ }
+ $tbody[]=$rowData;//加入行数据
+ }
+ $excel[]=['type'=>'table','info'=>['thead'=>$thead,'tbody'=>$tbody]];//表格数据
+ //节点数据
+ $excel[]=['type'=>'node','info'=>[
+ '单据金额:'.$sourceVo['total'],
+ '单据费用:'.$sourceVo['cost'],
+ '实际金额:'.$sourceVo['actual'],
+ '核销金额:'.$sourceVo['extension']['amount'],
+ '结算账户:'.arraySeek($sourceVo,'accountData|name'),
+ '发票信息:'.$sourceVo['invoice'],
+ '关联人员:'.arraySeek($sourceVo,'peopleData|name'),
+ '物流信息:'.$sourceVo['extension']['logistics'],
+ '备注信息:'.$sourceVo['data']]
+ ];
+ //生成execl
+ $files[]=buildExcel($sourceVo['number'],$excel,false);
+
+ }
+ buildZip('销售退货单_'.time(),$files);
+ }
+ }else{
+ return json(['state'=>'error','info'=>'传入数据不完整!']);
+ }
+ }
+}
\ No newline at end of file
diff --git a/serve/app/controller/Srt.php b/serve/app/controller/Srt.php
new file mode 100644
index 0000000..e4f8c5d
--- /dev/null
+++ b/serve/app/controller/Srt.php
@@ -0,0 +1,968 @@
+'time'],'startTime'],
+ [['endTime'=>'time'],'endTime'],
+ [['startArrival'=>'arrival'],'startTime'],
+ [['endArrival'=>'arrival'],'endTime']
+ ]);
+ $sql['class'][]=['examine','=',1];
+ $sql['class']=frameScope($sql['class']);//组织数据
+ $sql['class']=sqlAuth('sor',$sql['class']);//数据鉴权
+ //INFO语句
+ $sql['info']=fastSql($input,[['warehouse','fullIn']]);
+ //商品匹配
+ if(existFull($input,['goods'])){
+ $goods=array_column(Db::name('goods')->where([['name|py','like','%'.$input['goods'].'%']])->select()->toArray(),'id');
+ $sql['info'][]=['goods','in',$goods];
+ }
+ $sql['or']=[];
+ //状态匹配
+ if(existFull($input,['state'])){
+ foreach ($input['state'] as $stateVo) {
+ $sql['or'][]=[['handle','=',0],Db::raw('handle > 0 AND handle < nums'),['handle','=',Db::raw('nums')]][$stateVo];
+ }
+ }
+ //判断排序
+ if(empty($input['type'])){
+ //单据排序
+ $record=Db::name('sor')->alias('class')->join(['is_sor_info'=>'info'],'class.id=info.pid')->where($sql['class'])->where($sql['info'])->where(function($query)use($sql){$query->whereOr($sql['or']);})->fieldRaw('class.id as class,group_concat(info.id) as info')->group('class.id')->order('class.id', 'desc')->select()->toArray();
+ $data=[];
+ $count=count($record);
+ if(!empty($record)){
+ $classList = \app\model\Sor::with(['frameData','customerData'])->where([['id','in',array_column($record,'class')]])->append(['extension'])->page($input['page'],$input['limit'])->select()->toArray();
+ $infoList = \app\model\SorInfo::with(['goodsData','warehouseData'])->where([['pid','in',array_column($classList,'id')],['id','in',array_unique(explode(',',implode(',',array_column($record,'info'))))]])->select()->toArray();
+ foreach ($classList as $class) {
+ $class['key']=$class['id'];
+ $class['money']=$class['actual'];
+ $class['nmy']=0;
+ $info=search($infoList)->where([['pid','=',$class['id']]])->select();
+ foreach ($info as $key=>$vo) {
+ $info[$key]['key']=$class['id'].'_'.$vo['id'];
+ $info[$key]['price']=math()->chain($vo['tpt'])->div($vo['nums'])->round(2)->done();
+ $info[$key]['money']=$vo['tpt'];
+ $info[$key]['extension']['state']=$vo['handle']==0?'未出库':($vo['handle']==$vo['nums']?'已出库':'部分出库');
+ $info[$key]['nns']=math()->chain($vo['nums'])->sub($vo['handle'])->done();
+ $info[$key]['nmy']=math()->chain($info[$key]['price'])->mul($info[$key]['nns'])->done();
+ //汇总数据
+ $class['nmy']=math()->chain($class['nmy'])->add($info[$key]['nmy'])->done();
+ }
+ $class['node']=$info;
+ $data[]=$class;
+ }
+ }
+ }else{
+ //商品排序
+ $record=Db::name('sor_info')->alias('info')->join(['is_sor'=>'class'],'info.pid=class.id')->where($sql['class'])->where($sql['info'])->where(function($query)use($sql){$query->whereOr($sql['or']);})->fieldRaw('info.id as row,group_concat(info.id) as info')->group('info.goods,info.attr,info.warehouse')->order('info.id', 'desc')->select()->toArray();
+ $data=[];
+ $count=count($record);
+ if(!empty($record)){
+ $record = array_slice($record,$input['limit']*($input['page']-1),$input['limit']);
+ $infoList = \app\model\SorInfo::with(['goodsData','warehouseData'])->where([['id','in',array_unique(explode(',',implode(',',array_column($record,'info'))))]])->select()->toArray();
+ $classList = \app\model\Sor::with(['frameData','customerData'])->where([['id','in',array_unique(array_column($infoList,'pid'))]])->append(['extension'])->select()->toArray();
+ foreach ($record as $recordVo) {
+ $info=search($infoList)->where([['id','in',explode(',',$recordVo['info'])]])->select();
+ $row=$info[0];
+ $row['key']=$row['id'];
+ $row['unit']='';
+ $row['price']='';
+ $row['nums']=0;
+ $row['money']=0;
+ $row['nns']=0;
+ $row['nmy']=0;
+ foreach ($info as $vo) {
+ $class=search($classList)->where([['id','=',$vo['pid']]])->find();
+ $class['key']=$vo['id'].'_'.$class['id'];
+ $class['unit']=$vo['unit'];
+ $class['price']=math()->chain($vo['tpt'])->div($vo['nums'])->round(2)->done();
+ $class['nums']=$vo['nums'];
+ $class['money']=$vo['tpt'];
+ $class['extension']['state']=$vo['handle']==0?'未出库':($vo['handle']==$vo['nums']?'已出库':'部分出库');
+ $class['nns']=math()->chain($vo['nums'])->sub($vo['handle'])->done();
+ $class['nmy']=math()->chain($class['price'])->mul($class['nns'])->done();
+ $class['data']=$vo['data'];
+ $class['basic']=['nums'=>$vo['nums'],'nns'=>$class['nns']];
+ //汇总数据
+ $row['money']=math()->chain($row['money'])->add($vo['tpt'])->done();
+ $row['nmy']=math()->chain($row['nmy'])->add($class['nmy'])->done();
+ //单位转换
+ if($vo['goodsData']['unit']=='-1'){
+ $radix=unitRadix($vo['unit'],$vo['goodsData']['units']);
+ $row['nums']=math()->chain($class['nums'])->mul($radix)->add($row['nums'])->done();
+ $row['nns']=math()->chain($class['nns'])->mul($radix)->add($row['nns'])->done();
+ }else{
+ $row['nums']=math()->chain($class['nums'])->add($row['nums'])->done();
+ $row['nns']=math()->chain($class['nns'])->add($row['nns'])->done();
+ }
+ $row['node'][]=$class;
+ }
+ $row['extension']['state']=$row['nns']==0?'已出库':($row['nns']==$row['nums']?'未出库':'部分出库');
+ //单位处理
+ if($row['goodsData']['unit']=='-1'){
+ $row['nums']=unitSwitch($row['nums'],$row['goodsData']['units']);
+ $row['nns']=unitSwitch($row['nns'],$row['goodsData']['units']);
+ }
+ $data[]=$row;
+ }
+ }
+ }
+ $result=[
+ 'state'=>'success',
+ 'count'=>$count,
+ 'info'=>$data
+ ];//返回数据
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //销售订单跟踪表-导出
+ public function sttExports(){
+ $input=input('get.');
+ existFull($input,['state'])||$input['state']=[];
+ existFull($input,['warehouse'])||$input['warehouse']=[];
+ if(is_arrays($input,['state','warehouse']) && isset($input['type'])){
+ pushLog('导出销售订单跟踪表');//日志
+ $sql=[];
+ //CLASS语句
+ $sql['class']=fastSql($input,[
+ ['customer','fullEq'],
+ ['number','fullLike'],
+ [['startTime'=>'time'],'startTime'],
+ [['endTime'=>'time'],'endTime'],
+ [['startArrival'=>'arrival'],'startTime'],
+ [['endArrival'=>'arrival'],'endTime']
+ ]);
+ $sql['class'][]=['examine','=',1];
+ $sql['class']=frameScope($sql['class']);//组织数据
+ $sql['class']=sqlAuth('sor',$sql['class']);//数据鉴权
+ //INFO语句
+ $sql['info']=fastSql($input,[['warehouse','fullDivisionIn']]);
+ //商品匹配
+ if(existFull($input,['goods'])){
+ $goods=array_column(Db::name('goods')->where([['name|py','like','%'.$input['goods'].'%']])->select()->toArray(),'id');
+ $sql['info'][]=['goods','in',$goods];
+ }
+ $sql['or']=[];
+ //状态匹配
+ if(existFull($input,['state'])){
+ foreach ($input['state'] as $stateVo) {
+ $sql['or'][]=[['handle','=',0],Db::raw('handle > 0 AND handle < nums'),['handle','=',Db::raw('nums')]][$stateVo];
+ }
+ }
+ //判断排序
+ if(empty($input['type'])){
+ //单据排序
+ $record=Db::name('sor')->alias('class')->join(['is_sor_info'=>'info'],'class.id=info.pid')->where($sql['class'])->where($sql['info'])->where(function($query)use($sql){$query->whereOr($sql['or']);})->fieldRaw('class.id as class,group_concat(info.id) as info')->group('class.id')->order('class.id', 'desc')->select()->toArray();
+ $data=[];
+ $count=count($record);
+ if(!empty($record)){
+ $classList = \app\model\Sor::with(['frameData','customerData'])->where([['id','in',array_column($record,'class')]])->append(['extension'])->select()->toArray();
+ $infoList = \app\model\SorInfo::with(['goodsData','warehouseData'])->where([['pid','in',array_column($classList,'id')],['id','in',array_unique(explode(',',implode(',',array_column($record,'info'))))]])->select()->toArray();
+ foreach ($classList as $class) {
+ $class['key']=$class['id'];
+ $class['money']=$class['actual'];
+ $class['nmy']=0;
+ $info=search($infoList)->where([['pid','=',$class['id']]])->select();
+ foreach ($info as $key=>$vo) {
+ $info[$key]['key']=$class['id'].'_'.$vo['id'];
+ $info[$key]['price']=math()->chain($vo['tpt'])->div($vo['nums'])->round(2)->done();
+ $info[$key]['money']=$vo['tpt'];
+ $info[$key]['extension']['state']=$vo['handle']==0?'未出库':($vo['handle']==$vo['nums']?'已出库':'部分出库');
+ $info[$key]['nns']=math()->chain($vo['nums'])->sub($vo['handle'])->done();
+ $info[$key]['nmy']=math()->chain($info[$key]['price'])->mul($info[$key]['nns'])->done();
+ //汇总数据
+ $class['nmy']=math()->chain($class['nmy'])->add($info[$key]['nmy'])->done();
+ }
+ $class['node']=$info;
+ $data[]=$class;
+ }
+ }
+ }else{
+ //商品排序
+ $record=Db::name('sor_info')->alias('info')->join(['is_sor'=>'class'],'info.pid=class.id')->where($sql['class'])->where($sql['info'])->where(function($query)use($sql){$query->whereOr($sql['or']);})->fieldRaw('info.id as row,group_concat(info.id) as info')->group('info.goods,info.attr,info.warehouse')->order('info.id', 'desc')->select()->toArray();
+ $data=[];
+ $count=count($record);
+ if(!empty($record)){
+ $infoList = \app\model\SorInfo::with(['goodsData','warehouseData'])->where([['id','in',array_unique(explode(',',implode(',',array_column($record,'info'))))]])->select()->toArray();
+ $classList = \app\model\Sor::with(['frameData','customerData'])->where([['id','in',array_unique(array_column($infoList,'pid'))]])->append(['extension'])->select()->toArray();
+ foreach ($record as $recordVo) {
+ $info=search($infoList)->where([['id','in',explode(',',$recordVo['info'])]])->select();
+ $row=$info[0];
+ $row['key']=$row['id'];
+ $row['unit']='';
+ $row['price']='';
+ $row['nums']=0;
+ $row['money']=0;
+ $row['nns']=0;
+ $row['nmy']=0;
+ foreach ($info as $vo) {
+ $class=search($classList)->where([['id','=',$vo['pid']]])->find();
+ $class['key']=$vo['id'].'_'.$class['id'];
+ $class['unit']=$vo['unit'];
+ $class['price']=math()->chain($vo['tpt'])->div($vo['nums'])->round(2)->done();
+ $class['nums']=$vo['nums'];
+ $class['money']=$vo['tpt'];
+ $class['extension']['state']=$vo['handle']==0?'未出库':($vo['handle']==$vo['nums']?'已出库':'部分出库');
+ $class['nns']=math()->chain($vo['nums'])->sub($vo['handle'])->done();
+ $class['nmy']=math()->chain($class['price'])->mul($class['nns'])->done();
+ $class['data']=$vo['data'];
+ $class['basic']=['nums'=>$vo['nums'],'nns'=>$class['nns']];
+ //汇总数据
+ $row['money']=math()->chain($row['money'])->add($vo['tpt'])->done();
+ $row['nmy']=math()->chain($row['nmy'])->add($class['nmy'])->done();
+ //单位转换
+ if($vo['goodsData']['unit']=='-1'){
+ $radix=unitRadix($vo['unit'],$vo['goodsData']['units']);
+ $row['nums']=math()->chain($class['nums'])->mul($radix)->add($row['nums'])->done();
+ $row['nns']=math()->chain($class['nns'])->mul($radix)->add($row['nns'])->done();
+ }else{
+ $row['nums']=math()->chain($class['nums'])->add($row['nums'])->done();
+ $row['nns']=math()->chain($class['nns'])->add($row['nns'])->done();
+ }
+ $row['node'][]=$class;
+ }
+ $row['extension']['state']=$row['nns']==0?'已出库':($row['nns']==$row['nums']?'未出库':'部分出库');
+ //单位处理
+ if($row['goodsData']['unit']=='-1'){
+ $row['nums']=unitSwitch($row['nums'],$row['goodsData']['units']);
+ $row['nns']=unitSwitch($row['nns'],$row['goodsData']['units']);
+ }
+ $data[]=$row;
+ }
+ }
+ }
+ //结构重组
+ $source=[];
+ foreach ($data as $dataVo) {
+ $source[]=$dataVo;
+ if(!empty($dataVo['node'])){
+ foreach ($dataVo['node'] as $node) {
+ $source[]=$node;
+ }
+ }
+ }
+ //开始构造导出数据
+ $excel=[];//初始化导出数据
+ //标题数据
+ $excel[]=['type'=>'title','info'=>'销售订单跟踪表'];
+ //表格数据
+ $field=[
+ [
+ 'frameData|name'=>'所属组织',
+ 'customerData|name'=>'客户',
+ 'time'=>'单据时间',
+ 'number'=>'单据编号',
+ 'goodsData|name'=>'商品名称',
+ 'attr'=>'辅助属性',
+ 'warehouseData|name'=>'仓库',
+ ],[
+ 'goodsData|name'=>'商品名称',
+ 'attr'=>'辅助属性',
+ 'warehouseData|name'=>'仓库',
+ 'frameData|name'=>'所属组织',
+ 'customerData|name'=>'客户',
+ 'time'=>'单据时间',
+ 'number'=>'单据编号'
+ ],[
+ 'unit'=>'单位',
+ 'price'=>'单价',
+ 'nums'=>'数量',
+ 'money'=>'金额',
+ 'extension|state'=>'出库状态',
+ 'nns'=>'未出库数量',
+ 'nmy'=>'未出库金额',
+ 'arrival'=>'到货日期',
+ 'data'=>'备注信息'
+ ]
+ ];
+ $field=array_merge(empty($input['type'])?$field[0]:$field[1],$field[2]);
+ $thead=array_values($field);//表格标题
+ $tbody=[];//表格内容
+ //构造表内数据
+ foreach ($source as $sourceVo) {
+ $rowData=[];
+ foreach (array_keys($field) as $fieldVo) {
+ $rowData[]=arraySeek($sourceVo,$fieldVo);//多键名数据赋值
+ }
+ $tbody[]=$rowData;//加入行数据
+ }
+ $excel[]=['type'=>'table','info'=>['thead'=>$thead,'tbody'=>$tbody]];//表格数据
+ //导出execl
+ buildExcel('销售订单跟踪表',$excel);
+ }else{
+ return json(['state'=>'error','info'=>'传入参数不完整!']);
+ }
+ }
+ //销售明细表
+ public function slt(){
+ $input=input('post.');
+ $sheet=['sell','sre'];
+ existFull($input,['mold'])||$input['mold']=$sheet;
+ if(existFull($input,['page','limit']) && is_arrays($input,['warehouse','mold']) && arrayInArray($input['mold'],$sheet)){
+ $sql=[];
+ //CLASS语句
+ $sql['class']=fastSql($input,[
+ ['customer','fullEq'],
+ ['number','fullLike'],
+ [['startTime'=>'time'],'startTime'],
+ [['endTime'=>'time'],'endTime'],
+ [['data'=>'class.data'],'fullLike']
+ ]);
+ $sql['class'][]=['examine','=',1];
+ $sql['class']=frameScope($sql['class']);//组织数据
+ //数据鉴权[结构一致]
+ $sql['class']=sqlAuth('sell',$sql['class']);
+ //INFO语句
+ $sql['info']=fastSql($input,[['warehouse','fullIn']]);
+ //商品匹配
+ if(existFull($input,['goods'])){
+ $goods=array_column(Db::name('goods')->where([['name|py','like','%'.$input['goods'].'%']])->select()->toArray(),'id');
+ $sql['info'][]=['goods','in',$goods];
+ }
+ //组装查询语句
+ $union=[];
+ foreach ($input['mold'] as $mold) {
+ $union[]=Db::name($mold.'_info')->alias('info')->join(['is_'.$mold=>'class'],'info.pid=class.id')->where($sql['info'])->where($sql['class'])->fieldRaw('info.id as info,class.id as class,time,"'.$mold.'" as mold')->buildSql();
+ }
+ $union=implode(' UNION ALL ',$union);
+ //获取总条数
+ $count=DB::query('SELECT COUNT(*) as count FROM ('.$union.') as nodcloud')[0]["count"];
+ $record=DB::query('SELECT * FROM ('.$union.') as nodcloud ORDER BY `time` DESC LIMIT '.pageCalc($input['page'],$input['limit'],'str'));
+ $list=[];
+ foreach ($input['mold'] as $mold) {
+ $gather=search($record)->where([['mold','=',$mold]])->select();
+ $table=[
+ "class"=>"app\\model\\".ucfirst($mold),
+ 'info'=>"app\\model\\".ucfirst($mold).'Info',
+ ];
+ $list[$mold]['info']=$table['info']::with(['goodsData','warehouseData'])->where([['id','in',array_column($gather,'info')]])->select()->toArray();
+ $list[$mold]['class']=$table['class']::with(['frameData','customerData'])->where([['id','in',array_column($list[$mold]['info'],'pid')]])->append(['extension'])->select()->toArray();
+ }
+ $data=[];
+ foreach ($record as $recordVo) {
+ $mold=$recordVo['mold'];
+ $data[]=[
+ 'mold'=>$mold,
+ 'name'=>['sell'=>'销售单','sre'=>'销售退货单'][$mold],
+ 'class'=>search($list[$mold]['class'])->where([['id','=',$recordVo['class']]])->find(),
+ 'info'=>search($list[$mold]['info'])->where([['id','=',$recordVo['info']]])->find()
+ ];
+ }
+ $result=[
+ 'state'=>'success',
+ 'count'=>$count,
+ 'info'=>$data
+ ];//返回数据
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //销售明细表-导出
+ public function sltExports(){
+ $input=input('get.');
+ $sheet=['sell','sre'];
+ existFull($input,['warehouse'])||$input['warehouse']=[];
+ existFull($input,['mold'])||$input['mold']=$sheet;
+ if(is_arrays($input,['warehouse','mold']) && arrayInArray($input['mold'],$sheet)){
+ pushLog('导出销售明细表');//日志
+ $sql=[];
+ //CLASS语句
+ $sql['class']=fastSql($input,[
+ ['customer','fullEq'],
+ ['number','fullLike'],
+ [['startTime'=>'time'],'startTime'],
+ [['endTime'=>'time'],'endTime'],
+ [['data'=>'class.data'],'fullLike']
+ ]);
+ $sql['class'][]=['examine','=',1];
+ $sql['class']=frameScope($sql['class']);//组织数据
+ //数据鉴权[结构一致]
+ $sql['class']=sqlAuth('sell',$sql['class']);
+ //INFO语句
+ $sql['info']=fastSql($input,[['warehouse','fullDivisionIn']]);
+ //商品匹配
+ if(existFull($input,['goods'])){
+ $goods=array_column(Db::name('goods')->where([['name|py','like','%'.$input['goods'].'%']])->select()->toArray(),'id');
+ $sql['info'][]=['goods','in',$goods];
+ }
+ //组装查询语句
+ $union=[];
+ foreach ($input['mold'] as $mold) {
+ $union[]=Db::name($mold.'_info')->alias('info')->join(['is_'.$mold=>'class'],'info.pid=class.id')->where($sql['info'])->where($sql['class'])->fieldRaw('info.id as info,class.id as class,time,"'.$mold.'" as mold')->buildSql();
+ }
+ $union=implode(' UNION ALL ',$union);
+ //获取总条数
+ $record=DB::query('SELECT * FROM ('.$union.') as nodcloud ORDER BY `time` DESC');
+ $list=[];
+ foreach ($input['mold'] as $mold) {
+ $gather=search($record)->where([['mold','=',$mold]])->select();
+ $table=[
+ "class"=>"app\\model\\".ucfirst($mold),
+ 'info'=>"app\\model\\".ucfirst($mold).'Info',
+ ];
+ $list[$mold]['info']=$table['info']::with(['goodsData','warehouseData'])->where([['id','in',array_column($gather,'info')]])->select()->toArray();
+ $list[$mold]['class']=$table['class']::with(['frameData','customerData'])->where([['id','in',array_column($list[$mold]['info'],'pid')]])->append(['extension'])->select()->toArray();
+ }
+ $data=[];
+ foreach ($record as $recordVo) {
+ $mold=$recordVo['mold'];
+ $data[]=[
+ 'mold'=>$mold,
+ 'name'=>['sell'=>'销售单','sre'=>'销售退货单'][$mold],
+ 'class'=>search($list[$mold]['class'])->where([['id','=',$recordVo['class']]])->find(),
+ 'info'=>search($list[$mold]['info'])->where([['id','=',$recordVo['info']]])->find()
+ ];
+ }
+ $source=$data;
+ //开始构造导出数据
+ $excel=[];//初始化导出数据
+ //标题数据
+ $excel[]=['type'=>'title','info'=>'销售明细表'];
+ //表格数据
+ $field=[
+ 'name'=>'单据类型',
+ 'class|frameData|name'=>'所属组织',
+ 'class|customerData|name'=>'客户',
+ 'class|time'=>'单据时间',
+ 'class|number'=>'单据编号',
+ 'info|goodsData|name'=>'商品名称',
+ 'info|attr'=>'辅助属性',
+ 'info|warehouseData|name'=>'仓库',
+ 'info|unit'=>'单位',
+ 'info|price'=>'单价',
+ 'info|nums'=>'数量',
+ 'info|dsc'=>'折扣额',
+ 'info|total'=>'金额',
+ 'info|tat'=>'税额',
+ 'info|tpt'=>'价税合计',
+ 'class|data'=>'备注信息',
+ ];
+ $thead=array_values($field);//表格标题
+ $tbody=[];//表格内容
+ //构造表内数据
+ foreach ($source as $sourceVo) {
+ $rowData=[];
+ foreach (array_keys($field) as $fieldVo) {
+ $rowData[]=arraySeek($sourceVo,$fieldVo);//多键名数据赋值
+ }
+ $tbody[]=$rowData;//加入行数据
+ }
+ $excel[]=['type'=>'table','info'=>['thead'=>$thead,'tbody'=>$tbody]];//表格数据
+ //汇总数据
+ $math=['sell'=>[],'sre'=>[]];
+ foreach ($source as $sourceVo) {
+ $math[$sourceVo['mold']][]=$sourceVo['info']['tpt'];
+ }
+ $excel[]=['type'=>'node','info'=>[
+ '总数:'.count($source),
+ '销售总金额:'.mathArraySum($math['sell']),
+ '销售退货总金额:'.mathArraySum($math['sre'])
+ ]];
+ //导出execl
+ buildExcel('销售明细表',$excel);
+ }else{
+ return json(['state'=>'error','info'=>'传入参数不完整!']);
+ }
+ }
+ //销售汇总表
+ public function ssy(){
+ $input=input('post.');
+ if(existFull($input,['page','limit']) && is_array($input['warehouse']) && isset($input['type'])){
+ $sql=[];
+ //CLASS语句
+ $sql['class']=fastSql($input,[
+ ['customer','fullEq'],
+ ['user','fullEq'],
+ ['people','fullEq'],
+ [['startTime'=>'time'],'startTime'],
+ [['endTime'=>'time'],'endTime']
+ ]);
+ $sql['class'][]=['examine','=',1];
+ $sql['class']=frameScope($sql['class']);//组织数据
+ $sql['class']=sqlAuth('sell',$sql['class']);//数据鉴权[结构一致]
+ //INFO语句
+ $sql['info']=fastSql($input,[['warehouse','fullIn']]);
+ //商品匹配
+ if(existFull($input,['goods'])){
+ $goods=array_column(Db::name('goods')->where([['name|py','like','%'.$input['goods'].'%']])->select()->toArray(),'id');
+ $sql['info'][]=['goods','in',$goods];
+ }
+ //构造语句
+ $union=[];
+ $tab=['sell','sre'];
+ foreach ($tab as $t) {
+ $union[]=Db::name($t.'_info')->alias('info')->join(['is_'.$t=>'class'],'info.pid=class.id')->where($sql['class'])->where($sql['info'])->fieldRaw('"'.$t.'" as mold,class.customer as customer,class.user as user,class.people as people,info.id as info,goods,attr,warehouse,unit,nums,tpt')->buildSql();
+ }
+ $union=implode(' UNION ALL ',$union);
+ //判断类型
+ if($input['type']==0){
+ //按商品
+ $count=count(DB::query('SELECT COUNT(*) as count FROM ('.$union.') as nodcloud group by goods,attr,warehouse'));
+ $record = DB::query('SELECT group_concat(mold) as mold,group_concat(info) as info,group_concat(unit) as unit,group_concat(nums) as nums,group_concat(tpt) as tpt FROM ( '.$union.' ) as nodcloud group by goods,attr,warehouse ORDER BY `goods` DESC LIMIT '.pageCalc($input['page'],$input['limit'],'str'));
+ }else if($input['type']==1){
+ //按客户
+ $count=count(DB::query('SELECT COUNT(*) as count FROM ('.$union.') as nodcloud group by customer,goods,attr,warehouse'));
+ $record = DB::query('SELECT group_concat(mold) as mold,customer,group_concat(info) as info,group_concat(unit) as unit,group_concat(nums) as nums,group_concat(tpt) as tpt FROM ( '.$union.' ) as nodcloud group by customer,goods,attr,warehouse ORDER BY `customer` DESC LIMIT '.pageCalc($input['page'],$input['limit'],'str'));
+ }else if($input['type']==2){
+ //按用户
+ $count=count(DB::query('SELECT COUNT(*) as count FROM ('.$union.') as nodcloud group by user,goods,attr,warehouse'));
+ $record = DB::query('SELECT group_concat(mold) as mold,user,group_concat(info) as info,group_concat(unit) as unit,group_concat(nums) as nums,group_concat(tpt) as tpt FROM ( '.$union.' ) as nodcloud group by user,goods,attr,warehouse ORDER BY `user` DESC LIMIT '.pageCalc($input['page'],$input['limit'],'str'));
+ }else{
+ //按人员
+ $count=count(DB::query('SELECT COUNT(*) as count FROM ('.$union.') as nodcloud group by people,goods,attr,warehouse'));
+ $record = DB::query('SELECT group_concat(mold) as mold,people,group_concat(info) as info,group_concat(unit) as unit,group_concat(nums) as nums,group_concat(tpt) as tpt FROM ( '.$union.' ) as nodcloud group by people,goods,attr,warehouse ORDER BY `people` DESC LIMIT '.pageCalc($input['page'],$input['limit'],'str'));
+ }
+ //构造数据
+ $group = [];
+ foreach($record as $vo){
+ $moldList = explode(",", $vo['mold']);
+ $infoList = explode(",", $vo['info']);
+ $unitList = explode(",", $vo['unit']);
+ $numsList = explode(",", $vo['nums']);
+ $tptList = explode(",", $vo['tpt']);
+ $row=['mold'=>$moldList[0],'info'=>$infoList[0]];
+ foreach ($moldList as $key => $mold) {
+ $row[$mold]['unit'][]=$unitList[$key];
+ $row[$mold]['nums'][]=$numsList[$key];
+ $row[$mold]['tpt'][]=$tptList[$key];
+ }
+ $input['type']==1&&$row['customer']=$vo['customer'];//客户转存
+ $input['type']==2&&$row['user']=$vo['user'];//用户转存
+ $input['type']==3&&$row['people']=$vo['people'];//人员转存
+ $group[]=$row;
+ }
+ //数据匹配
+ $infoList=[];
+ foreach ($tab as $t) {
+ $mold="app\\model\\".ucfirst($t).'Info';
+ $gather=search($group)->where([['mold','=',$t]])->select();
+ $infoList[$t]=$mold::with(['goodsData','warehouseData'])->where([['id','in',array_column($gather,'info')]])->select()->toArray();
+ }
+ //查询类型-匹配客户
+ $input['type']==1&&$customerList=db::name('customer')->where([['id','in',array_column($group,'customer')]])->select()->toArray();
+ //查询类型-匹配用户
+ $input['type']==2&&$userList=db::name('user')->where([['id','in',array_column($group,'user')]])->select()->toArray();
+ //查询类型-匹配人员
+ $input['type']==3&&$peopleList=db::name('people')->where([['id','in',array_column($group,'people')]])->select()->toArray();
+ //数据处理
+ $data=[];
+ foreach ($group as $groupVo) {
+ $row=search($infoList[$groupVo['mold']])->where([['id','=',$groupVo['info']]])->find();
+ $row['unit']=$row['goodsData']['unit']==-1?'多单位':$row['unit'];
+ foreach ($tab as $t) {
+ if(isset($groupVo[$t])){
+ if($row['goodsData']['unit']==-1){
+ $base=0;
+ foreach ($groupVo[$t]['unit'] as $key=> $unit) {
+ $radix=unitRadix($unit,$row['goodsData']['units']);
+ $base=math()->chain($groupVo[$t]['nums'][$key])->mul($radix)->add($base)->done();
+ }
+ $row[$t]=['base'=>$base,'nums'=>unitSwitch($base,$row['goodsData']['units']),'money'=>mathArraySum($groupVo[$t]['tpt'])];
+ $row[$t]['price']=math()->chain($row[$t]['money'])->div($base)->round(2)->done();
+ }else{
+ $row[$t]=['nums'=>mathArraySum($groupVo[$t]['nums']),'money'=>mathArraySum($groupVo[$t]['tpt'])];
+ $row[$t]['price']=math()->chain($row[$t]['money'])->div($row[$t]['nums'])->round(2)->done();
+ $row[$t]['base']=$row[$t]['nums'];
+ }
+ }else{
+ $row[$t]=['base'=>0,'price'=>0,'nums'=>0,'money'=>0];
+ }
+ }
+ $row['summary']['nums']=math()->chain($row['sell']['base'])->sub($row['sre']['base'])->done();
+ $row['goodsData']['unit']==-1&&$row['summary']['nums']=unitSwitch($row['summary']['nums'],$row['goodsData']['units']);
+ $row['summary']['money']=math()->chain($row['sell']['money'])->sub($row['sre']['money'])->done();
+ //类型匹配
+ $input['type']==1&&$row['customer']=search($customerList)->where([['id','=',$groupVo['customer']]])->find();//匹配客户
+ $input['type']==2&&$row['user']=search($userList)->where([['id','=',$groupVo['user']]])->find();//匹配用户
+ $input['type']==3&&$row['people']=search($peopleList)->where([['id','=',$groupVo['people']]])->find();//匹配人员
+ $data[]=$row;
+ }
+ $result=[
+ 'state'=>'success',
+ 'count'=>$count,
+ 'info'=>$data
+ ];//返回数据
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //销售汇总表-导出
+ public function ssyExports(){
+ $input=input('get.');
+ existFull($input,['warehouse'])||$input['warehouse']=[];
+ if(is_array($input['warehouse']) && isset($input['type'])){
+ pushLog('导出销售汇总表');//日志
+ $sql=[];
+ //CLASS语句
+ $sql['class']=fastSql($input,[
+ ['customer','fullEq'],
+ ['user','fullEq'],
+ ['people','fullEq'],
+ [['startTime'=>'time'],'startTime'],
+ [['endTime'=>'time'],'endTime']
+ ]);
+ $sql['class'][]=['examine','=',1];
+ $sql['class']=frameScope($sql['class']);//组织数据
+ $sql['class']=sqlAuth('sell',$sql['class']);//数据鉴权[结构一致]
+ //INFO语句
+ $sql['info']=fastSql($input,[['warehouse','fullDivisionIn']]);
+ //商品匹配
+ if(existFull($input,['goods'])){
+ $goods=array_column(Db::name('goods')->where([['name|py','like','%'.$input['goods'].'%']])->select()->toArray(),'id');
+ $sql['info'][]=['goods','in',$goods];
+ }
+ //构造语句
+ $union=[];
+ $tab=['sell','sre'];
+ foreach ($tab as $t) {
+ $union[]=Db::name($t.'_info')->alias('info')->join(['is_'.$t=>'class'],'info.pid=class.id')->where($sql['class'])->where($sql['info'])->fieldRaw('"'.$t.'" as mold,class.customer as customer,class.user as user,class.people as people,info.id as info,goods,attr,warehouse,unit,nums,tpt')->buildSql();
+ }
+ $union=implode(' UNION ALL ',$union);
+ //判断类型
+ if($input['type']==0){
+ //按商品
+ $count=count(DB::query('SELECT COUNT(*) as count FROM ('.$union.') as nodcloud group by goods,attr,warehouse'));
+ $record = DB::query('SELECT group_concat(mold) as mold,group_concat(info) as info,group_concat(unit) as unit,group_concat(nums) as nums,group_concat(tpt) as tpt FROM ( '.$union.' ) as nodcloud group by goods,attr,warehouse ORDER BY `goods` DESC');
+ }else if($input['type']==1){
+ //按客户
+ $count=count(DB::query('SELECT COUNT(*) as count FROM ('.$union.') as nodcloud group by customer,goods,attr,warehouse'));
+ $record = DB::query('SELECT group_concat(mold) as mold,customer,group_concat(info) as info,group_concat(unit) as unit,group_concat(nums) as nums,group_concat(tpt) as tpt FROM ( '.$union.' ) as nodcloud group by customer,goods,attr,warehouse ORDER BY `customer` DESC');
+ }else if($input['type']==2){
+ //按用户
+ $count=count(DB::query('SELECT COUNT(*) as count FROM ('.$union.') as nodcloud group by user,goods,attr,warehouse'));
+ $record = DB::query('SELECT group_concat(mold) as mold,user,group_concat(info) as info,group_concat(unit) as unit,group_concat(nums) as nums,group_concat(tpt) as tpt FROM ( '.$union.' ) as nodcloud group by user,goods,attr,warehouse ORDER BY `user` DESC');
+ }else{
+ //按人员
+ $count=count(DB::query('SELECT COUNT(*) as count FROM ('.$union.') as nodcloud group by people,goods,attr,warehouse'));
+ $record = DB::query('SELECT group_concat(mold) as mold,people,group_concat(info) as info,group_concat(unit) as unit,group_concat(nums) as nums,group_concat(tpt) as tpt FROM ( '.$union.' ) as nodcloud group by people,goods,attr,warehouse ORDER BY `people` DESC');
+ }
+ //构造数据
+ $group = [];
+ foreach($record as $vo){
+ $moldList = explode(",", $vo['mold']);
+ $infoList = explode(",", $vo['info']);
+ $unitList = explode(",", $vo['unit']);
+ $numsList = explode(",", $vo['nums']);
+ $tptList = explode(",", $vo['tpt']);
+ $row=['mold'=>$moldList[0],'info'=>$infoList[0]];
+ foreach ($moldList as $key => $mold) {
+ $row[$mold]['unit'][]=$unitList[$key];
+ $row[$mold]['nums'][]=$numsList[$key];
+ $row[$mold]['tpt'][]=$tptList[$key];
+ }
+ $input['type']==1&&$row['customer']=$vo['customer'];//客户转存
+ $input['type']==2&&$row['user']=$vo['user'];//用户转存
+ $input['type']==3&&$row['people']=$vo['people'];//人员转存
+ $group[]=$row;
+ }
+ //数据匹配
+ $infoList=[];
+ foreach ($tab as $t) {
+ $mold="app\\model\\".ucfirst($t).'Info';
+ $gather=search($group)->where([['mold','=',$t]])->select();
+ $infoList[$t]=$mold::with(['goodsData','warehouseData'])->where([['id','in',array_column($gather,'info')]])->select()->toArray();
+ }
+ //查询类型-匹配客户
+ $input['type']==1&&$customerList=db::name('customer')->where([['id','in',array_column($group,'customer')]])->select()->toArray();
+ //查询类型-匹配用户
+ $input['type']==2&&$userList=db::name('user')->where([['id','in',array_column($group,'user')]])->select()->toArray();
+ //查询类型-匹配人员
+ $input['type']==3&&$peopleList=db::name('people')->where([['id','in',array_column($group,'people')]])->select()->toArray();
+ //数据处理
+ $data=[];
+ foreach ($group as $groupVo) {
+ $row=search($infoList[$groupVo['mold']])->where([['id','=',$groupVo['info']]])->find();
+ $row['unit']=$row['goodsData']['unit']==-1?'多单位':$row['unit'];
+ foreach ($tab as $t) {
+ if(isset($groupVo[$t])){
+ if($row['goodsData']['unit']==-1){
+ $base=0;
+ foreach ($groupVo[$t]['unit'] as $key=> $unit) {
+ $radix=unitRadix($unit,$row['goodsData']['units']);
+ $base=math()->chain($groupVo[$t]['nums'][$key])->mul($radix)->add($base)->done();
+ }
+ $row[$t]=['base'=>$base,'nums'=>unitSwitch($base,$row['goodsData']['units']),'money'=>mathArraySum($groupVo[$t]['tpt'])];
+ $row[$t]['price']=math()->chain($row[$t]['money'])->div($base)->round(2)->done();
+ }else{
+ $row[$t]=['nums'=>mathArraySum($groupVo[$t]['nums']),'money'=>mathArraySum($groupVo[$t]['tpt'])];
+ $row[$t]['price']=math()->chain($row[$t]['money'])->div($row[$t]['nums'])->round(2)->done();
+ $row[$t]['base']=$row[$t]['nums'];
+ }
+ }else{
+ $row[$t]=['base'=>0,'price'=>0,'nums'=>0,'money'=>0];
+ }
+ }
+ $row['summary']['nums']=math()->chain($row['sell']['base'])->sub($row['sre']['base'])->done();
+ $row['goodsData']['unit']==-1&&$row['summary']['nums']=unitSwitch($row['summary']['nums'],$row['goodsData']['units']);
+ $row['summary']['money']=math()->chain($row['sell']['money'])->sub($row['sre']['money'])->done();
+ //类型匹配
+ $input['type']==1&&$row['customer']=search($customerList)->where([['id','=',$groupVo['customer']]])->find();//匹配客户
+ $input['type']==2&&$row['user']=search($userList)->where([['id','=',$groupVo['user']]])->find();//匹配用户
+ $input['type']==3&&$row['people']=search($peopleList)->where([['id','=',$groupVo['people']]])->find();//匹配人员
+ $data[]=$row;
+ }
+ $source=$data;
+ //开始构造导出数据
+ $excel=[];//初始化导出数据
+ //标题数据
+ $excel[]=['type'=>'title','info'=>'销售汇总表'];
+ //表格数据
+ $field=[
+ [
+ "customer|name"=>"客户"
+ ],
+ [
+ "user|name"=>"用户"
+ ],
+ [
+ "people|name"=>"关联人员"
+ ],
+ [
+ "goodsData|name"=>"商品名称",
+ "attr"=>"辅助属性",
+ "warehouseData|name"=>"仓库",
+ "unit"=>"单位",
+ "sell|price"=>"销售单价",
+ "sell|nums"=>"销售数量",
+ "sell|money"=>"销售金额",
+ "sre|price"=>"购退单价",
+ "sre|nums"=>"购退数量",
+ "sre|money"=>"购退金额",
+ "summary|nums"=>"汇总数量",
+ "summary|money"=>"汇总金额"
+ ]
+ ];
+ $field=[$field[3],array_merge($field[0],$field[3]),array_merge($field[1],$field[3]),array_merge($field[2],$field[3]),][$input['type']];
+ $thead=array_values($field);//表格标题
+ $tbody=[];//表格内容
+ //构造表内数据
+ foreach ($source as $sourceVo) {
+ $rowData=[];
+ foreach (array_keys($field) as $fieldVo) {
+ $rowData[]=arraySeek($sourceVo,$fieldVo);//多键名数据赋值
+ }
+ $tbody[]=$rowData;//加入行数据
+ }
+ $excel[]=['type'=>'table','info'=>['thead'=>$thead,'tbody'=>$tbody]];//表格数据
+ //汇总数据
+ $excel[]=['type'=>'node','info'=>[
+ '总数:'.count($source),
+ '销售总金额:'.mathArraySum(arrayColumns($source,['sell','money'])),
+ '销售退货总金额:'.mathArraySum(arrayColumns($source,['sre','money'])),
+ '汇总金额:'.mathArraySum(arrayColumns($source,['summary','money']))
+ ]];
+ //导出execl
+ buildExcel('销售汇总表',$excel);
+ }else{
+ return json(['state'=>'error','info'=>'传入参数不完整!']);
+ }
+ }
+ //销售收款表
+ public function sbt(){
+ $input=input('post.');
+ $sheet=['sell','sre'];
+ existFull($input,['mold'])||$input['mold']=$sheet;
+ if(existFull($input,['page','limit']) && is_arrays($input,['nucleus','mold']) && arrayInArray($input['mold'],$sheet)){
+ $sql=[];
+ //CLASS语句
+ $sql=fastSql($input,[
+ ['customer','fullEq'],
+ ['number','fullLike'],
+ [['startTime'=>'time'],'startTime'],
+ [['endTime'=>'time'],'endTime'],
+ ['nucleus','fullIn']
+ ]);
+ $sql[]=['examine','=',1];
+ $sql=frameScope($sql);//组织数据
+ $sql=sqlAuth('sell',$sql);//数据鉴权[结构一致]
+ //组装语句
+ $union=[];
+ foreach ($input['mold'] as $mold) {
+ $union[]=Db::name($mold)->where($sql)->fieldRaw('"'.$mold.'" as mold,id,time')->buildSql();
+ }
+ $union=implode(' UNION ALL ',$union);
+ //获取总条数
+ $count=DB::query('SELECT COUNT(*) as count FROM ('.$union.') as nodcloud')[0]["count"];
+ $record=DB::query('SELECT * FROM ('.$union.') as nodcloud ORDER BY `time` DESC LIMIT '.pageCalc($input['page'],$input['limit'],'str'));
+ //匹配数据
+ $list=[];
+ foreach ($input['mold'] as $mold) {
+ $gather=search($record)->where([['mold','=',$mold]])->select();
+ $db="app\\model\\".ucfirst($mold);
+ $list[$mold]=$db::with(['frameData','customerData','billData'])->where([['id','in',array_column($gather,'id')]])->append(['extension'])->select()->toArray();
+ }
+ //构造数据
+ $data=[];
+ foreach ($record as $recordVo) {
+ $mold=$recordVo['mold'];
+ $row=search($list[$mold])->where([['id','=',$recordVo['id']]])->find();
+ $row['key']=$mold.'_'.$recordVo['id'];
+ $row['name']=['sell'=>'销售单','sre'=>'销售退货单'][$mold];
+ $row['balance']=$row['extension']['anwo'];
+ $row['rate']=in_array($row['nucleus'],['0','2'])?['0%','','100%'][$row['nucleus']]:math()->chain($row['extension']['amount'])->div($row['actual'])->mul(100)->round(2)->done().'%';
+ $row['node']=[];
+ $bill=search($row['billData'])->where([['type','=','bill']])->select();
+ foreach ($bill as $billVo) {
+ $node=[
+ 'key'=>$row['key'].'_'.$billVo['id'],
+ 'name'=>'核销单',
+ 'time'=>$billVo['time'],
+ 'number'=>$billVo['sourceData']['number'],
+ 'money'=>$billVo['money'],
+ ];
+ //反转金额
+ in_array($mold,['sre'])&&$node['money']*=-1;
+ $row['node'][]=$node;
+ }
+ //反转金额
+ if(in_array($mold,['sre'])){
+ $row['total']*=-1;
+ $row['actual']*=-1;
+ $row['money']*=-1;
+ $row['balance']*=-1;
+ }
+ $data[]=$row;
+ }
+ $result=[
+ 'state'=>'success',
+ 'count'=>$count,
+ 'info'=>$data
+ ];//返回数据
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //销售收款表-导出
+ public function sbtExports(){
+ $input=input('get.');
+ $sheet=['sell','sre'];
+ existFull($input,['nucleus'])||$input['nucleus']=[];
+ existFull($input,['mold'])||$input['mold']=$sheet;
+ if(is_arrays($input,['nucleus','mold']) && arrayInArray($input['mold'],$sheet)){
+ pushLog('导出销售收款表');//日志
+ $sql=[];
+ //CLASS语句
+ $sql=fastSql($input,[
+ ['customer','fullEq'],
+ ['number','fullLike'],
+ [['startTime'=>'time'],'startTime'],
+ [['endTime'=>'time'],'endTime'],
+ ['nucleus','fullDivisionIn']
+ ]);
+ $sql[]=['examine','=',1];
+ $sql=frameScope($sql);//组织数据
+ $sql=sqlAuth('sell',$sql);//数据鉴权[结构一致]
+ //组装语句
+ $union=[];
+ foreach ($input['mold'] as $mold) {
+ $union[]=Db::name($mold)->where($sql)->fieldRaw('"'.$mold.'" as mold,id,time')->buildSql();
+ }
+ $union=implode(' UNION ALL ',$union);
+ //获取总条数
+ $record=DB::query('SELECT * FROM ('.$union.') as nodcloud ORDER BY `time` DESC');
+ //匹配数据
+ $list=[];
+ foreach ($input['mold'] as $mold) {
+ $gather=search($record)->where([['mold','=',$mold]])->select();
+ $db="app\\model\\".ucfirst($mold);
+ $list[$mold]=$db::with(['frameData','customerData','billData'])->where([['id','in',array_column($gather,'id')]])->append(['extension'])->select()->toArray();
+ }
+ //构造数据
+ $data=[];
+ foreach ($record as $recordVo) {
+ $mold=$recordVo['mold'];
+ $row=search($list[$mold])->where([['id','=',$recordVo['id']]])->find();
+ $row['key']=$mold.'_'.$recordVo['id'];
+ $row['name']=['sell'=>'销售单','sre'=>'销售退货单'][$mold];
+ $row['balance']=$row['extension']['anwo'];
+ $row['rate']=in_array($row['nucleus'],['0','2'])?['0%','','100%'][$row['nucleus']]:math()->chain($row['extension']['amount'])->div($row['actual'])->mul(100)->round(2)->done().'%';
+ $row['node']=[];
+ $bill=search($row['billData'])->where([['type','=','bill']])->select();
+ foreach ($bill as $billVo) {
+ $node=[
+ 'key'=>$row['key'].'_'.$billVo['id'],
+ 'name'=>'核销单',
+ 'time'=>$billVo['time'],
+ 'number'=>$billVo['sourceData']['number'],
+ 'money'=>$billVo['money'],
+ ];
+ //反转金额
+ in_array($mold,['sre'])&&$node['money']*=-1;
+ $row['node'][]=$node;
+ }
+ //反转金额
+ if(in_array($mold,['sre'])){
+ $row['total']*=-1;
+ $row['actual']*=-1;
+ $row['money']*=-1;
+ $row['balance']*=-1;
+ }
+ $data[]=$row;
+ }
+ $source=[];
+ foreach ($data as $dataVo) {
+ $source[]=$dataVo;
+ if(!empty($dataVo['node'])){
+ foreach ($dataVo['node'] as $node) {
+ $source[]=$node;
+ }
+ }
+ }
+ //开始构造导出数据
+ $excel=[];//初始化导出数据
+ //标题数据
+ $excel[]=['type'=>'title','info'=>'销售收款表'];
+ //表格数据
+ $field=[
+ "name"=>"单据类型",
+ "frameData|name"=>"所属组织",
+ "customerData|name"=>"客户",
+ "time"=>"单据时间",
+ "number"=>"单据编号",
+ "total"=>"单据金额",
+ "actual"=>"实际金额",
+ "money"=>"单据付款",
+ "balance"=>"应付款余额",
+ "rate"=>"付款率",
+ "extension|nucleus"=>"核销状态",
+ "data"=>"备注信息"
+ ];
+ $thead=array_values($field);//表格标题
+ $tbody=[];//表格内容
+ //构造表内数据
+ foreach ($source as $sourceVo) {
+ $rowData=[];
+ foreach (array_keys($field) as $fieldVo) {
+ $rowData[]=arraySeek($sourceVo,$fieldVo);//多键名数据赋值
+ }
+ $tbody[]=$rowData;//加入行数据
+ }
+ $excel[]=['type'=>'table','info'=>['thead'=>$thead,'tbody'=>$tbody]];//表格数据
+ //汇总数据
+ $excel[]=['type'=>'node','info'=>[
+ '总数:'.count($source),
+ '应收款总余额:'.mathArraySum(array_column($source,'balance'))
+ ]];
+ //导出execl
+ buildExcel('销售收款表',$excel);
+ }else{
+ return json(['state'=>'error','info'=>'传入参数不完整!']);
+ }
+ }
+}
diff --git a/serve/app/controller/Stock.php b/serve/app/controller/Stock.php
new file mode 100644
index 0000000..f8f2130
--- /dev/null
+++ b/serve/app/controller/Stock.php
@@ -0,0 +1,437 @@
+where(empty($input['warehouse'])?sqlAuth('warehouse',[]):[['id','in',$input['warehouse']]])->order(['id'=>'desc'])->select()->toArray();
+ //构造表头|集合
+ $column=[];
+ foreach ($warehouse as $warehouseVo) {
+ $column[]=['id'=>$warehouseVo['id'],'key'=>'stock_'.$warehouseVo['id'],'name'=>$warehouseVo['name']];
+ }
+ //匹配商品
+ $sql=fastSql($input,[
+ [['name'=>'name|py'],'fullLike'],
+ ['number','fullLike'],
+ ['spec','fullLike'],
+ ['brand','fullEq'],
+ ['code','fullLike']
+ ]);//构造SQL
+ //商品类型
+ $sql[]=['type','=',0];
+ //辅助属性扩展查询
+ $sqlOr=existFull($input,['code'])?[['id','in',array_column(Db::name('attr')->where([['code','=',$input['code']]])->select()->toArray(),'pid')]]:[];
+ //商品分类树结构查询
+ existFull($input,['category'])&&$sql[]=['category','in',findTreeArr('category',$input['category'],'id')];
+ //查询类型
+ if($input['state']==0){
+ //获取总条数
+ $count = Goods::where($sql)->whereOr($sqlOr)->count();
+ //查询分页数据
+ $info = Goods::with(['categoryData','attr'])->where($sql)->whereOr($sqlOr)->order(['id'=>'desc'])->page($input['page'],$input['limit'])->append(['extension'])->select()->toArray();
+ }elseif($input['state']==1){
+ $exists=Db::name('room')->where([['warehouse','in',array_column($warehouse,'id')],['nums','<>',0],['goods','=',Db::raw('goods.id')]])->buildSql(false);
+ //获取总条数
+ $count = Goods::where($sql)->whereOr($sqlOr)->alias('goods')->whereExists($exists)->count();
+ //查询分页数据
+ $info = Goods::with(['categoryData','attr'])->where($sql)->whereOr($sqlOr)->alias('goods')->whereExists($exists)->order(['id'=>'desc'])->page($input['page'],$input['limit'])->append(['extension'])->select()->toArray();
+ }else{
+ //子查询
+ $exists=Db::name('room')->where([['warehouse','in',array_column($warehouse,'id')],['goods','=',Db::raw('goods.id')],['nums','<=',Db::raw('goods.stock')]])->buildSql(false);
+ //获取总条数
+ $count = Goods::where($sql)->whereOr($sqlOr)->alias('goods')->whereExists($exists)->count();
+ //查询分页数据
+ $info = Goods::with(['categoryData','attr'])->where($sql)->whereOr($sqlOr)->alias('goods')->whereExists($exists)->order(['id'=>'desc'])->page($input['page'],$input['limit'])->append(['extension'])->select()->toArray();
+ }
+ //唯一标识|属性处理
+ foreach ($info as $infoKey=>$infoVo) {
+ $info[$infoKey]['key']=$infoVo['id'];
+ foreach ($infoVo['attr'] as $attrKey=>$attrVo) {
+ $info[$infoKey]['attr'][$attrKey]['key']=$infoVo['id'].'.'.$attrVo['id'];
+ //属性处理
+ if(existFull($input,['code']) && !in_array($input['code'],[$infoVo['code'],$attrVo['code']])){
+ unset($info[$infoKey]['attr'][$attrKey]);
+ }
+ }
+ //重建索引
+ $info[$infoKey]['attr']=array_values($info[$infoKey]['attr']);
+ }
+ //查询库存数据
+ $room=Db::name('room')->where([['warehouse','in',array_column($warehouse,'id')],['goods','in',array_column($info,'id')]])->select()->toArray();
+ //库存集合[w:仓库|g:商品|a:属性]
+ $gather=['g'=>[],'wg'=>[],'ga'=>[],'wga'=>[]];
+ foreach ($room as $roomVo) {
+ //商品
+ $g=md5_16($roomVo['goods']);
+ $gather['g'][$g]=math()->chain($gather['g'][$g]??0)->add($roomVo['nums'])->done();
+ //仓库|商品
+ $wg=md5_16($roomVo['warehouse'].'&'.$roomVo['goods']);
+ $gather['wg'][$wg]=math()->chain($gather['wg'][$wg]??0)->add($roomVo['nums'])->done();
+ //判断属性
+ if(!empty($roomVo['attr'])){
+ //商品|属性
+ $ga=md5_16($roomVo['goods'].'&'.$roomVo['attr']);
+ $gather['ga'][$ga]=math()->chain($gather['ga'][$ga]??0)->add($roomVo['nums'])->done();
+ //仓库|商品|属性
+ $wga=md5_16($roomVo['warehouse'].'&'.$roomVo['goods'].'&'.$roomVo['attr']);
+ $gather['wga'][$wga]=math()->chain($gather['wga'][$wga]??0)->add($roomVo['nums'])->done();
+ }
+ }
+ //数量匹配|库存处理
+ foreach ($info as $infoKey=>$infoVo) {
+ //商品
+ $g=md5_16($infoVo['id']);
+ $info[$infoKey]['summary']=isset($gather['g'][$g])?($infoVo['unit']=='-1'?unitSwitch($gather['g'][$g],$infoVo['units']):$gather['g'][$g]):0;
+ //仓库|商品
+ foreach ($column as $columnVo) {
+ $wg=md5_16($columnVo['id'].'&'.$infoVo['id']);
+ $info[$infoKey]['stock_'.$columnVo['id']]=isset($gather['wg'][$wg])?($infoVo['unit']=='-1'?unitSwitch($gather['wg'][$wg],$infoVo['units']):$gather['wg'][$wg]):0;
+ }
+ //匹配辅助属性
+ foreach ($infoVo['attr'] as $attrKey=>$attrVo) {
+ //商品|属性
+ $ga=md5_16($infoVo['id'].'&'.$attrVo['name']);
+ $info[$infoKey]['attr'][$attrKey]['summary']=isset($gather['ga'][$ga])?($infoVo['unit']=='-1'?unitSwitch($gather['ga'][$ga],$infoVo['units']):$gather['ga'][$ga]):0;
+ //仓库|商品|属性
+ foreach ($column as $columnVo) {
+ $wga=md5_16($columnVo['id'].'&'.$infoVo['id'].'&'.$attrVo['name']);
+ $info[$infoKey]['attr'][$attrKey]['stock_'.$columnVo['id']]=isset($gather['wga'][$wga])?($infoVo['unit']=='-1'?unitSwitch($gather['wga'][$wga],$infoVo['units']):$gather['wga'][$wga]):0;
+ $input['state']==2&&$info[$infoKey]['attr'][$attrKey]['stocks'][]=$info[$infoKey]['attr'][$attrKey]['stock_'.$columnVo['id']];
+ }
+ //非零库存|排除属性为零
+ if($input['state']==1 && $info[$infoKey]['attr'][$attrKey]['summary']==0){
+ unset($info[$infoKey]['attr'][$attrKey]);
+ }
+ //预警库存
+ if($input['state']==2){
+ $exist=false;
+ foreach ($info[$infoKey]['attr'][$attrKey]['stocks'] as $stockVo) {
+ if($stockVo<=$info[$infoKey]['stock']){
+ $exist=true;
+ break;
+ }
+ }
+ if(!$exist)unset($info[$infoKey]['attr'][$attrKey]);
+ }
+ }
+ //重建索引
+ $info[$infoKey]['attr']=array_values($info[$infoKey]['attr']);
+ }
+ $result=[
+ 'state'=>'success',
+ 'count'=>$count,
+ 'info'=>$info,
+ 'column'=>$column
+ ];//返回数据
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //导出
+ public function exports(){
+ $input=input('get.');
+ existFull($input,['warehouse'])||$input['warehouse']=[];
+ if(isset($input['warehouse']) && is_array($input['warehouse']) && isset($input['state']) && in_array($input['state'],[0,1,2])){
+ pushLog('导出库存列表');//日志
+ //匹配仓库
+ $warehouse = Db::name('warehouse')->where(empty($input['warehouse'])?sqlAuth('warehouse',[]):[['id','in',$input['warehouse']]])->order(['id'=>'desc'])->select()->toArray();
+ //构造表头
+ $column=[];
+ foreach ($warehouse as $warehouseVo) {
+ $column['stock_'.$warehouseVo['id']]=$warehouseVo['name'];
+ }
+ //匹配商品
+ $sql=fastSql($input,[
+ [['name'=>'name|py'],'fullLike'],
+ ['number','fullLike'],
+ ['spec','fullLike'],
+ ['brand','fullEq'],
+ ['code','fullLike']
+ ]);//构造SQL
+ //商品类型
+ $sql[]=['type','=',0];
+ //辅助属性扩展查询
+ $sqlOr=existFull($input,['code'])?[['id','in',array_column(Db::name('attr')->where([['code','=',$input['code']]])->select()->toArray(),'pid')]]:[];
+ //商品分类树结构查询
+ existFull($input,['category'])&&$sql[]=['category','in',findTreeArr('category',$input['category'],'id')];
+ //查询类型
+ if($input['state']==0){
+ //查询分页数据
+ $info = Goods::with(['categoryData','attr'])->where($sql)->whereOr($sqlOr)->order(['id'=>'desc'])->append(['extension'])->select()->toArray();
+ }elseif($input['state']==1){
+ $exists=Db::name('room')->where([['warehouse','in',array_column($warehouse,'id')],['nums','<>',0],['goods','=',Db::raw('goods.id')]])->buildSql(false);
+ //查询分页数据
+ $info = Goods::with(['categoryData','attr'])->where($sql)->whereOr($sqlOr)->alias('goods')->whereExists($exists)->order(['id'=>'desc'])->append(['extension'])->select()->toArray();
+ }else{
+ //子查询
+ $exists=Db::name('room')->where([['warehouse','in',array_column($warehouse,'id')],['goods','=',Db::raw('goods.id')],['nums','<=',Db::raw('goods.stock')]])->buildSql(false);
+ //获取总条数
+ $count = Goods::where($sql)->whereOr($sqlOr)->alias('goods')->whereExists($exists)->count();
+ //查询分页数据
+ $info = Goods::with(['categoryData','attr'])->where($sql)->whereOr($sqlOr)->alias('goods')->whereExists($exists)->order(['id'=>'desc'])->append(['extension'])->select()->toArray();
+ }
+ //属性处理
+ foreach ($info as $infoKey=>$infoVo) {
+ foreach ($infoVo['attr'] as $attrKey=>$attrVo) {
+ //属性处理
+ if(existFull($input,['code']) && !in_array($input['code'],[$infoVo['code'],$attrVo['code']])){
+ unset($info[$infoKey]['attr'][$attrKey]);
+ }
+ }
+ //重建索引
+ $info[$infoKey]['attr']=array_values($info[$infoKey]['attr']);
+ }
+ //查询库存数据
+ $room=Db::name('room')->where([['warehouse','in',array_column($warehouse,'id')],['goods','in',array_column($info,'id')]])->select()->toArray();
+ //库存集合[w:仓库|g:商品|a:属性]
+ $gather=['g'=>[],'wg'=>[],'ga'=>[],'wga'=>[]];
+ foreach ($room as $roomVo) {
+ //商品
+ $g=md5_16($roomVo['goods']);
+ $gather['g'][$g]=math()->chain($gather['g'][$g]??0)->add($roomVo['nums'])->done();
+ //仓库|商品
+ $wg=md5_16($roomVo['warehouse'].'&'.$roomVo['goods']);
+ $gather['wg'][$wg]=math()->chain($gather['wg'][$wg]??0)->add($roomVo['nums'])->done();
+ //判断属性
+ if(!empty($roomVo['attr'])){
+ //商品|属性
+ $ga=md5_16($roomVo['goods'].'&'.$roomVo['attr']);
+ $gather['ga'][$ga]=math()->chain($gather['ga'][$ga]??0)->add($roomVo['nums'])->done();
+ //仓库|商品|属性
+ $wga=md5_16($roomVo['warehouse'].'&'.$roomVo['goods'].'&'.$roomVo['attr']);
+ $gather['wga'][$wga]=math()->chain($gather['wga'][$wga]??0)->add($roomVo['nums'])->done();
+ }
+ }
+
+ //数量匹配|库存处理
+ foreach ($info as $infoKey=>$infoVo) {
+ //商品
+ $g=md5_16($infoVo['id']);
+ $info[$infoKey]['summary']=isset($gather['g'][$g])?($infoVo['unit']=='-1'?unitSwitch($gather['g'][$g],$infoVo['units']):$gather['g'][$g]):0;
+ //仓库|商品
+ foreach ($warehouse as $warehouseVo) {
+ $wg=md5_16($warehouseVo['id'].'&'.$infoVo['id']);
+ $info[$infoKey]['stock_'.$warehouseVo['id']]=isset($gather['wg'][$wg])?($infoVo['unit']=='-1'?unitSwitch($gather['wg'][$wg],$infoVo['units']):$gather['wg'][$wg]):0;
+
+ }
+ //匹配辅助属性
+ foreach ($infoVo['attr'] as $attrKey=>$attrVo) {
+ //商品|属性
+ $ga=md5_16($infoVo['id'].'&'.$attrVo['name']);
+ $info[$infoKey]['attr'][$attrKey]['summary']=isset($gather['ga'][$ga])?($infoVo['unit']=='-1'?unitSwitch($gather['ga'][$ga],$infoVo['units']):$gather['ga'][$ga]):0;
+ //仓库|商品|属性
+ foreach ($warehouse as $warehouseVo) {
+ $wga=md5_16($warehouseVo['id'].'&'.$infoVo['id'].'&'.$attrVo['name']);
+ $info[$infoKey]['attr'][$attrKey]['stock_'.$warehouseVo['id']]=isset($gather['wga'][$wga])?($infoVo['unit']=='-1'?unitSwitch($gather['wga'][$wga],$infoVo['units']):$gather['wga'][$wga]):0;
+ $input['state']==2&&$info[$infoKey]['attr'][$attrKey]['stocks'][]=$info[$infoKey]['attr'][$attrKey]['stock_'.$warehouseVo['id']];
+ }
+ //非零库存|排除属性为零
+ if($input['state']==1 && $info[$infoKey]['attr'][$attrKey]['summary']==0){
+ unset($info[$infoKey]['attr'][$attrKey]);
+ }
+ //预警库存
+ if($input['state']==2){
+ $exist=false;
+ foreach ($info[$infoKey]['attr'][$attrKey]['stocks'] as $stockVo) {
+ if($stockVo<=$info[$infoKey]['stock']){
+ $exist=true;
+ break;
+ }
+ }
+ if(!$exist)unset($info[$infoKey]['attr'][$attrKey]);
+ }
+ }
+ //重建索引
+ $info[$infoKey]['attr']=array_values($info[$infoKey]['attr']);
+ }
+ //结构重组
+ $source=[];
+ foreach ($info as $infoVo) {
+ $source[]=$infoVo;
+ if(!empty($infoVo['attr'])){
+ foreach ($infoVo['attr'] as $attrVo) {
+ $attrVo['name']='|- '.$attrVo['name'];
+ $source[]=$attrVo;
+ }
+ }
+ }
+ //开始构造导出数据
+ $excel=[];//初始化导出数据
+ //标题数据
+ $excel[]=['type'=>'title','info'=>'库存列表'];
+ //表格数据
+ $field=array_merge(['name'=>'商品名称','summary'=>'库存数量'],$column,['stock'=>'预警阈值','number'=>'商品编号','spec'=>'规格型号','categoryData|name'=>'商品分类','brand'=>'商品品牌','extension|unit'=>'商品单位','code'=>'商品条码','data'=>'商品备注']);
+ $thead=array_values($field);//表格标题
+ $tbody=[];//表格内容
+ //构造表内数据
+ foreach ($source as $sourceVo) {
+ $rowData=[];
+ foreach (array_keys($field) as $fieldVo) {
+ $rowData[]=arraySeek($sourceVo,$fieldVo);//多键名数据赋值
+ }
+ $tbody[]=$rowData;//加入行数据
+ }
+ $excel[]=['type'=>'table','info'=>['thead'=>$thead,'tbody'=>$tbody]];//表格数据
+ //导出execl
+ buildExcel('库存列表',$excel);
+ }else{
+ return json(['state'=>'error','info'=>'传入数据不完整!']);
+ }
+ }
+ //详情列表
+ public function detailRecord(){
+ $input=input('post.');
+ $sheet=['buy','bre','sell','sre','swapOut','swapEnter','entry','extry'];
+ existFull($input,['type'])||$input['type']=$sheet;
+ if(existFull($input,['page','limit','goods','warehouse']) && is_arrays($input,['warehouse','type']) && arrayInArray($input['type'],$sheet)){
+ //构造SQL|ROOM
+ $roomSql=fastSql($input,[
+ ['warehouse','fullIn'],
+ ['goods','fullEq']
+ ]);
+ isset($input['attr'])&&$roomSql[]=['attr','=',$input['attr']];
+ //查询仓储数据
+ $room=Db::name('room')->where($roomSql)->field(['id'])->select()->toArray();
+ if(empty($room)){
+ $count=0;
+ $info=[];
+ }else{
+ //构造SQL|ROOMINFO
+ $infoSql=fastSql($input,[['type','fullIn']]);
+ $infoSql[]=['pid','in',array_column($room,'id')];
+ //子查询SQL
+ $existsSql=fastSql($input,[
+ ['number','fullLike'],
+ [['startTime'=>'time'],'startTime'],
+ [['endTime'=>'time'],'endTime']
+ ]);
+ $existsSql[]=['id','=',Db::raw('info.class')];
+ $existsSql=frameScope($existsSql);
+ //多源匹配
+ $union=[];
+ //数据关系表
+ $table=['buy'=>'buy','bre'=>'bre','sell'=>'sell','sre'=>'sre','swapOut'=>'swap','swapEnter'=>'swap','entry'=>'entry','extry'=>'extry'];
+ foreach ($table as $k=>$v) {
+ //匹配类型|减少查询
+ if(in_array($k,$input['type'])){
+ $union[]=Db::name($v)->where([['info.type','=',$k]])->where(array_merge($existsSql,sqlAuth($v,[])))->limit(1)->buildSql();
+ }
+ }
+ //合并子查询
+ $union=implode(' UNION ALL ',$union);
+ $count=RoomInfo::alias('info')->where($infoSql)->whereExists($union)->count();
+ $info=RoomInfo::with(['sourceData'=>['frameData']])->alias('info')->where($infoSql)->whereExists($union)->page($input['page'],$input['limit'])->order(['id'=>'desc'])->append(['extension'])->select()->toArray();
+ //处理多单位
+ if(!empty($info)){
+ $goods=Db::name('goods')->where([['id','=',$input['goods']]])->find();
+ if($goods['unit']=='-1'){
+ foreach ($info as $infoKey=>$infoVo) {
+ $info[$infoKey]['nums']=unitSwitch($infoVo['nums'],json_decode($goods['units'],true));
+ }
+ }
+ }
+ }
+ $result=[
+ 'state'=>'success',
+ 'count'=>$count,
+ 'info'=>$info
+ ];//返回数据
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //详情导出
+ public function detailExports(){
+ $input=input('get.');
+ $sheet=['buy','bre','sell','sre','swapOut','swapEnter','entry','extry'];
+ existFull($input,['type'])||$input['type']=$sheet;
+ if(existFull($input,['goods','warehouse']) && is_arrays($input,['warehouse','type']) && arrayInArray($input['type'],$sheet)){
+ pushLog('导出库存详情');//日志
+ //商品数据
+ $goods=Db::name('goods')->where([['id','=',$input['goods']]])->find();
+ //构造SQL|ROOM
+ $roomSql=fastSql($input,[
+ ['warehouse','fullIn'],
+ ['goods','fullEq']
+ ]);
+ isset($input['attr'])&&$roomSql[]=['attr','=',$input['attr']];
+ //查询仓储数据
+ $room=Db::name('room')->where($roomSql)->field(['id'])->select()->toArray();
+ if(empty($room)){
+ $source=[];
+ }else{
+ //构造SQL|ROOMINFO
+ $infoSql=fastSql($input,[['type','fullIn']]);
+ $infoSql[]=['pid','in',array_column($room,'id')];
+ //子查询SQL
+ $existsSql=fastSql($input,[
+ ['number','fullLike'],
+ [['startTime'=>'time'],'startTime'],
+ [['endTime'=>'time'],'endTime']
+ ]);
+ $existsSql[]=['id','=',Db::raw('info.class')];
+ $existsSql=frameScope($existsSql);
+ //多源匹配
+ $union=[];
+ //数据关系表
+ $table=['buy'=>'buy','bre'=>'bre','sell'=>'sell','sre'=>'sre','swapOut'=>'swap','swapEnter'=>'swap','entry'=>'entry','extry'=>'extry'];
+ foreach ($table as $k=>$v) {
+ //匹配类型|减少查询
+ if(in_array($k,$input['type'])){
+ $union[]=Db::name($v)->where([['info.type','=',$k]])->where(array_merge($existsSql,sqlAuth($v,[])))->limit(1)->buildSql();
+ }
+ }
+ //合并子查询
+ $union=implode(' UNION ALL ',$union);
+ $source=RoomInfo::with(['sourceData'=>['frameData']])->alias('info')->where($infoSql)->whereExists($union)->order(['id'=>'desc'])->append(['extension'])->select()->toArray();
+ //处理多单位
+ if(!empty($source)){
+ $goods=Db::name('goods')->where([['id','=',$input['goods']]])->find();
+ if($goods['unit']=='-1'){
+ foreach ($source as $sourceKey=>$sourceVo) {
+ $source[$sourceKey]['nums']=unitSwitch($sourceVo['nums'],json_decode($goods['units'],true));
+ }
+ }
+ }
+ }
+ //开始构造导出数据
+ $excel=[];//初始化导出数据
+ //标题数据
+ $excel[]=['type'=>'title','info'=>'库存详情'];
+ //表格数据
+ $field=[
+ 'sourceData|frameData|name'=>'所属组织',
+ 'sourceData|time'=>'操作时间',
+ 'extension|type'=>'单据类型',
+ 'sourceData|number'=>'单据编号',
+ 'extension|direction'=>'操作类型',
+ 'nums'=>'操作数量'
+ ];
+ $thead=array_values($field);//表格标题
+ $tbody=[];//表格内容
+ //构造表内数据
+ foreach ($source as $sourceVo) {
+ $rowData=[];
+ foreach (array_keys($field) as $fieldVo) {
+ $rowData[]=arraySeek($sourceVo,$fieldVo);//多键名数据赋值
+ }
+ $tbody[]=$rowData;//加入行数据
+ }
+ $excel[]=['type'=>'table','info'=>['thead'=>$thead,'tbody'=>$tbody]];//表格数据
+ //导出execl
+ buildExcel('库存详情',$excel);
+ }else{
+ return json(['state'=>'error','info'=>'传入数据不完整!']);
+ }
+ }
+}
\ No newline at end of file
diff --git a/serve/app/controller/Summary.php b/serve/app/controller/Summary.php
new file mode 100644
index 0000000..e074a9c
--- /dev/null
+++ b/serve/app/controller/Summary.php
@@ -0,0 +1,289 @@
+where([['time','>',$period]])->count();
+ //计价方式
+ $fun=getSys('fun');
+ $info=[
+ 'valuation'=>['base'=>'基础计价','ma'=>'移动平均','fifo'=>'先进先出'][$fun['valuation']],
+ 'branch'=>['总仓核算','分仓核算'][$fun['branch']],
+ 'rule'=>['def'=>'结存结余','attr'=>'辅助属性','batch'=>'批次日期','aab'=>'属性批次'][$fun['rule']],
+ ];
+ //初始结账
+ $summary=Db::name('summary')->where([['time','>',$period]])->field(['id'])->select()->toArray();
+ $fifo=Db::name('fifo')->where([['out','in',array_column($summary,'id')]])->select()->toArray();
+ $relation=[];
+ foreach ($fifo as $v) {
+ $relation[]=['id'=>$v['in'],'handle'=>$v['handle']];
+ }
+ if(!empty($relation)){
+ Db::name('summary')->duplicate(['handle'=>Db::raw('handle - VALUES(`handle`)')])->insertAll($relation);
+ Db::name('fifo')->where([['id','in',array_column($fifo,'id')]])->delete();
+ }
+ Db::name('summary')->where([['id','in',array_column($summary,'id')]])->delete();
+ pushLog('执行数据校准');//日志
+ //返回数据
+ $result=[
+ 'state'=>'success',
+ 'count'=>$count,
+ 'info'=>$info
+ ];
+ return json($result);
+ }
+ //收发处理
+ public function note($type,$class,$mold){
+ //场景判断
+ if($mold){
+ //记录
+ $info=Db::name('room_info')->where([['type','=',$type],['class','=',$class]])->order(['time','id'])->field(['id'])->select()->toArray();
+ $this->handle(array_column($info,'id'));
+ }else{
+ //清除
+ $summary=Db::name('summary')->where([['type','=',$type],['class','=',$class]])->field(['id'])->select()->toArray();
+ $fifo=Db::name('fifo')->where([['out','in',array_column($summary,'id')]])->select()->toArray();
+ $relation=[];
+ foreach ($fifo as $v) {
+ $relation[]=['id'=>$v['in'],'handle'=>$v['handle']];
+ }
+ if(!empty($relation)){
+ Db::name('summary')->duplicate(['handle'=>Db::raw('handle - VALUES(`handle`)')])->insertAll($relation);
+ Db::name('fifo')->where([['id','in',array_column($fifo,'id')]])->delete();
+ }
+ Db::name('summary')->where([['id','in',array_column($summary,'id')]])->delete();
+ }
+ }
+ //轮询数据
+ public function poll() {
+ $input=input('post.');
+ if(existFull($input,['page','limit'])){
+ Db::startTrans();
+ try {
+ $period=getPeriod();
+ $info=Db::name('room_info')->where([['time','>',$period]])->page($input['page'],$input['limit'])->order(['time','id'])->field(['id'])->select()->toArray();
+ $this->handle(array_column($info,'id'));
+
+ Db::commit();
+ $result=['state'=>'success'];
+ } catch (\Exception $e) {
+ dd($e);
+ Db::rollback();
+ $result=['state'=>'error','info'=>'内部错误,操作已撤销!'];
+ }
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //收发记录
+ public function handle($arr){
+ if(empty($arr)) return;
+ //查询记录
+ $info = Db::name('room_info')->where([['id','in',$arr]])->order(['time','id'])->select()->toArray();
+ //匹配单据
+ $union=[];
+ $tab=['buy'=>'buy','bre'=>'bre','sell'=>'sell','sre'=>'sre','swapOut'=>'swap','swapEnter'=>'swap','entry'=>'entry','extry'=>'extry'];
+ foreach ($tab as $t=>$m) {
+ $gather=search($info)->where([['type','=',$t]])->select();
+ if(!empty($gather)){
+ $union[]=Db::name($m.'_info')->where([['id','in',array_column($gather,'info')]])->fieldRaw('"'.$t.'" as mold,id,goods,attr,'.($t=='swapEnter'?'storehouse as warehouse':'warehouse').',batch,mfd,serial')->buildSql();
+ }
+ }
+ //合并子查询
+ $union=implode(' UNION ALL ',$union);
+ $record=DB::query('SELECT * FROM ('.$union.') as nodcloud');
+ //构造数据
+ $summary=[];
+ //exist结存|balance结余
+ //[0,0,0,0]=[商品总仓|商品分仓|规则总仓|规则分仓]
+ $def=['exist'=>[0,0,0,0],'balance'=>[0,0,0,0]];
+ foreach ($info as $vo) {
+ $row=search($record)->where([['mold','=',$vo['type']],['id','=',$vo['info']]])->find();
+ $summary[]=[
+ 'pid'=>$vo['id'],
+ 'type'=>$vo['type'],
+ 'class'=>$vo['class'],
+ 'info'=>$vo['info'],
+ 'time'=>$vo['time'],
+ 'goods'=>$row['goods'],
+ 'attr'=>$row['attr'],
+ 'warehouse'=>$row['warehouse'],
+ 'batch'=>$row['batch'],
+ 'mfd'=>$row['mfd'],
+ 'serial'=>$row['serial'],
+ 'direction'=>$vo['direction'],
+ 'price'=>$vo['price'],
+ 'nums'=>$vo['nums'],
+ 'uct'=>0,
+ 'bct'=>0,
+ 'exist'=>json_encode($def['exist']),
+ 'balance'=>json_encode($def['balance']),
+ 'handle'=>0
+ ];
+ }
+ Db::name('summary')->insertAll($summary);
+ $summary=Db::name('summary')->where([['pid','in',array_column($summary,'pid')]])->order(['id'])->select()->toArray();
+ //处理数据
+ $fun=getSys('fun');
+ $goods=Db::name('goods')->where([['id','in',array_column($summary,'goods')]])->field(['id','buy'])->select()->toArray();
+ $attr=Db::name('attr')->where([['pid','in',array_column($summary,'goods')]])->field(['pid','name','buy'])->select()->toArray();
+ foreach ($summary as $vo) {
+ $sql=[
+ [['id','<',$vo['id']],['goods','=',$vo['goods']]],
+ [['warehouse','=',$vo['warehouse']]]
+ ];
+ //规则语句
+ if($fun['rule']=='def'){
+ $sql[]=[];
+ }else if($fun['rule']=='attr'){
+ $sql[]=[['attr','=',$vo['attr']]];
+ }else if($fun['rule']=='batch'){
+ $sql[]=[['batch','=',$vo['batch']],['mfd','=',$vo['mfd']]];
+ }else{
+ $sql[]=[['attr','=',$vo['attr']],['batch','=',$vo['batch']],['mfd','=',$vo['mfd']]];
+ }
+ //[商品总仓|商品分仓|规则总仓|规则分仓]
+ $senten=[$sql[0],array_merge($sql[0],$sql[1]),array_merge($sql[0],$sql[2]),array_merge($sql[0],$sql[1],$sql[2])];
+ $first=[];
+ $first[]=Db::name('summary')->where($senten[0])->order(['id'=>'DESC'])->find();
+ $first[]=Db::name('summary')->where($senten[1])->order(['id'=>'DESC'])->find();
+ $first[]=Db::name('summary')->where($senten[2])->order(['id'=>'DESC'])->find();
+ $first[]=Db::name('summary')->where($senten[3])->order(['id'=>'DESC'])->find();
+ //默认值
+ foreach ($first as $k=>$v) {
+ if(empty($v)){
+ $first[$k]=$def;
+ }else{
+ $first[$k]=['exist'=>json_decode($v['exist']),'balance'=>json_decode($v['balance'])];
+ }
+ }
+ //数据处理
+ $g=search($goods)->where([['id','=',$vo['goods']]])->find();
+ $a=search($attr)->where([['pid','=',$vo['goods']],['name','=',$vo['attr']]])->find();
+ $buy=empty($a)?$g['buy']:$a['buy'];
+ //序列判断
+ $serial=json_decode($vo['serial']);
+ if(empty($serial)){
+ //计价方法
+ if($fun['valuation']=='base'){
+ //基础计价法
+ if(in_array($vo['type'],['buy','bre','swapOut','swapEnter','entry','extry'])){
+ $uct=$vo['price'];
+ }else{
+ $uct=$buy;
+ }
+ }else if($fun['valuation']=='ma'){
+ //移动平均法
+ if(in_array($vo['type'],['buy','bre','swapOut','swapEnter','entry','extry'])){
+ $uct=$vo['price'];
+ }else{
+ //[空|负]库存取采购价
+ //正常库存取结余除结存
+ if(empty($fun['branch'])){
+ $uct=$first[2]['exist'][2]<=0?$buy:math()->chain($first[2]['balance'][2])->div($first[2]['exist'][2])->done();
+ }else{
+ $uct=$first[3]['exist'][3]<=0?$buy:math()->chain($first[3]['balance'][3])->div($first[3]['exist'][3])->round(2)->done();
+ }
+ }
+ }else{
+ //先进先出法
+ if(in_array($vo['type'],['buy','swapEnter','entry'])){
+ $uct=$vo['price'];
+ }else if(in_array($vo['type'],['sre','vre'])){
+ $uct=$buy;
+ }else{
+ $where=[
+ ['id','<',$vo['id']],
+ ['goods','=',$vo['goods']],
+ ['attr','=',$vo['attr']],
+ ['batch','=',$vo['batch']],
+ ['mfd','=',$vo['mfd']],
+ ['direction','=',1],
+ [DB::raw('nums'),'<>',DB::raw('handle')]
+ ];
+ empty($fun['branch'])&&$where[]=['warehouse','=',$vo['warehouse']];
+ $build=DB::name('summary')->where($where)->fieldRaw('id,uct,(nums - handle) as usable,(@sum := @sum + (nums - handle)) as sum')->order('id')->buildSql(false);
+ $build=str_replace("WHERE","CROSS JOIN ( SELECT @sum := 0 ) t WHERE",$build);
+ $list=DB::query('SELECT * FROM ('.$build.') as nodcloud WHERE sum < '.$vo['nums'].' or (sum >= '.$vo['nums'].' and sum - usable < '.$vo['nums'].');');
+ if(empty($list)){
+ //[无入库]取采购价
+ $uct=$buy;
+ }else{
+ $uct=0;
+ $knot=$vo['nums'];
+ $relation=[];
+ foreach ($list as $v) {
+ if($knot<=$v['usable']){
+ $relation[]=['id'=>$v['id'],'handle'=>$knot];
+ $calc=math()->chain($knot)->mul($v['uct'])->done();
+ $uct=math()->chain($uct)->add($calc)->done();
+ break;
+ }else{
+ $relation[]=['id'=>$v['id'],'handle'=>$v['usable']];
+ $calc=math()->chain($v['usable'])->mul($v['uct'])->done();
+ $uct=math()->chain($uct)->add($calc)->done();
+ $knot=math()->chain($knot)->sub($v['usable'])->done();
+ }
+ }
+ $uct=math()->chain($uct)->div($vo['nums'])->done();
+ Db::name('summary')->duplicate(['handle'=>Db::raw('handle + VALUES(`handle`)')])->insertAll($relation);
+ $fifo=[];
+ foreach ($relation as $v) {
+ $fifo[]=['out'=>$vo['id'],'in'=>$v['id'],'handle'=>$v['handle']];
+ }
+ Db::name('fifo')->insertAll($fifo);
+ }
+ }
+ }
+ }else{
+ //序列产品
+ if(in_array($vo['type'],['buy','swapEnter','entry'])){
+ //[无入库]取采购价
+ $uct=$vo['price'];
+ }else{
+ $uct=0;
+ foreach ($serial as $v) {
+ $row=DB::name('summary')->where([
+ ['id','<',$vo['id']],
+ ['goods','=',$vo['goods']],
+ ['serial','like','%"'.$v.'"%']
+ ])->field(['uct'])->order(['id'=>'DESC'])->find();
+ $uct=math()->chain($uct)->add(empty($row)?$buy:$row['uct'])->done();
+ }
+ $uct=math()->chain($uct)->div($vo['nums'])->done();
+ }
+
+
+ }
+ //综合处理
+ $uct=math()->chain($uct)->round($fun['digit']['money'])->done();
+ $exist=[
+ empty($vo['direction'])?math()->chain($first[0]['exist'][0])->sub($vo['nums'])->done():math()->chain($first[0]['exist'][0])->add($vo['nums'])->done(),
+ empty($vo['direction'])?math()->chain($first[1]['exist'][1])->sub($vo['nums'])->done():math()->chain($first[1]['exist'][1])->add($vo['nums'])->done(),
+ empty($vo['direction'])?math()->chain($first[2]['exist'][2])->sub($vo['nums'])->done():math()->chain($first[2]['exist'][2])->add($vo['nums'])->done(),
+ empty($vo['direction'])?math()->chain($first[3]['exist'][3])->sub($vo['nums'])->done():math()->chain($first[3]['exist'][3])->add($vo['nums'])->done()
+ ];
+ $bct=math()->chain($uct)->mul($vo['nums'])->done();
+ $balance=[
+ empty($vo['direction'])?math()->chain($first[0]['balance'][0])->sub($bct)->done():math()->chain($first[0]['balance'][0])->add($bct)->done(),
+ empty($vo['direction'])?math()->chain($first[1]['balance'][1])->sub($bct)->done():math()->chain($first[1]['balance'][1])->add($bct)->done(),
+ empty($vo['direction'])?math()->chain($first[2]['balance'][2])->sub($bct)->done():math()->chain($first[2]['balance'][2])->add($bct)->done(),
+ empty($vo['direction'])?math()->chain($first[3]['balance'][3])->sub($bct)->done():math()->chain($first[3]['balance'][3])->add($bct)->done()
+ ];
+ foreach ($exist as $k=>$v){
+ $v==0&&$balance[$k]=0;
+ }
+ $exist=json_encode($exist);
+ $balance=json_encode($balance);
+ Db::name('summary')->where([['id','=',$vo['id']]])->update(['uct'=>$uct,'bct'=>$bct,'exist'=>$exist,'balance'=>$balance]);
+ }
+ }
+}
\ No newline at end of file
diff --git a/serve/app/controller/Supplier.php b/serve/app/controller/Supplier.php
new file mode 100644
index 0000000..515c41d
--- /dev/null
+++ b/serve/app/controller/Supplier.php
@@ -0,0 +1,246 @@
+'name|py'],'fullLike'],
+ ['number','fullLike'],
+ ['category','fullEq'],
+ ['contacts','fullLike'],
+ [['tel'=>'contacts'],'fullLike'],
+ ['user','fullEq'],
+ ['data','fullLike']
+ ]);//构造SQL
+ $sql=frameScope($sql);//组织数据
+ $sql=sqlAuth('supplier',$sql);//数据鉴权
+ $count = Suppliers::where($sql)->count();//获取总条数
+ $info = Suppliers::with(['frameData','userData'])->where($sql)->page($input['page'],$input['limit'])->order(['id'=>'desc'])->select();//查询分页数据
+ $result=[
+ 'state'=>'success',
+ 'count'=>$count,
+ 'info'=>$info
+ ];//返回数据
+ return json($result);
+ }
+ //新增|更新
+ public function save(){
+ $input=input('post.');
+ if(isset($input['id'])){
+ //构造|验证
+ try {
+ //排除balance字段|防止更新应付款余额
+ unset($input['balance']);
+ $input['py']=zhToPy($input['name']);//首拼信息
+ empty($input['id'])?$this->validate($input,'app\validate\Supplier'):$this->validate($input,'app\validate\Supplier.update');
+ } catch (ValidateException $e) {
+ return json(['state'=>'error','info'=>$e->getError()]);
+ exit;
+ }
+
+ //处理数据
+ Db::startTrans();
+ try {
+ if(empty($input['id'])){
+ //创建数据
+ Suppliers::create($input);
+ pushLog('新增供应商[ '.$input['name'].' ]');//日志
+ }else{
+ //更新数据
+ Suppliers::update($input);
+ pushLog('更新供应商[ '.$input['name'].' ]');//日志
+ }
+
+ Db::commit();
+ $result=['state'=>'success'];
+ } catch (\Exception $e) {
+ Db::rollback();
+ $result=['state'=>'error','info'=>'内部错误,操作已撤销!'];
+ }
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //获取
+ public function get(){
+ $input=input('post.');
+ if(existFull($input,['id'])){
+ $result=[
+ 'state'=>'success',
+ 'info'=>Suppliers::where([['id','=',$input['id']]])->find()
+ ];
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //删除
+ public function del(){
+ $input=input('post.');
+ if(existFull($input,['parm']) && is_array($input['parm'])){
+ $exist=moreTableFind([
+ ['table'=>'bor','where'=>[['supplier','in',$input['parm']]]],
+ ['table'=>'buy','where'=>[['supplier','in',$input['parm']]]],
+ ['table'=>'bre','where'=>[['supplier','in',$input['parm']]]],
+ ['table'=>'entry','where'=>[['supplier','in',$input['parm']]]],
+ ['table'=>'omy','where'=>[['supplier','in',$input['parm']]]],
+ ['table'=>'bill','where'=>[['customer','in',$input['parm']]]],
+ ['table'=>'oce','where'=>[['supplier','in',$input['parm']]]],
+ ]);
+ if(empty($exist)){
+ $data=Db::name('supplier')->where([['id','in',$input['parm']]])->order(['id'=>'desc'])->select()->toArray();
+ Db::startTrans();
+ try {
+ Db::name('supplier')->where([['id','in',$input['parm']]])->delete();
+ Db::name('log')->insert(['time'=>time(),'user'=>getUserID(),'info'=>'删除供应商[ '.implode(' | ',array_column($data,'name')).' ]']);
+
+ Db::commit();
+ $result=['state'=>'success'];
+ } catch (\Exception $e) {
+ Db::rollback();
+ $result=['state'=>'error','info'=>'内部错误,操作已撤销!'];
+ }
+ }else{
+ $result=['state'=>'error','info'=>'存在数据关联,删除失败!'];
+ }
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //导入
+ public function import(){
+ delOverdueFile('static.upload.xlsx');//删除过期文件
+ $file=request()->file('file');//获取上传文件
+ if(empty($file)){
+ $result=['state'=>'error','info'=>'传入数据不完整!'];
+ }else{
+ try{
+ validate(['file'=>['fileSize'=>2*1024*1024,'fileExt'=>'xlsx']])->check(['file'=>$file]);
+ $fileInfo = Filesystem::disk('upload')->putFile('xlsx', $file, 'uniqid');
+ $filePath = pathChange('static.upload').$fileInfo;
+ $data=getXlsx($filePath);
+ unset($data[1]);//删除标题行
+ unset($data[2]);//删除列名行
+ $sql=[];//初始化SQL
+ $frame=Db::name('frame')->where([['name','in',array_column($data,'C')]])->select()->toArray();
+ foreach ($data as $dataKey=>$dataVo) {
+ $record=[
+ 'name'=>$dataVo['A'],
+ 'py'=>zhToPy($dataVo['A']),
+ 'number'=>$dataVo['B'],
+ 'frame'=>$dataVo['C'],
+ 'user'=>getUserID(),
+ 'category'=>$dataVo['D'],
+ 'rate'=>$dataVo['E'],
+ 'bank'=>$dataVo['F'],
+ 'account'=>$dataVo['G'],
+ 'tax'=>$dataVo['H'],
+ 'data'=>$dataVo['I'],
+ 'contacts'=>(empty($dataVo['J'])&&empty($dataVo['K']))?[]:[['main'=>true,'name'=>$dataVo['J'],'tel'=>$dataVo['K'],'add'=>$dataVo['L'],'data'=>$dataVo['M']]],
+ 'more'=>[]
+ ];
+
+ //所属组织匹配
+ $frameFind=search($frame)->where([['name','=',$record['frame']]])->find();
+ if(empty($frameFind)){
+ throw new ValidateException('模板文件第'.$dataKey.'行所属组织[ '.$record['frame'].' ]未匹配!');
+ }else{
+ $record['frame']=$frameFind['id'];
+ }
+ //数据合法性验证
+ try {
+ $this->validate($record,'app\validate\Supplier');
+ $sql[]=$record;//加入SQL
+ } catch (ValidateException $e) {
+ //返回错误信息
+ return json(['state'=>'error','info'=>'模板文件第[ '.$dataKey.' ]行'.$e->getError()]);
+ exit;
+ }
+ }
+ //判断编号重复
+ $column=array_column($sql,'number');
+ $unique=array_unique($column);
+ $diff=array_diff_assoc($column,$unique);
+ if(!empty($diff)){
+ //返回错误信息
+ return json(['state'=>'error','info'=>'模板文件供应商编号[ '.implode(' | ',$diff).' ]重复!']);
+ }
+ //处理关联数据
+ foreach($sql as $sqlKey=>$sqlVo){
+ $sys=getSys(['srCategory']);
+ //供应商类别
+ if(!in_array($sqlVo['category'],$sys['srCategory'])){
+ $sys['srCategory'][]=$sqlVo['category'];
+ Sys::where([['name','=','srCategory']])->update(['info'=>json_encode($sys['srCategory'])]);
+ }
+ }
+ //新增数据
+ $supplier = new Suppliers;
+ $supplier->saveAll($sql);
+ pushLog('批量导入[ '.count($sql).' ]条供应商数据');//日志
+ $result=['state'=>'success','info'=>'成功导入'.count($sql).'行供应商数据'];
+ }catch(ValidateException $e) {
+ $result=['state'=>'error','info'=>$e->getMessage()];//返回错误信息
+ }
+ }
+ return json($result);
+ }
+ //导出
+ public function exports(){
+ $input=input('get.');
+ if(existFull($input,['parm']) && is_array($input['parm'])){
+ $info=Suppliers::with(['frameData','userData'])->where([['id','in',$input['parm']]])->order(['id'=>'desc'])->select()->toArray();//查询数据
+ foreach ($info as $infoKey=>$infoVo) {
+ $contactsArr=[];
+ foreach ($infoVo['contacts'] as $contactsVo) {
+ $contactsArr[]=$contactsVo['name'].' | '.$contactsVo['tel'].' | '.$contactsVo['add'].' | '.$contactsVo['data'];
+ }
+ $info[$infoKey]['contacts']=implode(chr(10),$contactsArr);
+ }
+ $field=[
+ 'name'=>'供应商名称',
+ 'number'=>'供应商编号',
+ 'category'=>'供应商类别',
+ 'rate'=>'增值税税率',
+ 'bank'=>'开户银行',
+ 'account'=>'银行账号',
+ 'tax'=>'纳税号码',
+ 'balance'=>'应付款余额',
+ 'frameData|name'=>'所属组织',
+ 'userData|name'=>'所属用户',
+ 'data'=>'备注信息',
+ 'contacts'=>'联系资料'
+ ];
+ //开始构造导出数据
+ $excel=[];//初始化导出数据
+ //标题数据
+ $excel[]=['type'=>'title','info'=>'供应商信息'];
+ //表格数据
+ $thead=array_values($field);//表格标题
+ $tbody=[];//表格内容
+ //构造表内数据
+ foreach ($info as $infoVo) {
+ $rowData=[];
+ foreach (array_keys($field) as $fieldVo) {
+ $rowData[]=arraySeek($infoVo,$fieldVo);//多键名数据赋值
+ }
+ $tbody[]=$rowData;//加入行数据
+ }
+ $excel[]=['type'=>'table','info'=>['thead'=>$thead,'tbody'=>$tbody]];//表格数据
+ //统计数据
+ $excel[]=['type'=>'node','info'=>['总数:'.count($info)]];
+ //导出execl
+ pushLog('导出供应商信息');//日志
+ buildExcel('供应商信息',$excel);
+ }else{
+ return json(['state'=>'error','info'=>'传入数据不完整!']);
+ }
+ }
+}
\ No newline at end of file
diff --git a/serve/app/controller/Swap.php b/serve/app/controller/Swap.php
new file mode 100644
index 0000000..5098005
--- /dev/null
+++ b/serve/app/controller/Swap.php
@@ -0,0 +1,1229 @@
+'time'],'startTime'],
+ [['endTime'=>'time'],'endTime'],
+ ['examine','fullDec1'],
+ ['cse','fullDec1'],
+ ['user','fullEq'],
+ ['data','fullLike']
+ ]);//构造SQL
+ //商品信息扩展查询
+ if(existFull($input,['goods'])){
+ $goods=array_column(Db::name('goods')->where([['name|py','like','%'.$input['goods'].'%']])->select()->toArray(),'id');
+ $sql[]=['id','in',array_column(Db::name('swap_info')->where([['goods','in',$goods]])->select()->toArray(),'pid')];
+ }
+ $sql=frameScope($sql);//组织数据
+ $sql=sqlAuth('swap',$sql);//数据鉴权
+ $count = Swaps::where($sql)->count();//获取总条数
+ $info = Swaps::with(['frameData','peopleData','userData','costData','recordData'])->where($sql)->append(['extension'])->page($input['page'],$input['limit'])->order(['id'=>'desc'])->select()->toArray();//查询分页数据
+ $result=[
+ 'state'=>'success',
+ 'count'=>$count,
+ 'info'=>$info
+ ];//返回数据
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //新增|更新
+ public function save(){
+ $input=input('post.');
+ if(existFull($input,['class','info']) && isset($input['class']['id']) && isset($input['cost'])){
+ //构造|验证CLASS
+ try {
+ $class=$input['class'];
+ $class['frame']=userInfo(getUserID(),'frame');
+ $class['user']=getUserID();
+ $class['cse']=empty($class['cost'])?3:0;
+ $class['examine']=0;
+ empty($class['id'])?$this->validate($class,'app\validate\Swap'):$this->validate($class,'app\validate\Swap.update');
+ $period=getPeriod();
+ if(strtotime($class['time'])<=$period){
+ throw new ValidateException('单据日期与结账日期冲突!');
+ }
+ } catch (ValidateException $e) {
+ return json(['state'=>'error','info'=>$e->getError()]);
+ exit;
+ }
+
+ //验证INFO
+ foreach ($input['info'] as $infoKey=>$infoVo) {
+ try {
+ $this->validate($infoVo,'app\validate\SwapInfo');
+ } catch (ValidateException $e) {
+ return json(['state'=>'error','info'=>'商品信息第'.($infoKey+1).'条'.$e->getError()]);
+ exit;
+ }
+ }
+
+ //验证Cost
+ foreach ($input['cost'] as $costKey=>$costVo) {
+ try {
+ $this->validate($costVo,'app\validate\Cost');
+ } catch (ValidateException $e) {
+ return json(['state'=>'error','info'=>'单据费用第'.($infoKey+1).'条'.$e->getError()]);
+ exit;
+ }
+ }
+
+ //处理数据
+ Db::startTrans();
+ try {
+ //CLASS数据
+ if(empty($class['id'])){
+ //创建数据
+ $createInfo=Swaps::create($class);
+ $class['id']=$createInfo['id'];//转存主键
+ Db::name('record')->insert(['type'=>'swap','source'=>$class['id'],'time'=>time(),'user'=>getUserID(),'info'=>'新增单据']);
+ pushLog('新增调拨单[ '.$class['number'].' ]');//日志
+ }else{
+ //更新数据
+ $updateInfo=Swaps::update($class);
+ Db::name('record')->insert(['type'=>'swap','source'=>$class['id'],'time'=>time(),'user'=>getUserID(),'info'=>'更新单据']);
+ pushLog('更新调拨单[ '.$class['number'].' ]');//日志
+ }
+
+ //INFO数据
+ SwapInfo::where([['pid','=',$class['id']]])->delete();
+ foreach ($input['info'] as $infoKey=>$infoVo) {
+ $input['info'][$infoKey]['pid']=$class['id'];
+ }
+ $model = new SwapInfo;
+ $model->saveAll($input['info']);
+
+ //COST数据
+ Cost::where([['type','=','swap'],['class','=',$class['id']]])->delete();
+ foreach ($input['cost'] as $costKey=>$costVo) {
+ unset($input['cost'][$costKey]['id']);
+ $input['cost'][$costKey]['type']='swap';
+ $input['cost'][$costKey]['class']=$class['id'];
+ $input['cost'][$costKey]['time']=$class['time'];
+ $input['cost'][$costKey]['settle']=0;
+ $input['cost'][$costKey]['state']=0;
+ }
+ $model = new Cost;
+ $model->saveAll($input['cost']);
+
+ Db::commit();
+ $result=['state'=>'success','info'=>$class['id']];
+ } catch (\Exception $e) {
+ Db::rollback();
+ $result=['state'=>'error','info'=>'内部错误,操作已撤销!'];
+ }
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //获取
+ public function get(){
+ $input=input('post.');
+ if(existFull($input,['parm'])){
+ $class=Swaps::where([['id','=',$input['parm']]])->find();
+ $info=SwapInfo::with(['goodsData','warehouseData','storehouseData'])->where([['pid','=',$input['parm']]])->order(['id'=>'asc'])->select();
+ $cost=Cost::where([['type','=','swap'],['class','=',$input['parm']]])->order(['id'=>'asc'])->select();
+ $result=['state'=>'success','info'=>[
+ 'class'=>$class,
+ 'info'=>$info,
+ 'cost'=>$cost
+ ]];
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //删除
+ public function del(){
+ $input=input('post.');
+ if(existFull($input,['parm']) && is_array($input['parm'])){
+ $data=Db::name('swap')->where([['id','in',$input['parm']]])->order(['id'=>'desc'])->select()->toArray();
+ $search=search($data)->where([['examine','=','1']])->find();
+ if(empty($search)){
+ Db::startTrans();
+ try {
+ Db::name('swap')->where([['id','in',$input['parm']]])->delete();
+ Db::name('swap_info')->where([['pid','in',$input['parm']]])->delete();
+ Db::name('cost')->where([['type','=','swap'],['class','in',$input['parm']]])->delete();
+ Db::name('log')->insert(['time'=>time(),'user'=>getUserID(),'info'=>'删除调拨单[ '.implode(' | ',array_column($data,'number')).' ]']);
+
+ Db::commit();
+ $result=['state'=>'success'];
+ } catch (\Exception $e) {
+ Db::rollback();
+ $result=['state'=>'error','info'=>'内部错误,操作已撤销!'];
+ }
+ }else{
+ $result=['state'=>'error','info'=>'单据['.$search['number'].']已审核,不可删除!'];
+ }
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //审核|反审核
+ public function examine(){
+ $input=input('post.');
+ if(existFull($input,['parm']) && is_array($input['parm'])){
+ //1 基础数据
+ $fun=getSys('fun');
+ $period=getPeriod();
+ $classList=Db::name('swap')->where([['id','in',$input['parm']]])->order(['id'=>'desc'])->select()->toArray();
+ $infoList=Db::name('swap_info')->where([['pid','in',$input['parm']]])->order(['id'=>'asc'])->select()->toArray();
+ //2 综合处理
+ foreach ($input['parm'] as $parmVo) {
+ //1 匹配数据
+ $class=search($classList)->where([['id','=',$parmVo]])->find();
+ $info=search($infoList)->where([['pid','=',$parmVo]])->select();
+ //1.1 商品数据
+ $goodsList=Db::name('goods')->where([['id','in',array_unique(array_column($info,'goods'))]])->select()->toArray();
+ //1.2 综合匹配
+ if(empty($class['examine'])){
+ //1 构造数据
+ $batchGather=[];
+ $serialGather=[];
+ $roomWhereOrSql=[];
+ $toRoomWhereOrSql=[];
+ foreach ($info as $infoVo) {
+ //1 批次号
+ empty($infoVo['batch'])||$batchGather[]=$infoVo['batch'];
+ //2 序列号
+ $serialGather=array_merge($serialGather,json_decode($infoVo['serial']));
+ //3 仓储条件|调出
+ empty($infoVo['warehouse'])||$roomWhereOrSql[]=[['warehouse','=',$infoVo['warehouse']],['goods','=',$infoVo['goods']],['attr','=',$infoVo['attr']]];
+ //4 仓储条件|调入
+ empty($infoVo['storehouse'])||$toRoomWhereOrSql[]=[['warehouse','=',$infoVo['storehouse']],['goods','=',$infoVo['goods']],['attr','=',$infoVo['attr']]];
+ }
+ //3 匹配数据
+ empty($batchGather)||$batchList=Db::name('batch')->where([['number','in',$batchGather]])->select()->toArray();
+ empty($serialGather)||$serialList=Db::name('serial')->where([['number','in',$serialGather]])->select()->toArray();
+ //4 仓储数据|调出
+ if(!empty($roomWhereOrSql)){
+ //1 去重转存
+ $roomWhereOrSql=array_unique($roomWhereOrSql,SORT_REGULAR);
+ //2 仓储匹配
+ $roomList=Db::name('room')->whereOr($roomWhereOrSql)->select()->toArray();
+ }
+ //5 仓储数据|调入
+ if(!empty($toRoomWhereOrSql)){
+ //1 去重转存
+ $toRoomWhereOrSql=array_unique($toRoomWhereOrSql,SORT_REGULAR);
+ //2 仓储匹配
+ $toRoomList=Db::name('room')->whereOr($toRoomWhereOrSql)->select()->toArray();
+ }
+ }
+ //2 CLASS验证
+ if($class['time']<=$period){
+ return json(['state'=>'error','info'=>'操作单据[ '.$class['number'].' ]失败,原因:单据日期与结账日期冲突!']);
+ exit;
+ }
+ if(empty($class['examine'])){
+ //2 单据费用
+ $cost=Db::name('cost')->alias('cost')->where([['type','=','swap'],['class','=',$class['id']]])->whereExists(function($query){
+ $query->name('oce_info')->where([['source','=',Db::raw('cost.id')]])->limit(1);
+ })->find();
+ if(!empty($cost)){
+ return json(['state'=>'error','info'=>'反审核单据[ '.$class['number'].' ]失败,原因:该单据存在关联其它支出单!']);
+ exit;
+ }
+ }
+ //3 INFO验证|构造
+ foreach ($info as $infoKey=>$infoVo) {
+ //1 匹配商品
+ $goods=search($goodsList)->where([['id','=',$infoVo['goods']]])->find();
+ //2 商品类型
+ if(empty($goods['type'])){
+ //场景验证
+ if(empty($class['examine'])){
+ //1 匹配数据
+ $room=search($roomList)->where([['warehouse','=',$infoVo['warehouse']],['goods','=',$infoVo['goods']],['attr','=',$infoVo['attr']]],true)->find();
+ (empty($room)||empty($infoVo['batch']))||$batch=search($batchList)->where([['room','=',$room['id']],['number','=',$infoVo['batch']],['time','=',$infoVo['mfd']]],true)->find();
+ //2 多单位处理
+ if($goods['unit']==-1){
+ //多单位|转存
+ $radix=unitRadix($infoVo['unit'],json_decode($goods['units'],true));
+ $info[$infoKey]['basic']=[
+ 'nums'=>math()->chain($infoVo['nums'])->mul($radix)->done(),
+ 'price'=>math()->chain($infoVo['price'])->div($radix)->round(4)->done()
+ ];
+ }else{
+ //常规单位|转存
+ $info[$infoKey]['basic']=[
+ 'nums'=>$infoVo['nums'],
+ 'price'=>$infoVo['price']
+ ];
+ }
+ //3 序列号
+ $serialData=json_decode($infoVo['serial']);
+ if(empty($serialData)){
+ $info[$infoKey]['serial']=[];
+ }else{
+ //序列号状态[不存在|未销售]
+ $serialCollect=search($serialList)->where([['goods','=',$infoVo['goods']],['number','in',$serialData]])->select();
+ foreach ($serialCollect as $serialCollectVo) {
+ if($serialCollectVo['state']==0){
+ if(empty($room) || $room['id']!=$serialCollectVo['room']){
+ return json(['state'=>'error','info'=>'审核单据[ '.$class['number'].' ]失败,原因:第'.($infoKey+1).'行序列号[ '.$serialCollectVo['number'].' ]与仓库不匹配!']);
+ exit;
+ }
+ if((empty($infoVo['batch'])&&!empty($serialCollectVo['batch']))||(!empty($infoVo['batch'])&&(empty($batch)||$batch['id']!=$serialCollectVo['batch']))){
+ return json(['state'=>'error','info'=>'审核单据[ '.$class['number'].' ]失败,原因:第'.($infoKey+1).'行序列号[ '.$serialCollectVo['number'].' ]与批次不匹配!']);
+ exit;
+ }
+ }else{
+ return json(['state'=>'error','info'=>'审核单据[ '.$class['number'].' ]失败,原因:第'.($infoKey+1).'行序列号[ '.$serialCollectVo['number'].' ]状态不正确!']);
+ exit;
+ }
+ }
+ $info[$infoKey]['serial']=$serialData;
+ }
+ //4 负库存验证
+ if($fun['overflow']==false){
+ //1 仓储验证
+ if(empty($room)){
+ return json(['state'=>'error','info'=>'审核单据[ '.$class['number'].' ]失败,原因:第'.($infoKey+1).'行仓储信息不存在!']);
+ exit;
+ }else{
+ if(bccomp($info[$infoKey]['basic']['nums'],$room['nums'])==1){
+ return json(['state'=>'error','info'=>'审核单据[ '.$class['number'].' ]失败,原因:第'.($infoKey+1).'行仓储库存不足!']);
+ exit;
+ }else{
+ $roomList[$room['rowKey']]['nums']=math()->chain($room['nums'])->sub($info[$infoKey]['basic']['nums'])->done();
+ }
+ }
+ //2 批次验证
+ if(!empty($infoVo['batch'])){
+ $batchFind=search($batchList)->where([['room','=',$room['id']],['number','=',$infoVo['batch']],['time','=',$infoVo['mfd']]],true)->find();
+ if(empty($batchFind)){
+ return json(['state'=>'error','info'=>'审核单据[ '.$class['number'].' ]失败,原因:第'.($infoKey+1).'行批次信息无效!']);
+ exit;
+ }else{
+ if(bccomp($info[$infoKey]['basic']['nums'],$batchFind['nums'])==1){
+ return json(['state'=>'error','info'=>'审核单据[ '.$class['number'].' ]失败,原因:第'.($infoKey+1).'行批次库存不足!']);
+ exit;
+ }else{
+ $batchList[$batchFind['rowKey']]['nums']=math()->chain($batchFind['nums'])->sub($info[$infoKey]['basic']['nums'])->done();
+ }
+ }
+ }
+ //3 序列号验证
+ if(!empty($serialData)){
+ $serialCount=search($serialList)->where([['room','=',$room['id']],['number','in',$serialData]])->count();
+ if($serialCount != count($serialData)){
+ return json(['state'=>'error','info'=>'审核单据[ '.$class['number'].' ]失败,原因:第'.($infoKey+1).'行存在无效序列号!']);
+ exit;
+ }
+ }
+ }
+ }else{
+ //1 验证序列号|调出
+ $serialInfoCollect=Db::name('serial_info')->where([['type','=','swapOut'],['info','in',array_column($info,'id')]])->select()->toArray();
+ if(!empty($serialInfoCollect)){
+ //序列号状态对[已调拨]
+ $serialFind=Db::name('serial')->where([['id','in',array_column($serialInfoCollect,'pid')],['state','<>',2]])->find();
+ if(!empty($serialFind)){
+ return json(['state'=>'error','info'=>'反审核单据[ '.$class['number'].' ]失败,原因:第'.($infoKey+1).'行序列号[ '.$serialFind['number'].' ]状态不正确!']);
+ exit;
+ }
+ }
+ //2 验证序列号|调入
+ $serialInfoCollect=Db::name('serial_info')->where([['type','=','swapEnter'],['info','in',array_column($info,'id')]])->select()->toArray();
+ if(!empty($serialInfoCollect)){
+ //序列号状态对[未销售]
+ $serialFind=Db::name('serial')->where([['id','in',array_column($serialInfoCollect,'pid')],['state','<>',0]])->find();
+ if(!empty($serialFind)){
+ return json(['state'=>'error','info'=>'反审核单据[ '.$class['number'].' ]失败,原因:第'.($infoKey+1).'行序列号[ '.$serialFind['number'].' ]状态不正确!']);
+ exit;
+ }
+ }
+ }
+ }
+ }
+ //4 数据处理
+ Db::startTrans();
+ try {
+ //场景验证
+ if(empty($class['examine'])){
+ //审核
+ //1 构造数据
+ $outStore=['room'=>[],'roomInfo'=>[],'batch'=>[],'batchInfo'=>[],'serial'=>[],'serialInfo'=>[],'serve'=>[],'serveInfo'=>[]];
+ $enterStore=['room'=>[],'roomInfo'=>[],'batch'=>[],'batchInfo'=>[],'serial'=>[],'serialInfo'=>[],'serve'=>[],'serveInfo'=>[]];
+ foreach ($info as $infoKey=>$infoVo){
+ //判断商品类型
+ $goods=search($goodsList)->where([['id','=',$infoVo['goods']]])->find();
+ if(empty($goods['type'])){
+ //常规商品
+ //--- 调出数据 ---
+ //1 仓储
+ $outStore['room'][]=['warehouse'=>$infoVo['warehouse'],'goods'=>$infoVo['goods'],'attr'=>$infoVo['attr'],'nums'=>$infoVo['basic']['nums']];
+ //2 仓储详情
+ $outStore['roomInfo'][]=['pid'=>null,'type'=>'swapOut','class'=>$class['id'],'info'=>$infoVo['id'],'time'=>$class['time'],'direction'=>0,'price'=>$infoVo['basic']['price'],'nums'=>$infoVo['basic']['nums']];
+ //3 批次号
+ if(empty($infoVo['batch'])){
+ $outStore['batch'][]=[];
+ $outStore['batchInfo'][]=[];
+ }else{
+ $outStore['batch'][]=['room'=>null,'warehouse'=>$infoVo['warehouse'],'goods'=>$infoVo['goods'],'number'=>$infoVo['batch'],'time'=>$infoVo['mfd'],'nums'=>$infoVo['basic']['nums']];
+ $outStore['batchInfo'][]=['pid'=>null,'type'=>'swapOut','class'=>$class['id'],'info'=>$infoVo['id'],'direction'=>0,'nums'=>$infoVo['basic']['nums']];
+ }
+ //4 序列号
+ if(empty($infoVo['serial'])){
+ $outStore['serial'][]=[];
+ $outStore['serialInfo'][]=[];
+ }else{
+ $serial=[];
+ $serialInfo=[];
+ foreach ($infoVo['serial'] as $serialVo) {
+ $serial[]=['room'=>null,'warehouse'=>$infoVo['warehouse'],'batch'=>null,'goods'=>$infoVo['goods'],'number'=>$serialVo,'state'=>2];
+ $serialInfo[]=['pid'=>null,'type'=>'swapOut','class'=>$class['id'],'info'=>$infoVo['id']];
+ }
+ $outStore['serial'][]=$serial;
+ $outStore['serialInfo'][]=$serialInfo;
+ }
+ //--- 调入数据 ---
+ //5 仓储
+ $enterStore['room'][]=['warehouse'=>$infoVo['storehouse'],'goods'=>$infoVo['goods'],'attr'=>$infoVo['attr'],'nums'=>$infoVo['basic']['nums']];
+ //6 仓储详情
+ $enterStore['roomInfo'][]=['pid'=>null,'type'=>'swapEnter','class'=>$class['id'],'info'=>$infoVo['id'],'time'=>$class['time'],'direction'=>1,'price'=>$infoVo['basic']['price'],'nums'=>$infoVo['basic']['nums']];
+ //7 批次号
+ if(empty($infoVo['batch'])){
+ $enterStore['batch'][]=[];
+ $enterStore['batchInfo'][]=[];
+ }else{
+ $enterStore['batch'][]=['room'=>null,'warehouse'=>$infoVo['storehouse'],'goods'=>$infoVo['goods'],'number'=>$infoVo['batch'],'time'=>$infoVo['mfd'],'nums'=>$infoVo['basic']['nums']];
+ $enterStore['batchInfo'][]=['pid'=>null,'type'=>'swapEnter','class'=>$class['id'],'info'=>$infoVo['id'],'direction'=>1,'nums'=>$infoVo['basic']['nums']];
+ }
+ //8 序列号
+ if(empty($infoVo['serial'])){
+ $enterStore['serial'][]=[];
+ $enterStore['serialInfo'][]=[];
+ }else{
+ $serial=[];
+ $serialInfo=[];
+ foreach ($infoVo['serial'] as $serialVo) {
+ $serial[]=['room'=>null,'warehouse'=>$infoVo['storehouse'],'batch'=>null,'goods'=>$infoVo['goods'],'number'=>$serialVo,'state'=>0];
+ $serialInfo[]=['pid'=>null,'type'=>'swapEnter','class'=>$class['id'],'info'=>$infoVo['id']];
+ }
+ $enterStore['serial'][]=$serial;
+ $enterStore['serialInfo'][]=$serialInfo;
+ }
+ }else{
+ //9 服务商品
+ $outStore['serve'][]=['goods'=>$infoVo['goods'],'attr'=>$infoVo['attr'],'nums'=>$infoVo['nums']];
+ $outStore['serveInfo'][]=['pid'=>null,'type'=>'swap','class'=>$class['id'],'info'=>$infoVo['id'],'time'=>$class['time'],'price'=>$infoVo['price'],'nums'=>$infoVo['nums']];
+ }
+ }
+ //--- 调出数据 ---
+ //2 仓储
+ if(!empty($outStore['room'])){
+ //1 构造数据
+ $roomInsert=[];
+ foreach ($outStore['room'] as $roomVo) {
+ $roomFind=search($roomList)->where([['warehouse','=',$roomVo['warehouse']],['goods','=',$roomVo['goods']],['attr','=',$roomVo['attr']]])->find();
+ if(empty($roomFind)){
+ $roomVo['nums']=0;
+ $roomInsert[]=$roomVo;
+ }
+ }
+ //2 创建数据|去重
+ empty($roomInsert)||Db::name('room')->insertAll(array_unique($roomInsert,SORT_REGULAR));
+ //3 匹配主键|构造更新
+ $roomDuplicate=[];
+ $room=Db::name('room')->whereOr($roomWhereOrSql)->select()->toArray();
+ foreach ($outStore['room'] as $roomKey=>$roomVo) {
+ $roomFind=search($room)->where([['warehouse','=',$roomVo['warehouse']],['goods','=',$roomVo['goods']],['attr','=',$roomVo['attr']]])->find();
+ $outStore['room'][$roomKey]['id']=$roomFind['id'];
+ $roomDuplicate[]=['id'=>$roomFind['id'],'nums'=>$roomVo['nums']];
+ }
+ //4 更新数据
+ Db::name('room')->duplicate(['nums'=>Db::raw('nums - VALUES(`nums`)')])->insertAll($roomDuplicate);
+ }
+ //3 仓储详情
+ if(!empty($outStore['roomInfo'])){
+ //1 填充数据
+ foreach ($outStore['roomInfo'] as $roomInfoKey=>$roomInfoVo) {
+ $outStore['roomInfo'][$roomInfoKey]['pid']=$outStore['room'][$roomInfoKey]['id'];
+ }
+ //2 创建数据
+ Db::name('room_info')->insertAll($outStore['roomInfo']);
+ }
+ //4 批次号
+ if(!empty($outStore['batch'])){
+ //1 构造数据
+ $batchData=[];
+ foreach ($outStore['batch'] as $batchKey=>$batchVo) {
+ if(!empty($batchVo)){
+ $outStore['batch'][$batchKey]['room']=$outStore['room'][$batchKey]['id'];
+ $batchData[]=$outStore['batch'][$batchKey];
+ }
+ }
+ //2 排除数据|[[],[],[]]
+ if(!empty($batchData)){
+ //1 构造数据
+ $batchInsert=[];
+ foreach ($batchData as $batchDataKey=>$batchDataVo) {
+ $batchFind=search($batchList)->where([['room','=',$batchDataVo['room']],['number','=',$batchDataVo['number']],['time','=',$batchDataVo['time']]])->find();
+ if(empty($batchFind)){
+ $batchDataVo['nums']=0;
+ $batchInsert[]=$batchDataVo;
+ }
+ }
+ //2 创建数据|去重
+ empty($batchInsert)||Db::name('batch')->insertAll(array_unique($batchInsert,SORT_REGULAR));
+ //3 匹配主键|构造更新
+ $batchDuplicate=[];
+ $batch=Db::name('batch')->where([['number','in',$batchGather]])->select()->toArray();
+ foreach ($outStore['batch'] as $batchKey=>$batchVo) {
+ if(!empty($batchVo)){
+ $batchFind=search($batch)->where([['room','=',$batchVo['room']],['number','=',$batchVo['number']],['time','=',$batchVo['time']]])->find();
+ $outStore['batch'][$batchKey]['id']=$batchFind['id'];
+ $batchDuplicate[]=['id'=>$batchFind['id'],'nums'=>$batchVo['nums']];
+ }
+ }
+ //4 更新数据
+ Db::name('batch')->duplicate(['nums'=>Db::raw('nums - VALUES(`nums`)')])->insertAll($batchDuplicate);
+ }
+ }
+ //5 批次号详情
+ if(!empty($outStore['batchInfo'])){
+ //1 构造数据
+ $batchInfoInstall=[];
+ foreach ($outStore['batchInfo'] as $batchInfoKey=>$batchInfoVo) {
+ if(!empty($batchInfoVo)){
+ $batchInfoVo['pid']=$outStore['batch'][$batchInfoKey]['id'];
+ $batchInfoInstall[]=$batchInfoVo;
+ }
+ }
+ //2 排除数据|[[],[],[]]
+ if(!empty($batchInfoInstall)){
+ //创建数据
+ Db::name('batch_info')->insertAll($batchInfoInstall);
+ }
+ }
+ //6 序列号
+ if(!empty($outStore['serial'])){
+ //1 构造数据
+ $serialData=[];
+ foreach ($outStore['serial'] as $serialKey=>$item) {
+ if(!empty($item)){
+ foreach ($item as $itemKey=>$itemVo) {
+ $outStore['serial'][$serialKey][$itemKey]['room']=$outStore['room'][$serialKey]['id'];
+ $outStore['serial'][$serialKey][$itemKey]['batch']=empty($outStore['batch'][$serialKey])?0:$outStore['batch'][$serialKey]['id'];
+ $serialData[]=$outStore['serial'][$serialKey][$itemKey];
+ }
+ }
+ }
+ //2 排除数据|[[],[],[]]
+ if(!empty($serialData)){
+ //1 构造数据
+ $serialInsert=[];
+ foreach ($serialData as $serialDataKey=>$serialDataVo) {
+ $serialFind=search($serialList)->where([['room','=',$serialDataVo['room']],['batch','=',$serialDataVo['batch']],['number','=',$serialDataVo['number']]])->find();
+ if(empty($serialFind)){
+ $serialInsert[]=$serialDataVo;
+ }
+ }
+ //2 创建数据
+ empty($serialInsert)||Db::name('serial')->insertAll($serialInsert);
+ //3 匹配主键|构造更新
+ $serialDuplicate=[];
+ $serial=Db::name('serial')->where([['number','in',$serialGather]])->select()->toArray();
+ foreach ($outStore['serial'] as $serialKey=>$item) {
+ if(!empty($item)){
+ foreach ($item as $itemKey=>$itemVo) {
+ $serialFind=search($serial)->where([['room','=',$itemVo['room']],['batch','=',$itemVo['batch']],['number','=',$itemVo['number']]])->find();
+ $outStore['serial'][$serialKey][$itemKey]['id']=$serialFind['id'];
+ $serialFind['state']==0&&$serialDuplicate[]=$serialFind['id'];
+ }
+ }
+ }
+ //4 更新数据|状态变更
+ empty($serialDuplicate)||Db::name('serial')->where([['id','in',$serialDuplicate]])->update(['state'=>2]);
+ }
+ }
+ //7 序列号详情
+ if(!empty($outStore['serialInfo'])){
+ //1 构造数据
+ $serialInfoInstall=[];
+ foreach ($outStore['serialInfo'] as $serialInfoKey=>$item) {
+ if(!empty($item)){
+ foreach ($item as $itemKey=>$itemVo) {
+ $itemVo['pid']=$outStore['serial'][$serialInfoKey][$itemKey]['id'];
+ $serialInfoInstall[]=$itemVo;
+ }
+ }
+ }
+ //2 排除数据|[[],[],[]]
+ if(!empty($serialInfoInstall)){
+ //创建数据
+ Db::name('serial_info')->insertAll($serialInfoInstall);
+ }
+ }
+ //8 服务商品
+ if(!empty($outStore['serve'])){
+ //1 匹配数据|去重
+ $serveWhereOrSql=array_unique(array_map(function($item){
+ return [['goods','=',$item['goods']],['attr','=',$item['attr']]];
+ },$outStore['serve']),SORT_REGULAR);
+ $serve=Db::name('serve')->whereOr($serveWhereOrSql)->select()->toArray();
+ //2 构造数据
+ $serveInsert=[];
+ foreach ($outStore['serve'] as $serveVo) {
+ $serveFind=search($serve)->where([['goods','=',$serveVo['goods']],['attr','=',$serveVo['attr']]])->find();
+ if(empty($serveFind)){
+ $serveVo['nums']=0;
+ $serveInsert[]=$serveVo;
+ }
+ }
+ //3 创建数据|去重
+ empty($serveInsert)||Db::name('serve')->insertAll(array_unique($serveInsert,SORT_REGULAR));
+ //4 匹配主键|构造更新
+ $serveDuplicate=[];
+ $serve=Db::name('serve')->whereOr($serveWhereOrSql)->select()->toArray();
+ foreach ($outStore['serve'] as $serveKey=>$serveVo) {
+ $serveFind=search($serve)->where([['goods','=',$serveVo['goods']],['attr','=',$serveVo['attr']]])->find();
+ $outStore['serve'][$serveKey]['id']=$serveFind['id'];
+ $serveDuplicate[]=['id'=>$serveFind['id'],'nums'=>$serveVo['nums']];
+ }
+ //5 更新数据
+ Db::name('serve')->duplicate(['nums'=>Db::raw('nums + VALUES(`nums`)')])->insertAll($serveDuplicate);
+ }
+ //9 服务商品详情
+ if(!empty($outStore['serveInfo'])){
+ //1 填充数据
+ foreach ($outStore['serveInfo'] as $serveInfoKey=>$serveInfoVo) {
+ $outStore['serveInfo'][$serveInfoKey]['pid']=$outStore['serve'][$serveInfoKey]['id'];
+ }
+ //2 创建数据
+ Db::name('serve_info')->insertAll($outStore['serveInfo']);
+ }
+ // --- 调入数据 ---
+ //10 仓储
+ if(!empty($enterStore['room'])){
+ //1 构造数据
+ $roomInsert=[];
+ foreach ($enterStore['room'] as $roomVo) {
+ $roomFind=search($roomList)->where([['warehouse','=',$roomVo['warehouse']],['goods','=',$roomVo['goods']],['attr','=',$roomVo['attr']]])->find();
+ if(empty($roomFind)){
+ $roomVo['nums']=0;
+ $roomInsert[]=$roomVo;
+ }
+ }
+ //2 创建数据|去重
+ empty($roomInsert)||Db::name('room')->insertAll(array_unique($roomInsert,SORT_REGULAR));
+ //3 匹配主键|构造更新
+ $roomDuplicate=[];
+ $room=Db::name('room')->whereOr($toRoomWhereOrSql)->select()->toArray();
+ foreach ($enterStore['room'] as $roomKey=>$roomVo) {
+ $roomFind=search($room)->where([['warehouse','=',$roomVo['warehouse']],['goods','=',$roomVo['goods']],['attr','=',$roomVo['attr']]])->find();
+ $enterStore['room'][$roomKey]['id']=$roomFind['id'];
+ $roomDuplicate[]=['id'=>$roomFind['id'],'nums'=>$roomVo['nums']];
+ }
+ //4 更新数据
+ Db::name('room')->duplicate(['nums'=>Db::raw('nums + VALUES(`nums`)')])->insertAll($roomDuplicate);
+ }
+ //11 仓储详情
+ if(!empty($enterStore['roomInfo'])){
+ //1 填充数据
+ foreach ($enterStore['roomInfo'] as $roomInfoKey=>$roomInfoVo) {
+ $enterStore['roomInfo'][$roomInfoKey]['pid']=$enterStore['room'][$roomInfoKey]['id'];
+ }
+ //2 创建数据
+ Db::name('room_info')->insertAll($enterStore['roomInfo']);
+ }
+ //12 批次号
+ if(!empty($enterStore['batch'])){
+ //1 构造数据
+ $batchData=[];
+ foreach ($enterStore['batch'] as $batchKey=>$batchVo) {
+ if(!empty($batchVo)){
+ $enterStore['batch'][$batchKey]['room']=$enterStore['room'][$batchKey]['id'];
+ $batchData[]=$enterStore['batch'][$batchKey];
+ }
+ }
+ //2 排除数据|[[],[],[]]
+ if(!empty($batchData)){
+ //1 构造数据
+ $batchInsert=[];
+ foreach ($batchData as $batchDataKey=>$batchDataVo) {
+ $batchFind=search($batchList)->where([['room','=',$batchDataVo['room']],['number','=',$batchDataVo['number']],['time','=',$batchDataVo['time']]])->find();
+ if(empty($batchFind)){
+ $batchDataVo['nums']=0;
+ $batchInsert[]=$batchDataVo;
+ }
+ }
+ //2 创建数据|去重
+ empty($batchInsert)||Db::name('batch')->insertAll(array_unique($batchInsert,SORT_REGULAR));
+ //3 匹配主键|构造更新
+ $batchDuplicate=[];
+ $batch=Db::name('batch')->where([['number','in',$batchGather]])->select()->toArray();
+ foreach ($enterStore['batch'] as $batchKey=>$batchVo) {
+ if(!empty($batchVo)){
+ $batchFind=search($batch)->where([['room','=',$batchVo['room']],['number','=',$batchVo['number']],['time','=',$batchVo['time']]])->find();
+ $enterStore['batch'][$batchKey]['id']=$batchFind['id'];
+ $batchDuplicate[]=['id'=>$batchFind['id'],'nums'=>$batchVo['nums']];
+ }
+ }
+ //4 更新数据
+ Db::name('batch')->duplicate(['nums'=>Db::raw('nums + VALUES(`nums`)')])->insertAll($batchDuplicate);
+ }
+ }
+ //13 批次号详情
+ if(!empty($enterStore['batchInfo'])){
+ //1 构造数据
+ $batchInfoInstall=[];
+ foreach ($enterStore['batchInfo'] as $batchInfoKey=>$batchInfoVo) {
+ if(!empty($batchInfoVo)){
+ $batchInfoVo['pid']=$enterStore['batch'][$batchInfoKey]['id'];
+ $batchInfoInstall[]=$batchInfoVo;
+ }
+ }
+ //2 排除数据|[[],[],[]]
+ if(!empty($batchInfoInstall)){
+ //创建数据
+ Db::name('batch_info')->insertAll($batchInfoInstall);
+ }
+ }
+ //14 序列号
+ if(!empty($enterStore['serial'])){
+ //1 构造数据
+ $serialInsert=[];
+ foreach ($enterStore['serial'] as $serialKey=>$item) {
+ if(!empty($item)){
+ foreach ($item as $itemKey=>$itemVo) {
+ $enterStore['serial'][$serialKey][$itemKey]['room']=$enterStore['room'][$serialKey]['id'];
+ $enterStore['serial'][$serialKey][$itemKey]['batch']=empty($enterStore['batch'][$serialKey])?0:$enterStore['batch'][$serialKey]['id'];
+ $serialInsert[]=$enterStore['serial'][$serialKey][$itemKey];
+ }
+ }
+ }
+ //2 排除数据|[[],[],[]]
+ if(!empty($serialInsert)){
+ //1 创建数据
+ Db::name('serial')->insertAll($serialInsert);
+ //2 匹配主键
+ $serial=Db::name('serial')->where([['number','in',$serialGather]])->select()->toArray();
+ foreach ($enterStore['serial'] as $serialKey=>$item) {
+ if(!empty($item)){
+ foreach ($item as $itemKey=>$itemVo) {
+ $serialFind=search($serial)->where([['room','=',$itemVo['room']],['batch','=',$itemVo['batch']],['number','=',$itemVo['number']]])->find();
+ $enterStore['serial'][$serialKey][$itemKey]['id']=$serialFind['id'];
+ }
+ }
+ }
+ }
+ }
+ //15 序列号详情
+ if(!empty($enterStore['serialInfo'])){
+ //1 构造数据
+ $serialInfoInstall=[];
+ foreach ($enterStore['serialInfo'] as $serialInfoKey=>$item) {
+ if(!empty($item)){
+ foreach ($item as $itemKey=>$itemVo) {
+ $itemVo['pid']=$enterStore['serial'][$serialInfoKey][$itemKey]['id'];
+ $serialInfoInstall[]=$itemVo;
+ }
+ }
+ }
+ //2 排除数据|[[],[],[]]
+ if(!empty($serialInfoInstall)){
+ //创建数据
+ Db::name('serial_info')->insertAll($serialInfoInstall);
+ }
+ }
+
+ //16 更新单据
+ Db::name('swap')->where([['id','=',$class['id']]])->update(['examine'=>1]);
+ //17 单据记录
+ Db::name('record')->insert(['type'=>'swap','source'=>$class['id'],'time'=>time(),'user'=>getUserID(),'info'=>'审核单据']);
+ //18 收发记录
+ $summary=new Summary;
+ $summary->note('swapOut',$class['id'],true);
+ $summary->note('swapEnter',$class['id'],true);
+ //19 记录操作
+ pushLog('审核调拨单[ '.$class['number'].' ]');//单据日志
+ }else{
+ //反审核
+ //--- 调出数据 ---
+ //1 匹配数据
+ $roomInfoList=Db::name('room_info')->where([['type','=','swapOut'],['info','in',array_column($info,'id')]])->select()->toArray();
+ $batchInfoList=Db::name('batch_info')->where([['type','=','swapOut'],['info','in',array_column($info,'id')]])->select()->toArray();
+ $serialInfoList=Db::name('serial_info')->where([['type','=','swapOut'],['info','in',array_column($info,'id')]])->select()->toArray();
+ $serveInfoList=Db::name('serve_info')->where([['type','=','swap'],['info','in',array_column($info,'id')]])->select()->toArray();
+ //1 仓储
+ $roomDuplicate=[];
+ foreach ($roomInfoList as $roomInfoVo) {
+ $roomDuplicate[]=['id'=>$roomInfoVo['pid'],'nums'=>$roomInfoVo['nums']];
+ }
+ //2.1 更新仓储
+ Db::name('room')->duplicate(['nums'=>Db::raw('nums + VALUES(`nums`)')])->insertAll($roomDuplicate);
+ //2.2 删除仓储详情
+ Db::name('room_info')->where([['id','in',array_column($roomInfoList,'id')]])->delete();
+ //2.3 仓储|冗余
+ $roomPk=array_unique(array_column($roomInfoList,'pid'));
+ $roomInfoData=Db::name('room_info')->where([['pid','in',$roomPk]])->select()->toArray();
+ $roomDiff=array_diff($roomPk,array_unique(array_column($roomInfoData,'pid')));
+ empty($roomDiff)||Db::name('room')->where([['id','in',$roomDiff]])->delete();
+ //3 批次号
+ if(!empty($batchInfoList)){
+ //1 构造数据
+ $batchInfoDuplicate=array_map(function($item){
+ return ['id'=>$item['pid'],'nums'=>$item['nums']];
+ },$batchInfoList);
+ //2 更新批次号
+ Db::name('batch')->duplicate(['nums'=>Db::raw('nums + VALUES(`nums`)')])->insertAll($batchInfoDuplicate);
+ //3 删除批次号详情
+ Db::name('batch_info')->where([['id','in',array_column($batchInfoList,'id')]])->delete();
+ //4 批次号|冗余
+ $batchPk=array_unique(array_column($batchInfoList,'pid'));
+ $batchInfoData=Db::name('batch_info')->where([['pid','in',$batchPk]])->select()->toArray();
+ $batchDiff=array_diff($batchPk,array_unique(array_column($batchInfoData,'pid')));
+ empty($batchDiff)||Db::name('batch')->where([['id','in',$batchDiff]])->delete();
+ }
+ //4 序列号
+ if(!empty($serialInfoList)){
+ //1 更新序列号
+ Db::name('serial')->where([['id','in',array_column($serialInfoList,'pid')]])->update(['state'=>0]);
+ //2 删除序列号详情
+ Db::name('serial_info')->where([['id','in',array_column($serialInfoList,'id')]])->delete();
+ //3 序列号|冗余
+ $serialPk=array_unique(array_column($serialInfoList,'pid'));
+ $serialInfoData=Db::name('serial_info')->where([['pid','in',$serialPk]])->select()->toArray();
+ $serialDiff=array_diff($serialPk,array_unique(array_column($serialInfoData,'pid')));
+ empty($serialDiff)||Db::name('serial')->where([['id','in',$serialDiff]])->delete();
+ }
+ //5 服务
+ if(!empty($serveInfoList)){
+ //1 构造数据
+ $serveInfoDuplicate=array_map(function($item){
+ return ['id'=>$item['pid'],'nums'=>$item['nums']];
+ },$serveInfoList);
+ //2 更新服务
+ Db::name('serve')->duplicate(['nums'=>Db::raw('nums - VALUES(`nums`)')])->insertAll($serveInfoDuplicate);
+ //3 删除服务详情
+ Db::name('serve_info')->where([['id','in',array_column($serveInfoList,'id')]])->delete();
+ //4 服务|冗余
+ $servePk=array_unique(array_column($serveInfoList,'pid'));
+ $serveInfoData=Db::name('serve_info')->where([['pid','in',$servePk]])->select()->toArray();
+ $serveDiff=array_diff($servePk,array_unique(array_column($serveInfoData,'pid')));
+ empty($serveDiff)||Db::name('serve')->where([['id','in',$serveDiff]])->delete();
+ }
+ //--- 调入数据 ---
+ //6 匹配数据
+ $roomInfoList=Db::name('room_info')->where([['type','=','swapEnter'],['info','in',array_column($info,'id')]])->select()->toArray();
+ $batchInfoList=Db::name('batch_info')->where([['type','=','swapEnter'],['info','in',array_column($info,'id')]])->select()->toArray();
+ $serialInfoList=Db::name('serial_info')->where([['type','=','swapEnter'],['info','in',array_column($info,'id')]])->select()->toArray();
+ //7 仓储
+ $roomDuplicate=[];
+ foreach ($roomInfoList as $roomInfoVo) {
+ $roomDuplicate[]=['id'=>$roomInfoVo['pid'],'nums'=>$roomInfoVo['nums']];
+ }
+ //7.1 更新仓储
+ Db::name('room')->duplicate(['nums'=>Db::raw('nums - VALUES(`nums`)')])->insertAll($roomDuplicate);
+ //7.2 删除仓储详情
+ Db::name('room_info')->where([['id','in',array_column($roomInfoList,'id')]])->delete();
+ //7.3 仓储|冗余
+ $roomPk=array_unique(array_column($roomInfoList,'pid'));
+ $roomInfoData=Db::name('room_info')->where([['pid','in',$roomPk]])->select()->toArray();
+ $roomDiff=array_diff($roomPk,array_unique(array_column($roomInfoData,'pid')));
+ empty($roomDiff)||Db::name('room')->where([['id','in',$roomDiff]])->delete();
+ //8 批次号
+ if(!empty($batchInfoList)){
+ //1 构造数据
+ $batchInfoDuplicate=array_map(function($item){
+ return ['id'=>$item['pid'],'nums'=>$item['nums']];
+ },$batchInfoList);
+ //2 更新批次号
+ Db::name('batch')->duplicate(['nums'=>Db::raw('nums - VALUES(`nums`)')])->insertAll($batchInfoDuplicate);
+ //3 删除批次号详情
+ Db::name('batch_info')->where([['id','in',array_column($batchInfoList,'id')]])->delete();
+ //4 批次号|冗余
+ $batchPk=array_unique(array_column($batchInfoList,'pid'));
+ $batchInfoData=Db::name('batch_info')->where([['pid','in',$batchPk]])->select()->toArray();
+ $batchDiff=array_diff($batchPk,array_unique(array_column($batchInfoData,'pid')));
+ empty($batchDiff)||Db::name('batch')->where([['id','in',$batchDiff]])->delete();
+ }
+ //9 序列号
+ if(!empty($serialInfoList)){
+ //1 删除序列号
+ Db::name('serial')->where([['id','in',array_column($serialInfoList,'pid')]])->delete();
+ //2 删除序列号详情
+ Db::name('serial_info')->where([['id','in',array_column($serialInfoList,'id')]])->delete();
+ }
+ //10 更新单据
+ Db::name('swap')->where([['id','=',$class['id']]])->update(['examine'=>0]);
+ //11 单据记录
+ Db::name('record')->insert(['type'=>'swap','source'=>$class['id'],'time'=>time(),'user'=>getUserID(),'info'=>'反审核单据']);
+ //12 收发记录
+ $summary=new Summary;
+ $summary->note('swapOut',$class['id'],false);
+ $summary->note('swapEnter',$class['id'],false);
+ //13 记录操作
+ pushLog('反审核调拨单[ '.$class['number'].' ]');//单据日志
+ }
+
+ Db::commit();
+ } catch (\Exception $e) {
+ Db::rollback();
+ return json(['state'=>'error','info'=>'内部错误,操作已撤销!']);
+ exit;
+ }
+ }
+ $result=['state'=>'success'];
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //上传
+ public function upload(){
+ $file = request()->file('file');
+ //获取上传文件
+ if (empty($file)) {
+ $result = ['state' => 'error','info' => '传入数据不完整!'];
+ } else {
+ //文件限制5MB
+ try{
+ validate(['file'=>['fileSize'=>5*1024*1024,'fileExt'=>'png,gif,jpg,jpeg,txt,doc,docx,rtf,xls,xlsx,ppt,pptx,pdf,zip,rar']])->check(['file'=>$file]);
+ $fileInfo=Filesystem::disk('upload')->putFile('swap', $file, 'uniqid');
+ $filePath=request()->domain().'/static/upload/'.$fileInfo;
+ $result=['state'=>'success','info'=>$filePath];
+ }catch(ValidateException $e) {
+ $result = ['state' => 'error','info' => $e->getMessage()];
+ }
+ }
+ return json($result);
+ }
+ //导入
+ public function import(){
+ delOverdueFile('static.upload.xlsx');//删除过期文件
+ $file=request()->file('file');//获取上传文件
+ if(empty($file)){
+ $result=['state'=>'error','info'=>'传入数据不完整!'];
+ }else{
+ $fun=getSys('fun');
+ try{
+ validate(['file'=>['fileSize'=>2*1024*1024,'fileExt'=>'xlsx']])->check(['file'=>$file]);
+ $fileInfo = Filesystem::disk('upload')->putFile('xlsx', $file, 'uniqid');
+ $filePath = pathChange('static.upload').$fileInfo;
+ $data=getXlsx($filePath);
+ unset($data[1]);//删除标题行
+ unset($data[2]);//删除列名行
+ //初始化CLASS
+ //关联人员匹配
+ if(empty($data[3]['D'])){
+ $people=['id'=>0];
+ }else{
+ $people=Db::name('people')->where([['name','=',$data[3]['D']]])->find();
+ if(empty($people)){
+ throw new ValidateException('关联人员[ '.$data[3]['D'].' ]未匹配!');
+ }
+ }
+ $class=[
+ 'frame'=>userInfo(getUserID(),'frame'),
+ 'time'=>$data[3]['A'],
+ 'number'=>$data[3]['B'],
+ 'total'=>0,
+ 'people'=>$people['id'],
+ 'logistics'=>["key"=>"auto","name"=>"自动识别","number"=>$data[3]['E']],
+ 'file'=>[],
+ 'data'=>$data[3]['F'],
+ 'more'=>[],
+ 'examine'=>0,
+ 'cse'=>0,
+ 'user'=>getUserID()
+ ];
+ $this->validate($class,'app\validate\Swap');//数据合法性验证
+ //初始化INFO
+ $info=[];
+ $goods=Goods::with(['attr'])->where([['name','in',array_column($data,'G')]])->select()->toArray();
+ $warehouse=Db::name('warehouse')->where([['name','in',array_column($data,'J')]])->select()->toArray();
+ $storehouse=Db::name('warehouse')->where([['name','in',array_column($data,'K')]])->select()->toArray();
+ foreach ($data as $dataKey=>$dataVo) {
+ $record=[
+ 'goods'=>$dataVo['G'],
+ 'attr'=>$dataVo['H'],
+ 'unit'=>$dataVo['I'],
+ 'warehouse'=>$dataVo['J'],
+ 'storehouse'=>$dataVo['K'],
+ 'batch'=>$dataVo['L'],
+ 'mfd'=>$dataVo['M'],
+ 'price'=>$dataVo['N'],
+ 'nums'=>$dataVo['O'],
+ 'serial'=>explode(',',$dataVo['P']),
+ 'total'=>$dataVo['Q'],
+ 'data'=>$dataVo['R']
+ ];
+ //商品匹配
+ $goodsFind=search($goods)->where([['name','=',$record['goods']]])->find();
+ if(empty($goodsFind)){
+ throw new ValidateException('模板文件第'.$dataKey.'行商品名称[ '.$record['goods'].' ]未匹配!');
+ }else{
+ $record['goods']=$goodsFind['id'];
+ }
+ //辅助属性匹配
+ if(empty($goodsFind['attr'])){
+ $record['attr']='';
+ }else{
+ if(empty($record['attr'])){
+ throw new ValidateException('模板文件第'.$dataKey.'行辅助属性不可为空!');
+ }else{
+ $attrFind=search($goodsFind['attr'])->where([['name','=',$record['attr']]])->find();
+ if(empty($attrFind)){
+ throw new ValidateException('模板文件第'.$dataKey.'行辅助属性[ '.$record['attr'].' ]未匹配!');
+ }
+ }
+ }
+ //单位匹配
+ if($goodsFind['unit']==-1){
+ if(empty($record['unit'])){
+ throw new ValidateException('模板文件第'.$dataKey.'行单位不可为空!');
+ }else{
+ $unitFind=search($goodsFind['units'])->where([['name','=',$record['unit']]])->find();
+ if(empty($unitFind) && $goodsFind['units'][0]['source']!=$record['unit']){
+ throw new ValidateException('模板文件第'.$dataKey.'行单位[ '.$record['unit'].' ]未匹配!');
+ }
+ }
+ }else{
+ $record['unit']=$goodsFind['unit'];
+ }
+ //调出仓库匹配
+ if(empty($goodsFind['type'])){
+ //常规产品
+ $warehouseFind=search($warehouse)->where([['name','=',$record['warehouse']]])->find();
+ if(empty($warehouseFind)){
+ throw new ValidateException('模板文件第'.$dataKey.'行调出仓库[ '.$record['warehouse'].' ]未匹配!');
+ }else{
+ $record['warehouse']=$warehouseFind['id'];
+ }
+ }else{
+ //服务产品
+ $record['warehouse']=null;
+ }
+ //调入仓库匹配
+ if(empty($goodsFind['type'])){
+ //常规产品
+ $storehouseFind=search($storehouse)->where([['name','=',$record['storehouse']]])->find();
+ if(empty($storehouseFind)){
+ throw new ValidateException('模板文件第'.$dataKey.'行调入仓库[ '.$record['storehouse'].' ]未匹配!');
+ }else{
+ $record['storehouse']=$storehouseFind['id'];
+ }
+ }else{
+ //服务产品
+ $record['storehouse']=null;
+ }
+ //调入调出匹配
+ if(empty($goodsFind['type'])){
+ if($record['warehouse']==$record['storehouse']){
+ throw new ValidateException('模板文件第'.$dataKey.'行调出调入仓库不可相等!');
+ }
+ }
+ //批次号匹配
+ if(empty($goodsFind['batch'])){
+ $record['batch']='';
+ }else{
+ if(empty($record['batch'])){
+ throw new ValidateException('模板文件第'.$dataKey.'行批次号不可为空!');
+ }
+ }
+ //生产日期匹配
+ if(empty($goodsFind['validity'])){
+ $record['mfd']='';
+ }else{
+ if(empty($record['mfd'])){
+ throw new ValidateException('模板文件第'.$dataKey.'行生产日期不可为空!');
+ }
+ }
+ //成本匹配
+ if(!preg_match("/^\d+(\.\d{0,".$fun['digit']['money']."})?$/",$record['price'])){
+ throw new ValidateException('模板文件第'.$dataKey.'行成本不正确!');
+ }
+ //数量匹配
+ if(!preg_match("/^\d+(\.\d{0,".$fun['digit']['nums']."})?$/",$record['nums'])){
+ throw new ValidateException('模板文件第'.$dataKey.'行数量不正确!');
+ }
+ //序列号匹配
+ if(empty($goodsFind['serial'])){
+ $record['serial']=[];
+ }else{
+ if(count($record['serial'])==1 && empty($record['serial'][0])){
+ throw new ValidateException('模板文件第'.$dataKey.'行序列号不可为空!');
+ }else{
+ if(count($record['serial'])!=$record['nums']){
+ throw new ValidateException('模板文件第'.$dataKey.'行序列号个数与数量不符!');
+ }
+ }
+ }
+ try{
+ $this->validate($record,'app\validate\SwapInfo');//数据合法性验证
+ $record['total']=math()->chain($record['price'])->mul($record['nums'])->round($fun['digit']['money'])->done();
+ //转存数据
+ $class['total']=math()->chain($class['total'])->add($record['total'])->done();//累加单据金额
+ $info[]=$record;
+ } catch (ValidateException $e) {
+ return json(['state'=>'error','info'=>'模板文件第'.$dataKey.'行'.$e->getMessage()]);//返回错误信息
+ exit;
+ }
+ }
+ //序列号重复验证
+ $serials=[];
+ foreach ($info as $infoVo) {
+ $serials = array_merge($serials,$infoVo['serial']);
+ }
+ if(count($serials)!=count(array_unique($serials))){
+ throw new ValidateException('商品信息中存在重复序列号!');
+ }
+ Db::startTrans();
+ try {
+ //新增CLASS
+ $classData=Swaps::create($class);
+ //新增INFO
+ foreach ($info as $infoKey=>$infoVo) {
+ $info[$infoKey]['pid']=$classData['id'];
+ }
+ $model = new SwapInfo;
+ $model->saveAll($info);
+ Db::name('record')->insert(['type'=>'swap','source'=>$classData['id'],'time'=>time(),'user'=>getUserID(),'info'=>'导入单据']);
+ pushLog('导入调拨单[ '.$classData['number'].' ]');//日志
+
+ Db::commit();
+ $result=['state'=>'success'];
+ } catch (\Exception $e) {
+ Db::rollback();
+ $result=['state'=>'error','info'=>'内部错误,操作已撤销!'];
+ }
+ }catch(ValidateException $e) {
+ $result=['state'=>'error','info'=>$e->getMessage()];//返回错误信息
+ }
+ }
+ return json($result);
+ }
+ //导出
+ public function exports(){
+ $input=input('get.');
+ if(existFull($input,['scene','parm']) && is_array($input['parm'])){
+ pushLog('导出调拨单列表');//日志
+ $source=Swaps::with(['frameData','peopleData','userData','recordData'])->where([['id','in',$input['parm']]])->append(['extension'])->order(['id'=>'desc'])->select()->toArray();//查询CLASS数据
+ if($input['scene']=='simple'){
+ //简易报表
+ //开始构造导出数据
+ $excel=[];//初始化导出数据
+ //标题数据
+ $excel[]=['type'=>'title','info'=>'调拨单列表'];
+ //表格数据
+ $field=[
+ 'frameData|name'=>'所属组织',
+ 'time'=>'单据时间',
+ 'number'=>'单据编号',
+ 'total'=>'单据成本',
+ 'cost'=>'单据费用',
+ 'peopleData|name'=>'关联人员',
+ 'extension|examine'=>'审核状态',
+ 'extension|cse'=>'费用状态',
+ 'userData|name'=>'制单人',
+ 'data'=>'备注信息'
+ ];
+ $thead=array_values($field);//表格标题
+ $tbody=[];//表格内容
+ //构造表内数据
+ foreach ($source as $sourceVo) {
+ $rowData=[];
+ foreach (array_keys($field) as $fieldVo) {
+ $rowData[]=arraySeek($sourceVo,$fieldVo);//多键名数据赋值
+ }
+ $tbody[]=$rowData;//加入行数据
+ }
+ $excel[]=['type'=>'table','info'=>['thead'=>$thead,'tbody'=>$tbody]];//表格数据
+ //统计数据
+ $excel[]=['type'=>'node','info'=>[
+ '总数:'.count($source),
+ '总单据成本:'.mathArraySum(array_column($source,'total')),
+ '总单据费用:'.mathArraySum(array_column($source,'cost'))
+ ]];
+ //导出execl
+ buildExcel('调拨单列表',$excel);
+ }else{
+ //详细报表
+ $files=[];//初始化文件列表
+ foreach ($source as $sourceVo) {
+ //开始构造导出数据
+ $excel=[];//初始化导出数据
+ //标题数据
+ $excel[]=['type'=>'title','info'=>'调拨单'];
+ //节点数据
+ $excel[]=['type'=>'node','info'=>[
+ '单据日期:'.$sourceVo['time'],
+ '单据编号:'.$sourceVo['number']]
+ ];
+ //表格数据
+ $field=[
+ 'goodsData|name'=>'商品名称',
+ 'goodsData|spec'=>'规格型号',
+ 'attr'=>'辅助属性',
+ 'unit'=>'单位',
+ 'warehouseData|name'=>'调出仓库',
+ 'storehouseData|name'=>'调入仓库',
+ 'batch'=>'批次号',
+ 'mfd'=>'生产日期',
+ 'price'=>'成本',
+ 'nums'=>'数量',
+ 'extension|serial'=>'序列号',
+ 'total'=>'总成本',
+ 'data'=>'备注信息'
+ ];
+ //构造表内数据
+ $info=SwapInfo::with(['goodsData','warehouseData','storehouseData'])->where([['pid','=',$sourceVo['id']]])->order(['id'=>'asc'])->append(['extension'])->select()->toArray();
+ //批次号匹配
+ if(empty(search($info)->where([['goodsData|batch','=',true]])->find())){
+ unset($field['batch']);
+ }
+ //生产日期匹配
+ if(empty(search($info)->where([['goodsData|validity','=',true]])->find())){
+ unset($field['mfd']);
+ }
+ //序列号匹配
+ if(empty(search($info)->where([['goodsData|serial','=',true]])->find())){
+ unset($field['extension|serial']);
+ }
+ $thead=array_values($field);//表格标题
+ $tbody=[];//表格内容
+ foreach ($info as $infoVo) {
+ $rowData=[];
+ foreach (array_keys($field) as $fieldVo) {
+ $rowData[]=arraySeek($infoVo,$fieldVo);//多键名数据赋值
+ }
+ $tbody[]=$rowData;//加入行数据
+ }
+ $excel[]=['type'=>'table','info'=>['thead'=>$thead,'tbody'=>$tbody]];//表格数据
+ //节点数据
+ $excel[]=['type'=>'node','info'=>[
+ '单据成本:'.$sourceVo['total'],
+ '单据费用:'.$sourceVo['cost'],
+ '关联人员:'.arraySeek($sourceVo,'peopleData|name'),
+ '物流信息:'.$sourceVo['extension']['logistics'],
+ '备注信息:'.$sourceVo['data']]
+ ];
+ //生成execl
+ $files[]=buildExcel($sourceVo['number'],$excel,false);
+
+ }
+ buildZip('调拨单_'.time(),$files);
+ }
+ }else{
+ return json(['state'=>'error','info'=>'传入数据不完整!']);
+ }
+ }
+}
\ No newline at end of file
diff --git a/serve/app/controller/Sys.php b/serve/app/controller/Sys.php
new file mode 100644
index 0000000..0bead33
--- /dev/null
+++ b/serve/app/controller/Sys.php
@@ -0,0 +1,41 @@
+'success','info'=>getSys()]);
+ }
+ //保存
+ public function save(){
+ $input=input('post.');
+ if(is_array($input)){
+ $sql=[];
+ //查找对应主键
+ $keys=array_keys($input);
+ $sys=Syss::where([['name','in',$keys]])->field(['id','name'])->select();
+ //构造数据
+ foreach ($sys as $row){
+ $sql[]=['id'=>$row['id'],'info'=>$input[$row['name']]];
+ }
+ Db::startTrans();
+ try {
+ //数据处理
+ $model=new Syss;
+ $model->saveAll($sql);
+ pushLog('修改系统参数');
+
+ Db::commit();
+ $result=['state'=>'success'];
+ } catch (\Exception $e) {
+ Db::rollback();
+ $result=['state'=>'error','info'=>'内部错误,操作已撤销!'];
+ }
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+}
\ No newline at end of file
diff --git a/serve/app/controller/User.php b/serve/app/controller/User.php
new file mode 100644
index 0000000..0d1b5c5
--- /dev/null
+++ b/serve/app/controller/User.php
@@ -0,0 +1,161 @@
+'name|py'],'fullLike'],
+ ['user','fullLike'],
+ ['tel','fullLike'],
+ ['data','fullLike']
+ ]);//构造SQL
+ $sql=frameScope($sql);//组织数据
+ $sql=sqlAuth('user',$sql);//数据鉴权
+ $count = Users::where($sql)->count();//获取总条数
+ $info = Users::with(['frameData','roleData'])->where($sql)->page($input['page'],$input['limit'])->order(['id'=>'desc'])->select();//查询分页数据
+ $result=[
+ 'state'=>'success',
+ 'count'=>$count,
+ 'info'=>$info
+ ];//返回数据
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //新增|更新
+ public function save(){
+ $input=input('post.');
+ if(isset($input['id'])){
+
+ //构造|验证
+ try {
+ $input['py']=zhToPy($input['name']);//首拼信息
+ if(empty($input['id'])){
+ $this->validate($input,'app\validate\User');
+ }else{
+ //设置TOKEN失效
+ $input['token']="";
+ //判断密码是否修改|留空不修改密码
+ if(isset($input['pwd']) && empty($input['pwd'])){
+ unset($input['pwd']);
+ }
+ $this->validate($input,'app\validate\User.update');
+ }
+ } catch (ValidateException $e) {
+ return json(['state'=>'error','info'=>$e->getError()]);
+ exit;
+ }
+
+ //处理数据
+ Db::startTrans();
+ try {
+ if(empty($input['id'])){
+ //创建数据
+ Users::create($input);
+ pushLog('新增用户[ '.$input['name'].' ]');//日志
+ }else{
+ //更新数据
+ Users::update($input);
+ pushLog('更新用户[ '.$input['name'].' ]');//日志
+ }
+
+ Db::commit();
+ $result=['state'=>'success'];
+ } catch (\Exception $e) {
+ Db::rollback();
+ $result=['state'=>'error','info'=>'内部错误,操作已撤销!'];
+ }
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //获取
+ public function get(){
+ $input=input('post.');
+ if(existFull($input,['id'])){
+ $result=[
+ 'state'=>'success',
+ 'info'=>Users::where([['id','=',$input['id']]])->find()
+ ];
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //删除
+ public function del(){
+ $input=input('post.');
+ if(existFull($input,['id'])){
+ //关联判断
+ $exist=moreTableFind([
+ ['table'=>'allot','where'=>[['user','=',$input['id']]]],
+ ['table'=>'barter','where'=>[['user','=',$input['id']]]],
+ ['table'=>'bill','where'=>[['user','=',$input['id']]]],
+ ['table'=>'bor','where'=>[['user','=',$input['id']]]],
+ ['table'=>'bre','where'=>[['user','=',$input['id']]]],
+ ['table'=>'buy','where'=>[['user','=',$input['id']]]],
+ ['table'=>'entry','where'=>[['user','=',$input['id']]]],
+ ['table'=>'extry','where'=>[['user','=',$input['id']]]],
+ ['table'=>'ice','where'=>[['user','=',$input['id']]]],
+ ['table'=>'imy','where'=>[['user','=',$input['id']]]],
+ ['table'=>'oce','where'=>[['user','=',$input['id']]]],
+ ['table'=>'omy','where'=>[['user','=',$input['id']]]],
+ ['table'=>'period','where'=>[['user','=',$input['id']]]],
+ ['table'=>'sell','where'=>[['user','=',$input['id']]]],
+ ['table'=>'sor','where'=>[['user','=',$input['id']]]],
+ ['table'=>'sre','where'=>[['user','=',$input['id']]]],
+ ['table'=>'swap','where'=>[['user','=',$input['id']]]],
+ ['table'=>'customer','where'=>[['user','=',$input['id']]]],
+ ['table'=>'often','where'=>[['user','=',$input['id']]]],
+ ['table'=>'record','where'=>[['user','=',$input['id']]]],
+ ['table'=>'supplier','where'=>[['user','=',$input['id']]]],
+ ]);
+ if(empty($exist)){
+ //逻辑处理
+ $find=Db::name('user')->where([['id','=',$input['id']]])->find();
+ Db::startTrans();
+ try {
+ Db::name('user')->where([['id','=',$input['id']]])->delete();
+ Db::name('log')->where([['user','=',$input['id']]])->delete();
+ pushLog('删除用户[ '.$find['name'].' ]');//日志
+
+ Db::commit();
+ $result=['state'=>'success'];
+ } catch (\Exception $e) {
+ Db::rollback();
+ $result=['state'=>'error','info'=>'内部错误,操作已撤销!'];
+ }
+ }else{
+ $result=['state'=>'error','info'=>'存在数据关联,删除失败!'];
+ }
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //上传
+ public function upload(){
+ $file=request()->file('file');//获取上传文件
+ if (empty($file)){
+ $result=['state'=>'error','info'=>'传入数据不完整!'];
+ }else{
+ try{
+ validate(['file'=>['fileSize'=>1*1024*1024,'fileExt'=>'png,gif,jpg,jpeg']])->check(['file'=>$file]);
+ $fileInfo=Filesystem::disk('upload')->putFile('user', $file, 'uniqid');
+ $filePath=request()->domain().'/static/upload/'.$fileInfo;
+ $result=['state'=>'success','info'=>$filePath];
+ }catch(ValidateException $e) {
+ $result=['state'=>'error','info'=>$e->getMessage()];
+ }
+ }
+ return json($result);
+ }
+}
diff --git a/serve/app/controller/Warehouse.php b/serve/app/controller/Warehouse.php
new file mode 100644
index 0000000..de215ed
--- /dev/null
+++ b/serve/app/controller/Warehouse.php
@@ -0,0 +1,118 @@
+count();//获取总条数
+ $info = Warehouses::with(['frameData'])->where($sql)->page($input['page'],$input['limit'])->order(['id'=>'desc'])->select();//查询分页数据
+ $result=[
+ 'state'=>'success',
+ 'count'=>$count,
+ 'info'=>$info
+ ];//返回数据
+ return json($result);
+ }
+ //新增|更新
+ public function save(){
+ $input=input('post.');
+ if(isset($input['id'])){
+ //验证数据
+ try {
+ empty($input['id'])?$this->validate($input,'app\validate\Warehouse'):$this->validate($input,'app\validate\Warehouse.update');
+ } catch (ValidateException $e) {
+ return json(['state'=>'error','info'=>$e->getError()]);
+ exit;
+ }
+
+ //处理数据
+ Db::startTrans();
+ try {
+ if(empty($input['id'])){
+ //创建数据
+ Warehouses::create($input);
+ pushLog('新增仓库[ '.$input['name'].' ]');//日志
+ }else{
+ //更新数据
+ Warehouses::update($input);
+ pushLog('更新仓库[ '.$input['name'].' ]');//日志
+ }
+
+ Db::commit();
+ $result=['state'=>'success'];
+ } catch (\Exception $e) {
+ Db::rollback();
+ $result=['state'=>'error','info'=>'内部错误,操作已撤销!'];
+ }
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //获取
+ public function get(){
+ $input=input('post.');
+ if(existFull($input,['id'])){
+ $result=[
+ 'state'=>'success',
+ 'info'=>Warehouses::where([['id','=',$input['id']]])->find()
+ ];
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //删除
+ public function del(){
+ $input=input('post.');
+ if(existFull($input,['id'])){
+ //关联判断
+ $exist=moreTableFind([
+ ['table'=>'sor_info','where'=>[['warehouse','=',$input['id']]]],
+ ['table'=>'sell_info','where'=>[['warehouse','=',$input['id']]]],
+ ['table'=>'sre_info','where'=>[['warehouse','=',$input['id']]]],
+ ['table'=>'bor_info','where'=>[['warehouse','=',$input['id']]]],
+ ['table'=>'buy_info','where'=>[['warehouse','=',$input['id']]]],
+ ['table'=>'bre_info','where'=>[['warehouse','=',$input['id']]]],
+ ['table'=>'extry_info','where'=>[['warehouse','=',$input['id']]]],
+ ['table'=>'entry_info','where'=>[['warehouse','=',$input['id']]]],
+ ['table'=>'swap_info','where'=>[['warehouse|storehouse','=',$input['id']]]],
+ ['table'=>'deploy','where'=>[['source','like','%"warehouse":'.$input['id'].'%']]]
+ ]);
+ if(empty($exist)){
+ //逻辑处理
+ $find=Db::name('warehouse')->where([['id','=',$input['id']]])->find();
+ Db::startTrans();
+ try {
+ Db::name('warehouse')->where([['id','=',$input['id']]])->delete();
+ pushLog('删除仓库[ '.$find['name'].' ]');//日志
+
+ Db::commit();
+ $result=['state'=>'success'];
+ } catch (\Exception $e) {
+ Db::rollback();
+ $result=['state'=>'error','info'=>'内部错误,操作已撤销!'];
+ }
+ }else{
+ $result=['state'=>'error','info'=>'存在数据关联,删除失败!'];
+ }
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+}
\ No newline at end of file
diff --git a/serve/app/controller/Wechat.php b/serve/app/controller/Wechat.php
new file mode 100644
index 0000000..ab45955
--- /dev/null
+++ b/serve/app/controller/Wechat.php
@@ -0,0 +1,169 @@
+appId=$deploy['wechat']['appid'];
+ $config->merchantId=$deploy['wechat']['mchid'];
+ $config->key=$deploy['wechat']['mchkey'];
+ //单据数据
+ $order=new \WxPayMicroPay;
+ $order->SetBody($deploy['wechat']['title']);
+ $order->SetOut_trade_no($input['number']);
+ $money=math()->chain($input['money'])->mul(100)->done();
+ $order->SetTotal_fee($money);
+ $order->SetAuth_code($input['code']);
+ //发送请求
+ $result=\WxPayApi::micropay($config,$order);
+ if($result['return_code']=='SUCCESS'){
+ //判断支付状态
+ if($result['result_code']=='SUCCESS'){
+ //支付成功
+ $result=['state'=>'success','info'=>$result['transaction_id']];
+ }else{
+ //支付失败
+ if(in_array($result['err_code'],['SYSTEMERROR','BANKERROR','USERPAYING'])){
+ //返回等待信息
+ $result=['state'=>'wait','info'=>'等待操作...'];
+ }else{
+ //确认失败,返回错误信息
+ $result=['state'=>'wrong','info'=>$result['err_code_des']];
+ }
+ }
+ }else{
+ $result=['state'=>'wrong','info'=>$result['return_msg']];
+ }
+ }else{
+ $result=['state'=>'error','info'=>'支付参数不完整!'];
+ }
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //查询单据
+ public function query(){
+ $input=input('post.');
+ if(existFull($input,['number'])){
+ //读取配置
+ $deploy=getFrameDeploy();
+ if(!empty($deploy)){
+ //微信支付SDK
+ $wxPayPath=root_path('extend/wechat');
+ require_once $wxPayPath."WxPay.Api.php";
+ require_once $wxPayPath."WxPay.Config.php";
+ //配置数据
+ $config=new \WxPayConfig;
+ $config->appId=$deploy['wechat']['appid'];
+ $config->merchantId=$deploy['wechat']['mchid'];
+ $config->key=$deploy['wechat']['mchkey'];
+ //单据数据
+ $order=new \WxPayOrderQuery;
+ $order->SetOut_trade_no($input['number']);
+ //发送请求
+ $result=\WxPayApi::orderQuery($config,$order);
+ if($result['return_code']=='SUCCESS'){
+ //判断查询状态
+ if($result['result_code']=='SUCCESS'){
+ //查询成功
+ if($result['trade_state']=='SUCCESS'){
+ //支付成功
+ $result=['state'=>'success','info'=>$result['transaction_id']];
+ }elseif($result['trade_state']=='USERPAYING'){
+ //用户支付中,返回等待信息
+ $result=['state'=>'wait','info'=>'等待操作...'];
+ }else{
+ //其他状态,返回数据
+ $result=['state'=>'wrong','info'=>$result['trade_state_desc']];
+ }
+ }else{
+ //查询失败
+ if($result['err_code']=='SYSTEMERROR'){
+ //返回等待信息
+ $result=['state'=>'wait','info'=>'等待操作...'];
+ }else{
+ //返回查询错误信息
+ $result=['state'=>'wrong','info'=>$result['err_code_des']];
+ }
+ }
+ }else{
+ $result=['state'=>'wrong','info'=>$result['return_msg']];
+ }
+ }else{
+ $result=['state'=>'error','info'=>'支付参数不完整!'];
+ }
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //撤销单据
+ //支付成功退款|未支付关闭单据
+ public function cancel(){
+ $input=input('post.');
+ if(existFull($input,['number'])){
+ //读取配置
+ $deploy=getFrameDeploy();
+ if(!empty($deploy)){
+ //微信支付SDK
+ $wxPayPath=root_path('extend/wechat');
+ require_once $wxPayPath."WxPay.Api.php";
+ require_once $wxPayPath."WxPay.Config.php";
+ $sslCert = tmpfile();
+ fwrite($sslCert,$deploy['wechat']['certText']);
+ $sslKey = tmpfile();
+ fwrite($sslKey,$deploy['wechat']['keyText']);
+ //配置数据
+ $config=new \WxPayConfig;
+ $config->appId=$deploy['wechat']['appid'];
+ $config->merchantId=$deploy['wechat']['mchid'];
+ $config->key=$deploy['wechat']['mchkey'];
+ $config->sslCertPath=stream_get_meta_data($sslCert)['uri'];
+ $config->sslKeyPath=stream_get_meta_data($sslKey)['uri'];
+ //单据数据
+ $order=new \WxPayReverse;
+ $order->SetOut_trade_no($input['number']);
+ //发送请求
+ $result=\WxPayApi::reverse($config,$order);
+ if($result['return_code']=='SUCCESS'){
+ //判断查询状态
+ if($result['result_code']=='SUCCESS'){
+ //撤销成功
+ $result=['state'=>'success','info'=>'撤销单据成功!'];
+ }else{
+ //查询失败
+ if(in_array($result['err_code'],['SYSTEMERROR','USERPAYING'])){
+ //等待信息
+ $result=['state'=>'wait','info'=>'等待操作...'];
+ }else{
+ //返回查询错误信息
+ $result=['state'=>'wrong','info'=>$result['err_code_des']];
+ }
+ }
+ }else{
+ $result=['state'=>'wrong','info'=>$result['return_msg']];
+ }
+ }else{
+ $result=['state'=>'error','info'=>'支付参数不完整!'];
+ }
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+}
\ No newline at end of file
diff --git a/serve/app/controller/Wrf.php b/serve/app/controller/Wrf.php
new file mode 100644
index 0000000..f075a62
--- /dev/null
+++ b/serve/app/controller/Wrf.php
@@ -0,0 +1,641 @@
+where(empty($input['warehouse'])?sqlAuth('warehouse',[]):[['id','in',$input['warehouse']]])->order(['id'=>'desc'])->select()->toArray();
+ //构造表头
+ $column=[];
+ foreach ($warehouse as $vo) {
+ $column[]=['id'=>$vo['id'],'name'=>$vo['name'],'uct'=>'uct_'.$vo['id'],'uns'=>'uns_'.$vo['id'],'bct'=>'bct_'.$vo['id']];
+ }
+ //匹配数据
+ $sql=fastSql($input,[
+ ['warehouse','fullIn'],
+ ['time','endTime']
+ ]);
+ $sql=sqlAuth('summary',$sql);
+ //商品信息扩展查询
+ if(existFull($input,['goods'])){
+ $goods=array_column(Db::name('goods')->where([['name|py','like','%'.$input['goods'].'%']])->select()->toArray(),'id');
+ $sql[]=['goods','in',$goods];
+ }
+ $count=Summary::where($sql)->group(['goods'])->count();
+ $info=Summary::with(['goodsData'])->where($sql)->group(['goods'])->page($input['page'],$input['limit'])->order(['goods'])->select()->toArray();
+ foreach ($info as $key=>$vo) {
+ //查询条件
+ $where=fastSql($input,[['time','endTime']]);
+ $where[]=['goods','=',$vo['goods']];
+ //单位数据
+ $info[$key]['unit']=$vo['goodsData']['unit']==-1?'多单位':$vo['goodsData']['unit'];
+ //分仓数据
+ $info[$key]['uns']=0;
+ foreach ($column as $v) {
+ $wb=Db::name('summary')->where(array_merge($where,[['warehouse','=',$v['id']]]))->order(['id'=>'DESC'])->find();
+
+ $wb=empty($wb)?['exist'=>[0,0,0,0],'balance'=>[0,0,0,0]]:['exist'=>json_decode($wb['exist']),'balance'=>json_decode($wb['balance'])];
+ if(empty($wb['exist'][1]) && empty($wb['balance'][1])){
+ $info[$key]['wb_'.$v['id']]=['uct'=>'','uns'=>'','bct'=>''];
+ }else{
+ $info[$key]['wb_'.$v['id']]=[
+ 'uct'=>empty($wb['exist'][1])?0:math()->chain($wb['balance'][1])->div($wb['exist'][1])->round(2)->done(),
+ 'uns'=>$vo['goodsData']['unit']==-1?unitSwitch($wb['exist'][1],$vo['goodsData']['units']):$wb['exist'][1],
+ 'bct'=>$wb['balance'][1]
+ ];
+ }
+ if(!empty($info[$key]['wb_'.$v['id']]['uns']) && $vo['goodsData']['unit'] != -1){
+ $info[$key]['uns']+=$info[$key]['wb_'.$v['id']]['uns'];
+ }elseif(!empty($info[$key]['wb_'.$v['id']]['uns']) && $vo['goodsData']['unit'] == -1){
+ $info[$key]['uns']+-$wb['exist'][1];
+ }
+
+ }
+ //汇总数据
+ $balance=Db::name('summary')->where($where)->order(['id'=>'DESC'])->find();
+ $balance=['exist'=>json_decode($balance['exist']),'balance'=>json_decode($balance['balance'])];
+ $info[$key]['balance']=[];
+ $info[$key]['balance']['uct']=empty($balance['exist'][0])?0:math()->chain($balance['balance'][0])->div($balance['exist'][0])->round(2)->done();
+ $info[$key]['balance']['uns']=$vo['goodsData']['unit']==-1?unitSwitch($info[$key]['uns'],$vo['goodsData']['units']):$info[$key]['uns'];
+ $info[$key]['balance']['bct']=math()->chain($info[$key]['balance']['uct'])->mul($info[$key]['balance']['uns'])->round(2)->done();
+
+ }
+
+ $result=[
+ 'state'=>'success',
+ 'count'=>$count,
+ 'info'=>$info,
+ 'column'=>$column
+ ];//返回数据
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //商品库存余额表-导出
+ public function wbsExports(){
+ $input=input('get.');
+ existFull($input,['warehouse'])||$input['warehouse']=[];
+ if(isset($input['warehouse']) && is_array($input['warehouse'])){
+ //匹配仓库
+ $warehouse = Db::name('warehouse')->where(empty($input['warehouse'])?sqlAuth('warehouse',[]):[['id','in',$input['warehouse']]])->order(['id'=>'desc'])->select()->toArray();
+ //构造表头
+ $column=[];
+ foreach ($warehouse as $vo) {
+ $column[]=['id'=>$vo['id'],'name'=>$vo['name'],'uct'=>'uct_'.$vo['id'],'uns'=>'uns_'.$vo['id'],'bct'=>'bct_'.$vo['id']];
+ }
+ //匹配数据
+ $sql=fastSql($input,[
+ ['warehouse','fullIn'],
+ ['time','endTime']
+ ]);
+ $sql=sqlAuth('summary',$sql);
+ //商品信息扩展查询
+ if(existFull($input,['goods'])){
+ $goods=array_column(Db::name('goods')->where([['name|py','like','%'.$input['goods'].'%']])->select()->toArray(),'id');
+ $sql[]=['goods','in',$goods];
+ }
+ $count=Summary::where($sql)->group(['goods'])->count();
+ $info=Summary::with(['goodsData'])->where($sql)->group(['goods'])->order(['goods'])->select()->toArray();
+ foreach ($info as $key=>$vo) {
+ //查询条件
+ $where=fastSql($input,[['time','endTime']]);
+ $where[]=['goods','=',$vo['goods']];
+ //单位数据
+ $info[$key]['unit']=$vo['goodsData']['unit']==-1?'多单位':$vo['goodsData']['unit'];
+ //分仓数据
+ foreach ($column as $v) {
+ $wb=Db::name('summary')->where(array_merge($where,[['warehouse','=',$v['id']]]))->order(['id'=>'DESC'])->find();
+ $wb=empty($wb)?['exist'=>[0,0,0,0],'balance'=>[0,0,0,0]]:['exist'=>json_decode($wb['exist']),'balance'=>json_decode($wb['balance'])];
+ if(empty($wb['exist'][1]) && empty($wb['balance'][1])){
+ $info[$key]['wb_'.$v['id']]=['uct'=>'','uns'=>'','bct'=>''];
+ }else{
+ $info[$key]['wb_'.$v['id']]=[
+ 'uct'=>empty($wb['exist'][1])?0:math()->chain($wb['balance'][1])->div($wb['exist'][1])->round(2)->done(),
+ 'uns'=>$vo['goodsData']['unit']==-1?unitSwitch($wb['exist'][1],$vo['goodsData']['units']):$wb['exist'][1],
+ 'bct'=>$wb['balance'][1]
+ ];
+ }
+ }
+ //汇总数据
+ $balance=Db::name('summary')->where($where)->order(['id'=>'DESC'])->find();
+ $balance=['exist'=>json_decode($balance['exist']),'balance'=>json_decode($balance['balance'])];
+ $info[$key]['balance']=[
+ 'uct'=>empty($balance['exist'][0])?0:math()->chain($balance['balance'][0])->div($balance['exist'][0])->round(2)->done(),
+ 'uns'=>$vo['goodsData']['unit']==-1?unitSwitch($balance['exist'][0],$vo['goodsData']['units']):$balance['exist'][0],
+ 'bct'=>$balance['balance'][0]
+ ];
+ }
+ $source=$info;
+ $columns=[];
+ foreach ($column as $v) {
+ $columns['wb_'.$v['id'].'|uct']=$v['name'].'成本';
+ $columns['wb_'.$v['id'].'|uns']=$v['name'].'数量';
+ $columns['wb_'.$v['id'].'|bct']=$v['name'].'总成本';
+ }
+ //开始构造导出数据
+ $excel=[];//初始化导出数据
+ //标题数据
+ $excel[]=['type'=>'title','info'=>'商品库存余额表'];
+ //表格数据
+ $field=array_merge(
+ [
+ 'goodsData|name'=>'商品名称',
+ 'unit'=>'单位'
+ ],
+ $columns,
+ [
+ 'balance|uct'=>'汇总成本',
+ 'balance|uns'=>'汇总数量',
+ 'balance|bct'=>'汇总总成本'
+ ]
+ );
+ $thead=array_values($field);//表格标题
+ $tbody=[];//表格内容
+ //构造表内数据
+ foreach ($source as $sourceVo) {
+ $rowData=[];
+ foreach (array_keys($field) as $fieldVo) {
+ $rowData[]=arraySeek($sourceVo,$fieldVo);//多键名数据赋值
+ }
+ $tbody[]=$rowData;//加入行数据
+ }
+ $excel[]=['type'=>'table','info'=>['thead'=>$thead,'tbody'=>$tbody]];//表格数据
+ //汇总数据
+ $excel[]=['type'=>'node','info'=>[
+ '总数:'.count($source),
+ ]];
+ //导出execl
+ buildExcel('商品库存余额表',$excel);
+ }else{
+ return json(['state'=>'error','info'=>'传入参数不完整!']);
+ }
+ }
+ //商品收发明细表
+ public function wds(){
+ $input=input('post.');
+ $sheet=['buy','bre','sell','sre','swapOut','swapEnter','entry','extry'];
+ existFull($input,['mold'])||$input['mold']=$sheet;
+ if(existFull($input,['page','limit']) && is_arrays($input,['warehouse','mold']) && arrayInArray($input['mold'],$sheet)){
+ $sql=fastSql($input,[
+ ['warehouse','fullIn'],
+ [['startTime'=>'time'],'startTime'],
+ [['endTime'=>'time'],'endTime'],
+ [['mold'=>'type'],'fullIn']
+ ]);
+ $sql=sqlAuth('summary',$sql);
+ //商品信息扩展查询
+ if(existFull($input,['goods'])){
+ $goods=array_column(Db::name('goods')->where([['name|py','like','%'.$input['goods'].'%']])->select()->toArray(),'id');
+ $sql[]=['goods','in',$goods];
+ }
+ //子查询
+ $existsSql=[['id','=',Db::raw('summary.class')]];
+ $existsSql=frameScope($existsSql);
+ //多源匹配
+ $union=[];
+ //数据关系表
+ $table=['buy'=>'buy','bre'=>'bre','sell'=>'sell','sre'=>'sre','swapOut'=>'swap','swapEnter'=>'swap','entry'=>'entry','extry'=>'extry'];
+ foreach ($table as $k=>$v) {
+ //匹配类型|减少查询
+ if(in_array($k,$input['mold'])){
+ $union[]=Db::name($v)->where([['summary.type','=',$k]])->where(array_merge($existsSql,sqlAuth($v,[])))->limit(1)->buildSql();
+ }
+ }
+ //合并子查询
+ $union=implode(' UNION ALL ',$union);
+ $count=Summary::alias('summary')->where($sql)->whereExists($union)->count();
+ $source=Summary::with(['sourceData'=>['frameData'],'goodsData','warehouseData'])->alias('summary')->where($sql)->whereExists($union)->page($input['page'],$input['limit'])->order(['goods','id'])->append(['extension'])->select()->toArray();
+ //匹配往来单位
+ $currentList=['customer'=>[],'supplier'=>[]];
+ //匹配客戶
+ foreach (search($source)->where([['type','in',['sell','sre','extry']]])->select() as $item) {
+ $currentList['customer'][]=$item['sourceData']['customer'];
+ }
+ empty($currentList['customer'])||$currentList['customer']=Db::name('customer')->where([['id','in',array_unique($currentList['customer'])]])->select()->toArray();
+ //匹配供应商
+ foreach (search($source)->where([['type','in',['buy','bre','entry']]])->select() as $item) {
+ $currentList['supplier'][]=$item['sourceData']['supplier'];
+ }
+ empty($currentList['supplier'])||$currentList['supplier']=Db::name('supplier')->where([['id','in',array_unique($currentList['supplier'])]])->select()->toArray();
+ $data=[];
+ $cur=0;
+ foreach ($source as $vo) {
+
+ if($cur!=$vo['goods']){
+ $state=Db::name('summary')->where([['id','<',$vo['id']],['goods','=',$vo['goods']],['warehouse','=',$vo['warehouse']]])->order(['id'=>'DESC'])->find();
+ $state=empty($state)?['exist'=>[0,0,0,0],'balance'=>[0,0,0,0]]:['exist'=>json_decode($state['exist']),'balance'=>json_decode($state['balance'])];
+ $data[]=[
+ 'extension'=>['type'=>'期初余额'],
+ 'goodsData'=>['name'=>$vo['goodsData']['name']],
+ 'balance'=>[
+ 'uct'=>empty($state['exist'][0])?0:math()->chain($state['balance'][0])->div($state['exist'][0])->round(2)->done(),
+ 'uns'=>$vo['goodsData']['unit']==-1?unitSwitch($state['exist'][0],$vo['goodsData']['units']):$state['exist'][0],
+ 'bct'=>$state['balance'][0]
+ ]
+ ];
+ $cur=$vo['goods'];
+ }
+ $row=$vo;
+ //往来单位
+ if(in_array($vo['type'],['buy','bre','entry'])){
+ $row['current']=search($currentList['supplier'])->where([['id','=',$vo['sourceData']['supplier']]])->find();
+ }else if(in_array($vo['type'],['sell','sre','extry'])){
+ $row['current']=search($currentList['customer'])->where([['id','=',$vo['sourceData']['customer']]])->find();
+ }else{
+ $row['current']=[];
+ }
+ $row['unit']=$vo['goodsData']['unit']==-1?'多单位':$vo['goodsData']['unit'];
+
+ //出入方向
+ $uns=$vo['goodsData']['unit']==-1?unitSwitch($vo['nums'],$vo['goodsData']['units']):$vo['nums'];
+ if(empty($vo['direction'])){
+ //出库
+ $row['in']=['uct'=>'','uns'=>'','bct'=>''];
+ $row['out']=['uct'=>$vo['uct'],'uns'=>$uns,'bct'=>$vo['bct']];
+ }else{
+ //入库
+ $row['in']=['uct'=>$vo['uct'],'uns'=>$uns,'bct'=>$vo['bct']];
+ $row['out']=['uct'=>'','uns'=>'','bct'=>''];
+ }
+ //汇总
+ $exist=json_decode($vo['exist']);
+ $balance=json_decode($vo['balance']);
+ $row['balance']=[
+ 'uct'=>empty($exist[0])?0:math()->chain($balance[0])->div($exist[0])->round(2)->done(),
+ 'uns'=>$vo['goodsData']['unit']==-1?unitSwitch($exist[0],$vo['goodsData']['units']):$exist[0],
+ 'bct'=>$balance[0]
+ ];
+ $data[]=$row;
+ }
+ $result=[
+ 'state'=>'success',
+ 'count'=>$count,
+ 'info'=>$data
+ ];//返回数据
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //商品收发明细表-导出
+ public function wdsExports(){
+ $input=input('get.');
+ $sheet=['buy','bre','sell','sre','swapOut','swapEnter','entry','extry'];
+ existFull($input,['warehouse'])||$input['warehouse']=[];
+ existFull($input,['mold'])||$input['mold']=$sheet;
+ if(is_arrays($input,['warehouse','mold']) && arrayInArray($input['mold'],$sheet)){
+ $sql=fastSql($input,[
+ ['warehouse','fullIn'],
+ [['startTime'=>'time'],'startTime'],
+ [['endTime'=>'time'],'endTime'],
+ [['mold'=>'type'],'fullIn']
+ ]);
+ $sql=sqlAuth('summary',$sql);
+ //商品信息扩展查询
+ if(existFull($input,['goods'])){
+ $goods=array_column(Db::name('goods')->where([['name|py','like','%'.$input['goods'].'%']])->select()->toArray(),'id');
+ $sql[]=['goods','in',$goods];
+ }
+ //子查询
+ $existsSql=[['id','=',Db::raw('summary.class')]];
+ $existsSql=frameScope($existsSql);
+ //多源匹配
+ $union=[];
+ //数据关系表
+ $table=['buy'=>'buy','bre'=>'bre','sell'=>'sell','sre'=>'sre','swapOut'=>'swap','swapEnter'=>'swap','entry'=>'entry','extry'=>'extry'];
+ foreach ($table as $k=>$v) {
+ //匹配类型|减少查询
+ if(in_array($k,$input['mold'])){
+ $union[]=Db::name($v)->where([['summary.type','=',$k]])->where(array_merge($existsSql,sqlAuth($v,[])))->limit(1)->buildSql();
+ }
+ }
+ //合并子查询
+ $union=implode(' UNION ALL ',$union);
+ $source=Summary::with(['sourceData'=>['frameData'],'goodsData','warehouseData'])->alias('summary')->where($sql)->whereExists($union)->order(['goods','id'])->append(['extension'])->select()->toArray();
+ //匹配往来单位
+ $currentList=['customer'=>[],'supplier'=>[]];
+ //匹配客戶
+ foreach (search($source)->where([['type','in',['sell','sre','extry']]])->select() as $item) {
+ $currentList['customer'][]=$item['sourceData']['customer'];
+ }
+ empty($currentList['customer'])||$currentList['customer']=Db::name('customer')->where([['id','in',array_unique($currentList['customer'])]])->select()->toArray();
+ //匹配供应商
+ foreach (search($source)->where([['type','in',['buy','bre','entry']]])->select() as $item) {
+ $currentList['supplier'][]=$item['sourceData']['supplier'];
+ }
+ empty($currentList['supplier'])||$currentList['supplier']=Db::name('supplier')->where([['id','in',array_unique($currentList['supplier'])]])->select()->toArray();
+ $data=[];
+ $cur=0;
+ foreach ($source as $vo) {
+ if($cur!=$vo['goods']){
+ $state=Db::name('summary')->where([['id','<',$vo['id']],['goods','=',$vo['goods']]])->order(['id'=>'DESC'])->find();
+ $state=empty($state)?['exist'=>[0,0,0,0],'balance'=>[0,0,0,0]]:['exist'=>json_decode($state['exist']),'balance'=>json_decode($state['balance'])];
+ $data[]=[
+ 'extension'=>['type'=>'期初余额'],
+ 'goodsData'=>['name'=>$vo['goodsData']['name']],
+ 'balance'=>[
+ 'uct'=>empty($state['exist'][0])?0:math()->chain($state['balance'][0])->div($state['exist'][0])->round(2)->done(),
+ 'uns'=>$vo['goodsData']['unit']==-1?unitSwitch($state['exist'][0],$vo['goodsData']['units']):$state['exist'][0],
+ 'bct'=>$state['balance'][0]
+ ]
+ ];
+ $cur=$vo['goods'];
+ }
+ $row=$vo;
+ //往来单位
+ if(in_array($vo['type'],['buy','bre','entry'])){
+ $row['current']=search($currentList['supplier'])->where([['id','=',$vo['sourceData']['supplier']]])->find();
+ }else if(in_array($vo['type'],['sell','sre','extry'])){
+ $row['current']=search($currentList['customer'])->where([['id','=',$vo['sourceData']['customer']]])->find();
+ }else{
+ $row['current']=[];
+ }
+ $row['unit']=$vo['goodsData']['unit']==-1?'多单位':$vo['goodsData']['unit'];
+
+ //出入方向
+ $uns=$vo['goodsData']['unit']==-1?unitSwitch($vo['nums'],$vo['goodsData']['units']):$vo['nums'];
+ if(empty($vo['direction'])){
+ //出库
+ $row['in']=['uct'=>'','uns'=>'','bct'=>''];
+ $row['out']=['uct'=>$vo['uct'],'uns'=>$uns,'bct'=>$vo['bct']];
+ }else{
+ //入库
+ $row['in']=['uct'=>$vo['uct'],'uns'=>$uns,'bct'=>$vo['bct']];
+ $row['out']=['uct'=>'','uns'=>'','bct'=>''];
+ }
+ //汇总
+ $exist=json_decode($vo['exist']);
+ $balance=json_decode($vo['balance']);
+ $row['balance']=[
+ 'uct'=>empty($exist[0])?0:math()->chain($balance[0])->div($exist[0])->round(2)->done(),
+ 'uns'=>$vo['goodsData']['unit']==-1?unitSwitch($exist[0],$vo['goodsData']['units']):$exist[0],
+ 'bct'=>$balance[0]
+ ];
+ $data[]=$row;
+ }
+ $source=$data;
+ //开始构造导出数据
+ $excel=[];//初始化导出数据
+ //标题数据
+ $excel[]=['type'=>'title','info'=>'商品收发明细表'];
+ //表格数据
+ $field=[
+ 'extension|type'=>'单据类型',
+ 'sourceData|frameData|name'=>'所属组织',
+ 'current|name'=>'往来单位',
+ 'sourceData|time'=>'单据时间',
+ 'sourceData|number'=>'单据编号',
+ 'goodsData|name'=>'商品名称',
+ 'attr'=>'辅助属性',
+ 'warehouseData|name'=>'仓库',
+ 'unit'=>'单位',
+ 'in|uct'=>'入库成本',
+ 'in|uns'=>'入库数量',
+ 'in|bct'=>'入库总成本',
+ 'out|uct'=>'出库成本',
+ 'out|uns'=>'出库数量',
+ 'out|bct'=>'出库总成本',
+ 'balance|uct'=>'汇总成本',
+ 'balance|uns'=>'汇总数量',
+ 'balance|bct'=>'汇总总成本'
+ ];
+ $thead=array_values($field);//表格标题
+ $tbody=[];//表格内容
+ //构造表内数据
+ foreach ($source as $sourceVo) {
+ $rowData=[];
+ foreach (array_keys($field) as $fieldVo) {
+ $rowData[]=arraySeek($sourceVo,$fieldVo);//多键名数据赋值
+ }
+ $tbody[]=$rowData;//加入行数据
+ }
+ $excel[]=['type'=>'table','info'=>['thead'=>$thead,'tbody'=>$tbody]];//表格数据
+ //导出execl
+ buildExcel('商品收发明细表',$excel);
+ }else{
+ return json(['state'=>'error','info'=>'传入参数不完整!']);
+ }
+ }
+ //商品收发汇总表
+ public function wss(){
+ $input=input('post.');
+ if(existFull($input,['page','limit']) && is_array($input['warehouse'])){
+ $sql=fastSql($input,[
+ ['warehouse','fullIn'],
+ [['startTime'=>'time'],'startTime'],
+ [['endTime'=>'time'],'endTime']
+ ]);
+ $sql=sqlAuth('summary',$sql);
+ //商品信息扩展查询
+ if(existFull($input,['goods'])){
+ $goods=array_column(Db::name('goods')->where([['name|py','like','%'.$input['goods'].'%']])->select()->toArray(),'id');
+ $sql[]=['goods','in',$goods];
+ }
+ //子查询
+ $existsSql=[['id','=',Db::raw('summary.class')]];
+ $existsSql=frameScope($existsSql);
+ //多源匹配
+ $union=[];
+ //数据关系表
+ $table=['buy'=>'buy','bre'=>'bre','sell'=>'sell','sre'=>'sre','swapOut'=>'swap','swapEnter'=>'swap','entry'=>'entry','extry'=>'extry'];
+ foreach ($table as $k=>$v) {
+ $union[]=Db::name($v)->where([['summary.type','=',$k]])->where(array_merge($existsSql,sqlAuth($v,[])))->limit(1)->buildSql();
+ }
+ //合并子查询
+ $union=implode(' UNION ALL ',$union);
+ $record=Db::name('summary')->alias('summary')->where($sql)->whereExists($union)->order(['id'])->select()->toArray();
+ //分页数据
+ $count=Summary::where([['id','in',array_column($record,'id')]])->group(['goods','warehouse'])->count();
+ $data=Summary::with(['goodsData','warehouseData'])->where([['id','in',array_column($record,'id')]])->group(['goods','warehouse'])->page($input['page'],$input['limit'])->order(['goods'])->select()->toArray();
+ foreach ($data as $key=>$vo) {
+ $data[$key]['unit']=$vo['goodsData']['unit']==-1?'多单位':$vo['goodsData']['unit'];
+ //期初
+ $scope=search($record)->where([['goods','=',$vo['goods']]])->select();
+ $state=Db::name('summary')->where([['id','<',$scope[0]['id']],['goods','=',$vo['goods']]])->order(['id'=>'DESC'])->find();
+ $state=empty($state)?['exist'=>[0,0,0,0],'balance'=>[0,0,0,0]]:['exist'=>json_decode($state['exist']),'balance'=>json_decode($state['balance'])];
+ $data[$key]['state']=[
+ 'uct'=>empty($state['exist'][0])?0:math()->chain($state['balance'][0])->div($state['exist'][0])->round(2)->done(),
+ 'uns'=>$vo['goodsData']['unit']==-1?unitSwitch($state['exist'][0],$vo['goodsData']['units']):$state['exist'][0],
+ 'bct'=>$state['balance'][0]
+ ];
+ $list=search($scope)->where([['goods','=',$vo['goods']],['warehouse','=',$vo['warehouse']]])->select();
+ foreach ($table as $t=>$m) {
+ $group=search($list)->where([['type','=',$t]])->select();
+ if(empty($group)){
+ $data[$key][$t]=['uct'=>'','uns'=>'','bct'=>''];
+ }else{
+ $uns=0;
+ $bct=0;
+ foreach ($group as $v) {
+ $uns=math()->chain($uns)->add($v['nums'])->done();
+ $bct=math()->chain($bct)->add($v['bct'])->done();
+ }
+ $data[$key][$t]=[
+ 'uct'=>math()->chain($bct)->div($uns)->round(2)->done(),
+ 'uns'=>$vo['goodsData']['unit']==-1?unitSwitch($uns,$vo['goodsData']['units']):$uns,
+ 'bct'=>$bct
+ ];
+ }
+ }
+ //汇总
+ $balance=$scope[count($scope)-1];
+ $balance=['exist'=>json_decode($balance['exist']),'balance'=>json_decode($balance['balance'])];
+ $sum=Db::name('summary')->where([['goods','=',$vo['goods']],['warehouse','=',$vo['warehouse']]])->order(['id'=>'desc'])->find();
+ $data[$key]['balance']=[];
+ $data[$key]['balance']['uct']=empty($balance['exist'][0])?0:math()->chain($balance['balance'][0])->div($balance['exist'][0])->round(2)->done();
+ $data[$key]['balance']['uns']=$vo['goodsData']['unit']==-1?unitSwitch(json_decode($sum['exist'])[1],$vo['goodsData']['units']):json_decode($sum['exist'])[1];
+ $data[$key]['balance']['bct']=math()->chain($data[$key]['balance']['uct'])->mul($data[$key]['balance']['uns'])->round(2)->done();
+
+
+ }
+ $result=[
+ 'state'=>'success',
+ 'count'=>$count,
+ 'info'=>$data
+ ];//返回数据
+ }else{
+ $result=['state'=>'error','info'=>'传入参数不完整!'];
+ }
+ return json($result);
+ }
+ //商品收发汇总表-导出
+ public function wssExports(){
+ $input=input('get.');
+ existFull($input,['warehouse'])||$input['warehouse']=[];
+ if(is_array($input['warehouse'])){
+ $sql=fastSql($input,[
+ ['warehouse','fullIn'],
+ [['startTime'=>'time'],'startTime'],
+ [['endTime'=>'time'],'endTime']
+ ]);
+ $sql=sqlAuth('summary',$sql);
+ //商品信息扩展查询
+ if(existFull($input,['goods'])){
+ $goods=array_column(Db::name('goods')->where([['name|py','like','%'.$input['goods'].'%']])->select()->toArray(),'id');
+ $sql[]=['goods','in',$goods];
+ }
+ //子查询
+ $existsSql=[['id','=',Db::raw('summary.class')]];
+ $existsSql=frameScope($existsSql);
+ //多源匹配
+ $union=[];
+ //数据关系表
+ $table=['buy'=>'buy','bre'=>'bre','sell'=>'sell','sre'=>'sre','swapOut'=>'swap','swapEnter'=>'swap','entry'=>'entry','extry'=>'extry'];
+ foreach ($table as $k=>$v) {
+ $union[]=Db::name($v)->where([['summary.type','=',$k]])->where(array_merge($existsSql,sqlAuth($v,[])))->limit(1)->buildSql();
+ }
+ //合并子查询
+ $union=implode(' UNION ALL ',$union);
+ $record=Db::name('summary')->alias('summary')->where($sql)->whereExists($union)->order(['id'])->select()->toArray();
+ //分页数据
+ $count=Summary::where([['id','in',array_column($record,'id')]])->group(['goods','warehouse'])->count();
+ $data=Summary::with(['goodsData','warehouseData'])->where([['id','in',array_column($record,'id')]])->group(['goods','warehouse'])->order(['goods'])->select()->toArray();
+ foreach ($data as $key=>$vo) {
+ $data[$key]['unit']=$vo['goodsData']['unit']==-1?'多单位':$vo['goodsData']['unit'];
+ //期初
+ $scope=search($record)->where([['goods','=',$vo['goods']]])->select();
+ $state=Db::name('summary')->where([['id','<',$scope[0]['id']],['goods','=',$vo['goods']]])->order(['id'=>'DESC'])->find();
+ $state=empty($state)?['exist'=>[0,0,0,0],'balance'=>[0,0,0,0]]:['exist'=>json_decode($state['exist']),'balance'=>json_decode($state['balance'])];
+ $data[$key]['state']=[
+ 'uct'=>empty($state['exist'][0])?0:math()->chain($state['balance'][0])->div($state['exist'][0])->round(2)->done(),
+ 'uns'=>$vo['goodsData']['unit']==-1?unitSwitch($state['exist'][0],$vo['goodsData']['units']):$state['exist'][0],
+ 'bct'=>$state['balance'][0]
+ ];
+ $list=search($scope)->where([['goods','=',$vo['goods']],['warehouse','=',$vo['warehouse']]])->select();
+ foreach ($table as $t=>$m) {
+ $group=search($list)->where([['type','=',$t]])->select();
+ if(empty($group)){
+ $data[$key][$t]=['uct'=>'','uns'=>'','bct'=>''];
+ }else{
+ $uns=0;
+ $bct=0;
+ foreach ($group as $v) {
+ $uns=math()->chain($uns)->add($v['nums'])->done();
+ $bct=math()->chain($bct)->add($v['bct'])->done();
+ }
+ $data[$key][$t]=[
+ 'uct'=>math()->chain($bct)->div($uns)->round(2)->done(),
+ 'uns'=>$vo['goodsData']['unit']==-1?unitSwitch($uns,$vo['goodsData']['units']):$uns,
+ 'bct'=>$bct
+ ];
+ }
+ }
+ //汇总
+ $balance=$scope[count($scope)-1];
+ $balance=['exist'=>json_decode($balance['exist']),'balance'=>json_decode($balance['balance'])];
+ $sum=Db::name('summary')->where([['goods','=',$vo['goods']],['warehouse','=',$vo['warehouse']]])->order(['id'=>'desc'])->find();
+ $data[$key]['balance']=[];
+ $data[$key]['balance']['uct']=empty($balance['exist'][0])?0:math()->chain($balance['balance'][0])->div($balance['exist'][0])->round(2)->done();
+ $data[$key]['balance']['uns']=$vo['goodsData']['unit']==-1?unitSwitch(json_decode($sum['exist'])[1],$vo['goodsData']['units']):json_decode($sum['exist'])[1];
+ $data[$key]['balance']['bct']=math()->chain($data[$key]['balance']['uct'])->mul($data[$key]['balance']['uns'])->round(2)->done();
+ }
+ $source=$data;
+ //开始构造导出数据
+ $excel=[];//初始化导出数据
+ //标题数据
+ $excel[]=['type'=>'title','info'=>'商品收发汇总表'];
+ //表格数据
+ $field=[
+ 'goodsData|name'=>'商品名称',
+ 'warehouseData|name'=>'仓库',
+ 'unit'=>'单位',
+ 'state|uct'=>'期初成本',
+ 'state|uns'=>'期初数量',
+ 'state|bct'=>'期初成本',
+ 'buy|uct'=>'采购成本',
+ 'buy|uns'=>'采购数量',
+ 'buy|bct'=>'采购总成本',
+ 'bre|uct'=>'购退成本',
+ 'bre|uns'=>'购退数量',
+ 'bre|bct'=>'购退总成本',
+ 'sell|uct'=>'销售成本',
+ 'sell|uns'=>'销售数量',
+ 'sell|bct'=>'销售总成本',
+ 'sre|uct'=>'销退成本',
+ 'sre|uns'=>'销退数量',
+ 'sre|bct'=>'销退总成本',
+ 'swapOut|uct'=>'调出成本',
+ 'swapOut|uns'=>'调出数量',
+ 'swapOut|bct'=>'调出总成本',
+ 'swapEnter|uct'=>'调入成本',
+ 'swapEnter|uns'=>'调入数量',
+ 'swapEnter|bct'=>'调入总成本',
+ 'entry|uct'=>'其入成本',
+ 'entry|uns'=>'其入数量',
+ 'entry|bct'=>'其入总成本',
+ 'extry|uct'=>'其出成本',
+ 'extry|uns'=>'其出数量',
+ 'extry|bct'=>'其出总成本',
+ 'balance|uct'=>'汇总成本',
+ 'balance|uns'=>'汇总数量',
+ 'balance|bct'=>'汇总总成本'
+ ];
+ $thead=array_values($field);//表格标题
+ $tbody=[];//表格内容
+ //构造表内数据
+ foreach ($source as $sourceVo) {
+ $rowData=[];
+ foreach (array_keys($field) as $fieldVo) {
+ $rowData[]=arraySeek($sourceVo,$fieldVo);//多键名数据赋值
+ }
+ $tbody[]=$rowData;//加入行数据
+ }
+ $excel[]=['type'=>'table','info'=>['thead'=>$thead,'tbody'=>$tbody]];//表格数据
+ //汇总数据
+ $excel[]=['type'=>'node','info'=>[
+ '总数:'.count($source),
+ ]];
+ //导出execl
+ buildExcel('商品收发汇总表',$excel);
+ }else{
+ return json(['state'=>'error','info'=>'传入参数不完整!']);
+ }
+ }
+}
diff --git a/serve/app/event.php b/serve/app/event.php
new file mode 100644
index 0000000..e9851bb
--- /dev/null
+++ b/serve/app/event.php
@@ -0,0 +1,17 @@
+ [
+ ],
+
+ 'listen' => [
+ 'AppInit' => [],
+ 'HttpRun' => [],
+ 'HttpEnd' => [],
+ 'LogLevel' => [],
+ 'LogWrite' => [],
+ ],
+
+ 'subscribe' => [
+ ],
+];
diff --git a/serve/app/middleware.php b/serve/app/middleware.php
new file mode 100644
index 0000000..60b8c09
--- /dev/null
+++ b/serve/app/middleware.php
@@ -0,0 +1,5 @@
+domain();
+ header('Access-Control-Allow-Origin:'.$origin);
+ header('access-control-allow-credentials:true');
+ header('access-control-allow-methods:GET,POST,OPTIONS');
+ header('access-control-allow-headers:Accept,X-PINGARUNER,CONTENT-TYPE,X-Requested-With,Token');
+ return $request->isOptions()?response('Hello NodCloud',200):$next($request);
+ }
+}
\ No newline at end of file
diff --git a/serve/app/model/Account.php b/serve/app/model/Account.php
new file mode 100644
index 0000000..756a191
--- /dev/null
+++ b/serve/app/model/Account.php
@@ -0,0 +1,34 @@
+'timestamp:Y-m-d',
+ ];
+
+ //组织属性关联
+ public function frameData(){
+ return $this->hasOne(Frame::class,'id','frame');
+ }
+
+ //期初余额_读取器
+ public function getInitialAttr($val,$data){
+ return floatval($val);
+ }
+
+ //账户余额_读取器
+ public function getBalanceAttr($val,$data){
+ return floatval($val);
+ }
+
+ //数据扩展
+ public function getExtensionAttr($val,$data){
+ $source=[];
+ //实际余额
+ $source['money']=math()->chain($data['balance'])->add($data['initial'])->done();
+ return $source;
+ }
+}
diff --git a/serve/app/model/AccountInfo.php b/serve/app/model/AccountInfo.php
new file mode 100644
index 0000000..565607f
--- /dev/null
+++ b/serve/app/model/AccountInfo.php
@@ -0,0 +1,42 @@
+'timestamp:Y-m-d'
+ ];
+ //单据关联
+ public function sourceData(){
+ return $this->morphTo(['type','class'],[
+ 'buy'=>Buy::class,
+ 'bre'=>Bre::class,
+ 'sell'=>Sell::class,
+ 'sre'=>Sre::class,
+ 'vend'=>Vend::class,
+ 'vre'=>Vre::class,
+ 'imy'=>Imy::class,
+ 'omy'=>Omy::class,
+ 'allotOut'=>Allot::class,
+ 'allotEnter'=>Allot::class,
+ 'ice'=>Ice::class,
+ 'oce'=>Oce::class,
+ ]);
+ }
+
+ //金额_读取器
+ public function getMoneyAttr($val,$data){
+ return floatval($val);
+ }
+
+ //数据扩展
+ public function getExtensionAttr($val,$data){
+ $source=[];
+ //单据类型
+ $source['type']=['buy'=>'采购单', 'bre'=>'采购退货单', 'sell'=>'销售单', 'sre'=>'销售退货单', 'vend'=>'零售单', 'vre'=>'零售退货单', 'imy'=>'收款单', 'omy'=>'付款单', 'allotOut'=>'转账单-出', 'allotEnter'=>'转账单-入', 'ice'=>'其它收入单', 'oce'=>'其它支出单'][$data['type']];
+ //操作类型
+ $source['direction']=["减少","增加"][$data['direction']];
+
+ return $source;
+ }
+}
diff --git a/serve/app/model/Allot.php b/serve/app/model/Allot.php
new file mode 100644
index 0000000..cc96f79
--- /dev/null
+++ b/serve/app/model/Allot.php
@@ -0,0 +1,73 @@
+'timestamp:Y-m-d',
+ 'file'=>'json'
+ ];
+
+ //所属组织关联
+ public function frameData(){
+ return $this->hasOne(Frame::class,'id','frame');
+ }
+
+ //关联人员关联
+ public function peopleData(){
+ return $this->hasOne(People::class,'id','people')->field(['id','name']);
+ }
+
+ //制单人关联
+ public function userData(){
+ return $this->hasOne(User::class,'id','user')->field(['id','name']);
+ }
+
+ //记录关联
+ public function recordData(){
+ return $this->hasMany(Record::class,'source','id')->with(['userData'])->where([['type','=','allot']])->append(['extension'])->order('id desc');
+ }
+
+ //单据金额_读取器
+ public function getTotalAttr($val,$data){
+ return floatval($val);
+ }
+
+ //关联人员_设置器
+ public function setPeopleAttr($val){
+ return empty($val)?0:$val;
+ }
+
+ //关联人员_读取器
+ public function getPeopleAttr($val){
+ return empty($val)?null:$val;
+ }
+
+ //扩展信息_设置器
+ public function setMoreAttr($val){
+ //兼容Api|修复PHP空对象json编码为[]
+ return json_encode((object)$val);
+ }
+
+ //扩展信息_读取器
+ public function getMoreAttr($val){
+ return json_decode($val);
+ }
+
+ //数据扩展
+ public function getExtensionAttr($val,$data){
+ $source=[];
+ //审核状态
+ $source['examine']=[0=>'未审核',1=>'已审核'][$data['examine']];
+ return $source;
+ }
+
+ //EVENT|更新前
+ public static function onBeforeUpdate($model){
+ $source=$model::where([['id','=',$model['id']]])->find();
+ if(!empty($source['examine'])){
+ exit(json(['state'=>'error','info'=>'[ ERROR ] 单据已审核!'],200)->send());
+ }
+ }
+}
diff --git a/serve/app/model/AllotInfo.php b/serve/app/model/AllotInfo.php
new file mode 100644
index 0000000..9b0a7cb
--- /dev/null
+++ b/serve/app/model/AllotInfo.php
@@ -0,0 +1,42 @@
+hasOne(Account::class,'id','account');
+ }
+
+ //转入账户关联
+ public function tatData(){
+ return $this->hasOne(Account::class,'id','tat');
+ }
+
+ //转出账户_设置器
+ public function setAccountAttr($val,$data){
+ return empty($val)?0:$val;
+ }
+
+ //转出账户_读取器
+ public function getAccountAttr($val,$data){
+ return empty($val)?null:$val;
+ }
+
+ //转入账户_设置器
+ public function setTatAttr($val,$data){
+ return empty($val)?0:$val;
+ }
+
+ //转入账户_读取器
+ public function getTatAttr($val,$data){
+ return empty($val)?null:$val;
+ }
+
+ //结算金额_读取器
+ public function getMoneyAttr($val,$data){
+ return floatval($val);
+ }
+
+}
diff --git a/serve/app/model/Attr.php b/serve/app/model/Attr.php
new file mode 100644
index 0000000..8464a51
--- /dev/null
+++ b/serve/app/model/Attr.php
@@ -0,0 +1,21 @@
+hasMany(AttributeInfo::class,'pid','id')->visible(['name']);
+ }
+}
diff --git a/serve/app/model/AttributeInfo.php b/serve/app/model/AttributeInfo.php
new file mode 100644
index 0000000..6fe36e5
--- /dev/null
+++ b/serve/app/model/AttributeInfo.php
@@ -0,0 +1,7 @@
+'timestamp:Y-m-d'
+ ];
+
+ //库存数量_读取器
+ public function getNumsAttr($val,$data){
+ return floatval($val);
+ }
+}
diff --git a/serve/app/model/BatchInfo.php b/serve/app/model/BatchInfo.php
new file mode 100644
index 0000000..fc52fe4
--- /dev/null
+++ b/serve/app/model/BatchInfo.php
@@ -0,0 +1,43 @@
+'timestamp:Y-m-d'
+ ];
+
+ //单据关联
+ public function sourceData(){
+ return $this->morphTo(['type','class'],[
+ 'buy'=>Buy::class,
+ 'bre'=>Bre::class,
+ 'sell'=>Sell::class,
+ 'sre'=>Sre::class,
+ 'vend'=>Vend::class,
+ 'vre'=>Vre::class,
+ 'barter'=>Barter::class,
+ 'swapOut'=>Swap::class,
+ 'swapEnter'=>Swap::class,
+ 'entry'=>Entry::class,
+ 'extry'=>Extry::class,
+ ]);
+ }
+
+ //基础数量_读取器
+ public function getNumsAttr($val,$data){
+ return floatval($val);
+ }
+
+ //数据扩展
+ public function getExtensionAttr($val,$data){
+ $source=[];
+ //单据类型
+ $source['type']=["buy"=>"采购单","bre"=>"采购退货单","sell"=>"销售单","sre"=>"销售退货单","vend"=>"零售单","vre"=>"零售退货单","barter"=>"积分兑换单","swapOut"=>"调拨单-出","swapEnter"=>"调拨单-入","entry"=>"其它入库单","extry"=>"其它出库单"][$data['type']];
+ //操作类型
+ $source['direction']=["减少","增加"][$data['direction']];
+
+ return $source;
+ }
+}
diff --git a/serve/app/model/Bill.php b/serve/app/model/Bill.php
new file mode 100644
index 0000000..47ed7aa
--- /dev/null
+++ b/serve/app/model/Bill.php
@@ -0,0 +1,109 @@
+'timestamp:Y-m-d',
+ 'file'=>'json'
+ ];
+
+ //所属组织关联
+ public function frameData(){
+ return $this->hasOne(Frame::class,'id','frame');
+ }
+
+ //客户关联
+ public function customerData(){
+ return $this->hasOne(Customer::class,'id','customer')->append(['extension']);
+ }
+
+ //供应商关联
+ public function supplierData(){
+ return $this->hasOne(Supplier::class,'id','supplier')->append(['extension']);
+ }
+
+ //制单人关联
+ public function userData(){
+ return $this->hasOne(User::class,'id','user')->field(['id','name']);
+ }
+
+ //关联人员关联
+ public function peopleData(){
+ return $this->hasOne(People::class,'id','people')->field(['id','name']);
+ }
+
+ //记录关联
+ public function recordData(){
+ return $this->hasMany(Record::class,'source','id')->with(['userData'])->where([['type','=','bill']])->append(['extension'])->order('id desc');
+ }
+
+ //客户_设置器
+ public function setCustomerAttr($val){
+ return empty($val)?0:$val;
+ }
+
+ //客户_读取器
+ public function getCustomerAttr($val){
+ return empty($val)?null:$val;
+ }
+
+ //供应商_设置器
+ public function setSupplierAttr($val){
+ return empty($val)?0:$val;
+ }
+
+ //供应商_读取器
+ public function getSupplierAttr($val){
+ return empty($val)?null:$val;
+ }
+ //总核金额_读取器
+ public function getPmyAttr($val,$data){
+ return floatval($val);
+ }
+
+ //总销金额_读取器
+ public function getSmpAttr($val,$data){
+ return floatval($val);
+ }
+
+ //扩展信息_设置器
+ public function setMoreAttr($val){
+ //兼容Api|修复PHP空对象json编码为[]
+ return json_encode((object)$val);
+ }
+
+ //扩展信息_读取器
+ public function getMoreAttr($val){
+ return json_decode($val);
+ }
+
+ //关联人员_设置器
+ public function setPeopleAttr($val){
+ return empty($val)?0:$val;
+ }
+
+ //关联人员_读取器
+ public function getPeopleAttr($val){
+ return empty($val)?null:$val;
+ }
+
+ //数据扩展
+ public function getExtensionAttr($val,$data){
+ $source=[];
+ //核销类型
+ $source['type']=[0=>'预收冲应收',1=>'预付冲应付',2=>'应收冲应付',3=>'销退冲销售',4=>'购退冲采购'][$data['type']];
+ //审核状态
+ $source['examine']=[0=>'未审核',1=>'已审核'][$data['examine']];
+ return $source;
+ }
+
+ //EVENT|更新前
+ public static function onBeforeUpdate($model){
+ $source=$model::where([['id','=',$model['id']]])->find();
+ if(!empty($source['examine'])){
+ exit(json(['state'=>'error','info'=>'[ ERROR ] 单据已审核!'],200)->send());
+ }
+ }
+}
diff --git a/serve/app/model/BillInfo.php b/serve/app/model/BillInfo.php
new file mode 100644
index 0000000..f2739da
--- /dev/null
+++ b/serve/app/model/BillInfo.php
@@ -0,0 +1,35 @@
+morphTo(['mold','source'],[
+ 'imy' => Imy::class,
+ 'omy' => Omy::class,
+ 'buy' => Buy::class,
+ 'bre' => Bre::class,
+ 'sell' => Sell::class,
+ 'sre' => Sre::class,
+ 'ice' => Ice::class,
+ 'oce' => Oce::class,
+ ]);
+ }
+
+ //核销金额_读取器
+ public function getMoneyAttr($val,$data){
+ return floatval($val);
+ }
+
+ //数据扩展
+ public function getExtensionAttr($val,$data){
+ $source=[];
+ //核销类型
+ $source['bill']=['cia'=>'预收','pia'=>'预付','re'=>'应收','cw'=>'应付','sre'=>'销退','sell'=>'销售','bre'=>'购退','buy'=>'采购'][$data['bill']];
+ //单据类型
+ $source['mold']=['imy'=>'收款单','omy'=>'付款单','buy'=>'采购单','bre'=>'采购退货单','sell'=>'销售单','sre'=>'销售退货单','ice'=>'其它收入单','oce'=>'其它支出单'][$data['mold']];
+ return $source;
+ }
+}
diff --git a/serve/app/model/Bor.php b/serve/app/model/Bor.php
new file mode 100644
index 0000000..ba0028a
--- /dev/null
+++ b/serve/app/model/Bor.php
@@ -0,0 +1,96 @@
+'timestamp:Y-m-d',
+ 'arrival'=>'timestamp:Y-m-d',
+ 'logistics'=>'json',
+ 'file'=>'json'
+ ];
+
+ //所属组织关联
+ public function frameData(){
+ return $this->hasOne(Frame::class,'id','frame');
+ }
+
+ //供应商关联
+ public function supplierData(){
+ return $this->hasOne(Supplier::class,'id','supplier')->append(['extension']);
+ }
+
+ //关联人员关联
+ public function peopleData(){
+ return $this->hasOne(People::class,'id','people')->field(['id','name']);
+ }
+
+ //制单人关联
+ public function userData(){
+ return $this->hasOne(User::class,'id','user')->field(['id','name']);
+ }
+
+ //记录关联
+ public function recordData(){
+ return $this->hasMany(Record::class,'source','id')->with(['userData'])->where([['type','=','bor']])->append(['extension'])->order('id desc');
+ }
+
+ //单据金额_读取器
+ public function getTotalAttr($val,$data){
+ return floatval($val);
+ }
+
+ //实际金额_读取器
+ public function getActualAttr($val,$data){
+ return floatval($val);
+ }
+
+ //关联人员_设置器
+ public function setPeopleAttr($val){
+ return empty($val)?0:$val;
+ }
+
+ //关联人员_读取器
+ public function getPeopleAttr($val){
+ return empty($val)?null:$val;
+ }
+
+ //扩展信息_设置器
+ public function setMoreAttr($val){
+ //兼容Api|修复PHP空对象json编码为[]
+ return json_encode((object)$val);
+ }
+
+ //扩展信息_读取器
+ public function getMoreAttr($val){
+ return json_decode($val);
+ }
+
+ //数据扩展
+ public function getExtensionAttr($val,$data){
+ $source=[];
+ //物流信息
+ $logistics=json_decode($data['logistics'],true);
+ if(empty($logistics['key'])){
+ $source['logistics']='';
+ }elseif($logistics['key']=='auto'){
+ $source['logistics']=$logistics['number'];
+ }else{
+ $source['logistics']=$logistics['name'].'|'.$logistics['number'];
+ }
+ //审核状态
+ $source['examine']=[0=>'未审核',1=>'已审核'][$data['examine']];
+ //入库状态
+ $source['state']=[0=>'未入库',1=>'部分入库',2=>'已入库',3=>'关闭'][$data['state']];
+ return $source;
+ }
+
+ //EVENT|更新前
+ public static function onBeforeUpdate($model){
+ $source=$model::where([['id','=',$model['id']]])->find();
+ if(!empty($source['examine'])){
+ exit(json(['state'=>'error','info'=>'[ ERROR ] 单据已审核!'],200)->send());
+ }
+ }
+}
diff --git a/serve/app/model/BorInfo.php b/serve/app/model/BorInfo.php
new file mode 100644
index 0000000..29d74e0
--- /dev/null
+++ b/serve/app/model/BorInfo.php
@@ -0,0 +1,72 @@
+hasOne(Goods::class,'id','goods');
+ }
+
+ //仓库关联
+ public function warehouseData(){
+ return $this->hasOne(Warehouse::class,'id','warehouse');
+ }
+
+ //仓库_设置器
+ public function setWarehouseAttr($val,$data){
+ return empty($val)?0:$val;
+ }
+
+ //仓库_读取器
+ public function getWarehouseAttr($val,$data){
+ return empty($val)?null:$val;
+ }
+
+ //单价_读取器
+ public function getPriceAttr($val,$data){
+ return floatval($val);
+ }
+
+ //数量_读取器
+ public function getNumsAttr($val,$data){
+ return floatval($val);
+ }
+
+ //折扣率_读取器
+ public function getDiscountAttr($val,$data){
+ return floatval($val);
+ }
+
+ //折扣额_读取器
+ public function getDscAttr($val,$data){
+ return floatval($val);
+ }
+
+ //金额_读取器
+ public function getTotalAttr($val,$data){
+ return floatval($val);
+ }
+
+ //税率_读取器
+ public function getTaxAttr($val,$data){
+ return floatval($val);
+ }
+
+ //税额_读取器
+ public function getTatAttr($val,$data){
+ return floatval($val);
+ }
+
+ //价税合计_读取器
+ public function getTptAttr($val,$data){
+ return floatval($val);
+ }
+
+ //入库数量_读取器
+ public function getHandleAttr($val,$data){
+ return floatval($val);
+ }
+
+}
diff --git a/serve/app/model/Bre.php b/serve/app/model/Bre.php
new file mode 100644
index 0000000..ff0360c
--- /dev/null
+++ b/serve/app/model/Bre.php
@@ -0,0 +1,151 @@
+'timestamp:Y-m-d',
+ 'logistics'=>'json',
+ 'file'=>'json'
+ ];
+
+ //所属组织关联
+ public function frameData(){
+ return $this->hasOne(Frame::class,'id','frame');
+ }
+
+ //供应商关联
+ public function supplierData(){
+ return $this->hasOne(Supplier::class,'id','supplier')->append(['extension']);
+ }
+
+ //结算账户关联
+ public function accountData(){
+ return $this->hasOne(Account::class,'id','account');
+ }
+
+ //关联人员关联
+ public function peopleData(){
+ return $this->hasOne(People::class,'id','people')->field(['id','name']);
+ }
+
+ //制单人关联
+ public function userData(){
+ return $this->hasOne(User::class,'id','user')->field(['id','name']);
+ }
+
+ //核销关联
+ public function billData(){
+ return $this->hasMany(BreBill::class,'pid','id')->with(['sourceData'])->visible(['sourceData'=>['id','number']])->append(['extension'])->order('id desc');
+ }
+
+ //费用详情关联
+ public function costData(){
+ return $this->hasMany(Cost::class,'class','id')->with(['ietData'])->where([['type','=','bre']])->append(['extension'])->order('id desc');
+ }
+
+ //发票关联
+ public function invoiceData(){
+ return $this->hasMany(Invoice::class,'class','id')->where([['type','=','bre']])->order('id desc');
+ }
+
+ //记录关联
+ public function recordData(){
+ return $this->hasMany(Record::class,'source','id')->with(['userData'])->where([['type','=','bre']])->append(['extension'])->order('id desc');
+ }
+
+ //单据金额_读取器
+ public function getTotalAttr($val,$data){
+ return floatval($val);
+ }
+
+ //实际金额_读取器
+ public function getActualAttr($val,$data){
+ return floatval($val);
+ }
+
+ //实付金额_读取器
+ public function getMoneyAttr($val,$data){
+ return floatval($val);
+ }
+
+ //单据费用_读取器
+ public function getCostAttr($val,$data){
+ return floatval($val);
+ }
+
+ //结算账户_设置器
+ public function setAccountAttr($val,$data){
+ return empty($val)?0:$val;
+ }
+
+ //结算账户_读取器
+ public function getAccountAttr($val,$data){
+ return empty($val)?null:$val;
+ }
+
+ //关联人员_设置器
+ public function setPeopleAttr($val){
+ return empty($val)?0:$val;
+ }
+
+ //关联人员_读取器
+ public function getPeopleAttr($val){
+ return empty($val)?null:$val;
+ }
+
+ //扩展信息_设置器
+ public function setMoreAttr($val){
+ //兼容Api|修复PHP空对象json编码为[]
+ return json_encode((object)$val);
+ }
+
+ //扩展信息_读取器
+ public function getMoreAttr($val){
+ return json_decode($val);
+ }
+
+ //数据扩展
+ public function getExtensionAttr($val,$data){
+ $source=[];
+ //物流信息
+ $logistics=json_decode($data['logistics'],true);
+ if(empty($logistics['key'])){
+ $source['logistics']='';
+ }elseif($logistics['key']=='auto'){
+ $source['logistics']=$logistics['number'];
+ }else{
+ $source['logistics']=$logistics['name'].'|'.$logistics['number'];
+ }
+ //审核状态
+ $source['examine']=[0=>'未审核',1=>'已审核'][$data['examine']];
+ //核销状态
+ $source['nucleus']=[0=>'未核销',1=>'部分核销',2=>'已核销'][$data['nucleus']];
+ //费用状态
+ $source['cse']=[0=>'未结算',1=>'部分结算',2=>'已结算',3=>'无需结算'][$data['cse']];
+ //发票状态
+ $source['invoice']=[0=>'未开具',1=>'部分开具',2=>'已开具',3=>'无需开具'][$data['invoice']];
+ //核对状态
+ $source['check']=[0=>'未核对',1=>'已核对'][$data['check']];
+ //已核销金额
+ if($data['nucleus']==0){
+ $source['amount']=0;
+ }else if($data['nucleus']==1){
+ $source['amount']=db('bre_bill')->where([['pid','=',$data['id']]])->sum('money');
+ }else{
+ $source['amount']=floatval($data['actual']);
+ }
+ //未核销金额
+ $source['anwo']=math()->chain($data['actual'])->sub($source['amount'])->done();
+ return $source;
+ }
+
+ //EVENT|更新前
+ public static function onBeforeUpdate($model){
+ $source=$model::where([['id','=',$model['id']]])->find();
+ if(!empty($source['examine'])){
+ exit(json(['state'=>'error','info'=>'[ ERROR ] 单据已审核!'],200)->send());
+ }
+ }
+}
diff --git a/serve/app/model/BreBill.php b/serve/app/model/BreBill.php
new file mode 100644
index 0000000..25945e9
--- /dev/null
+++ b/serve/app/model/BreBill.php
@@ -0,0 +1,31 @@
+'timestamp:Y-m-d'
+ ];
+
+ //结算账户关联
+ public function sourceData(){
+ return $this->morphTo(['type','source'],[
+ 'bre' => Bre::class,
+ 'bill' => Bill::class
+ ]);
+ }
+
+ //核销金额_读取器
+ public function getMoneyAttr($val,$data){
+ return floatval($val);
+ }
+
+ //数据扩展
+ public function getExtensionAttr($val,$data){
+ $source=[];
+ //单据类型
+ $source['type']=['bre'=>'采购退货单','bill'=>'核销单'][$data['type']];
+ return $source;
+ }
+}
diff --git a/serve/app/model/BreInfo.php b/serve/app/model/BreInfo.php
new file mode 100644
index 0000000..35b81c7
--- /dev/null
+++ b/serve/app/model/BreInfo.php
@@ -0,0 +1,88 @@
+'json'
+ ];
+
+ //商品关联
+ public function goodsData(){
+ return $this->hasOne(Goods::class,'id','goods');
+ }
+
+ //仓库关联
+ public function warehouseData(){
+ return $this->hasOne(Warehouse::class,'id','warehouse');
+ }
+
+ //仓库_设置器
+ public function setWarehouseAttr($val,$data){
+ return empty($val)?0:$val;
+ }
+
+ //仓库_读取器
+ public function getWarehouseAttr($val,$data){
+ return empty($val)?null:$val;
+ }
+
+ //生产日期_设置器
+ public function setMfdAttr($val,$data){
+ return empty($val)?0:strtotime($val);
+ }
+
+ //生产日期_读取器
+ public function getMfdAttr($val,$data){
+ return empty($val)?'':date('Y-m-d',$val);
+ }
+
+ //单价_读取器
+ public function getPriceAttr($val,$data){
+ return floatval($val);
+ }
+
+ //数量_读取器
+ public function getNumsAttr($val,$data){
+ return floatval($val);
+ }
+
+ //折扣率_读取器
+ public function getDiscountAttr($val,$data){
+ return floatval($val);
+ }
+
+ //折扣额_读取器
+ public function getDscAttr($val,$data){
+ return floatval($val);
+ }
+
+ //金额_读取器
+ public function getTotalAttr($val,$data){
+ return floatval($val);
+ }
+
+ //税率_读取器
+ public function getTaxAttr($val,$data){
+ return floatval($val);
+ }
+
+ //税额_读取器
+ public function getTatAttr($val,$data){
+ return floatval($val);
+ }
+
+ //价税合计_读取器
+ public function getTptAttr($val,$data){
+ return floatval($val);
+ }
+
+ //数据扩展
+ public function getExtensionAttr($val,$data){
+ $source=[];
+ //序列号
+ $source['serial']=implode(',',json_decode($data['serial']));
+ return $source;
+ }
+}
diff --git a/serve/app/model/Buy.php b/serve/app/model/Buy.php
new file mode 100644
index 0000000..48708eb
--- /dev/null
+++ b/serve/app/model/Buy.php
@@ -0,0 +1,151 @@
+'timestamp:Y-m-d',
+ 'logistics'=>'json',
+ 'file'=>'json'
+ ];
+
+ //所属组织关联
+ public function frameData(){
+ return $this->hasOne(Frame::class,'id','frame');
+ }
+
+ //供应商关联
+ public function supplierData(){
+ return $this->hasOne(Supplier::class,'id','supplier')->append(['extension']);
+ }
+
+ //结算账户关联
+ public function accountData(){
+ return $this->hasOne(Account::class,'id','account');
+ }
+
+ //关联人员关联
+ public function peopleData(){
+ return $this->hasOne(People::class,'id','people')->field(['id','name']);
+ }
+
+ //制单人关联
+ public function userData(){
+ return $this->hasOne(User::class,'id','user')->field(['id','name']);
+ }
+
+ //核销关联
+ public function billData(){
+ return $this->hasMany(BuyBill::class,'pid','id')->with(['sourceData'])->visible(['sourceData'=>['id','number']])->append(['extension'])->order('id desc');
+ }
+
+ //费用详情关联
+ public function costData(){
+ return $this->hasMany(Cost::class,'class','id')->with(['ietData'])->where([['type','=','buy']])->append(['extension'])->order('id desc');
+ }
+
+ //发票关联
+ public function invoiceData(){
+ return $this->hasMany(Invoice::class,'class','id')->where([['type','=','buy']])->order('id desc');
+ }
+
+ //记录关联
+ public function recordData(){
+ return $this->hasMany(Record::class,'source','id')->with(['userData'])->where([['type','=','buy']])->append(['extension'])->order('id desc');
+ }
+
+ //单据金额_读取器
+ public function getTotalAttr($val,$data){
+ return floatval($val);
+ }
+
+ //实际金额_读取器
+ public function getActualAttr($val,$data){
+ return floatval($val);
+ }
+
+ //实付金额_读取器
+ public function getMoneyAttr($val,$data){
+ return floatval($val);
+ }
+
+ //单据费用_读取器
+ public function getCostAttr($val,$data){
+ return floatval($val);
+ }
+
+ //结算账户_设置器
+ public function setAccountAttr($val,$data){
+ return empty($val)?0:$val;
+ }
+
+ //结算账户_读取器
+ public function getAccountAttr($val,$data){
+ return empty($val)?null:$val;
+ }
+
+ //关联人员_设置器
+ public function setPeopleAttr($val){
+ return empty($val)?0:$val;
+ }
+
+ //关联人员_读取器
+ public function getPeopleAttr($val){
+ return empty($val)?null:$val;
+ }
+
+ //扩展信息_设置器
+ public function setMoreAttr($val){
+ //兼容Api|修复PHP空对象json编码为[]
+ return json_encode((object)$val);
+ }
+
+ //扩展信息_读取器
+ public function getMoreAttr($val){
+ return json_decode($val);
+ }
+
+ //数据扩展
+ public function getExtensionAttr($val,$data){
+ $source=[];
+ //物流信息
+ $logistics=json_decode($data['logistics'],true);
+ if(empty($logistics['key'])){
+ $source['logistics']='';
+ }elseif($logistics['key']=='auto'){
+ $source['logistics']=$logistics['number'];
+ }else{
+ $source['logistics']=$logistics['name'].'|'.$logistics['number'];
+ }
+ //审核状态
+ $source['examine']=[0=>'未审核',1=>'已审核'][$data['examine']];
+ //核销状态
+ $source['nucleus']=[0=>'未核销',1=>'部分核销',2=>'已核销'][$data['nucleus']];
+ //费用状态
+ $source['cse']=[0=>'未结算',1=>'部分结算',2=>'已结算',3=>'无需结算'][$data['cse']];
+ //发票状态
+ $source['invoice']=[0=>'未开具',1=>'部分开具',2=>'已开具',3=>'无需开具'][$data['invoice']];
+ //核对状态
+ $source['check']=[0=>'未核对',1=>'已核对'][$data['check']];
+ //已核销金额
+ if($data['nucleus']==0){
+ $source['amount']=0;
+ }else if($data['nucleus']==1){
+ $source['amount']=db('buy_bill')->where([['pid','=',$data['id']]])->sum('money');
+ }else{
+ $source['amount']=floatval($data['actual']);
+ }
+ //未核销金额
+ $source['anwo']=math()->chain($data['actual'])->sub($source['amount'])->done();
+ return $source;
+ }
+
+ //EVENT|更新前
+ public static function onBeforeUpdate($model){
+ $source=$model::where([['id','=',$model['id']]])->find();
+ if(!empty($source['examine'])){
+ exit(json(['state'=>'error','info'=>'[ ERROR ] 单据已审核!'],200)->send());
+ }
+ }
+}
diff --git a/serve/app/model/BuyBill.php b/serve/app/model/BuyBill.php
new file mode 100644
index 0000000..944b0b7
--- /dev/null
+++ b/serve/app/model/BuyBill.php
@@ -0,0 +1,31 @@
+'timestamp:Y-m-d'
+ ];
+
+ //核销单据关联
+ public function sourceData(){
+ return $this->morphTo(['type','source'],[
+ 'buy' => Buy::class,
+ 'bill' => Bill::class
+ ]);
+ }
+
+ //核销金额_读取器
+ public function getMoneyAttr($val,$data){
+ return floatval($val);
+ }
+
+ //数据扩展
+ public function getExtensionAttr($val,$data){
+ $source=[];
+ //单据类型
+ $source['type']=['buy'=>'采购单','bill'=>'核销单'][$data['type']];
+ return $source;
+ }
+}
diff --git a/serve/app/model/BuyInfo.php b/serve/app/model/BuyInfo.php
new file mode 100644
index 0000000..d538433
--- /dev/null
+++ b/serve/app/model/BuyInfo.php
@@ -0,0 +1,93 @@
+'json'
+ ];
+
+ //商品关联
+ public function goodsData(){
+ return $this->hasOne(Goods::class,'id','goods');
+ }
+
+ //仓库关联
+ public function warehouseData(){
+ return $this->hasOne(Warehouse::class,'id','warehouse');
+ }
+
+ //仓库_设置器
+ public function setWarehouseAttr($val,$data){
+ return empty($val)?0:$val;
+ }
+
+ //仓库_读取器
+ public function getWarehouseAttr($val,$data){
+ return empty($val)?null:$val;
+ }
+
+ //生产日期_设置器
+ public function setMfdAttr($val,$data){
+ return empty($val)?0:strtotime($val);
+ }
+
+ //生产日期_读取器
+ public function getMfdAttr($val,$data){
+ return empty($val)?'':date('Y-m-d',$val);
+ }
+
+ //单价_读取器
+ public function getPriceAttr($val,$data){
+ return floatval($val);
+ }
+
+ //数量_读取器
+ public function getNumsAttr($val,$data){
+ return floatval($val);
+ }
+
+ //折扣率_读取器
+ public function getDiscountAttr($val,$data){
+ return floatval($val);
+ }
+
+ //折扣额_读取器
+ public function getDscAttr($val,$data){
+ return floatval($val);
+ }
+
+ //金额_读取器
+ public function getTotalAttr($val,$data){
+ return floatval($val);
+ }
+
+ //税率_读取器
+ public function getTaxAttr($val,$data){
+ return floatval($val);
+ }
+
+ //税额_读取器
+ public function getTatAttr($val,$data){
+ return floatval($val);
+ }
+
+ //价税合计_读取器
+ public function getTptAttr($val,$data){
+ return floatval($val);
+ }
+
+ //退货数量_读取器
+ public function getRetreatAttr($val,$data){
+ return floatval($val);
+ }
+
+ //数据扩展
+ public function getExtensionAttr($val,$data){
+ $source=[];
+ //序列号
+ $source['serial']=implode(',',json_decode($data['serial']));
+ return $source;
+ }
+}
diff --git a/serve/app/model/Category.php b/serve/app/model/Category.php
new file mode 100644
index 0000000..d7da8bb
--- /dev/null
+++ b/serve/app/model/Category.php
@@ -0,0 +1,6 @@
+'条形码',1=>'二维码'][$data['type']];
+ return $source;
+ }
+}
diff --git a/serve/app/model/Cost.php b/serve/app/model/Cost.php
new file mode 100644
index 0000000..57cd0b0
--- /dev/null
+++ b/serve/app/model/Cost.php
@@ -0,0 +1,52 @@
+'timestamp:Y-m-d'
+ ];
+
+ //单据关联
+ public function sourceData(){
+ return $this->morphTo(['type','class'],[
+ 'buy' => Buy::class,
+ 'bre' => Bre::class,
+ 'sell' => Sell::class,
+ 'sre' => Sre::class,
+ 'vend' => Vend::class,
+ 'barter' => Barter::class,
+ 'vre' => Vre::class,
+ 'swap' => Swap::class,
+ 'entry' => Entry::class,
+ 'extry' => Extry::class
+
+ ]);
+ }
+
+ //收支关联
+ public function ietData(){
+ return $this->hasOne(Iet::class,'id','iet')->field(['id','name']);
+ }
+
+ //金额_读取器
+ public function getMoneyAttr($val,$data){
+ return floatval($val);
+ }
+
+ //结算金额_读取器
+ public function getSettleAttr($val,$data){
+ return floatval($val);
+ }
+
+ //数据扩展
+ public function getExtensionAttr($val,$data){
+ $source=[];
+ //单据类型
+ $source['type']=['buy'=>'采购单','bre'=>'采购退货单','sell'=>'销售单','sre'=>'销售退货单','vend'=>'零售单','vre'=>'零售退货单','barter'=>'积分兑换单','swap'=>'调拨单','entry'=>'其它入库单','extry'=>'其它出库单'][$data['type']];
+ //结算状态
+ $source['state']=[0=>'未结算',1=>'部分结算',2=>'已结算'][$data['state']];
+ return $source;
+ }
+}
diff --git a/serve/app/model/CostInfo.php b/serve/app/model/CostInfo.php
new file mode 100644
index 0000000..707a92e
--- /dev/null
+++ b/serve/app/model/CostInfo.php
@@ -0,0 +1,20 @@
+'timestamp:Y-m-d'
+ ];
+
+ //单据关联
+ public function oceData(){
+ return $this->hasOne(Oce::class,'id','oce');
+ }
+
+ //结算金额_读取器
+ public function getMoneyAttr($val,$data){
+ return floatval($val);
+ }
+}
diff --git a/serve/app/model/Customer.php b/serve/app/model/Customer.php
new file mode 100644
index 0000000..6eabd3a
--- /dev/null
+++ b/serve/app/model/Customer.php
@@ -0,0 +1,55 @@
+ 'json'
+ ];
+
+ //所属组织关联
+ public function frameData(){
+ return $this->hasOne(Frame::class,'id','frame');
+ }
+
+ //所属用户关联
+ public function userData(){
+ return $this->hasOne(User::class,'id','user')->field(['id','name']);
+ }
+
+ //应收款余额_读取器
+ public function getBalanceAttr($val,$data){
+ return floatval($val);
+ }
+
+ //客户积分_读取器
+ public function getIntegralAttr($val,$data){
+ return floatval($val);
+ }
+
+ //扩展信息_设置器
+ public function setMoreAttr($val){
+ //兼容Api|修复PHP空对象json编码为[]
+ return json_encode((object)$val);
+ }
+
+ //扩展信息_读取器
+ public function getMoreAttr($val){
+ return json_decode($val);
+ }
+
+ //数据扩展
+ public function getExtensionAttr($val,$data){
+ $source=[];
+ //主联系人
+ $contact=json_decode($data['contacts'],true);
+ if(empty($contact)){
+ $source['contact']='';
+ }else{
+ $find=search($contact)->where([['main','=',true]])->find();
+ $source['contact']=$find['name'].' | '.$find['tel'].' | '.$find['add'];
+ }
+ return $source;
+ }
+}
diff --git a/serve/app/model/Deploy.php b/serve/app/model/Deploy.php
new file mode 100644
index 0000000..1ab1f1b
--- /dev/null
+++ b/serve/app/model/Deploy.php
@@ -0,0 +1,15 @@
+ 'json'
+ ];
+
+ //组织属性关联
+ public function frameData(){
+ return $this->hasOne(Frame::class,'id','frame');
+ }
+}
diff --git a/serve/app/model/Entry.php b/serve/app/model/Entry.php
new file mode 100644
index 0000000..9015334
--- /dev/null
+++ b/serve/app/model/Entry.php
@@ -0,0 +1,114 @@
+'timestamp:Y-m-d',
+ 'logistics'=>'json',
+ 'file'=>'json'
+ ];
+
+ //所属组织关联
+ public function frameData(){
+ return $this->hasOne(Frame::class,'id','frame');
+ }
+
+ //关联人员关联
+ public function peopleData(){
+ return $this->hasOne(People::class,'id','people')->field(['id','name']);
+ }
+
+ //制单人关联
+ public function userData(){
+ return $this->hasOne(User::class,'id','user')->field(['id','name']);
+ }
+
+ //费用详情关联
+ public function costData(){
+ return $this->hasMany(Cost::class,'class','id')->with(['ietData'])->where([['type','=','entry']])->append(['extension'])->order('id desc');
+ }
+
+ //供应商关联
+ public function supplierData(){
+ return $this->hasOne(Supplier::class,'id','supplier')->append(['extension']);
+ }
+
+ //记录关联
+ public function recordData(){
+ return $this->hasMany(Record::class,'source','id')->with(['userData'])->where([['type','=','entry']])->append(['extension'])->order('id desc');
+ }
+
+ //单据成本_读取器
+ public function getTotalAttr($val,$data){
+ return floatval($val);
+ }
+
+ //单据费用_读取器
+ public function getCostAttr($val,$data){
+ return floatval($val);
+ }
+
+ //关联人员_设置器
+ public function setPeopleAttr($val){
+ return empty($val)?0:$val;
+ }
+
+ //关联人员_读取器
+ public function getPeopleAttr($val){
+ return empty($val)?null:$val;
+ }
+
+ //供应商_设置器
+ public function setSupplierAttr($val){
+ return empty($val)?0:$val;
+ }
+
+ //供应商_读取器
+ public function getSupplierAttr($val){
+ return empty($val)?null:$val;
+ }
+
+ //扩展信息_设置器
+ public function setMoreAttr($val){
+ //兼容Api|修复PHP空对象json编码为[]
+ return json_encode((object)$val);
+ }
+
+ //扩展信息_读取器
+ public function getMoreAttr($val){
+ return json_decode($val);
+ }
+
+ //数据扩展
+ public function getExtensionAttr($val,$data){
+ $source=[];
+ //单据类型
+ $source['type']=[0=>'其它入库单',1=>'盘盈单'][$data['type']];
+ //物流信息
+ $logistics=json_decode($data['logistics'],true);
+ if(empty($logistics['key'])){
+ $source['logistics']='';
+ }elseif($logistics['key']=='auto'){
+ $source['logistics']=$logistics['number'];
+ }else{
+ $source['logistics']=$logistics['name'].'|'.$logistics['number'];
+ }
+ //费用状态
+ $source['cse']=[0=>'未结算',1=>'部分结算',2=>'已结算',3=>'无需结算'][$data['cse']];
+ //审核状态
+ $source['examine']=[0=>'未审核',1=>'已审核'][$data['examine']];
+ //核对状态
+ $source['check']=[0=>'未核对',1=>'已核对'][$data['check']];
+ return $source;
+ }
+
+ //EVENT|更新前
+ public static function onBeforeUpdate($model){
+ $source=$model::where([['id','=',$model['id']]])->find();
+ if(!empty($source['examine'])){
+ exit(json(['state'=>'error','info'=>'[ ERROR ] 单据已审核!'],200)->send());
+ }
+ }
+}
diff --git a/serve/app/model/EntryInfo.php b/serve/app/model/EntryInfo.php
new file mode 100644
index 0000000..cb51deb
--- /dev/null
+++ b/serve/app/model/EntryInfo.php
@@ -0,0 +1,63 @@
+'json'
+ ];
+
+ //商品关联
+ public function goodsData(){
+ return $this->hasOne(Goods::class,'id','goods');
+ }
+
+ //仓库关联
+ public function warehouseData(){
+ return $this->hasOne(Warehouse::class,'id','warehouse');
+ }
+
+ //仓库_设置器
+ public function setWarehouseAttr($val,$data){
+ return empty($val)?0:$val;
+ }
+
+ //仓库_读取器
+ public function getWarehouseAttr($val,$data){
+ return empty($val)?null:$val;
+ }
+
+ //生产日期_设置器
+ public function setMfdAttr($val,$data){
+ return empty($val)?0:strtotime($val);
+ }
+
+ //生产日期_读取器
+ public function getMfdAttr($val,$data){
+ return empty($val)?'':date('Y-m-d',$val);
+ }
+
+ //成本_读取器
+ public function getPriceAttr($val,$data){
+ return floatval($val);
+ }
+
+ //数量_读取器
+ public function getNumsAttr($val,$data){
+ return floatval($val);
+ }
+
+ //总成本_读取器
+ public function getTotalAttr($val,$data){
+ return floatval($val);
+ }
+
+ //数据扩展
+ public function getExtensionAttr($val,$data){
+ $source=[];
+ //序列号
+ $source['serial']=implode(',',json_decode($data['serial']));
+ return $source;
+ }
+}
diff --git a/serve/app/model/Extry.php b/serve/app/model/Extry.php
new file mode 100644
index 0000000..234fb83
--- /dev/null
+++ b/serve/app/model/Extry.php
@@ -0,0 +1,114 @@
+'timestamp:Y-m-d',
+ 'logistics'=>'json',
+ 'file'=>'json'
+ ];
+
+ //所属组织关联
+ public function frameData(){
+ return $this->hasOne(Frame::class,'id','frame');
+ }
+
+ //关联人员关联
+ public function peopleData(){
+ return $this->hasOne(People::class,'id','people')->field(['id','name']);
+ }
+
+ //制单人关联
+ public function userData(){
+ return $this->hasOne(User::class,'id','user')->field(['id','name']);
+ }
+
+ //费用详情关联
+ public function costData(){
+ return $this->hasMany(Cost::class,'class','id')->with(['ietData'])->where([['type','=','extry']])->append(['extension'])->order('id desc');
+ }
+
+ //记录关联
+ public function recordData(){
+ return $this->hasMany(Record::class,'source','id')->with(['userData'])->where([['type','=','extry']])->append(['extension'])->order('id desc');
+ }
+
+ //客户关联
+ public function customerData(){
+ return $this->hasOne(Customer::class,'id','customer')->append(['extension']);
+ }
+
+ //单据成本_读取器
+ public function getTotalAttr($val,$data){
+ return floatval($val);
+ }
+
+ //单据费用_读取器
+ public function getCostAttr($val,$data){
+ return floatval($val);
+ }
+
+ //关联人员_设置器
+ public function setPeopleAttr($val){
+ return empty($val)?0:$val;
+ }
+
+ //关联人员_读取器
+ public function getPeopleAttr($val){
+ return empty($val)?null:$val;
+ }
+
+ //客户_设置器
+ public function setCustomerAttr($val){
+ return empty($val)?0:$val;
+ }
+
+ //客户_读取器
+ public function getCustomerAttr($val){
+ return empty($val)?null:$val;
+ }
+
+ //扩展信息_设置器
+ public function setMoreAttr($val){
+ //兼容Api|修复PHP空对象json编码为[]
+ return json_encode((object)$val);
+ }
+
+ //扩展信息_读取器
+ public function getMoreAttr($val){
+ return json_decode($val);
+ }
+
+ //数据扩展
+ public function getExtensionAttr($val,$data){
+ $source=[];
+ //单据类型
+ $source['type']=[0=>'其它出库单',1=>'盘亏单'][$data['type']];
+ //物流信息
+ $logistics=json_decode($data['logistics'],true);
+ if(empty($logistics['key'])){
+ $source['logistics']='';
+ }elseif($logistics['key']=='auto'){
+ $source['logistics']=$logistics['number'];
+ }else{
+ $source['logistics']=$logistics['name'].'|'.$logistics['number'];
+ }
+ //费用状态
+ $source['cse']=[0=>'未结算',1=>'部分结算',2=>'已结算',3=>'无需结算'][$data['cse']];
+ //审核状态
+ $source['examine']=[0=>'未审核',1=>'已审核'][$data['examine']];
+ //核对状态
+ $source['check']=[0=>'未核对',1=>'已核对'][$data['check']];
+ return $source;
+ }
+
+ //EVENT|更新前
+ public static function onBeforeUpdate($model){
+ $source=$model::where([['id','=',$model['id']]])->find();
+ if(!empty($source['examine'])){
+ exit(json(['state'=>'error','info'=>'[ ERROR ] 单据已审核!'],200)->send());
+ }
+ }
+}
diff --git a/serve/app/model/ExtryInfo.php b/serve/app/model/ExtryInfo.php
new file mode 100644
index 0000000..6e0a925
--- /dev/null
+++ b/serve/app/model/ExtryInfo.php
@@ -0,0 +1,63 @@
+'json'
+ ];
+
+ //商品关联
+ public function goodsData(){
+ return $this->hasOne(Goods::class,'id','goods');
+ }
+
+ //仓库关联
+ public function warehouseData(){
+ return $this->hasOne(Warehouse::class,'id','warehouse');
+ }
+
+ //仓库_设置器
+ public function setWarehouseAttr($val,$data){
+ return empty($val)?0:$val;
+ }
+
+ //仓库_读取器
+ public function getWarehouseAttr($val,$data){
+ return empty($val)?null:$val;
+ }
+
+ //生产日期_设置器
+ public function setMfdAttr($val,$data){
+ return empty($val)?0:strtotime($val);
+ }
+
+ //生产日期_读取器
+ public function getMfdAttr($val,$data){
+ return empty($val)?'':date('Y-m-d',$val);
+ }
+
+ //成本_读取器
+ public function getPriceAttr($val,$data){
+ return floatval($val);
+ }
+
+ //数量_读取器
+ public function getNumsAttr($val,$data){
+ return floatval($val);
+ }
+
+ //总成本_读取器
+ public function getTotalAttr($val,$data){
+ return floatval($val);
+ }
+
+ //数据扩展
+ public function getExtensionAttr($val,$data){
+ $source=[];
+ //序列号
+ $source['serial']=implode(',',json_decode($data['serial']));
+ return $source;
+ }
+}
diff --git a/serve/app/model/Field.php b/serve/app/model/Field.php
new file mode 100644
index 0000000..541dceb
--- /dev/null
+++ b/serve/app/model/Field.php
@@ -0,0 +1,21 @@
+ 'json'
+ ];
+
+
+
+ //数据扩展
+ public function getExtensionAttr($val,$data){
+ $source=[];
+ //模块标识
+ $source['key']=["user"=>"用户管理","people"=>"人员管理","customer"=>"客户管理","supplier"=>"供应商管理","goods"=>"商品管理","bor"=>"采购订单","buy"=>"采购单","bre"=>"采购退货单","sor"=>"销售订单","sell"=>"销售单","sre"=>"销售退货单","vend"=>"零售单","vre"=>"零售退货单","barter"=>"积分兑换单","swap"=>"调拨单","entry"=>"其它入库单","extry"=>"其它出库单","imy"=>"收款单","omy"=>"付款单","bill"=>"核销单","allot"=>"转账单","ice"=>"其它收入单","oce"=>"其它支出单"][$data['key']];
+ return $source;
+ }
+}
diff --git a/serve/app/model/Frame.php b/serve/app/model/Frame.php
new file mode 100644
index 0000000..685fb70
--- /dev/null
+++ b/serve/app/model/Frame.php
@@ -0,0 +1,6 @@
+ 'json',
+ 'units' => 'json',
+ 'strategy' => 'json',
+ 'serial' => 'boolean',
+ 'batch' => 'boolean',
+ 'validity' => 'boolean'
+ ];
+
+ //商品类别关联
+ public function categoryData(){
+ return $this->hasOne(Category::class,'id','category');
+ }
+
+ //辅助属性关联
+ public function attr(){
+ return $this->hasMany(Attr::class,'pid','id');
+ }
+
+ //采购价格_读取器
+ public function getBuyAttr($val,$data){
+ return floatval($val);
+ }
+
+ //销售价格_读取器
+ public function getSellAttr($val,$data){
+ return floatval($val);
+ }
+
+ //零售价格_读取器
+ public function getRetailAttr($val,$data){
+ return floatval($val);
+ }
+
+ //兑换积分_读取器
+ public function getIntegralAttr($val,$data){
+ return floatval($val);
+ }
+
+ //库存阈值_读取器
+ public function getStockAttr($val,$data){
+ return floatval($val);
+ }
+
+ //扩展信息_设置器
+ public function setMoreAttr($val){
+ //兼容Api|修复PHP空对象json编码为[]
+ return json_encode((object)$val);
+ }
+
+ //扩展信息_读取器
+ public function getMoreAttr($val){
+ return json_decode($val);
+ }
+
+ //数据扩展
+ public function getExtensionAttr($val,$data){
+ $source=[];
+ //商品单位
+ $source['unit']=$data['unit']==-1?'多单位':$data['unit'];
+ //商品类型
+ $source['type']=[0=>'常规商品',1=>'服务商品'][$data['type']];
+ return $source;
+ }
+}
diff --git a/serve/app/model/Ice.php b/serve/app/model/Ice.php
new file mode 100644
index 0000000..99fc9d2
--- /dev/null
+++ b/serve/app/model/Ice.php
@@ -0,0 +1,130 @@
+'timestamp:Y-m-d',
+ 'file'=>'json'
+ ];
+
+ //所属组织关联
+ public function frameData(){
+ return $this->hasOne(Frame::class,'id','frame');
+ }
+
+ //客户关联
+ public function customerData(){
+ return $this->hasOne(Customer::class,'id','customer')->append(['extension']);
+ }
+
+ //资金账户关联
+ public function accountData(){
+ return $this->hasOne(Account::class,'id','account')->field(['id','name']);
+ }
+
+ //关联人员关联
+ public function peopleData(){
+ return $this->hasOne(People::class,'id','people')->field(['id','name']);
+ }
+
+ //制单人关联
+ public function userData(){
+ return $this->hasOne(User::class,'id','user')->field(['id','name']);
+ }
+
+ //核销关联
+ public function billData(){
+ return $this->hasMany(IceBill::class,'pid','id')->with(['sourceData'])->visible(['sourceData'=>['id','number']])->append(['extension'])->order('id desc');
+ }
+
+ //记录关联
+ public function recordData(){
+ return $this->hasMany(Record::class,'source','id')->with(['userData'])->where([['type','=','ice']])->append(['extension'])->order('id desc');
+ }
+
+ //单据金额_读取器
+ public function getTotalAttr($val,$data){
+ return floatval($val);
+ }
+
+ //实际金额_读取器
+ public function getActualAttr($val,$data){
+ return floatval($val);
+ }
+
+ //实收金额_读取器
+ public function getMoneyAttr($val,$data){
+ return floatval($val);
+ }
+
+ //结算账户_设置器
+ public function setAccountAttr($val,$data){
+ return empty($val)?0:$val;
+ }
+
+ //结算账户_读取器
+ public function getAccountAttr($val,$data){
+ return empty($val)?null:$val;
+ }
+
+ //关联人员_设置器
+ public function setPeopleAttr($val){
+ return empty($val)?0:$val;
+ }
+
+ //关联人员_读取器
+ public function getPeopleAttr($val){
+ return empty($val)?null:$val;
+ }
+
+ //客户_设置器
+ public function setCustomerAttr($val){
+ return empty($val)?0:$val;
+ }
+
+ //客户_读取器
+ public function getCustomerAttr($val){
+ return empty($val)?null:$val;
+ }
+
+ //扩展信息_设置器
+ public function setMoreAttr($val){
+ //兼容Api|修复PHP空对象json编码为[]
+ return json_encode((object)$val);
+ }
+
+ //扩展信息_读取器
+ public function getMoreAttr($val){
+ return json_decode($val);
+ }
+
+ //数据扩展
+ public function getExtensionAttr($val,$data){
+ $source=[];
+ //审核状态
+ $source['examine']=[0=>'未审核',1=>'已审核'][$data['examine']];
+ //核销状态
+ $source['nucleus']=[0=>'未核销',1=>'部分核销',2=>'已核销'][$data['nucleus']];
+ //已核销金额
+ if($data['nucleus']==0){
+ $source['amount']=0;
+ }else if($data['nucleus']==1){
+ $source['amount']=db('ice_bill')->where([['pid','=',$data['id']]])->sum('money');
+ }else{
+ $source['amount']=floatval($data['actual']);
+ }
+ //未核销金额
+ $source['anwo']=math()->chain($data['actual'])->sub($source['amount'])->done();
+ return $source;
+ }
+
+ //EVENT|更新前
+ public static function onBeforeUpdate($model){
+ $source=$model::where([['id','=',$model['id']]])->find();
+ if(!empty($source['examine'])){
+ exit(json(['state'=>'error','info'=>'[ ERROR ] 单据已审核!'],200)->send());
+ }
+ }
+}
diff --git a/serve/app/model/IceBill.php b/serve/app/model/IceBill.php
new file mode 100644
index 0000000..912cef9
--- /dev/null
+++ b/serve/app/model/IceBill.php
@@ -0,0 +1,31 @@
+'timestamp:Y-m-d'
+ ];
+
+ //关联单据
+ public function sourceData(){
+ return $this->morphTo(['type','source'],[
+ 'ice' => Ice::class,
+ 'bill' => Bill::class
+ ]);
+ }
+
+ //核销金额_读取器
+ public function getMoneyAttr($val,$data){
+ return floatval($val);
+ }
+
+ //数据扩展
+ public function getExtensionAttr($val,$data){
+ $source=[];
+ //单据类型
+ $source['type']=['ice'=>'其它收入单','bill'=>'核销单'][$data['type']];
+ return $source;
+ }
+}
diff --git a/serve/app/model/IceInfo.php b/serve/app/model/IceInfo.php
new file mode 100644
index 0000000..afcabcd
--- /dev/null
+++ b/serve/app/model/IceInfo.php
@@ -0,0 +1,32 @@
+hasOne(Iet::class,'id','iet');
+ }
+
+ //所属组织关联
+ public function frameData(){
+ return $this->hasOne(Frame::class,'id','frame');
+ }
+
+ //结算账户_设置器
+ public function setAccountAttr($val,$data){
+ return empty($val)?0:$val;
+ }
+
+ //结算账户_读取器
+ public function getAccountAttr($val,$data){
+ return empty($val)?null:$val;
+ }
+
+ //结算金额_读取器
+ public function getMoneyAttr($val,$data){
+ return floatval($val);
+ }
+
+}
diff --git a/serve/app/model/Iet.php b/serve/app/model/Iet.php
new file mode 100644
index 0000000..763abe6
--- /dev/null
+++ b/serve/app/model/Iet.php
@@ -0,0 +1,14 @@
+'收入',1=>'支出'][$data['type']];
+ return $source;
+ }
+}
diff --git a/serve/app/model/Imy.php b/serve/app/model/Imy.php
new file mode 100644
index 0000000..9787cd7
--- /dev/null
+++ b/serve/app/model/Imy.php
@@ -0,0 +1,95 @@
+'timestamp:Y-m-d',
+ 'file'=>'json'
+ ];
+
+ //所属组织关联
+ public function frameData(){
+ return $this->hasOne(Frame::class,'id','frame');
+ }
+
+ //客户关联
+ public function customerData(){
+ return $this->hasOne(Customer::class,'id','customer')->append(['extension']);
+ }
+
+ //关联人员关联
+ public function peopleData(){
+ return $this->hasOne(People::class,'id','people')->field(['id','name']);
+ }
+
+ //制单人关联
+ public function userData(){
+ return $this->hasOne(User::class,'id','user')->field(['id','name']);
+ }
+
+ //核销关联
+ public function billData(){
+ return $this->hasMany(ImyBill::class,'pid','id')->with(['sourceData'])->visible(['sourceData'=>['id','number']])->append(['extension'])->order('id desc');
+ }
+
+ //记录关联
+ public function recordData(){
+ return $this->hasMany(Record::class,'source','id')->with(['userData'])->where([['type','=','imy']])->append(['extension'])->order('id desc');
+ }
+
+ //单据金额_读取器
+ public function getTotalAttr($val,$data){
+ return floatval($val);
+ }
+
+ //关联人员_设置器
+ public function setPeopleAttr($val){
+ return empty($val)?0:$val;
+ }
+
+ //关联人员_读取器
+ public function getPeopleAttr($val){
+ return empty($val)?null:$val;
+ }
+
+ //扩展信息_设置器
+ public function setMoreAttr($val){
+ //兼容Api|修复PHP空对象json编码为[]
+ return json_encode((object)$val);
+ }
+
+ //扩展信息_读取器
+ public function getMoreAttr($val){
+ return json_decode($val);
+ }
+
+ //数据扩展
+ public function getExtensionAttr($val,$data){
+ $source=[];
+ //审核状态
+ $source['examine']=[0=>'未审核',1=>'已审核'][$data['examine']];
+ //核销状态
+ $source['nucleus']=[0=>'未核销',1=>'部分核销',2=>'已核销'][$data['nucleus']];
+ //已核销金额
+ if($data['nucleus']==0){
+ $source['amount']=0;
+ }else if($data['nucleus']==1){
+ $source['amount']=db('imy_bill')->where([['pid','=',$data['id']]])->sum('money');
+ }else{
+ $source['amount']=floatval($data['total']);
+ }
+ //未核销金额
+ $source['anwo']=math()->chain($data['total'])->sub($source['amount'])->done();
+ return $source;
+ }
+
+ //EVENT|更新前
+ public static function onBeforeUpdate($model){
+ $source=$model::where([['id','=',$model['id']]])->find();
+ if(!empty($source['examine'])){
+ exit(json(['state'=>'error','info'=>'[ ERROR ] 单据已审核!'],200)->send());
+ }
+ }
+}
diff --git a/serve/app/model/ImyBill.php b/serve/app/model/ImyBill.php
new file mode 100644
index 0000000..5d493d7
--- /dev/null
+++ b/serve/app/model/ImyBill.php
@@ -0,0 +1,28 @@
+'timestamp:Y-m-d'
+ ];
+
+ //关联单据
+ public function sourceData(){
+ return $this->hasOne(Bill::class,'id','source');
+ }
+
+ //核销金额_读取器
+ public function getMoneyAttr($val,$data){
+ return floatval($val);
+ }
+
+ //数据扩展
+ public function getExtensionAttr($val,$data){
+ $source=[];
+ //单据类型
+ $source['type']='核销单';
+ return $source;
+ }
+}
diff --git a/serve/app/model/ImyInfo.php b/serve/app/model/ImyInfo.php
new file mode 100644
index 0000000..2e82fca
--- /dev/null
+++ b/serve/app/model/ImyInfo.php
@@ -0,0 +1,27 @@
+hasOne(Account::class,'id','account');
+ }
+
+ //结算账户_设置器
+ public function setAccountAttr($val,$data){
+ return empty($val)?0:$val;
+ }
+
+ //结算账户_读取器
+ public function getAccountAttr($val,$data){
+ return empty($val)?null:$val;
+ }
+
+ //结算金额_读取器
+ public function getMoneyAttr($val,$data){
+ return floatval($val);
+ }
+
+}
diff --git a/serve/app/model/Invoice.php b/serve/app/model/Invoice.php
new file mode 100644
index 0000000..5498063
--- /dev/null
+++ b/serve/app/model/Invoice.php
@@ -0,0 +1,29 @@
+'timestamp:Y-m-d',
+ 'file'=>'json'
+ ];
+
+ //单据关联
+ public function sourceData(){
+ return $this->morphTo(['type','class'],[
+ 'buy' => Buy::class,
+ 'bre' => Bre::class,
+ 'sell' => Sell::class,
+ 'sre' => Sre::class,
+ 'vend' => Vend::class,
+ 'vre' => Vre::class
+ ]);
+ }
+
+
+ //开票金额_读取器
+ public function getMoneyAttr($val,$data){
+ return floatval($val);
+ }
+}
diff --git a/serve/app/model/Log.php b/serve/app/model/Log.php
new file mode 100644
index 0000000..060b08e
--- /dev/null
+++ b/serve/app/model/Log.php
@@ -0,0 +1,17 @@
+'timestamp:Y-m-d H:i:s',
+ ];
+
+ //用户属性关联
+ public function userData(){
+ return $this->hasOne(User::class,'id','user')->field(['id','name']);
+ }
+
+}
diff --git a/serve/app/model/Menu.php b/serve/app/model/Menu.php
new file mode 100644
index 0000000..23f2e09
--- /dev/null
+++ b/serve/app/model/Menu.php
@@ -0,0 +1,16 @@
+'标签模式',1=>'新页模式'][$data['model']];
+ //菜单类型
+ $source['type']=[0=>'独立菜单',1=>'附属菜单'][$data['type']];
+ return $source;
+ }
+}
diff --git a/serve/app/model/Mould.php b/serve/app/model/Mould.php
new file mode 100644
index 0000000..8d9d449
--- /dev/null
+++ b/serve/app/model/Mould.php
@@ -0,0 +1,10 @@
+ 'json'
+ ];
+}
diff --git a/serve/app/model/Oce.php b/serve/app/model/Oce.php
new file mode 100644
index 0000000..10ae6d2
--- /dev/null
+++ b/serve/app/model/Oce.php
@@ -0,0 +1,130 @@
+'timestamp:Y-m-d',
+ 'file'=>'json'
+ ];
+
+ //所属组织关联
+ public function frameData(){
+ return $this->hasOne(Frame::class,'id','frame');
+ }
+
+ //供应商关联
+ public function supplierData(){
+ return $this->hasOne(Supplier::class,'id','supplier')->append(['extension']);
+ }
+
+ //资金账户关联
+ public function accountData(){
+ return $this->hasOne(Account::class,'id','account')->field(['id','name']);
+ }
+
+ //关联人员关联
+ public function peopleData(){
+ return $this->hasOne(People::class,'id','people')->field(['id','name']);
+ }
+
+ //制单人关联
+ public function userData(){
+ return $this->hasOne(User::class,'id','user')->field(['id','name']);
+ }
+
+ //核销关联
+ public function billData(){
+ return $this->hasMany(OceBill::class,'pid','id')->with(['sourceData'])->visible(['sourceData'=>['id','number']])->append(['extension'])->order('id desc');
+ }
+
+ //记录关联
+ public function recordData(){
+ return $this->hasMany(Record::class,'source','id')->with(['userData'])->where([['type','=','oce']])->append(['extension'])->order('id desc');
+ }
+
+ //单据金额_读取器
+ public function getTotalAttr($val,$data){
+ return floatval($val);
+ }
+
+ //实际金额_读取器
+ public function getActualAttr($val,$data){
+ return floatval($val);
+ }
+
+ //实付金额_读取器
+ public function getMoneyAttr($val,$data){
+ return floatval($val);
+ }
+
+ //结算账户_设置器
+ public function setAccountAttr($val,$data){
+ return empty($val)?0:$val;
+ }
+
+ //结算账户_读取器
+ public function getAccountAttr($val,$data){
+ return empty($val)?null:$val;
+ }
+
+ //关联人员_设置器
+ public function setPeopleAttr($val){
+ return empty($val)?0:$val;
+ }
+
+ //关联人员_读取器
+ public function getPeopleAttr($val){
+ return empty($val)?null:$val;
+ }
+
+ //供应商_设置器
+ public function setSupplierAttr($val){
+ return empty($val)?0:$val;
+ }
+
+ //供应商_读取器
+ public function getSupplierAttr($val){
+ return empty($val)?null:$val;
+ }
+
+ //扩展信息_设置器
+ public function setMoreAttr($val){
+ //兼容Api|修复PHP空对象json编码为[]
+ return json_encode((object)$val);
+ }
+
+ //扩展信息_读取器
+ public function getMoreAttr($val){
+ return json_decode($val);
+ }
+
+ //数据扩展
+ public function getExtensionAttr($val,$data){
+ $source=[];
+ //审核状态
+ $source['examine']=[0=>'未审核',1=>'已审核'][$data['examine']];
+ //核销状态
+ $source['nucleus']=[0=>'未核销',1=>'部分核销',2=>'已核销'][$data['nucleus']];
+ //已核销金额
+ if($data['nucleus']==0){
+ $source['amount']=0;
+ }else if($data['nucleus']==1){
+ $source['amount']=db('oce_bill')->where([['pid','=',$data['id']]])->sum('money');
+ }else{
+ $source['amount']=floatval($data['actual']);
+ }
+ //未核销金额
+ $source['anwo']=math()->chain($data['actual'])->sub($source['amount'])->done();
+ return $source;
+ }
+
+ //EVENT|更新前
+ public static function onBeforeUpdate($model){
+ $source=$model::where([['id','=',$model['id']]])->find();
+ if(!empty($source['examine'])){
+ exit(json(['state'=>'error','info'=>'[ ERROR ] 单据已审核!'],200)->send());
+ }
+ }
+}
diff --git a/serve/app/model/OceBill.php b/serve/app/model/OceBill.php
new file mode 100644
index 0000000..14e1bce
--- /dev/null
+++ b/serve/app/model/OceBill.php
@@ -0,0 +1,31 @@
+'timestamp:Y-m-d'
+ ];
+
+ //关联单据
+ public function sourceData(){
+ return $this->morphTo(['type','source'],[
+ 'oce' => Oce::class,
+ 'bill' => Bill::class
+ ]);
+ }
+
+ //核销金额_读取器
+ public function getMoneyAttr($val,$data){
+ return floatval($val);
+ }
+
+ //数据扩展
+ public function getExtensionAttr($val,$data){
+ $source=[];
+ //单据类型
+ $source['type']=['oce'=>'其它支出单','bill'=>'核销单'][$data['type']];
+ return $source;
+ }
+}
diff --git a/serve/app/model/OceInfo.php b/serve/app/model/OceInfo.php
new file mode 100644
index 0000000..77269ed
--- /dev/null
+++ b/serve/app/model/OceInfo.php
@@ -0,0 +1,32 @@
+hasOne(Iet::class,'id','iet');
+ }
+
+ //所属组织关联
+ public function frameData(){
+ return $this->hasOne(Frame::class,'id','frame');
+ }
+
+ //结算账户_设置器
+ public function setAccountAttr($val,$data){
+ return empty($val)?0:$val;
+ }
+
+ //结算账户_读取器
+ public function getAccountAttr($val,$data){
+ return empty($val)?null:$val;
+ }
+
+ //结算金额_读取器
+ public function getMoneyAttr($val,$data){
+ return floatval($val);
+ }
+
+}
diff --git a/serve/app/model/Omy.php b/serve/app/model/Omy.php
new file mode 100644
index 0000000..2fb8611
--- /dev/null
+++ b/serve/app/model/Omy.php
@@ -0,0 +1,95 @@
+'timestamp:Y-m-d',
+ 'file'=>'json'
+ ];
+
+ //所属组织关联
+ public function frameData(){
+ return $this->hasOne(Frame::class,'id','frame');
+ }
+
+ //供应商关联
+ public function supplierData(){
+ return $this->hasOne(Supplier::class,'id','supplier')->append(['extension']);
+ }
+
+ //关联人员关联
+ public function peopleData(){
+ return $this->hasOne(People::class,'id','people')->field(['id','name']);
+ }
+
+ //制单人关联
+ public function userData(){
+ return $this->hasOne(User::class,'id','user')->field(['id','name']);
+ }
+
+ //核销关联
+ public function billData(){
+ return $this->hasMany(OmyBill::class,'pid','id')->with(['sourceData'])->visible(['sourceData'=>['id','number']])->append(['extension'])->order('id desc');
+ }
+
+ //记录关联
+ public function recordData(){
+ return $this->hasMany(Record::class,'source','id')->with(['userData'])->where([['type','=','omy']])->append(['extension'])->order('id desc');
+ }
+
+ //单据金额_读取器
+ public function getTotalAttr($val,$data){
+ return floatval($val);
+ }
+
+ //关联人员_设置器
+ public function setPeopleAttr($val){
+ return empty($val)?0:$val;
+ }
+
+ //关联人员_读取器
+ public function getPeopleAttr($val){
+ return empty($val)?null:$val;
+ }
+
+ //扩展信息_设置器
+ public function setMoreAttr($val){
+ //兼容Api|修复PHP空对象json编码为[]
+ return json_encode((object)$val);
+ }
+
+ //扩展信息_读取器
+ public function getMoreAttr($val){
+ return json_decode($val);
+ }
+
+ //数据扩展
+ public function getExtensionAttr($val,$data){
+ $source=[];
+ //审核状态
+ $source['examine']=[0=>'未审核',1=>'已审核'][$data['examine']];
+ //核销状态
+ $source['nucleus']=[0=>'未核销',1=>'部分核销',2=>'已核销'][$data['nucleus']];
+ //已核销金额
+ if($data['nucleus']==0){
+ $source['amount']=0;
+ }else if($data['nucleus']==1){
+ $source['amount']=db('omy_bill')->where([['pid','=',$data['id']]])->sum('money');
+ }else{
+ $source['amount']=floatval($data['total']);
+ }
+ //未核销金额
+ $source['anwo']=math()->chain($data['total'])->sub($source['amount'])->done();
+ return $source;
+ }
+
+ //EVENT|更新前
+ public static function onBeforeUpdate($model){
+ $source=$model::where([['id','=',$model['id']]])->find();
+ if(!empty($source['examine'])){
+ exit(json(['state'=>'error','info'=>'[ ERROR ] 单据已审核!'],200)->send());
+ }
+ }
+}
diff --git a/serve/app/model/OmyBill.php b/serve/app/model/OmyBill.php
new file mode 100644
index 0000000..d281750
--- /dev/null
+++ b/serve/app/model/OmyBill.php
@@ -0,0 +1,28 @@
+'timestamp:Y-m-d'
+ ];
+
+ //关联单据
+ public function sourceData(){
+ return $this->hasOne(Bill::class,'id','source');
+ }
+
+ //核销金额_读取器
+ public function getMoneyAttr($val,$data){
+ return floatval($val);
+ }
+
+ //数据扩展
+ public function getExtensionAttr($val,$data){
+ $source=[];
+ //单据类型
+ $source['type']='核销单';
+ return $source;
+ }
+}
diff --git a/serve/app/model/OmyInfo.php b/serve/app/model/OmyInfo.php
new file mode 100644
index 0000000..ac376b6
--- /dev/null
+++ b/serve/app/model/OmyInfo.php
@@ -0,0 +1,27 @@
+hasOne(Account::class,'id','account');
+ }
+
+ //结算账户_设置器
+ public function setAccountAttr($val,$data){
+ return empty($val)?0:$val;
+ }
+
+ //结算账户_读取器
+ public function getAccountAttr($val,$data){
+ return empty($val)?null:$val;
+ }
+
+ //结算金额_读取器
+ public function getMoneyAttr($val,$data){
+ return floatval($val);
+ }
+
+}
diff --git a/serve/app/model/People.php b/serve/app/model/People.php
new file mode 100644
index 0000000..55fda9f
--- /dev/null
+++ b/serve/app/model/People.php
@@ -0,0 +1,48 @@
+ 'json'
+ ];
+
+ //所属组织关联
+ public function frameData(){
+ return $this->hasOne(Frame::class,'id','frame');
+ }
+
+ //所属用户关联
+ public function userData(){
+ return $this->hasOne(User::class,'id','user')->field(['id','name']);
+ }
+
+ //应收款余额_读取器
+ public function getBalanceAttr($val,$data){
+ return floatval($val);
+ }
+
+ //客户积分_读取器
+ public function getIntegralAttr($val,$data){
+ return floatval($val);
+ }
+
+ //扩展信息_设置器
+ public function setMoreAttr($val){
+ //兼容Api|修复PHP空对象json编码为[]
+ return json_encode((object)$val);
+ }
+
+ //扩展信息_读取器
+ public function getMoreAttr($val){
+ return json_decode($val);
+ }
+
+ //数据扩展
+ public function getExtensionAttr($val,$data){
+ $source=[];
+ $source['sex']=[0=>'女',1=>'男'][$data['sex']];
+ return $source;
+ }
+}
diff --git a/serve/app/model/Period.php b/serve/app/model/Period.php
new file mode 100644
index 0000000..eb8c004
--- /dev/null
+++ b/serve/app/model/Period.php
@@ -0,0 +1,18 @@
+'timestamp:Y-m-d',
+ 'time'=>'timestamp:Y-m-d',
+ ];
+
+ //用户属性关联
+ public function userData(){
+ return $this->hasOne(User::class,'id','user')->field(['id','name']);
+ }
+
+}
diff --git a/serve/app/model/Record.php b/serve/app/model/Record.php
new file mode 100644
index 0000000..3bf1016
--- /dev/null
+++ b/serve/app/model/Record.php
@@ -0,0 +1,19 @@
+hasOne(User::class,'id','user')->field(['id','name']);
+ }
+
+ //数据扩展
+ public function getExtensionAttr($val,$data){
+ $source=[];
+ //时间文本
+ $source['time']=date('Y-m-d H:i',$data['time']);
+ return $source;
+ }
+}
diff --git a/serve/app/model/Role.php b/serve/app/model/Role.php
new file mode 100644
index 0000000..207ec08
--- /dev/null
+++ b/serve/app/model/Role.php
@@ -0,0 +1,10 @@
+ 'json',
+ 'auth' => 'json'
+ ];
+}
diff --git a/serve/app/model/RoomInfo.php b/serve/app/model/RoomInfo.php
new file mode 100644
index 0000000..8516b33
--- /dev/null
+++ b/serve/app/model/RoomInfo.php
@@ -0,0 +1,48 @@
+'timestamp:Y-m-d'
+ ];
+
+ //单据关联
+ public function sourceData(){
+ return $this->morphTo(['type','class'],[
+ 'buy'=>Buy::class,
+ 'bre'=>Bre::class,
+ 'sell'=>Sell::class,
+ 'sre'=>Sre::class,
+ 'vend'=>Vend::class,
+ 'vre'=>Vre::class,
+ 'barter'=>Barter::class,
+ 'swapOut'=>Swap::class,
+ 'swapEnter'=>Swap::class,
+ 'entry'=>Entry::class,
+ 'extry'=>Extry::class,
+ ]);
+ }
+
+ //基础单价_读取器
+ public function getPriceAttr($val,$data){
+ return floatval($val);
+ }
+
+ //基础数量_读取器
+ public function getNumsAttr($val,$data){
+ return floatval($val);
+ }
+
+ //数据扩展
+ public function getExtensionAttr($val,$data){
+ $source=[];
+ //单据类型
+ $source['type']=["buy"=>"采购单","bre"=>"采购退货单","sell"=>"销售单","sre"=>"销售退货单","vend"=>"零售单","vre"=>"零售退货单","barter"=>"积分兑换单","swapOut"=>"调拨单-出","swapEnter"=>"调拨单-入","entry"=>"其它入库单","extry"=>"其它出库单"][$data['type']];
+ //操作类型
+ $source['direction']=["减少","增加"][$data['direction']];
+
+ return $source;
+ }
+}
diff --git a/serve/app/model/Sell.php b/serve/app/model/Sell.php
new file mode 100644
index 0000000..f0f0768
--- /dev/null
+++ b/serve/app/model/Sell.php
@@ -0,0 +1,151 @@
+'timestamp:Y-m-d',
+ 'logistics'=>'json',
+ 'file'=>'json'
+ ];
+
+ //所属组织关联
+ public function frameData(){
+ return $this->hasOne(Frame::class,'id','frame');
+ }
+
+ //客户关联
+ public function customerData(){
+ return $this->hasOne(Customer::class,'id','customer')->append(['extension']);
+ }
+
+ //结算账户关联
+ public function accountData(){
+ return $this->hasOne(Account::class,'id','account');
+ }
+
+ //关联人员关联
+ public function peopleData(){
+ return $this->hasOne(People::class,'id','people')->field(['id','name']);
+ }
+
+ //制单人关联
+ public function userData(){
+ return $this->hasOne(User::class,'id','user')->field(['id','name']);
+ }
+
+ //核销关联
+ public function billData(){
+ return $this->hasMany(SellBill::class,'pid','id')->with(['sourceData'])->visible(['sourceData'=>['id','number']])->append(['extension'])->order('id desc');
+ }
+
+ //费用详情关联
+ public function costData(){
+ return $this->hasMany(Cost::class,'class','id')->with(['ietData'])->where([['type','=','sell']])->append(['extension'])->order('id desc');
+ }
+
+ //发票关联
+ public function invoiceData(){
+ return $this->hasMany(Invoice::class,'class','id')->where([['type','=','sell']])->order('id desc');
+ }
+
+ //记录关联
+ public function recordData(){
+ return $this->hasMany(Record::class,'source','id')->with(['userData'])->where([['type','=','sell']])->append(['extension'])->order('id desc');
+ }
+
+ //单据金额_读取器
+ public function getTotalAttr($val,$data){
+ return floatval($val);
+ }
+
+ //实际金额_读取器
+ public function getActualAttr($val,$data){
+ return floatval($val);
+ }
+
+ //实收金额_读取器
+ public function getMoneyAttr($val,$data){
+ return floatval($val);
+ }
+
+ //单据费用_读取器
+ public function getCostAttr($val,$data){
+ return floatval($val);
+ }
+
+ //结算账户_设置器
+ public function setAccountAttr($val,$data){
+ return empty($val)?0:$val;
+ }
+
+ //结算账户_读取器
+ public function getAccountAttr($val,$data){
+ return empty($val)?null:$val;
+ }
+
+ //关联人员_设置器
+ public function setPeopleAttr($val){
+ return empty($val)?0:$val;
+ }
+
+ //关联人员_读取器
+ public function getPeopleAttr($val){
+ return empty($val)?null:$val;
+ }
+
+ //扩展信息_设置器
+ public function setMoreAttr($val){
+ //兼容Api|修复PHP空对象json编码为[]
+ return json_encode((object)$val);
+ }
+
+ //扩展信息_读取器
+ public function getMoreAttr($val){
+ return json_decode($val);
+ }
+
+ //数据扩展
+ public function getExtensionAttr($val,$data){
+ $source=[];
+ //物流信息
+ $logistics=json_decode($data['logistics'],true);
+ if(empty($logistics['key'])){
+ $source['logistics']='';
+ }elseif($logistics['key']=='auto'){
+ $source['logistics']=$logistics['number'];
+ }else{
+ $source['logistics']=$logistics['name'].'|'.$logistics['number'];
+ }
+ //审核状态
+ $source['examine']=[0=>'未审核',1=>'已审核'][$data['examine']];
+ //核销状态
+ $source['nucleus']=[0=>'未核销',1=>'部分核销',2=>'已核销'][$data['nucleus']];
+ //费用状态
+ $source['cse']=[0=>'未结算',1=>'部分结算',2=>'已结算',3=>'无需结算'][$data['cse']];
+ //发票状态
+ $source['invoice']=[0=>'未开具',1=>'部分开具',2=>'已开具',3=>'无需开具'][$data['invoice']];
+ //核对状态
+ $source['check']=[0=>'未核对',1=>'已核对'][$data['check']];
+ //已核销金额
+ if($data['nucleus']==0){
+ $source['amount']=0;
+ }else if($data['nucleus']==1){
+ $source['amount']=db('sell_bill')->where([['pid','=',$data['id']]])->sum('money');
+ }else{
+ $source['amount']=floatval($data['actual']);
+ }
+ //未核销金额
+ $source['anwo']=math()->chain($data['actual'])->sub($source['amount'])->done();
+ return $source;
+ }
+
+ //EVENT|更新前
+ public static function onBeforeUpdate($model){
+ $source=$model::where([['id','=',$model['id']]])->find();
+ if(!empty($source['examine'])){
+ exit(json(['state'=>'error','info'=>'[ ERROR ] 单据已审核!'],200)->send());
+ }
+ }
+}
diff --git a/serve/app/model/SellBill.php b/serve/app/model/SellBill.php
new file mode 100644
index 0000000..5437376
--- /dev/null
+++ b/serve/app/model/SellBill.php
@@ -0,0 +1,31 @@
+'timestamp:Y-m-d'
+ ];
+
+ //关联单据
+ public function sourceData(){
+ return $this->morphTo(['type','source'],[
+ 'sell' => Sell::class,
+ 'bill' => Bill::class
+ ]);
+ }
+
+ //核销金额_读取器
+ public function getMoneyAttr($val,$data){
+ return floatval($val);
+ }
+
+ //数据扩展
+ public function getExtensionAttr($val,$data){
+ $source=[];
+ //单据类型
+ $source['type']=['sell'=>'销售单','bill'=>'核销单'][$data['type']];
+ return $source;
+ }
+}
diff --git a/serve/app/model/SellInfo.php b/serve/app/model/SellInfo.php
new file mode 100644
index 0000000..58f1a7b
--- /dev/null
+++ b/serve/app/model/SellInfo.php
@@ -0,0 +1,93 @@
+'json'
+ ];
+
+ //商品关联
+ public function goodsData(){
+ return $this->hasOne(Goods::class,'id','goods');
+ }
+
+ //仓库关联
+ public function warehouseData(){
+ return $this->hasOne(Warehouse::class,'id','warehouse');
+ }
+
+ //仓库_设置器
+ public function setWarehouseAttr($val,$data){
+ return empty($val)?0:$val;
+ }
+
+ //仓库_读取器
+ public function getWarehouseAttr($val,$data){
+ return empty($val)?null:$val;
+ }
+
+ //生产日期_设置器
+ public function setMfdAttr($val,$data){
+ return empty($val)?0:strtotime($val);
+ }
+
+ //生产日期_读取器
+ public function getMfdAttr($val,$data){
+ return empty($val)?'':date('Y-m-d',$val);
+ }
+
+ //单价_读取器
+ public function getPriceAttr($val,$data){
+ return floatval($val);
+ }
+
+ //数量_读取器
+ public function getNumsAttr($val,$data){
+ return floatval($val);
+ }
+
+ //折扣率_读取器
+ public function getDiscountAttr($val,$data){
+ return floatval($val);
+ }
+
+ //折扣额_读取器
+ public function getDscAttr($val,$data){
+ return floatval($val);
+ }
+
+ //金额_读取器
+ public function getTotalAttr($val,$data){
+ return floatval($val);
+ }
+
+ //税率_读取器
+ public function getTaxAttr($val,$data){
+ return floatval($val);
+ }
+
+ //税额_读取器
+ public function getTatAttr($val,$data){
+ return floatval($val);
+ }
+
+ //价税合计_读取器
+ public function getTptAttr($val,$data){
+ return floatval($val);
+ }
+
+ //退货数量_读取器
+ public function getRetreatAttr($val,$data){
+ return floatval($val);
+ }
+
+ //数据扩展
+ public function getExtensionAttr($val,$data){
+ $source=[];
+ //序列号
+ $source['serial']=implode(',',json_decode($data['serial']));
+ return $source;
+ }
+}
diff --git a/serve/app/model/Serial.php b/serve/app/model/Serial.php
new file mode 100644
index 0000000..43118b7
--- /dev/null
+++ b/serve/app/model/Serial.php
@@ -0,0 +1,14 @@
+'未销售',1=>'已销售',2=>'已调拨',3=>'已退货'][$data['state']];
+ return $source;
+ }
+}
diff --git a/serve/app/model/SerialInfo.php b/serve/app/model/SerialInfo.php
new file mode 100644
index 0000000..b63884a
--- /dev/null
+++ b/serve/app/model/SerialInfo.php
@@ -0,0 +1,31 @@
+morphTo(['type','class'],[
+ 'buy'=>Buy::class,
+ 'bre'=>Bre::class,
+ 'sell'=>Sell::class,
+ 'sre'=>Sre::class,
+ 'vend'=>Vend::class,
+ 'vre'=>Vre::class,
+ 'barter'=>Barter::class,
+ 'swapOut'=>Swap::class,
+ 'swapEnter'=>Swap::class,
+ 'entry'=>Entry::class,
+ 'extry'=>Extry::class,
+ ]);
+ }
+
+ //数据扩展
+ public function getExtensionAttr($val,$data){
+ $source=[];
+ //单据类型
+ $source['type']=["buy"=>"采购单","bre"=>"采购退货单","sell"=>"销售单","sre"=>"销售退货单","vend"=>"零售单","vre"=>"零售退货单","barter"=>"积分兑换单","swapOut"=>"调拨单-出","swapEnter"=>"调拨单-入","entry"=>"其它入库单","extry"=>"其它出库单"][$data['type']];
+ return $source;
+ }
+}
diff --git a/serve/app/model/Sor.php b/serve/app/model/Sor.php
new file mode 100644
index 0000000..a522d5e
--- /dev/null
+++ b/serve/app/model/Sor.php
@@ -0,0 +1,96 @@
+'timestamp:Y-m-d',
+ 'arrival'=>'timestamp:Y-m-d',
+ 'logistics'=>'json',
+ 'file'=>'json'
+ ];
+
+ //所属组织关联
+ public function frameData(){
+ return $this->hasOne(Frame::class,'id','frame');
+ }
+
+ //客户关联
+ public function customerData(){
+ return $this->hasOne(Customer::class,'id','customer')->append(['extension']);
+ }
+
+ //关联人员关联
+ public function peopleData(){
+ return $this->hasOne(People::class,'id','people')->field(['id','name']);
+ }
+
+ //制单人关联
+ public function userData(){
+ return $this->hasOne(User::class,'id','user')->field(['id','name']);
+ }
+
+ //记录关联
+ public function recordData(){
+ return $this->hasMany(Record::class,'source','id')->with(['userData'])->where([['type','=','sor']])->append(['extension'])->order('id desc');
+ }
+
+ //单据金额_读取器
+ public function getTotalAttr($val,$data){
+ return floatval($val);
+ }
+
+ //实际金额_读取器
+ public function getActualAttr($val,$data){
+ return floatval($val);
+ }
+
+ //关联人员_设置器
+ public function setPeopleAttr($val){
+ return empty($val)?0:$val;
+ }
+
+ //关联人员_读取器
+ public function getPeopleAttr($val){
+ return empty($val)?null:$val;
+ }
+
+ //扩展信息_设置器
+ public function setMoreAttr($val){
+ //兼容Api|修复PHP空对象json编码为[]
+ return json_encode((object)$val);
+ }
+
+ //扩展信息_读取器
+ public function getMoreAttr($val){
+ return json_decode($val);
+ }
+
+ //数据扩展
+ public function getExtensionAttr($val,$data){
+ $source=[];
+ //物流信息
+ $logistics=json_decode($data['logistics'],true);
+ if(empty($logistics['key'])){
+ $source['logistics']='';
+ }elseif($logistics['key']=='auto'){
+ $source['logistics']=$logistics['number'];
+ }else{
+ $source['logistics']=$logistics['name'].'|'.$logistics['number'];
+ }
+ //审核状态
+ $source['examine']=[0=>'未审核',1=>'已审核'][$data['examine']];
+ //出库状态
+ $source['state']=[0=>'未出库',1=>'部分出库',2=>'已出库',3=>'关闭'][$data['state']];
+ return $source;
+ }
+
+ //EVENT|更新前
+ public static function onBeforeUpdate($model){
+ $source=$model::where([['id','=',$model['id']]])->find();
+ if(!empty($source['examine'])){
+ exit(json(['state'=>'error','info'=>'[ ERROR ] 单据已审核!'],200)->send());
+ }
+ }
+}
diff --git a/serve/app/model/SorInfo.php b/serve/app/model/SorInfo.php
new file mode 100644
index 0000000..be9f714
--- /dev/null
+++ b/serve/app/model/SorInfo.php
@@ -0,0 +1,72 @@
+hasOne(Goods::class,'id','goods');
+ }
+
+ //仓库关联
+ public function warehouseData(){
+ return $this->hasOne(Warehouse::class,'id','warehouse');
+ }
+
+ //仓库_设置器
+ public function setWarehouseAttr($val,$data){
+ return empty($val)?0:$val;
+ }
+
+ //仓库_读取器
+ public function getWarehouseAttr($val,$data){
+ return empty($val)?null:$val;
+ }
+
+ //单价_读取器
+ public function getPriceAttr($val,$data){
+ return floatval($val);
+ }
+
+ //数量_读取器
+ public function getNumsAttr($val,$data){
+ return floatval($val);
+ }
+
+ //折扣率_读取器
+ public function getDiscountAttr($val,$data){
+ return floatval($val);
+ }
+
+ //折扣额_读取器
+ public function getDscAttr($val,$data){
+ return floatval($val);
+ }
+
+ //金额_读取器
+ public function getTotalAttr($val,$data){
+ return floatval($val);
+ }
+
+ //税率_读取器
+ public function getTaxAttr($val,$data){
+ return floatval($val);
+ }
+
+ //税额_读取器
+ public function getTatAttr($val,$data){
+ return floatval($val);
+ }
+
+ //价税合计_读取器
+ public function getTptAttr($val,$data){
+ return floatval($val);
+ }
+
+ //出库数量_读取器
+ public function getHandleAttr($val,$data){
+ return floatval($val);
+ }
+
+}
diff --git a/serve/app/model/Sre.php b/serve/app/model/Sre.php
new file mode 100644
index 0000000..aac8169
--- /dev/null
+++ b/serve/app/model/Sre.php
@@ -0,0 +1,151 @@
+'timestamp:Y-m-d',
+ 'logistics'=>'json',
+ 'file'=>'json'
+ ];
+
+ //所属组织关联
+ public function frameData(){
+ return $this->hasOne(Frame::class,'id','frame');
+ }
+
+ //客户关联
+ public function customerData(){
+ return $this->hasOne(Customer::class,'id','customer')->append(['extension']);
+ }
+
+ //结算账户关联
+ public function accountData(){
+ return $this->hasOne(Account::class,'id','account');
+ }
+
+ //关联人员关联
+ public function peopleData(){
+ return $this->hasOne(People::class,'id','people')->field(['id','name']);
+ }
+
+ //制单人关联
+ public function userData(){
+ return $this->hasOne(User::class,'id','user')->field(['id','name']);
+ }
+
+ //核销关联
+ public function billData(){
+ return $this->hasMany(SreBill::class,'pid','id')->with(['sourceData'])->visible(['sourceData'=>['id','number']])->append(['extension'])->order('id desc');
+ }
+
+ //费用详情关联
+ public function costData(){
+ return $this->hasMany(Cost::class,'class','id')->with(['ietData'])->where([['type','=','sre']])->append(['extension'])->order('id desc');
+ }
+
+ //发票关联
+ public function invoiceData(){
+ return $this->hasMany(Invoice::class,'class','id')->where([['type','=','bre']])->order('id desc');
+ }
+
+ //记录关联
+ public function recordData(){
+ return $this->hasMany(Record::class,'source','id')->with(['userData'])->where([['type','=','sre']])->append(['extension'])->order('id desc');
+ }
+
+ //单据金额_读取器
+ public function getTotalAttr($val,$data){
+ return floatval($val);
+ }
+
+ //实际金额_读取器
+ public function getActualAttr($val,$data){
+ return floatval($val);
+ }
+
+ //实付金额_读取器
+ public function getMoneyAttr($val,$data){
+ return floatval($val);
+ }
+
+ //单据费用_读取器
+ public function getCostAttr($val,$data){
+ return floatval($val);
+ }
+
+ //结算账户_设置器
+ public function setAccountAttr($val,$data){
+ return empty($val)?0:$val;
+ }
+
+ //结算账户_读取器
+ public function getAccountAttr($val,$data){
+ return empty($val)?null:$val;
+ }
+
+ //关联人员_设置器
+ public function setPeopleAttr($val){
+ return empty($val)?0:$val;
+ }
+
+ //关联人员_读取器
+ public function getPeopleAttr($val){
+ return empty($val)?null:$val;
+ }
+
+ //扩展信息_设置器
+ public function setMoreAttr($val){
+ //兼容Api|修复PHP空对象json编码为[]
+ return json_encode((object)$val);
+ }
+
+ //扩展信息_读取器
+ public function getMoreAttr($val){
+ return json_decode($val);
+ }
+
+ //数据扩展
+ public function getExtensionAttr($val,$data){
+ $source=[];
+ //物流信息
+ $logistics=json_decode($data['logistics'],true);
+ if(empty($logistics['key'])){
+ $source['logistics']='';
+ }elseif($logistics['key']=='auto'){
+ $source['logistics']=$logistics['number'];
+ }else{
+ $source['logistics']=$logistics['name'].'|'.$logistics['number'];
+ }
+ //审核状态
+ $source['examine']=[0=>'未审核',1=>'已审核'][$data['examine']];
+ //核销状态
+ $source['nucleus']=[0=>'未核销',1=>'部分核销',2=>'已核销'][$data['nucleus']];
+ //费用状态
+ $source['cse']=[0=>'未结算',1=>'部分结算',2=>'已结算',3=>'无需结算'][$data['cse']];
+ //发票状态
+ $source['invoice']=[0=>'未开具',1=>'部分开具',2=>'已开具',3=>'无需开具'][$data['invoice']];
+ //核对状态
+ $source['check']=[0=>'未核对',1=>'已核对'][$data['check']];
+ //已核销金额
+ if($data['nucleus']==0){
+ $source['amount']=0;
+ }else if($data['nucleus']==1){
+ $source['amount']=db('sre_bill')->where([['pid','=',$data['id']]])->sum('money');
+ }else{
+ $source['amount']=floatval($data['actual']);
+ }
+ //未核销金额
+ $source['anwo']=math()->chain($data['actual'])->sub($source['amount'])->done();
+ return $source;
+ }
+
+ //EVENT|更新前
+ public static function onBeforeUpdate($model){
+ $source=$model::where([['id','=',$model['id']]])->find();
+ if(!empty($source['examine'])){
+ exit(json(['state'=>'error','info'=>'[ ERROR ] 单据已审核!'],200)->send());
+ }
+ }
+}
diff --git a/serve/app/model/SreBill.php b/serve/app/model/SreBill.php
new file mode 100644
index 0000000..263293b
--- /dev/null
+++ b/serve/app/model/SreBill.php
@@ -0,0 +1,31 @@
+'timestamp:Y-m-d'
+ ];
+
+ //结算账户关联
+ public function sourceData(){
+ return $this->morphTo(['type','source'],[
+ 'sre' => Sre::class,
+ 'bill' => Bill::class
+ ]);
+ }
+
+ //核销金额_读取器
+ public function getMoneyAttr($val,$data){
+ return floatval($val);
+ }
+
+ //数据扩展
+ public function getExtensionAttr($val,$data){
+ $source=[];
+ //单据类型
+ $source['type']=['sre'=>'销售退货单','bill'=>'核销单'][$data['type']];
+ return $source;
+ }
+}
diff --git a/serve/app/model/SreInfo.php b/serve/app/model/SreInfo.php
new file mode 100644
index 0000000..37ce690
--- /dev/null
+++ b/serve/app/model/SreInfo.php
@@ -0,0 +1,88 @@
+'json'
+ ];
+
+ //商品关联
+ public function goodsData(){
+ return $this->hasOne(Goods::class,'id','goods');
+ }
+
+ //仓库关联
+ public function warehouseData(){
+ return $this->hasOne(Warehouse::class,'id','warehouse');
+ }
+
+ //仓库_设置器
+ public function setWarehouseAttr($val,$data){
+ return empty($val)?0:$val;
+ }
+
+ //仓库_读取器
+ public function getWarehouseAttr($val,$data){
+ return empty($val)?null:$val;
+ }
+
+ //生产日期_设置器
+ public function setMfdAttr($val,$data){
+ return empty($val)?0:strtotime($val);
+ }
+
+ //生产日期_读取器
+ public function getMfdAttr($val,$data){
+ return empty($val)?'':date('Y-m-d',$val);
+ }
+
+ //单价_读取器
+ public function getPriceAttr($val,$data){
+ return floatval($val);
+ }
+
+ //数量_读取器
+ public function getNumsAttr($val,$data){
+ return floatval($val);
+ }
+
+ //折扣率_读取器
+ public function getDiscountAttr($val,$data){
+ return floatval($val);
+ }
+
+ //折扣额_读取器
+ public function getDscAttr($val,$data){
+ return floatval($val);
+ }
+
+ //金额_读取器
+ public function getTotalAttr($val,$data){
+ return floatval($val);
+ }
+
+ //税率_读取器
+ public function getTaxAttr($val,$data){
+ return floatval($val);
+ }
+
+ //税额_读取器
+ public function getTatAttr($val,$data){
+ return floatval($val);
+ }
+
+ //价税合计_读取器
+ public function getTptAttr($val,$data){
+ return floatval($val);
+ }
+
+ //数据扩展
+ public function getExtensionAttr($val,$data){
+ $source=[];
+ //序列号
+ $source['serial']=implode(',',json_decode($data['serial']));
+ return $source;
+ }
+}
diff --git a/serve/app/model/Summary.php b/serve/app/model/Summary.php
new file mode 100644
index 0000000..8e7b999
--- /dev/null
+++ b/serve/app/model/Summary.php
@@ -0,0 +1,68 @@
+'timestamp:Y-m-d'
+ ];
+
+ //单据关联
+ public function sourceData(){
+ return $this->morphTo(['type','class'],[
+ 'buy'=>Buy::class,
+ 'bre'=>Bre::class,
+ 'sell'=>Sell::class,
+ 'sre'=>Sre::class,
+ 'vend'=>Vend::class,
+ 'vre'=>Vre::class,
+ 'barter'=>Barter::class,
+ 'swapOut'=>Swap::class,
+ 'swapEnter'=>Swap::class,
+ 'entry'=>Entry::class,
+ 'extry'=>Extry::class,
+ ]);
+ }
+
+ //仓库关联
+ public function warehouseData(){
+ return $this->hasOne(Warehouse::class,'id','warehouse');
+ }
+
+ //商品关联
+ public function goodsData(){
+ return $this->hasOne(Goods::class,'id','goods');
+ }
+
+ //基础单价_读取器
+ public function getPriceAttr($val,$data){
+ return floatval($val);
+ }
+
+ //基础数量_读取器
+ public function getNumsAttr($val,$data){
+ return floatval($val);
+ }
+
+ //单位成本_读取器
+ public function getUctAttr($val,$data){
+ return floatval($val);
+ }
+
+ //基础成本_读取器
+ public function getBctAttr($val,$data){
+ return floatval($val);
+ }
+
+ //数据扩展
+ public function getExtensionAttr($val,$data){
+ $source=[];
+ //单据类型
+ $source['type']=["buy"=>"采购单","bre"=>"采购退货单","sell"=>"销售单","sre"=>"销售退货单","vend"=>"零售单","vre"=>"零售退货单","barter"=>"积分兑换单","swapOut"=>"调拨单-出","swapEnter"=>"调拨单-入","entry"=>"其它入库单","extry"=>"其它出库单"][$data['type']];
+ //操作类型
+ $source['direction']=["减少","增加"][$data['direction']];
+
+ return $source;
+ }
+}
diff --git a/serve/app/model/Supplier.php b/serve/app/model/Supplier.php
new file mode 100644
index 0000000..860e59e
--- /dev/null
+++ b/serve/app/model/Supplier.php
@@ -0,0 +1,56 @@
+ 'json'
+ ];
+
+ //所属组织关联
+ public function frameData(){
+ return $this->hasOne(Frame::class,'id','frame');
+ }
+
+ //所属用户关联
+ public function userData(){
+ return $this->hasOne(User::class,'id','user')->field(['id','name']);
+ }
+
+ //增值税税率_读取器
+ public function getRateAttr($val,$data){
+ return floatval($val);
+ }
+
+ //应付款余额_读取器
+ public function getBalanceAttr($val,$data){
+ return floatval($val);
+ }
+
+ //扩展信息_设置器
+ public function setMoreAttr($val){
+ //兼容Api|修复PHP空对象json编码为[]
+ return json_encode((object)$val);
+ }
+
+ //扩展信息_读取器
+ public function getMoreAttr($val){
+ return json_decode($val);
+ }
+
+ //数据扩展
+ public function getExtensionAttr($val,$data){
+ $source=[];
+ //主联系人
+ $contact=json_decode($data['contacts'],true);
+ if(empty($contact)){
+ $source['contact']='';
+ }else{
+ $find=search($contact)->where([['main','=',true]])->find();
+ $source['contact']=$find['name'].' | '.$find['tel'].' | '.$find['add'];
+ }
+ return $source;
+ }
+
+}
diff --git a/serve/app/model/Swap.php b/serve/app/model/Swap.php
new file mode 100644
index 0000000..432379f
--- /dev/null
+++ b/serve/app/model/Swap.php
@@ -0,0 +1,108 @@
+'timestamp:Y-m-d',
+ 'logistics'=>'json',
+ 'file'=>'json'
+ ];
+
+ //所属组织关联
+ public function frameData(){
+ return $this->hasOne(Frame::class,'id','frame');
+ }
+
+ //关联人员关联
+ public function peopleData(){
+ return $this->hasOne(People::class,'id','people')->field(['id','name']);
+ }
+
+ //制单人关联
+ public function userData(){
+ return $this->hasOne(User::class,'id','user')->field(['id','name']);
+ }
+
+ //费用详情关联
+ public function costData(){
+ return $this->hasMany(Cost::class,'class','id')->with(['ietData'])->where([['type','=','swap']])->append(['extension'])->order('id desc');
+ }
+
+ //记录关联
+ public function recordData(){
+ return $this->hasMany(Record::class,'source','id')->with(['userData'])->where([['type','=','swap']])->append(['extension'])->order('id desc');
+ }
+
+ //单据成本_读取器
+ public function getTotalAttr($val,$data){
+ return floatval($val);
+ }
+
+ //单据费用_读取器
+ public function getCostAttr($val,$data){
+ return floatval($val);
+ }
+
+ //关联人员_设置器
+ public function setPeopleAttr($val){
+ return empty($val)?0:$val;
+ }
+
+ //关联人员_读取器
+ public function getPeopleAttr($val){
+ return empty($val)?null:$val;
+ }
+
+ //扩展信息_设置器
+ public function setMoreAttr($val){
+ //兼容Api|修复PHP空对象json编码为[]
+ return json_encode((object)$val);
+ }
+
+ //扩展信息_读取器
+ public function getMoreAttr($val){
+ return json_decode($val);
+ }
+
+ //数据扩展
+ public function getExtensionAttr($val,$data){
+ $source=[];
+ //物流信息
+ $logistics=json_decode($data['logistics'],true);
+ if(empty($logistics['key'])){
+ $source['logistics']='';
+ }elseif($logistics['key']=='auto'){
+ $source['logistics']=$logistics['number'];
+ }else{
+ $source['logistics']=$logistics['name'].'|'.$logistics['number'];
+ }
+ //审核状态
+ $source['examine']=[0=>'未审核',1=>'已审核'][$data['examine']];
+ //费用状态
+ $source['cse']=[0=>'未结算',1=>'部分结算',2=>'已结算',3=>'无需结算'][$data['cse']];
+ //联系信息
+ $sceneData=$this->sceneData;
+ if(empty($sceneData)){
+ $source['contact']='';
+ }else{
+ $contact=$sceneData['contacts'];
+ if(empty($contact)){
+ $source['contact']='';
+ }else{
+ $find=search($contact)->where([['main','=',true]])->find();
+ $source['contact']=$find['name'].' | '.$find['tel'].' | '.$find['add'];
+ }
+ }
+ return $source;
+ }
+
+ //EVENT|更新前
+ public static function onBeforeUpdate($model){
+ $source=$model::where([['id','=',$model['id']]])->find();
+ if(!empty($source['examine'])){
+ exit(json(['state'=>'error','info'=>'[ ERROR ] 单据已审核!'],200)->send());
+ }
+ }
+}
diff --git a/serve/app/model/SwapInfo.php b/serve/app/model/SwapInfo.php
new file mode 100644
index 0000000..00953d2
--- /dev/null
+++ b/serve/app/model/SwapInfo.php
@@ -0,0 +1,78 @@
+'json'
+ ];
+
+ //商品关联
+ public function goodsData(){
+ return $this->hasOne(Goods::class,'id','goods');
+ }
+
+ //调出仓库关联
+ public function warehouseData(){
+ return $this->hasOne(Warehouse::class,'id','warehouse');
+ }
+
+ //调入仓库关联
+ public function storehouseData(){
+ return $this->hasOne(Warehouse::class,'id','storehouse');
+ }
+
+ //调出仓库_设置器
+ public function setWarehouseAttr($val,$data){
+ return empty($val)?0:$val;
+ }
+
+ //调入仓库_设置器
+ public function setStorehouseAttr($val,$data){
+ return empty($val)?0:$val;
+ }
+
+ //调出仓库_读取器
+ public function getWarehouseAttr($val,$data){
+ return empty($val)?null:$val;
+ }
+
+ //调入仓库_读取器
+ public function getStorehouseAttr($val,$data){
+ return empty($val)?null:$val;
+ }
+
+ //生产日期_设置器
+ public function setMfdAttr($val,$data){
+ return empty($val)?0:strtotime($val);
+ }
+
+ //生产日期_读取器
+ public function getMfdAttr($val,$data){
+ return empty($val)?'':date('Y-m-d',$val);
+ }
+
+ //成本_读取器
+ public function getPriceAttr($val,$data){
+ return floatval($val);
+ }
+
+ //数量_读取器
+ public function getNumsAttr($val,$data){
+ return floatval($val);
+ }
+
+ //总成本_读取器
+ public function getTotalAttr($val,$data){
+ return floatval($val);
+ }
+
+ //数据扩展
+ public function getExtensionAttr($val,$data){
+ $source=[];
+ //序列号
+ $source['serial']=implode(',',json_decode($data['serial']));
+ return $source;
+ }
+}
diff --git a/serve/app/model/Sys.php b/serve/app/model/Sys.php
new file mode 100644
index 0000000..1b4a7d4
--- /dev/null
+++ b/serve/app/model/Sys.php
@@ -0,0 +1,17 @@
+hasOne(Frame::class,'id','frame');
+ }
+
+ //所属角色关联
+ public function roleData(){
+ return $this->hasOne(Role::class,'id','role')->field(['id','name']);
+ }
+
+ //用户密码_设置器
+ public function setPwdAttr($val){
+ return md5($val);
+ }
+
+ //用户角色_设置器
+ public function setRoleAttr($val){
+ return empty($val)?0:$val;
+ }
+
+ //扩展信息_设置器
+ public function setMoreAttr($val){
+ //兼容Api|修复PHP空对象json编码为[]
+ return json_encode((object)$val);
+ }
+
+ //扩展信息_读取器
+ public function getMoreAttr($val){
+ return json_decode($val);
+ }
+}
diff --git a/serve/app/model/Warehouse.php b/serve/app/model/Warehouse.php
new file mode 100644
index 0000000..61f393d
--- /dev/null
+++ b/serve/app/model/Warehouse.php
@@ -0,0 +1,12 @@
+hasOne(Frame::class,'id','frame');
+ }
+
+}
diff --git a/serve/app/provider.php b/serve/app/provider.php
new file mode 100644
index 0000000..73d99fa
--- /dev/null
+++ b/serve/app/provider.php
@@ -0,0 +1,9 @@
+ Request::class,
+ 'think\exception\Handle' => ExceptionHandle::class,
+];
diff --git a/serve/app/validate/Account.php b/serve/app/validate/Account.php
new file mode 100644
index 0000000..6ece8d0
--- /dev/null
+++ b/serve/app/validate/Account.php
@@ -0,0 +1,32 @@
+ ['require'],
+ 'number' => ['require','unique:account'],
+ 'frame' => ['require','integer'],
+ 'time' => ['require','date'],
+ 'initial' => ['require','float']
+ ];
+
+ //常规规则提示
+ protected $message = [
+ 'name.require' => '账户名称不可为空!',
+ 'number.require' => '账户编号不可为空!',
+ 'number.unique' => '账户编号重复!',
+ 'frame.require' => '所属组织不可为空!',
+ 'frame.integer' => '所属组织不正确!',
+ 'time.require' => '余额日期不可为空!',
+ 'time.date' => '余额日期不正确!',
+ 'initial.require' => '期初余额不可为空!',
+ 'initial.float' => '期初余额不正确!',
+ ];
+
+ //场景规则
+ protected $scene = [
+ 'update' => ['name','number','frame','time','initial']
+ ];
+}
\ No newline at end of file
diff --git a/serve/app/validate/Allot.php b/serve/app/validate/Allot.php
new file mode 100644
index 0000000..f8d4a8c
--- /dev/null
+++ b/serve/app/validate/Allot.php
@@ -0,0 +1,32 @@
+ ['require','date'],
+ 'number' => ['require','unique:allot'],
+ 'total' => ['require','float'],
+ 'people' => ['integer'],
+ 'file' => ['array'],
+ 'more' => ['array']
+ ];
+
+ //常规规则提示
+ protected $message = [
+ 'time.require' => '单据日期不可为空!',
+ 'time.date' => '单据日期不正确!',
+ 'number.require' => '单据编号不可为空!',
+ 'number.unique' => '单据编号重复!',
+ 'total.require' => '单据金额不可为空!',
+ 'total.float' => '单据金额不正确!',
+ 'people.integer' => '关联人员不正确!',
+ 'file.array' => '单据附件不正确!',
+ 'more.array' => '扩展信息不正确!'
+ ];
+
+ //场景规则
+ protected $scene = [
+ 'update' => ['time','number','total','people','file','more']
+ ];
+}
\ No newline at end of file
diff --git a/serve/app/validate/AllotInfo.php b/serve/app/validate/AllotInfo.php
new file mode 100644
index 0000000..2bc4fec
--- /dev/null
+++ b/serve/app/validate/AllotInfo.php
@@ -0,0 +1,22 @@
+ ['require','integer'],
+ 'tat' => ['require','integer'],
+ 'money' => ['require','float']
+ ];
+
+ //常规规则提示
+ protected $message = [
+ 'account.require' => '转入账户不可为空!',
+ 'account.integer' => '转入账户不正确!',
+ 'tat.require' => '转出账户不可为空!',
+ 'tat.integer' => '转出账户不正确!',
+ 'money.require' => '结算金额不可为空!',
+ 'money.float' => '结算金额不正确!'
+ ];
+}
\ No newline at end of file
diff --git a/serve/app/validate/Attr.php b/serve/app/validate/Attr.php
new file mode 100644
index 0000000..91d8856
--- /dev/null
+++ b/serve/app/validate/Attr.php
@@ -0,0 +1,29 @@
+ ['require'],
+ 'buy' => ['require','float'],
+ 'sell' => ['require','float'],
+ 'retail' => ['require','float']
+ ];
+
+ //常规规则提示
+ protected $message = [
+ 'name.require' => '属性名称不可为空!',
+ 'buy.require' => '采购价格不可为空!',
+ 'buy.float' => '采购价格不正确!',
+ 'sell.require' => '销售价格不可为空!',
+ 'sell.float' => '销售价格不正确!',
+ 'retail.require' => '零售价格不可为空!',
+ 'retail.float' => '零售价格不正确!'
+ ];
+
+ //场景规则
+ protected $scene = [
+ 'update' => ['name','buy','sell','retail']
+ ];
+}
\ No newline at end of file
diff --git a/serve/app/validate/Attribute.php b/serve/app/validate/Attribute.php
new file mode 100644
index 0000000..650b759
--- /dev/null
+++ b/serve/app/validate/Attribute.php
@@ -0,0 +1,45 @@
+ ['require','unique:attribute'],
+ 'info' => ['require','array','checkInfo'],
+ 'sort' => ['require','integer']
+ ];
+
+ //常规规则提示
+ protected $message = [
+ 'name.require' => '属性名称不可为空!',
+ 'name.unique' => '属性名称重复!',
+ 'info.require' => '属性内容不可为空!',
+ 'info.array' => '属性内容不正确!',
+ 'sort.require' => '属性排序不可为空!',
+ 'sort.integer' => '属性排序不正确!'
+ ];
+
+ //场景规则
+ protected $scene = [
+ 'update' => ['name','info','sort']
+ ];
+
+ //独立验证器
+ protected function checkInfo($value,$rule,$data){
+ $column=array_column($value,'name');
+ if(count($column)!=count(array_unique($column))){
+ $result = '属性内容存在重复!';
+ }else if(strpos(json_encode($column),'|')!==false){
+ $result = '属性内容不可包含[ | ]保留字符!';
+ }else{
+ //全局重复判断
+ $find=db('attribute_info')->where([['pid','<>',$data['id']],['name','in',$column]])->find();
+ if(empty($find)){
+ $result=true;
+ }else{
+ $result='属性内容与其他属性内容重复!';
+ }
+ }
+ return $result;
+ }
+}
\ No newline at end of file
diff --git a/serve/app/validate/Bill.php b/serve/app/validate/Bill.php
new file mode 100644
index 0000000..1552572
--- /dev/null
+++ b/serve/app/validate/Bill.php
@@ -0,0 +1,42 @@
+ ['integer'],
+ 'supplier' => ['integer'],
+ 'time' => ['require','date'],
+ 'number' => ['require','unique:bill'],
+ 'type' => ['require'],
+ 'pmy' => ['require','float'],
+ 'smp' => ['require','float'],
+ 'people' => ['integer'],
+ 'file' => ['array'],
+ 'more' => ['array']
+ ];
+
+ //常规规则提示
+ protected $message = [
+ 'customer.integer' => '客户不正确!',
+ 'supplier.integer' => '供应商不正确!',
+ 'time.require' => '单据日期不可为空!',
+ 'time.date' => '单据日期不正确!',
+ 'number.require' => '单据编号不可为空!',
+ 'number.unique' => '单据编号重复!',
+ 'type.require' => '核销类型不可为空!',
+ 'pmy.require' => '总核金额不可为空!',
+ 'pmy.float' => '总核金额不正确!',
+ 'smp.require' => '总销金额不可为空!',
+ 'smp.float' => '总销金额不正确!',
+ 'people.integer' => '关联人员不正确!',
+ 'file.array' => '单据附件不正确!',
+ 'more.array' => '扩展信息不正确!'
+ ];
+
+ //场景规则
+ protected $scene = [
+ 'update' => ['customer','supplier','time','number','type','pmy','smp','people','file','more']
+ ];
+}
\ No newline at end of file
diff --git a/serve/app/validate/BillInfo.php b/serve/app/validate/BillInfo.php
new file mode 100644
index 0000000..e1d46ad
--- /dev/null
+++ b/serve/app/validate/BillInfo.php
@@ -0,0 +1,23 @@
+ ['require','integer'],
+ 'bill' => ['require'],
+ 'mold' => ['require'],
+ 'money' => ['require','float']
+ ];
+
+ //常规规则提示
+ protected $message = [
+ 'source.require' => '关联单据不可为空!',
+ 'source.integer' => '关联单据不正确!',
+ 'bill.require' => '核销类型不可为空!',
+ 'mold.require' => '单据类型不可为空!',
+ 'money.require' => '核销金额不可为空!',
+ 'money.float' => '核销金额不正确!'
+ ];
+}
\ No newline at end of file
diff --git a/serve/app/validate/Bor.php b/serve/app/validate/Bor.php
new file mode 100644
index 0000000..110a8dd
--- /dev/null
+++ b/serve/app/validate/Bor.php
@@ -0,0 +1,43 @@
+ ['require','integer'],
+ 'time' => ['require','date'],
+ 'number' => ['require','unique:bor'],
+ 'total' => ['require','float'],
+ 'actual' => ['require','float'],
+ 'people' => ['integer'],
+ 'arrival' => ['date'],
+ 'logistics' => ['array'],
+ 'file' => ['array'],
+ 'more' => ['array']
+ ];
+
+ //常规规则提示
+ protected $message = [
+ 'supplier.require' => '供应商不可为空!',
+ 'supplier.integer' => '供应商不正确!',
+ 'time.require' => '单据日期不可为空!',
+ 'time.date' => '单据日期不正确!',
+ 'number.require' => '单据编号不可为空!',
+ 'number.unique' => '单据编号重复!',
+ 'total.require' => '单据金额不可为空!',
+ 'total.float' => '单据金额不正确!',
+ 'actual.require' => '实际金额不可为空!',
+ 'actual.float' => '实际金额不正确!',
+ 'people.integer' => '关联人员不正确!',
+ 'arrival.date' => '单据日期不正确!',
+ 'logistics.array' => '物流信息不正确!',
+ 'file.array' => '单据附件不正确!',
+ 'more.array' => '扩展信息不正确!',
+ ];
+
+ //场景规则
+ protected $scene = [
+ 'update' => ['supplier','time','number','total','actual','people','arrival','logistics','file','more']
+ ];
+}
\ No newline at end of file
diff --git a/serve/app/validate/BorInfo.php b/serve/app/validate/BorInfo.php
new file mode 100644
index 0000000..6ccae70
--- /dev/null
+++ b/serve/app/validate/BorInfo.php
@@ -0,0 +1,42 @@
+ ['require','integer'],
+ 'warehouse' => ['integer'],
+ 'price' => ['require','float'],
+ 'nums' => ['require','float'],
+ 'discount' => ['require','between:0,100'],
+ 'dsc' => ['require','float'],
+ 'total' => ['require','float'],
+ 'tax' => ['require','between:0,100'],
+ 'tat' => ['require','float'],
+ 'tpt' => ['require','float']
+ ];
+
+ //常规规则提示
+ protected $message = [
+ 'goods.require' => '商品信息不可为空!',
+ 'goods.integer' => '商品信息不正确!',
+ 'warehouse.integer' => '仓库不正确!',
+ 'price.require' => '单价不可为空!',
+ 'price.float' => '单价不正确!',
+ 'nums.require' => '数量不可为空!',
+ 'nums.float' => '数量不正确!',
+ 'discount.require' => '折扣率不可为空!',
+ 'discount.between' => '折扣率不正确!',
+ 'dsc.require' => '折扣额不可为空!',
+ 'dsc.float' => '折扣额不正确!',
+ 'total.require' => '金额不可为空!',
+ 'total.float' => '金额不正确!',
+ 'tax.require' => '税率不可为空!',
+ 'tax.between' => '税率不正确!',
+ 'tat.require' => '税额不可为空!',
+ 'tat.float' => '税额不正确!',
+ 'tpt.require' => '价税合计不可为空!',
+ 'tpt.float' => '价税合计不正确!'
+ ];
+}
\ No newline at end of file
diff --git a/serve/app/validate/Bre.php b/serve/app/validate/Bre.php
new file mode 100644
index 0000000..5ea3b01
--- /dev/null
+++ b/serve/app/validate/Bre.php
@@ -0,0 +1,49 @@
+ ['require','integer'],
+ 'supplier' => ['require','integer'],
+ 'time' => ['require','date'],
+ 'number' => ['require','unique:bre'],
+ 'total' => ['require','float'],
+ 'actual' => ['require','float'],
+ 'money' => ['require','float'],
+ 'account' => ['requireWith:money'],
+ 'people' => ['integer'],
+ 'logistics' => ['array'],
+ 'file' => ['array'],
+ 'more' => ['array']
+ ];
+
+ //常规规则提示
+ protected $message = [
+ 'source.require' => '关联单据不可为空!',
+ 'source.integer' => '关联单据不正确!',
+ 'supplier.require' => '供应商不可为空!',
+ 'supplier.integer' => '供应商不正确!',
+ 'time.require' => '单据日期不可为空!',
+ 'time.date' => '单据日期不正确!',
+ 'number.require' => '单据编号不可为空!',
+ 'number.unique' => '单据编号重复!',
+ 'total.require' => '单据金额不可为空!',
+ 'total.float' => '单据金额不正确!',
+ 'actual.require' => '实际金额不可为空!',
+ 'actual.float' => '实际金额不正确!',
+ 'money.require' => '实收金额不可为空!',
+ 'money.float' => '实收金额不正确!',
+ 'account.requireWith' => '结算账户不可为空!',
+ 'people.integer' => '关联人员不正确!',
+ 'logistics.array' => '物流信息不正确!',
+ 'file.array' => '单据附件不正确!',
+ 'more.array' => '扩展信息不正确!'
+ ];
+
+ //场景规则
+ protected $scene = [
+ 'update' => ['source','supplier','time','number','total','actual','money','account','people','logistics','file','more']
+ ];
+}
\ No newline at end of file
diff --git a/serve/app/validate/BreInfo.php b/serve/app/validate/BreInfo.php
new file mode 100644
index 0000000..dea792c
--- /dev/null
+++ b/serve/app/validate/BreInfo.php
@@ -0,0 +1,50 @@
+ ['require','integer'],
+ 'goods' => ['require','integer'],
+ 'warehouse' => ['integer'],
+ 'mfd' => ['date'],
+ 'price' => ['require','float'],
+ 'nums' => ['require','float'],
+ 'serial' => ['array'],
+ 'discount' => ['require','between:0,100'],
+ 'dsc' => ['require','float'],
+ 'total' => ['require','float'],
+ 'tax' => ['require','between:0,100'],
+ 'tat' => ['require','float'],
+ 'tpt' => ['require','float']
+ ];
+
+ //常规规则提示
+ protected $message = [
+ 'source.require' => '关联详情不可为空!',
+ 'source.integer' => '关联详情不正确!',
+ 'goods.require' => '商品信息不可为空!',
+ 'goods.integer' => '商品信息不正确!',
+ 'warehouse.integer' => '仓库不正确!',
+ 'mfd.require' => '生产日期不正确!',
+ 'price.require' => '单价不可为空!',
+ 'price.float' => '单价不正确!',
+ 'nums.require' => '数量不可为空!',
+ 'nums.float' => '数量不正确!',
+ 'serial.require' => '序列号不可为空!',
+ 'serial.array' => '序列号不正确!',
+ 'discount.require' => '折扣率不可为空!',
+ 'discount.between' => '折扣率不正确!',
+ 'dsc.require' => '折扣额不可为空!',
+ 'dsc.float' => '折扣额不正确!',
+ 'total.require' => '金额不可为空!',
+ 'total.float' => '金额不正确!',
+ 'tax.require' => '税率不可为空!',
+ 'tax.between' => '税率不正确!',
+ 'tat.require' => '税额不可为空!',
+ 'tat.float' => '税额不正确!',
+ 'tpt.require' => '价税合计不可为空!',
+ 'tpt.float' => '价税合计不正确!'
+ ];
+}
\ No newline at end of file
diff --git a/serve/app/validate/Buy.php b/serve/app/validate/Buy.php
new file mode 100644
index 0000000..c51c289
--- /dev/null
+++ b/serve/app/validate/Buy.php
@@ -0,0 +1,49 @@
+ ['require','integer'],
+ 'supplier' => ['require','integer'],
+ 'time' => ['require','date'],
+ 'number' => ['require','unique:buy'],
+ 'total' => ['require','float'],
+ 'actual' => ['require','float'],
+ 'money' => ['require','float'],
+ 'account' => ['requireWith:money'],
+ 'people' => ['integer'],
+ 'logistics' => ['array'],
+ 'file' => ['array'],
+ 'more' => ['array']
+ ];
+
+ //常规规则提示
+ protected $message = [
+ 'source.require' => '关联单据不可为空!',
+ 'source.integer' => '关联单据不正确!',
+ 'supplier.require' => '供应商不可为空!',
+ 'supplier.integer' => '供应商不正确!',
+ 'time.require' => '单据日期不可为空!',
+ 'time.date' => '单据日期不正确!',
+ 'number.require' => '单据编号不可为空!',
+ 'number.unique' => '单据编号重复!',
+ 'total.require' => '单据金额不可为空!',
+ 'total.float' => '单据金额不正确!',
+ 'actual.require' => '实际金额不可为空!',
+ 'actual.float' => '实际金额不正确!',
+ 'money.require' => '实付金额不可为空!',
+ 'money.float' => '实付金额不正确!',
+ 'account.requireWith' => '结算账户不可为空!',
+ 'people.integer' => '关联人员不正确!',
+ 'logistics.array' => '物流信息不正确!',
+ 'file.array' => '单据附件不正确!',
+ 'more.array' => '扩展信息不正确!'
+ ];
+
+ //场景规则
+ protected $scene = [
+ 'update' => ['source','supplier','time','number','total','actual','money','account','people','logistics','file','more']
+ ];
+}
\ No newline at end of file
diff --git a/serve/app/validate/BuyInfo.php b/serve/app/validate/BuyInfo.php
new file mode 100644
index 0000000..014ca93
--- /dev/null
+++ b/serve/app/validate/BuyInfo.php
@@ -0,0 +1,50 @@
+ ['require','integer'],
+ 'goods' => ['require','integer'],
+ 'warehouse' => ['integer'],
+ 'mfd' => ['date'],
+ 'price' => ['require','float'],
+ 'nums' => ['require','float'],
+ 'serial' => ['array'],
+ 'discount' => ['require','between:0,100'],
+ 'dsc' => ['require','float'],
+ 'total' => ['require','float'],
+ 'tax' => ['require','between:0,100'],
+ 'tat' => ['require','float'],
+ 'tpt' => ['require','float']
+ ];
+
+ //常规规则提示
+ protected $message = [
+ 'source.require' => '关联详情不可为空!',
+ 'source.integer' => '关联详情不正确!',
+ 'goods.require' => '商品信息不可为空!',
+ 'goods.integer' => '商品信息不正确!',
+ 'warehouse.integer' => '仓库不正确!',
+ 'mfd.require' => '生产日期不正确!',
+ 'price.require' => '单价不可为空!',
+ 'price.float' => '单价不正确!',
+ 'nums.require' => '数量不可为空!',
+ 'nums.float' => '数量不正确!',
+ 'serial.require' => '序列号不可为空!',
+ 'serial.array' => '序列号不正确!',
+ 'discount.require' => '折扣率不可为空!',
+ 'discount.between' => '折扣率不正确!',
+ 'dsc.require' => '折扣额不可为空!',
+ 'dsc.float' => '折扣额不正确!',
+ 'total.require' => '金额不可为空!',
+ 'total.float' => '金额不正确!',
+ 'tax.require' => '税率不可为空!',
+ 'tax.between' => '税率不正确!',
+ 'tat.require' => '税额不可为空!',
+ 'tat.float' => '税额不正确!',
+ 'tpt.require' => '价税合计不可为空!',
+ 'tpt.float' => '价税合计不正确!'
+ ];
+}
\ No newline at end of file
diff --git a/serve/app/validate/Category.php b/serve/app/validate/Category.php
new file mode 100644
index 0000000..4f15b3e
--- /dev/null
+++ b/serve/app/validate/Category.php
@@ -0,0 +1,25 @@
+ ['require'],
+ 'pid' => ['require','integer'],
+ 'sort' => ['require','integer']
+ ];
+
+ //常规规则提示
+ protected $message = [
+ 'name.require' => '类别名称不可为空!',
+ 'pid.require' => '所属类别不可为空!',
+ 'pid.integer' => '所属类别不正确!',
+ 'sort.require' => '类别排序不可为空!',
+ 'sort.integer' => '类别排序不正确!'
+ ];
+
+ //场景规则
+ protected $scene = [
+ 'update' => ['name','pid','sort']
+ ];
+}
\ No newline at end of file
diff --git a/serve/app/validate/Code.php b/serve/app/validate/Code.php
new file mode 100644
index 0000000..e6d5f56
--- /dev/null
+++ b/serve/app/validate/Code.php
@@ -0,0 +1,24 @@
+ ['require'],
+ 'info' => ['require'],
+ 'type' => ['require','integer']
+ ];
+
+ //常规规则提示
+ protected $message = [
+ 'name.require' => '条码名称不可为空!',
+ 'info.require' => '条码内容不可为空!',
+ 'type.require' => '条码类型不可为空!',
+ 'type.integer' => '条码类型不正确!'
+ ];
+
+ //场景规则
+ protected $scene = [
+ 'update' => ['name','info','type']
+ ];
+}
\ No newline at end of file
diff --git a/serve/app/validate/Cost.php b/serve/app/validate/Cost.php
new file mode 100644
index 0000000..ebdd2cf
--- /dev/null
+++ b/serve/app/validate/Cost.php
@@ -0,0 +1,19 @@
+ ['require','integer'],
+ 'money' => ['require','float']
+ ];
+
+ //常规规则提示
+ protected $message = [
+ 'iet.require' => '支出类别不可为空!',
+ 'iet.integer' => '支出类别不正确!',
+ 'money.require' => '金额不可为空!',
+ 'money.float' => '金额不正确!'
+ ];
+}
\ No newline at end of file
diff --git a/serve/app/validate/Customer.php b/serve/app/validate/Customer.php
new file mode 100644
index 0000000..3eff613
--- /dev/null
+++ b/serve/app/validate/Customer.php
@@ -0,0 +1,34 @@
+ ['require'],
+ 'number' => ['require','unique:customer'],
+ 'frame' => ['require','integer'],
+ 'user' => ['require','integer'],
+ 'contacts'=>['array'],
+ 'more' => ['array']
+ ];
+
+ //常规规则提示
+ protected $message = [
+ 'name.require' => '客户名称不可为空!',
+ 'number.require' => '客户编号不可为空!',
+ 'number.unique' => '客户编号重复!',
+ 'frame.require' => '所属组织不可为空!',
+ 'frame.integer' => '所属组织不正确!',
+ 'user.require' => '所属用户不可为空!',
+ 'user.integer' => '所属用户不正确!',
+ 'contacts.array' => '联系资料不正确!',
+ 'more.array' => '扩展信息不正确!',
+
+ ];
+
+ //场景规则
+ protected $scene = [
+ 'update' => ['name','number','frame','user','contacts','more'],
+ ];
+}
\ No newline at end of file
diff --git a/serve/app/validate/Deploy.php b/serve/app/validate/Deploy.php
new file mode 100644
index 0000000..32f3b73
--- /dev/null
+++ b/serve/app/validate/Deploy.php
@@ -0,0 +1,24 @@
+ ['require','integer','unique:deploy'],
+ 'source' => ['require','array']
+ ];
+
+ //常规规则提示
+ protected $message = [
+ 'frame.require' => '关联组织不可为空!',
+ 'frame.integer' => '关联组织不正确!',
+ 'frame.unique' => '关联组织重复!',
+ 'source.require' => '配置信息不可为空!',
+ 'source.array' => '配置信息不正确!'
+ ];
+
+ //场景规则
+ protected $scene = [
+ 'update' => ['frame','source']
+ ];
+}
\ No newline at end of file
diff --git a/serve/app/validate/Entry.php b/serve/app/validate/Entry.php
new file mode 100644
index 0000000..8522de8
--- /dev/null
+++ b/serve/app/validate/Entry.php
@@ -0,0 +1,35 @@
+ ['require','date'],
+ 'number' => ['require','unique:entry'],
+ 'total' => ['require','float'],
+ 'people' => ['integer'],
+ 'logistics' => ['array'],
+ 'file' => ['array'],
+ 'more' => ['array']
+ ];
+
+ //常规规则提示
+ protected $message = [
+ 'time.require' => '单据日期不可为空!',
+ 'time.date' => '单据日期不正确!',
+ 'number.require' => '单据编号不可为空!',
+ 'number.unique' => '单据编号重复!',
+ 'total.require' => '单据成本不可为空!',
+ 'total.float' => '单据成本不正确!',
+ 'people.integer' => '关联人员不正确!',
+ 'logistics.array' => '物流信息不正确!',
+ 'file.array' => '单据附件不正确!',
+ 'more.array' => '扩展信息不正确!'
+ ];
+
+ //场景规则
+ protected $scene = [
+ 'update' => ['time','number','total','people','logistics','file','more']
+ ];
+}
\ No newline at end of file
diff --git a/serve/app/validate/EntryInfo.php b/serve/app/validate/EntryInfo.php
new file mode 100644
index 0000000..c85d5ac
--- /dev/null
+++ b/serve/app/validate/EntryInfo.php
@@ -0,0 +1,32 @@
+ ['require','integer'],
+ 'warehouse' => ['integer'],
+ 'mfd' => ['date'],
+ 'price' => ['require','float'],
+ 'nums' => ['require','float'],
+ 'serial' => ['array'],
+ 'total' => ['require','float'],
+ ];
+
+ //常规规则提示
+ protected $message = [
+ 'goods.require' => '商品信息不可为空!',
+ 'goods.integer' => '商品信息不正确!',
+ 'warehouse.integer' => '仓库不正确!',
+ 'mfd.require' => '生产日期不正确!',
+ 'price.require' => '成本不可为空!',
+ 'price.float' => '成本不正确!',
+ 'nums.require' => '数量不可为空!',
+ 'nums.float' => '数量不正确!',
+ 'serial.require' => '序列号不可为空!',
+ 'serial.array' => '序列号不正确!',
+ 'total.require' => '总成本不可为空!',
+ 'total.float' => '总成本不正确!'
+ ];
+}
\ No newline at end of file
diff --git a/serve/app/validate/Extry.php b/serve/app/validate/Extry.php
new file mode 100644
index 0000000..3747883
--- /dev/null
+++ b/serve/app/validate/Extry.php
@@ -0,0 +1,35 @@
+ ['require','date'],
+ 'number' => ['require','unique:extry'],
+ 'total' => ['require','float'],
+ 'people' => ['integer'],
+ 'logistics' => ['array'],
+ 'file' => ['array'],
+ 'more' => ['array']
+ ];
+
+ //常规规则提示
+ protected $message = [
+ 'time.require' => '单据日期不可为空!',
+ 'time.date' => '单据日期不正确!',
+ 'number.require' => '单据编号不可为空!',
+ 'number.unique' => '单据编号重复!',
+ 'total.require' => '单据成本不可为空!',
+ 'total.float' => '单据成本不正确!',
+ 'people.integer' => '关联人员不正确!',
+ 'logistics.array' => '物流信息不正确!',
+ 'file.array' => '单据附件不正确!',
+ 'more.array' => '扩展信息不正确!'
+ ];
+
+ //场景规则
+ protected $scene = [
+ 'update' => ['time','number','total','people','logistics','file','more']
+ ];
+}
\ No newline at end of file
diff --git a/serve/app/validate/ExtryInfo.php b/serve/app/validate/ExtryInfo.php
new file mode 100644
index 0000000..738b81f
--- /dev/null
+++ b/serve/app/validate/ExtryInfo.php
@@ -0,0 +1,32 @@
+ ['require','integer'],
+ 'warehouse' => ['integer'],
+ 'mfd' => ['date'],
+ 'price' => ['require','float'],
+ 'nums' => ['require','float'],
+ 'serial' => ['array'],
+ 'total' => ['require','float'],
+ ];
+
+ //常规规则提示
+ protected $message = [
+ 'goods.require' => '商品信息不可为空!',
+ 'goods.integer' => '商品信息不正确!',
+ 'warehouse.integer' => '仓库不正确!',
+ 'mfd.require' => '生产日期不正确!',
+ 'price.require' => '成本不可为空!',
+ 'price.float' => '成本不正确!',
+ 'nums.require' => '数量不可为空!',
+ 'nums.float' => '数量不正确!',
+ 'serial.require' => '序列号不可为空!',
+ 'serial.array' => '序列号不正确!',
+ 'total.require' => '总成本不可为空!',
+ 'total.float' => '总成本不正确!'
+ ];
+}
\ No newline at end of file
diff --git a/serve/app/validate/Field.php b/serve/app/validate/Field.php
new file mode 100644
index 0000000..fe07bea
--- /dev/null
+++ b/serve/app/validate/Field.php
@@ -0,0 +1,24 @@
+ ['require'],
+ 'key' => ['require','unique:field'],
+ 'fields' => ['array']
+ ];
+
+ //常规规则提示
+ protected $message = [
+ 'name.require' => '模块名称不可为空!',
+ 'key.require' => '模块标识不可为空!',
+ 'key.unique' => '模块标识重复!',
+ 'fields.array' => '字段数据不正确!'
+ ];
+
+ //场景规则
+ protected $scene = [
+ 'update' => ['name','key','fields']
+ ];
+}
\ No newline at end of file
diff --git a/serve/app/validate/Frame.php b/serve/app/validate/Frame.php
new file mode 100644
index 0000000..57d02cd
--- /dev/null
+++ b/serve/app/validate/Frame.php
@@ -0,0 +1,25 @@
+ ['require'],
+ 'pid' => ['require','integer'],
+ 'sort' => ['require','integer']
+ ];
+
+ //常规规则提示
+ protected $message = [
+ 'name.require' => '组织名称不可为空!',
+ 'pid.require' => '所属组织不可为空!',
+ 'pid.integer' => '所属组织不正确!',
+ 'sort.require' => '组织排序不可为空!',
+ 'sort.integer' => '组织排序不正确!'
+ ];
+
+ //场景规则
+ protected $scene = [
+ 'update' => ['name','pid','sort']
+ ];
+}
\ No newline at end of file
diff --git a/serve/app/validate/Goods.php b/serve/app/validate/Goods.php
new file mode 100644
index 0000000..dcffe13
--- /dev/null
+++ b/serve/app/validate/Goods.php
@@ -0,0 +1,58 @@
+ ['require','unique:goods'],
+ 'number' => ['require','unique:goods'],
+ 'category' => ['require','integer'],
+ 'buy' => ['require','float'],
+ 'sell' => ['require','float'],
+ 'stock' => ['require','float'],
+ 'type' => ['require','integer'],
+ 'imgs' => ['array'],
+ 'units' => ['array'],
+ 'serial' => ['require','boolean'],
+ 'batch' => ['require','boolean'],
+ 'protect' => ['require','integer'],
+ 'threshold' => ['require','integer'],
+ 'more' => ['array'],
+ ];
+
+ //常规规则提示
+ protected $message = [
+ 'name.require' => '商品名称不可为空!',
+ 'name.unique' => '商品名称重复!',
+ 'number.require' => '商品编号不可为空!',
+ 'number.unique' => '商品编号重复!',
+ 'category.require' => '商品分类不可为空!',
+ 'category.integer' => '商品分类不正确!',
+ 'buy.require' => '采购价格不可为空!',
+ 'buy.float' => '采购价格不正确!',
+ 'sell.require' => '销售价格不可为空!',
+ 'sell.float' => '销售价格不正确!',
+ 'stock.require' => '库存阈值不可为空!',
+ 'stock.float' => '库存阈值不正确!',
+ 'type.require' => '商品类型不可为空!',
+ 'type.integer' => '商品类型不正确!',
+ 'imgs.array' => '商品图像不正确!',
+ 'units.array' => '多单位配置不正确!',
+ 'serial.require' => '序列商品不可为空!',
+ 'serial.boolean' => '序列商品不正确!',
+ 'batch.require' => '批次商品不可为空!',
+ 'batch.boolean' => '批次商品不正确!',
+ 'protect.require' => '保质期不可为空!',
+ 'protect.integer' => '保质期不正确!',
+ 'threshold.require' => '保质期不可为空!',
+ 'threshold.integer' => '预警阀值不正确!',
+ 'more.array' => '扩展信息不正确!',
+ ];
+
+ //场景规则
+ protected $scene = [
+ 'update' => ['name','number','category','buy','sell','stock','type','imgs','units','serial','batch','protect','threshold','more'],
+ 'imports' => ['name','number','buy','sell','stock','type','imgs','units','serial','batch','protect','threshold','more']
+ ];
+}
\ No newline at end of file
diff --git a/serve/app/validate/Ice.php b/serve/app/validate/Ice.php
new file mode 100644
index 0000000..81bf851
--- /dev/null
+++ b/serve/app/validate/Ice.php
@@ -0,0 +1,44 @@
+['integer'],
+ 'time' => ['require','date'],
+ 'number' => ['require','unique:ice'],
+ 'total' => ['require','float'],
+ 'actual' => ['require','float'],
+ 'money' => ['require','float'],
+ 'account' => ['requireWith:money'],
+ 'people' => ['integer'],
+ 'file' => ['array'],
+ 'more' => ['array']
+ ];
+
+ //常规规则提示
+ protected $message = [
+ 'customer.integer' => '客户不正确!',
+ 'time.require' => '单据日期不可为空!',
+ 'time.date' => '单据日期不正确!',
+ 'number.require' => '单据编号不可为空!',
+ 'number.unique' => '单据编号重复!',
+ 'total.require' => '单据金额不可为空!',
+ 'total.float' => '单据金额不正确!',
+ 'actual.require' => '实际金额不可为空!',
+ 'actual.float' => '实际金额不正确!',
+ 'money.require' => '实收金额不可为空!',
+ 'money.float' => '实收金额不正确!',
+ 'account.requireWith' => '结算账户不可为空!',
+ 'account.integer' => '资金账户不正确!',
+ 'people.integer' => '关联人员不正确!',
+ 'file.array' => '单据附件不正确!',
+ 'more.array' => '扩展信息不正确!'
+ ];
+
+ //场景规则
+ protected $scene = [
+ 'update' => ['customer','time','number','total','actual','money','account','people','file','more']
+ ];
+}
\ No newline at end of file
diff --git a/serve/app/validate/IceInfo.php b/serve/app/validate/IceInfo.php
new file mode 100644
index 0000000..a433731
--- /dev/null
+++ b/serve/app/validate/IceInfo.php
@@ -0,0 +1,19 @@
+ ['require','integer'],
+ 'money' => ['require','float']
+ ];
+
+ //常规规则提示
+ protected $message = [
+ 'iet.require' => '收入类型不可为空!',
+ 'iet.integer' => '收入类型不正确!',
+ 'money.require' => '结算金额不可为空!',
+ 'money.float' => '结算金额不正确!'
+ ];
+}
\ No newline at end of file
diff --git a/serve/app/validate/Iet.php b/serve/app/validate/Iet.php
new file mode 100644
index 0000000..7cdba02
--- /dev/null
+++ b/serve/app/validate/Iet.php
@@ -0,0 +1,21 @@
+ ['require', 'unique:iet'],
+ ];
+
+ //常规规则提示
+ protected $message = [
+ 'name.require' => '类别名称不可为空!',
+ 'name.unique' => '类别名称不可重复!',
+ ];
+
+ //场景规则
+ protected $scene = [
+ 'update' => ['name']
+ ];
+}
\ No newline at end of file
diff --git a/serve/app/validate/Imy.php b/serve/app/validate/Imy.php
new file mode 100644
index 0000000..4d86950
--- /dev/null
+++ b/serve/app/validate/Imy.php
@@ -0,0 +1,37 @@
+ ['require','integer'],
+ 'time' => ['require','date'],
+ 'number' => ['require','unique:imy'],
+ 'total' => ['require','float'],
+ 'people' => ['integer'],
+ 'file' => ['array'],
+ 'more' => ['array']
+ ];
+
+ //常规规则提示
+ protected $message = [
+
+ 'customer.require' => '客户不可为空!',
+ 'customer.integer' => '客户不正确!',
+ 'time.require' => '单据日期不可为空!',
+ 'time.date' => '单据日期不正确!',
+ 'number.require' => '单据编号不可为空!',
+ 'number.unique' => '单据编号重复!',
+ 'total.require' => '单据金额不可为空!',
+ 'total.float' => '单据金额不正确!',
+ 'people.integer' => '关联人员不正确!',
+ 'file.array' => '单据附件不正确!',
+ 'more.array' => '扩展信息不正确!'
+ ];
+
+ //场景规则
+ protected $scene = [
+ 'update' => ['customer','time','number','total','people','file','more']
+ ];
+}
\ No newline at end of file
diff --git a/serve/app/validate/ImyInfo.php b/serve/app/validate/ImyInfo.php
new file mode 100644
index 0000000..78429b6
--- /dev/null
+++ b/serve/app/validate/ImyInfo.php
@@ -0,0 +1,19 @@
+ ['require','integer'],
+ 'money' => ['require','float']
+ ];
+
+ //常规规则提示
+ protected $message = [
+ 'account.require' => '结算账户不可为空!',
+ 'account.integer' => '结算账户不正确!',
+ 'money.require' => '结算金额不可为空!',
+ 'money.float' => '结算金额不正确!'
+ ];
+}
\ No newline at end of file
diff --git a/serve/app/validate/Invoice.php b/serve/app/validate/Invoice.php
new file mode 100644
index 0000000..f843f87
--- /dev/null
+++ b/serve/app/validate/Invoice.php
@@ -0,0 +1,30 @@
+ ['require'],
+ 'class' => ['require','integer'],
+ 'time' => ['require','date'],
+ 'number' => ['require'],
+ 'title' => ['require'],
+ 'money' => ['require','float'],
+ 'file' => ['array'],
+ ];
+
+ //常规规则提示
+ protected $message = [
+ 'type.require' => '单据类型不可为空!',
+ 'class.require' => '所属单据不可为空!',
+ 'class.integer' => '所属单据不正确!',
+ 'time.require' => '开票时间不可为空!',
+ 'time.date' => '开票时间不正确!',
+ 'number.require' => '发票号码不可为空!',
+ 'title.require' => '发票抬头不可为空!',
+ 'money.require' => '开票金额不可为空!',
+ 'money.float' => '开票金额不正确!',
+ 'file.array' => '发票附件不正确!'
+ ];
+}
\ No newline at end of file
diff --git a/serve/app/validate/Menu.php b/serve/app/validate/Menu.php
new file mode 100644
index 0000000..4785ec2
--- /dev/null
+++ b/serve/app/validate/Menu.php
@@ -0,0 +1,31 @@
+ ['require'],
+ 'key' => ['require','unique:menu'],
+ 'pid' => ['require','integer'],
+ 'type' => ['require','integer'],
+ 'sort' => ['require','integer']
+ ];
+
+ //常规规则提示
+ protected $message = [
+ 'name.require' => '菜单名称不可为空!',
+ 'key.require' => '菜单标识不可为空!',
+ 'key.unique' => '菜单标识重复!',
+ 'pid.require' => '所属菜单不可为空!',
+ 'pid.integer' => '所属菜单不正确!',
+ 'type.require' => '菜单类型不可为空!',
+ 'type.integer' => '菜单类型不正确!',
+ 'sort.require' => '菜单排序不可为空!',
+ 'sort.integer' => '菜单排序不正确!'
+ ];
+
+ //场景规则
+ protected $scene = [
+ 'update' => ['name','key','pid','type','sort']
+ ];
+}
\ No newline at end of file
diff --git a/serve/app/validate/Mould.php b/serve/app/validate/Mould.php
new file mode 100644
index 0000000..7b23eaa
--- /dev/null
+++ b/serve/app/validate/Mould.php
@@ -0,0 +1,30 @@
+ ['require'],
+ 'key' => ['require'],
+ 'sort' => ['require','integer'],
+ 'source' => ['require','array'],
+ 'code' => ['require'],
+ ];
+
+ //常规规则提示
+ protected $message = [
+ 'name.require' => '模板名称不可为空!',
+ 'key.require' => '模板标识不可为空!',
+ 'sort.require' => '组织排序不可为空!',
+ 'sort.integer' => '组织排序不正确!',
+ 'source.require' => '数据源不可为空!',
+ 'source.array' => '数据源不正确!',
+ 'code.require' => '模板代码不可为空!',
+ ];
+
+ //场景规则
+ protected $scene = [
+ 'update' => ['name','key','sort','source','code']
+ ];
+}
\ No newline at end of file
diff --git a/serve/app/validate/Oce.php b/serve/app/validate/Oce.php
new file mode 100644
index 0000000..574d6d7
--- /dev/null
+++ b/serve/app/validate/Oce.php
@@ -0,0 +1,44 @@
+['integer'],
+ 'time' => ['require','date'],
+ 'number' => ['require','unique:oce'],
+ 'total' => ['require','float'],
+ 'actual' => ['require','float'],
+ 'account' => ['requireWith:money'],
+ 'account'=>['require','integer'],
+ 'people' => ['integer'],
+ 'file' => ['array'],
+ 'more' => ['array']
+ ];
+
+ //常规规则提示
+ protected $message = [
+ 'supplier.integer' => '供应商不正确!',
+ 'time.require' => '单据日期不可为空!',
+ 'time.date' => '单据日期不正确!',
+ 'number.require' => '单据编号不可为空!',
+ 'number.unique' => '单据编号重复!',
+ 'total.require' => '单据金额不可为空!',
+ 'total.float' => '单据金额不正确!',
+ 'actual.require' => '实际金额不可为空!',
+ 'actual.float' => '实际金额不正确!',
+ 'money.require' => '实付金额不可为空!',
+ 'money.float' => '实付金额不正确!',
+ 'account.requireWith' => '结算账户不可为空!',
+ 'account.integer' => '资金账户不正确!',
+ 'people.integer' => '关联人员不正确!',
+ 'file.array' => '单据附件不正确!',
+ 'more.array' => '扩展信息不正确!'
+ ];
+
+ //场景规则
+ protected $scene = [
+ 'update' => ['supplier','time','number','total','actual','money','account','people','file','more']
+ ];
+}
\ No newline at end of file
diff --git a/serve/app/validate/OceInfo.php b/serve/app/validate/OceInfo.php
new file mode 100644
index 0000000..cd8b8a5
--- /dev/null
+++ b/serve/app/validate/OceInfo.php
@@ -0,0 +1,22 @@
+ ['require','integer'],
+ 'iet' => ['require','integer'],
+ 'money' => ['require','float']
+ ];
+
+ //常规规则提示
+ protected $message = [
+ 'source.require' => '关联详情不可为空!',
+ 'source.integer' => '关联详情不正确!',
+ 'iet.require' => '收入类型不可为空!',
+ 'iet.integer' => '收入类型不正确!',
+ 'money.require' => '结算金额不可为空!',
+ 'money.float' => '结算金额不正确!'
+ ];
+}
\ No newline at end of file
diff --git a/serve/app/validate/Omy.php b/serve/app/validate/Omy.php
new file mode 100644
index 0000000..83e14aa
--- /dev/null
+++ b/serve/app/validate/Omy.php
@@ -0,0 +1,37 @@
+ ['require','integer'],
+ 'time' => ['require','date'],
+ 'number' => ['require','unique:omy'],
+ 'total' => ['require','float'],
+ 'people' => ['integer'],
+ 'file' => ['array'],
+ 'more' => ['array']
+ ];
+
+ //常规规则提示
+ protected $message = [
+
+ 'supplier.require' => '供应商不可为空!',
+ 'supplier.integer' => '供应商不正确!',
+ 'time.require' => '单据日期不可为空!',
+ 'time.date' => '单据日期不正确!',
+ 'number.require' => '单据编号不可为空!',
+ 'number.unique' => '单据编号重复!',
+ 'total.require' => '单据金额不可为空!',
+ 'total.float' => '单据金额不正确!',
+ 'people.integer' => '关联人员不正确!',
+ 'file.array' => '单据附件不正确!',
+ 'more.array' => '扩展信息不正确!'
+ ];
+
+ //场景规则
+ protected $scene = [
+ 'update' => ['supplier','time','number','total','people','file','more']
+ ];
+}
\ No newline at end of file
diff --git a/serve/app/validate/OmyInfo.php b/serve/app/validate/OmyInfo.php
new file mode 100644
index 0000000..647d436
--- /dev/null
+++ b/serve/app/validate/OmyInfo.php
@@ -0,0 +1,19 @@
+ ['require','integer'],
+ 'money' => ['require','float']
+ ];
+
+ //常规规则提示
+ protected $message = [
+ 'account.require' => '结算账户不可为空!',
+ 'account.integer' => '结算账户不正确!',
+ 'money.require' => '结算金额不可为空!',
+ 'money.float' => '结算金额不正确!'
+ ];
+}
\ No newline at end of file
diff --git a/serve/app/validate/People.php b/serve/app/validate/People.php
new file mode 100644
index 0000000..cba556e
--- /dev/null
+++ b/serve/app/validate/People.php
@@ -0,0 +1,31 @@
+ ['require'],
+ 'number' => ['require','unique:people'],
+ 'frame' => ['require','integer'],
+ 'sex' => ['require','integer'],
+ 'more' => ['array']
+ ];
+
+ //常规规则提示
+ protected $message = [
+ 'name.require' => '人员名称不可为空!',
+ 'number.require' => '人员编号不可为空!',
+ 'number.unique' => '人员编号重复!',
+ 'frame.require' => '所属组织不可为空!',
+ 'frame.integer' => '所属组织不正确!',
+ 'sex.require' => '性别不可为空!',
+ 'sex.integer' => '性别不正确!',
+ 'more.array' => '扩展信息不正确!',
+ ];
+
+ //场景规则
+ protected $scene = [
+ 'update' => ['name','number','frame','sex','more'],
+ ];
+}
\ No newline at end of file
diff --git a/serve/app/validate/Role.php b/serve/app/validate/Role.php
new file mode 100644
index 0000000..5aedc29
--- /dev/null
+++ b/serve/app/validate/Role.php
@@ -0,0 +1,26 @@
+ ['require'],
+ 'root' => ['require','array'],
+ 'auth' => ['require','array']
+ ];
+
+ //常规规则提示
+ protected $message = [
+ 'name.require' => '角色名称不可为空!',
+ 'root.require' => '功能权限不可为空!',
+ 'root.array' => '功能权限不正确!',
+ 'auth.require' => '数据权限不可为空!',
+ 'auth.array' => '数据权限不正确!',
+ ];
+
+ //场景规则
+ protected $scene = [
+ 'update' => ['name','root','auth']
+ ];
+}
\ No newline at end of file
diff --git a/serve/app/validate/Sell.php b/serve/app/validate/Sell.php
new file mode 100644
index 0000000..b33bbab
--- /dev/null
+++ b/serve/app/validate/Sell.php
@@ -0,0 +1,49 @@
+ ['require','integer'],
+ 'customer' => ['require','integer'],
+ 'time' => ['require','date'],
+ 'number' => ['require','unique:sell'],
+ 'total' => ['require','float'],
+ 'actual' => ['require','float'],
+ 'money' => ['require','float'],
+ 'account' => ['requireWith:money'],
+ 'people' => ['integer'],
+ 'logistics' => ['array'],
+ 'file' => ['array'],
+ 'more' => ['array']
+ ];
+
+ //常规规则提示
+ protected $message = [
+ 'source.require' => '关联单据不可为空!',
+ 'source.integer' => '关联单据不正确!',
+ 'customer.require' => '客户不可为空!',
+ 'customer.integer' => '客户不正确!',
+ 'time.require' => '单据日期不可为空!',
+ 'time.date' => '单据日期不正确!',
+ 'number.require' => '单据编号不可为空!',
+ 'number.unique' => '单据编号重复!',
+ 'total.require' => '单据金额不可为空!',
+ 'total.float' => '单据金额不正确!',
+ 'actual.require' => '实际金额不可为空!',
+ 'actual.float' => '实际金额不正确!',
+ 'money.require' => '实收金额不可为空!',
+ 'money.float' => '实收金额不正确!',
+ 'account.requireWith' => '结算账户不可为空!',
+ 'people.integer' => '关联人员不正确!',
+ 'logistics.array' => '物流信息不正确!',
+ 'file.array' => '单据附件不正确!',
+ 'more.array' => '扩展信息不正确!'
+ ];
+
+ //场景规则
+ protected $scene = [
+ 'update' => ['source','customer','time','number','total','actual','money','account','people','logistics','file','more']
+ ];
+}
\ No newline at end of file
diff --git a/serve/app/validate/SellInfo.php b/serve/app/validate/SellInfo.php
new file mode 100644
index 0000000..e486735
--- /dev/null
+++ b/serve/app/validate/SellInfo.php
@@ -0,0 +1,50 @@
+ ['require','integer'],
+ 'goods' => ['require','integer'],
+ 'warehouse' => ['integer'],
+ 'mfd' => ['date'],
+ 'price' => ['require','float'],
+ 'nums' => ['require','float'],
+ 'serial' => ['array'],
+ 'discount' => ['require','between:0,100'],
+ 'dsc' => ['require','float'],
+ 'total' => ['require','float'],
+ 'tax' => ['require','between:0,100'],
+ 'tat' => ['require','float'],
+ 'tpt' => ['require','float']
+ ];
+
+ //常规规则提示
+ protected $message = [
+ 'source.require' => '关联详情不可为空!',
+ 'source.integer' => '关联详情不正确!',
+ 'goods.require' => '商品信息不可为空!',
+ 'goods.integer' => '商品信息不正确!',
+ 'warehouse.integer' => '仓库不正确!',
+ 'mfd.require' => '生产日期不正确!',
+ 'price.require' => '单价不可为空!',
+ 'price.float' => '单价不正确!',
+ 'nums.require' => '数量不可为空!',
+ 'nums.float' => '数量不正确!',
+ 'serial.require' => '序列号不可为空!',
+ 'serial.array' => '序列号不正确!',
+ 'discount.require' => '折扣率不可为空!',
+ 'discount.between' => '折扣率不正确!',
+ 'dsc.require' => '折扣额不可为空!',
+ 'dsc.float' => '折扣额不正确!',
+ 'total.require' => '金额不可为空!',
+ 'total.float' => '金额不正确!',
+ 'tax.require' => '税率不可为空!',
+ 'tax.between' => '税率不正确!',
+ 'tat.require' => '税额不可为空!',
+ 'tat.float' => '税额不正确!',
+ 'tpt.require' => '价税合计不可为空!',
+ 'tpt.float' => '价税合计不正确!'
+ ];
+}
\ No newline at end of file
diff --git a/serve/app/validate/Sor.php b/serve/app/validate/Sor.php
new file mode 100644
index 0000000..db94ec4
--- /dev/null
+++ b/serve/app/validate/Sor.php
@@ -0,0 +1,41 @@
+ ['require','integer'],
+ 'time' => ['require','date'],
+ 'number' => ['require','unique:sor'],
+ 'total' => ['require','float'],
+ 'actual' => ['require','float'],
+ 'people' => ['integer'],
+ 'logistics' => ['array'],
+ 'file' => ['array'],
+ 'more' => ['array']
+ ];
+
+ //常规规则提示
+ protected $message = [
+ 'customer.require' => '客户不可为空!',
+ 'customer.integer' => '客户不正确!',
+ 'time.require' => '单据日期不可为空!',
+ 'time.date' => '单据日期不正确!',
+ 'number.require' => '单据编号不可为空!',
+ 'number.unique' => '单据编号重复!',
+ 'total.require' => '单据金额不可为空!',
+ 'total.float' => '单据金额不正确!',
+ 'actual.require' => '实际金额不可为空!',
+ 'actual.float' => '实际金额不正确!',
+ 'people.integer' => '关联人员不正确!',
+ 'logistics.array' => '物流信息不正确!',
+ 'file.array' => '单据附件不正确!',
+ 'more.array' => '扩展信息不正确!',
+ ];
+
+ //场景规则
+ protected $scene = [
+ 'update' => ['customer','time','number','total','actual','people','logistics','file','more']
+ ];
+}
\ No newline at end of file
diff --git a/serve/app/validate/SorInfo.php b/serve/app/validate/SorInfo.php
new file mode 100644
index 0000000..efe63c2
--- /dev/null
+++ b/serve/app/validate/SorInfo.php
@@ -0,0 +1,42 @@
+ ['require','integer'],
+ 'warehouse' => ['integer'],
+ 'price' => ['require','float'],
+ 'nums' => ['require','float'],
+ 'discount' => ['require','between:0,100'],
+ 'dsc' => ['require','float'],
+ 'total' => ['require','float'],
+ 'tax' => ['require','between:0,100'],
+ 'tat' => ['require','float'],
+ 'tpt' => ['require','float']
+ ];
+
+ //常规规则提示
+ protected $message = [
+ 'goods.require' => '商品信息不可为空!',
+ 'goods.integer' => '商品信息不正确!',
+ 'warehouse.integer' => '仓库不正确!',
+ 'price.require' => '单价不可为空!',
+ 'price.float' => '单价不正确!',
+ 'nums.require' => '数量不可为空!',
+ 'nums.float' => '数量不正确!',
+ 'discount.require' => '折扣率不可为空!',
+ 'discount.between' => '折扣率不正确!',
+ 'dsc.require' => '折扣额不可为空!',
+ 'dsc.float' => '折扣额不正确!',
+ 'total.require' => '金额不可为空!',
+ 'total.float' => '金额不正确!',
+ 'tax.require' => '税率不可为空!',
+ 'tax.between' => '税率不正确!',
+ 'tat.require' => '税额不可为空!',
+ 'tat.float' => '税额不正确!',
+ 'tpt.require' => '价税合计不可为空!',
+ 'tpt.float' => '价税合计不正确!'
+ ];
+}
\ No newline at end of file
diff --git a/serve/app/validate/Sre.php b/serve/app/validate/Sre.php
new file mode 100644
index 0000000..ea953c8
--- /dev/null
+++ b/serve/app/validate/Sre.php
@@ -0,0 +1,49 @@
+ ['require','integer'],
+ 'customer' => ['require','integer'],
+ 'time' => ['require','date'],
+ 'number' => ['require','unique:sre'],
+ 'total' => ['require','float'],
+ 'actual' => ['require','float'],
+ 'money' => ['require','float'],
+ 'account' => ['requireWith:money'],
+ 'people' => ['integer'],
+ 'logistics' => ['array'],
+ 'file' => ['array'],
+ 'more' => ['array']
+ ];
+
+ //常规规则提示
+ protected $message = [
+ 'source.require' => '关联单据不可为空!',
+ 'source.integer' => '关联单据不正确!',
+ 'customer.require' => '客户不可为空!',
+ 'customer.integer' => '客户不正确!',
+ 'time.require' => '单据日期不可为空!',
+ 'time.date' => '单据日期不正确!',
+ 'number.require' => '单据编号不可为空!',
+ 'number.unique' => '单据编号重复!',
+ 'total.require' => '单据金额不可为空!',
+ 'total.float' => '单据金额不正确!',
+ 'actual.require' => '实际金额不可为空!',
+ 'actual.float' => '实际金额不正确!',
+ 'money.require' => '实付金额不可为空!',
+ 'money.float' => '实付金额不正确!',
+ 'account.requireWith' => '结算账户不可为空!',
+ 'people.integer' => '关联人员不正确!',
+ 'logistics.array' => '物流信息不正确!',
+ 'file.array' => '单据附件不正确!',
+ 'more.array' => '扩展信息不正确!'
+ ];
+
+ //场景规则
+ protected $scene = [
+ 'update' => ['source','customer','time','number','total','actual','money','account','people','logistics','file','more']
+ ];
+}
\ No newline at end of file
diff --git a/serve/app/validate/SreInfo.php b/serve/app/validate/SreInfo.php
new file mode 100644
index 0000000..fad7d6d
--- /dev/null
+++ b/serve/app/validate/SreInfo.php
@@ -0,0 +1,50 @@
+ ['require','integer'],
+ 'goods' => ['require','integer'],
+ 'warehouse' => ['integer'],
+ 'mfd' => ['date'],
+ 'price' => ['require','float'],
+ 'nums' => ['require','float'],
+ 'serial' => ['array'],
+ 'discount' => ['require','between:0,100'],
+ 'dsc' => ['require','float'],
+ 'total' => ['require','float'],
+ 'tax' => ['require','between:0,100'],
+ 'tat' => ['require','float'],
+ 'tpt' => ['require','float']
+ ];
+
+ //常规规则提示
+ protected $message = [
+ 'source.require' => '关联详情不可为空!',
+ 'source.integer' => '关联详情不正确!',
+ 'goods.require' => '商品信息不可为空!',
+ 'goods.integer' => '商品信息不正确!',
+ 'warehouse.integer' => '仓库不正确!',
+ 'mfd.require' => '生产日期不正确!',
+ 'price.require' => '单价不可为空!',
+ 'price.float' => '单价不正确!',
+ 'nums.require' => '数量不可为空!',
+ 'nums.float' => '数量不正确!',
+ 'serial.require' => '序列号不可为空!',
+ 'serial.array' => '序列号不正确!',
+ 'discount.require' => '折扣率不可为空!',
+ 'discount.between' => '折扣率不正确!',
+ 'dsc.require' => '折扣额不可为空!',
+ 'dsc.float' => '折扣额不正确!',
+ 'total.require' => '金额不可为空!',
+ 'total.float' => '金额不正确!',
+ 'tax.require' => '税率不可为空!',
+ 'tax.between' => '税率不正确!',
+ 'tat.require' => '税额不可为空!',
+ 'tat.float' => '税额不正确!',
+ 'tpt.require' => '价税合计不可为空!',
+ 'tpt.float' => '价税合计不正确!'
+ ];
+}
\ No newline at end of file
diff --git a/serve/app/validate/Supplier.php b/serve/app/validate/Supplier.php
new file mode 100644
index 0000000..202fba7
--- /dev/null
+++ b/serve/app/validate/Supplier.php
@@ -0,0 +1,37 @@
+ ['require'],
+ 'number' => ['require','unique:supplier'],
+ 'frame' => ['require','integer'],
+ 'user' => ['require','integer'],
+ 'rate' => ['require','between:0,100'],
+ 'contacts'=>['array'],
+ 'more' => ['array']
+ ];
+
+ //常规规则提示
+ protected $message = [
+ 'name.require' => '供应商名称不可为空!',
+ 'number.require' => '供应商编号不可为空!',
+ 'number.unique' => '供应商编号重复!',
+ 'frame.require' => '所属组织不可为空!',
+ 'frame.integer' => '所属组织不正确!',
+ 'user.require' => '所属用户不可为空!',
+ 'user.integer' => '所属用户不正确!',
+ 'rate.require' => '增值税税率不可为空!',
+ 'rate.between' => '增值税税率不正确!',
+ 'contacts.array' => '联系资料不正确!',
+ 'more.array' => '扩展信息不正确!',
+
+ ];
+
+ //场景规则
+ protected $scene = [
+ 'update' => ['name','number','frame','user','rate','contacts','more']
+ ];
+}
\ No newline at end of file
diff --git a/serve/app/validate/Swap.php b/serve/app/validate/Swap.php
new file mode 100644
index 0000000..8ea056a
--- /dev/null
+++ b/serve/app/validate/Swap.php
@@ -0,0 +1,32 @@
+ ['require','date'],
+ 'number' => ['require','unique:swap'],
+ 'people' => ['integer'],
+ 'logistics' => ['array'],
+ 'file' => ['array'],
+ 'more' => ['array']
+ ];
+
+ //常规规则提示
+ protected $message = [
+ 'time.require' => '单据日期不可为空!',
+ 'time.date' => '单据日期不正确!',
+ 'number.require' => '单据编号不可为空!',
+ 'number.unique' => '单据编号重复!',
+ 'people.integer' => '关联人员不正确!',
+ 'logistics.array' => '物流信息不正确!',
+ 'file.array' => '单据附件不正确!',
+ 'more.array' => '扩展信息不正确!'
+ ];
+
+ //场景规则
+ protected $scene = [
+ 'update' => ['time','number','people','logistics','file','more']
+ ];
+}
\ No newline at end of file
diff --git a/serve/app/validate/SwapInfo.php b/serve/app/validate/SwapInfo.php
new file mode 100644
index 0000000..304931f
--- /dev/null
+++ b/serve/app/validate/SwapInfo.php
@@ -0,0 +1,31 @@
+ ['require','integer'],
+ 'warehouse' => ['integer'],
+ 'storehouse' => ['integer'],
+ 'mfd' => ['date'],
+ 'price' => ['require','float'],
+ 'nums' => ['require','float'],
+ 'serial' => ['array'],
+ ];
+
+ //常规规则提示
+ protected $message = [
+ 'goods.require' => '商品信息不可为空!',
+ 'goods.integer' => '商品信息不正确!',
+ 'warehouse.integer' => '调出仓库不正确!',
+ 'storehouse.integer' => '调入仓库不正确!',
+ 'mfd.require' => '生产日期不正确!',
+ 'price.require' => '单价不可为空!',
+ 'price.float' => '单价不正确!',
+ 'nums.require' => '数量不可为空!',
+ 'nums.float' => '数量不正确!',
+ 'serial.require' => '序列号不可为空!',
+ 'serial.array' => '序列号不正确!'
+ ];
+}
\ No newline at end of file
diff --git a/serve/app/validate/User.php b/serve/app/validate/User.php
new file mode 100644
index 0000000..29323e2
--- /dev/null
+++ b/serve/app/validate/User.php
@@ -0,0 +1,35 @@
+ ['require'],
+ 'frame' => ['require','integer'],
+ 'role' => ['integer'],
+ 'user' => ['require','unique:user'],
+ 'tel' => ['require','unique:user'],
+ 'pwd' => ['require'],
+ 'more' => ['array']
+ ];
+
+ //常规规则提示
+ protected $message = [
+ 'name.require' => '用户名称不可为空!',
+ 'frame.require' => '所属组织不可为空!',
+ 'frame.integer' => '所属组织不正确!',
+ 'role.integer' => '用户角色不正确!',
+ 'user.require' => '用户账号不可为空!',
+ 'user.unique' => '用户账号重复!',
+ 'tel.require' => '手机号码不可为空!',
+ 'tel.unique' => '手机号码重复!',
+ 'pwd.require' => '用户密码不可为空!',
+ 'more.array' => '扩展信息不正确!',
+ ];
+
+ //场景规则
+ protected $scene = [
+ 'update' => ['name','frame','role','user','tel','more']
+ ];
+}
\ No newline at end of file
diff --git a/serve/app/validate/Warehouse.php b/serve/app/validate/Warehouse.php
new file mode 100644
index 0000000..ff46ca6
--- /dev/null
+++ b/serve/app/validate/Warehouse.php
@@ -0,0 +1,26 @@
+ ['require','unique:warehouse'],
+ 'number' => ['require','unique:warehouse'],
+ 'frame' => ['require','integer']
+ ];
+
+ //常规规则提示
+ protected $message = [
+ 'name.require' => '仓库名称不可为空!',
+ 'name.unique' => '仓库名称重复!',
+ 'number.require' => '仓库编号不可为空!',
+ 'number.unique' => '仓库编号重复!',
+ 'frame.require' => '所属组织不可为空!',
+ 'frame.integer' => '所属组织不正确!'
+ ];
+
+ //场景规则
+ protected $scene = [
+ 'update' => ['name','number','frame']
+ ];
+}
\ No newline at end of file
diff --git a/serve/app/view/index/index.html b/serve/app/view/index/index.html
new file mode 100644
index 0000000..09fa5e1
--- /dev/null
+++ b/serve/app/view/index/index.html
@@ -0,0 +1 @@
+
点可云进销存软件
\ No newline at end of file
diff --git a/serve/composer.json b/serve/composer.json
new file mode 100644
index 0000000..1c26a63
--- /dev/null
+++ b/serve/composer.json
@@ -0,0 +1,61 @@
+{
+ "name": "topthink/think",
+ "description": "the new thinkphp framework",
+ "type": "project",
+ "keywords": [
+ "framework",
+ "thinkphp",
+ "ORM"
+ ],
+ "homepage": "http://thinkphp.cn/",
+ "license": "Apache-2.0",
+ "authors": [
+ {
+ "name": "liu21st",
+ "email": "liu21st@gmail.com"
+ }
+ ],
+ "require": {
+ "php": ">=7.1.0",
+ "topthink/framework": "^6.0.0",
+ "topthink/think-orm": "^2.0",
+ "ezyang/htmlpurifier": "^4.11",
+ "phpoffice/phpspreadsheet": "^1.9",
+ "endroid/qr-code": "^3.7",
+ "barcode-bakery/barcode-common": "*",
+ "barcode-bakery/barcode-1d": "*",
+ "alipaysdk/easysdk": "^2.0",
+ "topthink/think-view": "^1.0"
+ },
+ "repositories": [
+ {
+ "type": "path",
+ "url": "vendor/packages/barcode-common"
+ },
+ {
+ "type": "path",
+ "url": "vendor/packages/barcode-1d"
+ }
+ ],
+ "require-dev": {
+ "symfony/var-dumper": "^4.2",
+ "topthink/think-trace": "^1.0"
+ },
+ "autoload": {
+ "psr-4": {
+ "app\\": "app"
+ },
+ "psr-0": {
+ "": "extend/"
+ }
+ },
+ "config": {
+ "preferred-install": "dist"
+ },
+ "scripts": {
+ "post-autoload-dump": [
+ "@php think service:discover",
+ "@php think vendor:publish"
+ ]
+ }
+}
diff --git a/serve/composer.lock b/serve/composer.lock
new file mode 100644
index 0000000..c916131
--- /dev/null
+++ b/serve/composer.lock
@@ -0,0 +1,3525 @@
+{
+ "_readme": [
+ "This file locks the dependencies of your project to a known state",
+ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
+ "This file is @generated automatically"
+ ],
+ "content-hash": "48dc658954150aad85085b97433b801a",
+ "packages": [
+ {
+ "name": "adbario/php-dot-notation",
+ "version": "2.2.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/adbario/php-dot-notation.git",
+ "reference": "eee4fc81296531e6aafba4c2bbccfc5adab1676e"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/adbario/php-dot-notation/zipball/eee4fc81296531e6aafba4c2bbccfc5adab1676e",
+ "reference": "eee4fc81296531e6aafba4c2bbccfc5adab1676e",
+ "shasum": ""
+ },
+ "require": {
+ "ext-json": "*",
+ "php": ">=5.5"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^4.0|^5.0|^6.0",
+ "squizlabs/php_codesniffer": "^3.0"
+ },
+ "type": "library",
+ "autoload": {
+ "files": [
+ "src/helpers.php"
+ ],
+ "psr-4": {
+ "Adbar\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Riku Särkinen",
+ "email": "riku@adbar.io"
+ }
+ ],
+ "description": "PHP dot notation access to arrays",
+ "homepage": "https://github.com/adbario/php-dot-notation",
+ "keywords": [
+ "ArrayAccess",
+ "dotnotation"
+ ],
+ "support": {
+ "issues": "https://github.com/adbario/php-dot-notation/issues",
+ "source": "https://github.com/adbario/php-dot-notation/tree/2.x"
+ },
+ "time": "2019-01-01T23:59:15+00:00"
+ },
+ {
+ "name": "alibabacloud/tea",
+ "version": "3.1.21",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/aliyun/tea-php.git",
+ "reference": "379faffe240ee97134cf3f796cb28059f9fb7fa9"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/aliyun/tea-php/zipball/379faffe240ee97134cf3f796cb28059f9fb7fa9",
+ "reference": "379faffe240ee97134cf3f796cb28059f9fb7fa9",
+ "shasum": ""
+ },
+ "require": {
+ "adbario/php-dot-notation": "^2.2",
+ "ext-curl": "*",
+ "ext-json": "*",
+ "ext-libxml": "*",
+ "ext-mbstring": "*",
+ "ext-openssl": "*",
+ "ext-simplexml": "*",
+ "ext-xmlwriter": "*",
+ "guzzlehttp/guzzle": "^6.3|^7.0",
+ "php": ">=5.5"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "*",
+ "symfony/dotenv": "^3.4",
+ "symfony/var-dumper": "^3.4"
+ },
+ "suggest": {
+ "ext-sockets": "To use client-side monitoring"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "AlibabaCloud\\Tea\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "Apache-2.0"
+ ],
+ "authors": [
+ {
+ "name": "Alibaba Cloud SDK",
+ "email": "sdk-team@alibabacloud.com",
+ "homepage": "http://www.alibabacloud.com"
+ }
+ ],
+ "description": "Client of Tea for PHP",
+ "homepage": "https://www.alibabacloud.com/",
+ "keywords": [
+ "alibabacloud",
+ "client",
+ "cloud",
+ "tea"
+ ],
+ "support": {
+ "issues": "https://github.com/aliyun/tea-php/issues",
+ "source": "https://github.com/aliyun/tea-php"
+ },
+ "time": "2021-03-15T03:31:41+00:00"
+ },
+ {
+ "name": "alibabacloud/tea-fileform",
+ "version": "0.3.4",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/alibabacloud-sdk-php/tea-fileform.git",
+ "reference": "4bf0c75a045c8115aa8cb1a394bd08d8bb833181"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/alibabacloud-sdk-php/tea-fileform/zipball/4bf0c75a045c8115aa8cb1a394bd08d8bb833181",
+ "reference": "4bf0c75a045c8115aa8cb1a394bd08d8bb833181",
+ "shasum": ""
+ },
+ "require": {
+ "alibabacloud/tea": "^3.0",
+ "php": ">5.5"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^4.8.35|^5.4.3"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "AlibabaCloud\\Tea\\FileForm\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "Apache-2.0"
+ ],
+ "authors": [
+ {
+ "name": "Alibaba Cloud SDK",
+ "email": "sdk-team@alibabacloud.com"
+ }
+ ],
+ "description": "Alibaba Cloud Tea File Library for PHP",
+ "support": {
+ "issues": "https://github.com/alibabacloud-sdk-php/tea-fileform/issues",
+ "source": "https://github.com/alibabacloud-sdk-php/tea-fileform/tree/0.3.4"
+ },
+ "time": "2020-12-01T07:24:35+00:00"
+ },
+ {
+ "name": "alipaysdk/easysdk",
+ "version": "2.2.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/alipay/alipay-easysdk.git",
+ "reference": "7a1cfa83c7e140bded957498ea072c77611e6480"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/alipay/alipay-easysdk/zipball/7a1cfa83c7e140bded957498ea072c77611e6480",
+ "reference": "7a1cfa83c7e140bded957498ea072c77611e6480",
+ "shasum": ""
+ },
+ "require": {
+ "adbario/php-dot-notation": "^2.2",
+ "alibabacloud/tea": "^3.1",
+ "alibabacloud/tea-fileform": "^0.3.2",
+ "danielstjules/stringy": "^3.1",
+ "ext-ctype": "*",
+ "ext-curl": "*",
+ "ext-dom": "*",
+ "ext-fileinfo": "*",
+ "ext-json": "*",
+ "ext-libxml": "*",
+ "ext-mbstring": "*",
+ "ext-openssl": "*",
+ "ext-simplexml": "*",
+ "ext-xmlwriter": "*",
+ "guzzlehttp/guzzle": ">=6.3",
+ "mtdowling/jmespath.php": "^2.4",
+ "php": ">=7.0",
+ "pimple/pimple": "^3.0",
+ "psr/log": "^1.1",
+ "songshenzong/support": "^2.0",
+ "xin/container": "^2.0.1"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^7.5"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Alipay\\EasySDK\\": "php/src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "Apache-2.0"
+ ],
+ "authors": [
+ {
+ "name": "junying.wjy",
+ "email": "junying.wjy@antfin.com"
+ }
+ ],
+ "description": "支付宝官方 Alipay Easy SDK",
+ "support": {
+ "issues": "https://github.com/alipay/alipay-easysdk/issues",
+ "source": "https://github.com/alipay/alipay-easysdk/tree/v2.2.0"
+ },
+ "time": "2021-01-19T07:30:32+00:00"
+ },
+ {
+ "name": "bacon/bacon-qr-code",
+ "version": "2.0.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/Bacon/BaconQrCode.git",
+ "reference": "3e9d791b67d0a2912922b7b7c7312f4b37af41e4"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/Bacon/BaconQrCode/zipball/3e9d791b67d0a2912922b7b7c7312f4b37af41e4",
+ "reference": "3e9d791b67d0a2912922b7b7c7312f4b37af41e4",
+ "shasum": ""
+ },
+ "require": {
+ "dasprid/enum": "^1.0.3",
+ "ext-iconv": "*",
+ "php": "^7.1 || ^8.0"
+ },
+ "require-dev": {
+ "phly/keep-a-changelog": "^1.4",
+ "phpunit/phpunit": "^7 | ^8 | ^9",
+ "squizlabs/php_codesniffer": "^3.4"
+ },
+ "suggest": {
+ "ext-imagick": "to generate QR code images"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "BaconQrCode\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-2-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Ben Scholzen 'DASPRiD'",
+ "email": "mail@dasprids.de",
+ "homepage": "https://dasprids.de/",
+ "role": "Developer"
+ }
+ ],
+ "description": "BaconQrCode is a QR code generator for PHP.",
+ "homepage": "https://github.com/Bacon/BaconQrCode",
+ "support": {
+ "issues": "https://github.com/Bacon/BaconQrCode/issues",
+ "source": "https://github.com/Bacon/BaconQrCode/tree/2.0.3"
+ },
+ "time": "2020-10-30T02:02:47+00:00"
+ },
+ {
+ "name": "barcode-bakery/barcode-1d",
+ "version": "6.0.0",
+ "dist": {
+ "type": "path",
+ "url": "vendor/packages/barcode-1d",
+ "reference": "cd8c30d754d6595bfda13a0fa88e5033179d71f2"
+ },
+ "require": {
+ "ext-gd": "*",
+ "php": ">=5.6"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "BarcodeBakery\\Barcode\\": "src"
+ }
+ },
+ "license": [
+ "Commercial",
+ "CC-BY-NC-ND-4.0"
+ ],
+ "authors": [
+ {
+ "name": "Jean-Sébastien Goupil",
+ "email": "contact@barcodebakery.com"
+ }
+ ],
+ "description": "Generates 1D barcodes from a PHP server to a file or HTML document.",
+ "homepage": "http://www.barcodebakery.com",
+ "keywords": [
+ "bakery",
+ "barcode",
+ "codabar",
+ "code11",
+ "code128",
+ "code39",
+ "code39extended",
+ "code93",
+ "ean-13",
+ "ean-8",
+ "ean13",
+ "ean8",
+ "generator",
+ "i25",
+ "isbn",
+ "msi",
+ "s25",
+ "upc-a",
+ "upc-e",
+ "upcext2",
+ "upcext5"
+ ],
+ "support": {
+ "email": "contact@barcodebakery.com",
+ "docs": "http://www.barcodebakery.com"
+ },
+ "transport-options": {
+ "relative": true
+ }
+ },
+ {
+ "name": "barcode-bakery/barcode-common",
+ "version": "6.0.0",
+ "dist": {
+ "type": "path",
+ "url": "vendor/packages/barcode-common",
+ "reference": "289043a2fd5fc8e18c28f1565b50bfd21a712fbd"
+ },
+ "require": {
+ "ext-gd": "*",
+ "php": ">=5.6"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "BarcodeBakery\\Common\\": "src"
+ }
+ },
+ "license": [
+ "Commercial",
+ "CC-BY-NC-ND-4.0"
+ ],
+ "authors": [
+ {
+ "name": "Jean-Sébastien Goupil",
+ "email": "contact@barcodebakery.com"
+ }
+ ],
+ "description": "Base code for generating barcode with the Barcode Bakery library. See barcode-bakery/barcode-1d.",
+ "homepage": "http://www.barcodebakery.com",
+ "support": {
+ "email": "contact@barcodebakery.com",
+ "docs": "http://www.barcodebakery.com"
+ },
+ "transport-options": {
+ "relative": true
+ }
+ },
+ {
+ "name": "danielstjules/stringy",
+ "version": "3.1.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/danielstjules/Stringy.git",
+ "reference": "df24ab62d2d8213bbbe88cc36fc35a4503b4bd7e"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/danielstjules/Stringy/zipball/df24ab62d2d8213bbbe88cc36fc35a4503b4bd7e",
+ "reference": "df24ab62d2d8213bbbe88cc36fc35a4503b4bd7e",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.4.0",
+ "symfony/polyfill-mbstring": "~1.1"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "~4.0"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Stringy\\": "src/"
+ },
+ "files": [
+ "src/Create.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Daniel St. Jules",
+ "email": "danielst.jules@gmail.com",
+ "homepage": "http://www.danielstjules.com"
+ }
+ ],
+ "description": "A string manipulation library with multibyte support",
+ "homepage": "https://github.com/danielstjules/Stringy",
+ "keywords": [
+ "UTF",
+ "helpers",
+ "manipulation",
+ "methods",
+ "multibyte",
+ "string",
+ "utf-8",
+ "utility",
+ "utils"
+ ],
+ "support": {
+ "issues": "https://github.com/danielstjules/Stringy/issues",
+ "source": "https://github.com/danielstjules/Stringy"
+ },
+ "time": "2017-06-12T01:10:27+00:00"
+ },
+ {
+ "name": "dasprid/enum",
+ "version": "1.0.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/DASPRiD/Enum.git",
+ "reference": "5abf82f213618696dda8e3bf6f64dd042d8542b2"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/DASPRiD/Enum/zipball/5abf82f213618696dda8e3bf6f64dd042d8542b2",
+ "reference": "5abf82f213618696dda8e3bf6f64dd042d8542b2",
+ "shasum": ""
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^7 | ^8 | ^9",
+ "squizlabs/php_codesniffer": "^3.4"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "DASPRiD\\Enum\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-2-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Ben Scholzen 'DASPRiD'",
+ "email": "mail@dasprids.de",
+ "homepage": "https://dasprids.de/",
+ "role": "Developer"
+ }
+ ],
+ "description": "PHP 7.1 enum implementation",
+ "keywords": [
+ "enum",
+ "map"
+ ],
+ "support": {
+ "issues": "https://github.com/DASPRiD/Enum/issues",
+ "source": "https://github.com/DASPRiD/Enum/tree/1.0.3"
+ },
+ "time": "2020-10-02T16:03:48+00:00"
+ },
+ {
+ "name": "endroid/qr-code",
+ "version": "3.9.7",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/endroid/qr-code.git",
+ "reference": "94563d7b3105288e6ac53a67ae720e3669fac1f6"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/endroid/qr-code/zipball/94563d7b3105288e6ac53a67ae720e3669fac1f6",
+ "reference": "94563d7b3105288e6ac53a67ae720e3669fac1f6",
+ "shasum": ""
+ },
+ "require": {
+ "bacon/bacon-qr-code": "^2.0",
+ "khanamiryan/qrcode-detector-decoder": "^1.0.5",
+ "myclabs/php-enum": "^1.5",
+ "php": "^7.3||^8.0",
+ "symfony/options-resolver": "^3.4||^4.4||^5.0",
+ "symfony/property-access": "^3.4||^4.4||^5.0"
+ },
+ "require-dev": {
+ "endroid/quality": "^1.5.2",
+ "setasign/fpdf": "^1.8"
+ },
+ "suggest": {
+ "ext-gd": "Required for generating PNG images",
+ "roave/security-advisories": "Avoids installation of package versions with vulnerabilities",
+ "setasign/fpdf": "Required to use the FPDF writer.",
+ "symfony/security-checker": "Checks your composer.lock for vulnerabilities"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Endroid\\QrCode\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Jeroen van den Enden",
+ "email": "info@endroid.nl"
+ }
+ ],
+ "description": "Endroid QR Code",
+ "homepage": "https://github.com/endroid/qr-code",
+ "keywords": [
+ "bundle",
+ "code",
+ "endroid",
+ "php",
+ "qr",
+ "qrcode"
+ ],
+ "support": {
+ "issues": "https://github.com/endroid/qr-code/issues",
+ "source": "https://github.com/endroid/qr-code/tree/3.9.7"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/endroid",
+ "type": "github"
+ }
+ ],
+ "time": "2021-04-20T19:10:54+00:00"
+ },
+ {
+ "name": "ezyang/htmlpurifier",
+ "version": "v4.13.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/ezyang/htmlpurifier.git",
+ "reference": "08e27c97e4c6ed02f37c5b2b20488046c8d90d75"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/ezyang/htmlpurifier/zipball/08e27c97e4c6ed02f37c5b2b20488046c8d90d75",
+ "reference": "08e27c97e4c6ed02f37c5b2b20488046c8d90d75",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.2"
+ },
+ "require-dev": {
+ "simpletest/simpletest": "dev-master#72de02a7b80c6bb8864ef9bf66d41d2f58f826bd"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-0": {
+ "HTMLPurifier": "library/"
+ },
+ "files": [
+ "library/HTMLPurifier.composer.php"
+ ],
+ "exclude-from-classmap": [
+ "/library/HTMLPurifier/Language/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "LGPL-2.1-or-later"
+ ],
+ "authors": [
+ {
+ "name": "Edward Z. Yang",
+ "email": "admin@htmlpurifier.org",
+ "homepage": "http://ezyang.com"
+ }
+ ],
+ "description": "Standards compliant HTML filter written in PHP",
+ "homepage": "http://htmlpurifier.org/",
+ "keywords": [
+ "html"
+ ],
+ "support": {
+ "issues": "https://github.com/ezyang/htmlpurifier/issues",
+ "source": "https://github.com/ezyang/htmlpurifier/tree/master"
+ },
+ "time": "2020-06-29T00:56:53+00:00"
+ },
+ {
+ "name": "guzzlehttp/guzzle",
+ "version": "7.3.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/guzzle/guzzle.git",
+ "reference": "7008573787b430c1c1f650e3722d9bba59967628"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/guzzle/guzzle/zipball/7008573787b430c1c1f650e3722d9bba59967628",
+ "reference": "7008573787b430c1c1f650e3722d9bba59967628",
+ "shasum": ""
+ },
+ "require": {
+ "ext-json": "*",
+ "guzzlehttp/promises": "^1.4",
+ "guzzlehttp/psr7": "^1.7 || ^2.0",
+ "php": "^7.2.5 || ^8.0",
+ "psr/http-client": "^1.0"
+ },
+ "provide": {
+ "psr/http-client-implementation": "1.0"
+ },
+ "require-dev": {
+ "bamarni/composer-bin-plugin": "^1.4.1",
+ "ext-curl": "*",
+ "php-http/client-integration-tests": "^3.0",
+ "phpunit/phpunit": "^8.5.5 || ^9.3.5",
+ "psr/log": "^1.1"
+ },
+ "suggest": {
+ "ext-curl": "Required for CURL handler support",
+ "ext-intl": "Required for Internationalized Domain Name (IDN) support",
+ "psr/log": "Required for using the Log middleware"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "7.3-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "GuzzleHttp\\": "src/"
+ },
+ "files": [
+ "src/functions_include.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Michael Dowling",
+ "email": "mtdowling@gmail.com",
+ "homepage": "https://github.com/mtdowling"
+ },
+ {
+ "name": "Márk Sági-Kazár",
+ "email": "mark.sagikazar@gmail.com",
+ "homepage": "https://sagikazarmark.hu"
+ }
+ ],
+ "description": "Guzzle is a PHP HTTP client library",
+ "homepage": "http://guzzlephp.org/",
+ "keywords": [
+ "client",
+ "curl",
+ "framework",
+ "http",
+ "http client",
+ "psr-18",
+ "psr-7",
+ "rest",
+ "web service"
+ ],
+ "support": {
+ "issues": "https://github.com/guzzle/guzzle/issues",
+ "source": "https://github.com/guzzle/guzzle/tree/7.3.0"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/GrahamCampbell",
+ "type": "github"
+ },
+ {
+ "url": "https://github.com/Nyholm",
+ "type": "github"
+ },
+ {
+ "url": "https://github.com/alexeyshockov",
+ "type": "github"
+ },
+ {
+ "url": "https://github.com/gmponos",
+ "type": "github"
+ }
+ ],
+ "time": "2021-03-23T11:33:13+00:00"
+ },
+ {
+ "name": "guzzlehttp/promises",
+ "version": "1.4.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/guzzle/promises.git",
+ "reference": "8e7d04f1f6450fef59366c399cfad4b9383aa30d"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/guzzle/promises/zipball/8e7d04f1f6450fef59366c399cfad4b9383aa30d",
+ "reference": "8e7d04f1f6450fef59366c399cfad4b9383aa30d",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.5"
+ },
+ "require-dev": {
+ "symfony/phpunit-bridge": "^4.4 || ^5.1"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.4-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "GuzzleHttp\\Promise\\": "src/"
+ },
+ "files": [
+ "src/functions_include.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Michael Dowling",
+ "email": "mtdowling@gmail.com",
+ "homepage": "https://github.com/mtdowling"
+ }
+ ],
+ "description": "Guzzle promises library",
+ "keywords": [
+ "promise"
+ ],
+ "support": {
+ "issues": "https://github.com/guzzle/promises/issues",
+ "source": "https://github.com/guzzle/promises/tree/1.4.1"
+ },
+ "time": "2021-03-07T09:25:29+00:00"
+ },
+ {
+ "name": "guzzlehttp/psr7",
+ "version": "1.8.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/guzzle/psr7.git",
+ "reference": "dc960a912984efb74d0a90222870c72c87f10c91"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/guzzle/psr7/zipball/dc960a912984efb74d0a90222870c72c87f10c91",
+ "reference": "dc960a912984efb74d0a90222870c72c87f10c91",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.4.0",
+ "psr/http-message": "~1.0",
+ "ralouphie/getallheaders": "^2.0.5 || ^3.0.0"
+ },
+ "provide": {
+ "psr/http-message-implementation": "1.0"
+ },
+ "require-dev": {
+ "ext-zlib": "*",
+ "phpunit/phpunit": "~4.8.36 || ^5.7.27 || ^6.5.14 || ^7.5.20 || ^8.5.8 || ^9.3.10"
+ },
+ "suggest": {
+ "laminas/laminas-httphandlerrunner": "Emit PSR-7 responses"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.7-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "GuzzleHttp\\Psr7\\": "src/"
+ },
+ "files": [
+ "src/functions_include.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Michael Dowling",
+ "email": "mtdowling@gmail.com",
+ "homepage": "https://github.com/mtdowling"
+ },
+ {
+ "name": "Tobias Schultze",
+ "homepage": "https://github.com/Tobion"
+ }
+ ],
+ "description": "PSR-7 message implementation that also provides common utility methods",
+ "keywords": [
+ "http",
+ "message",
+ "psr-7",
+ "request",
+ "response",
+ "stream",
+ "uri",
+ "url"
+ ],
+ "support": {
+ "issues": "https://github.com/guzzle/psr7/issues",
+ "source": "https://github.com/guzzle/psr7/tree/1.8.2"
+ },
+ "time": "2021-04-26T09:17:50+00:00"
+ },
+ {
+ "name": "khanamiryan/qrcode-detector-decoder",
+ "version": "1.0.5",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/khanamiryan/php-qrcode-detector-decoder.git",
+ "reference": "6c8c23003a87ecd7458807cd49372b1fb590d1f5"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/khanamiryan/php-qrcode-detector-decoder/zipball/6c8c23003a87ecd7458807cd49372b1fb590d1f5",
+ "reference": "6c8c23003a87ecd7458807cd49372b1fb590d1f5",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.6"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^5.7 | ^7.5 | ^8.0 | ^9.0"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Zxing\\": "lib/"
+ },
+ "files": [
+ "lib/Common/customFunctions.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Ashot Khanamiryan",
+ "email": "a.khanamiryan@gmail.com",
+ "homepage": "https://github.com/khanamiryan",
+ "role": "Developer"
+ }
+ ],
+ "description": "QR code decoder / reader",
+ "homepage": "https://github.com/khanamiryan/php-qrcode-detector-decoder/",
+ "keywords": [
+ "barcode",
+ "qr",
+ "zxing"
+ ],
+ "support": {
+ "issues": "https://github.com/khanamiryan/php-qrcode-detector-decoder/issues",
+ "source": "https://github.com/khanamiryan/php-qrcode-detector-decoder/tree/1.0.5"
+ },
+ "time": "2021-04-20T18:34:35+00:00"
+ },
+ {
+ "name": "league/flysystem",
+ "version": "1.1.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/thephpleague/flysystem.git",
+ "reference": "9be3b16c877d477357c015cec057548cf9b2a14a"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/9be3b16c877d477357c015cec057548cf9b2a14a",
+ "reference": "9be3b16c877d477357c015cec057548cf9b2a14a",
+ "shasum": ""
+ },
+ "require": {
+ "ext-fileinfo": "*",
+ "league/mime-type-detection": "^1.3",
+ "php": "^7.2.5 || ^8.0"
+ },
+ "conflict": {
+ "league/flysystem-sftp": "<1.0.6"
+ },
+ "require-dev": {
+ "phpspec/prophecy": "^1.11.1",
+ "phpunit/phpunit": "^8.5.8"
+ },
+ "suggest": {
+ "ext-fileinfo": "Required for MimeType",
+ "ext-ftp": "Allows you to use FTP server storage",
+ "ext-openssl": "Allows you to use FTPS server storage",
+ "league/flysystem-aws-s3-v2": "Allows you to use S3 storage with AWS SDK v2",
+ "league/flysystem-aws-s3-v3": "Allows you to use S3 storage with AWS SDK v3",
+ "league/flysystem-azure": "Allows you to use Windows Azure Blob storage",
+ "league/flysystem-cached-adapter": "Flysystem adapter decorator for metadata caching",
+ "league/flysystem-eventable-filesystem": "Allows you to use EventableFilesystem",
+ "league/flysystem-rackspace": "Allows you to use Rackspace Cloud Files",
+ "league/flysystem-sftp": "Allows you to use SFTP server storage via phpseclib",
+ "league/flysystem-webdav": "Allows you to use WebDAV storage",
+ "league/flysystem-ziparchive": "Allows you to use ZipArchive adapter",
+ "spatie/flysystem-dropbox": "Allows you to use Dropbox storage",
+ "srmklive/flysystem-dropbox-v2": "Allows you to use Dropbox storage for PHP 5 applications"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.1-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "League\\Flysystem\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Frank de Jonge",
+ "email": "info@frenky.net"
+ }
+ ],
+ "description": "Filesystem abstraction: Many filesystems, one API.",
+ "keywords": [
+ "Cloud Files",
+ "WebDAV",
+ "abstraction",
+ "aws",
+ "cloud",
+ "copy.com",
+ "dropbox",
+ "file systems",
+ "files",
+ "filesystem",
+ "filesystems",
+ "ftp",
+ "rackspace",
+ "remote",
+ "s3",
+ "sftp",
+ "storage"
+ ],
+ "support": {
+ "issues": "https://github.com/thephpleague/flysystem/issues",
+ "source": "https://github.com/thephpleague/flysystem/tree/1.x"
+ },
+ "funding": [
+ {
+ "url": "https://offset.earth/frankdejonge",
+ "type": "other"
+ }
+ ],
+ "time": "2020-08-23T07:39:11+00:00"
+ },
+ {
+ "name": "league/flysystem-cached-adapter",
+ "version": "1.1.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/thephpleague/flysystem-cached-adapter.git",
+ "reference": "d1925efb2207ac4be3ad0c40b8277175f99ffaff"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/thephpleague/flysystem-cached-adapter/zipball/d1925efb2207ac4be3ad0c40b8277175f99ffaff",
+ "reference": "d1925efb2207ac4be3ad0c40b8277175f99ffaff",
+ "shasum": ""
+ },
+ "require": {
+ "league/flysystem": "~1.0",
+ "psr/cache": "^1.0.0"
+ },
+ "require-dev": {
+ "mockery/mockery": "~0.9",
+ "phpspec/phpspec": "^3.4",
+ "phpunit/phpunit": "^5.7",
+ "predis/predis": "~1.0",
+ "tedivm/stash": "~0.12"
+ },
+ "suggest": {
+ "ext-phpredis": "Pure C implemented extension for PHP"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "League\\Flysystem\\Cached\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "frankdejonge",
+ "email": "info@frenky.net"
+ }
+ ],
+ "description": "An adapter decorator to enable meta-data caching.",
+ "support": {
+ "issues": "https://github.com/thephpleague/flysystem-cached-adapter/issues",
+ "source": "https://github.com/thephpleague/flysystem-cached-adapter/tree/master"
+ },
+ "time": "2020-07-25T15:56:04+00:00"
+ },
+ {
+ "name": "league/mime-type-detection",
+ "version": "1.7.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/thephpleague/mime-type-detection.git",
+ "reference": "3b9dff8aaf7323590c1d2e443db701eb1f9aa0d3"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/thephpleague/mime-type-detection/zipball/3b9dff8aaf7323590c1d2e443db701eb1f9aa0d3",
+ "reference": "3b9dff8aaf7323590c1d2e443db701eb1f9aa0d3",
+ "shasum": ""
+ },
+ "require": {
+ "ext-fileinfo": "*",
+ "php": "^7.2 || ^8.0"
+ },
+ "require-dev": {
+ "friendsofphp/php-cs-fixer": "^2.18",
+ "phpstan/phpstan": "^0.12.68",
+ "phpunit/phpunit": "^8.5.8 || ^9.3"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "League\\MimeTypeDetection\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Frank de Jonge",
+ "email": "info@frankdejonge.nl"
+ }
+ ],
+ "description": "Mime-type detection for Flysystem",
+ "support": {
+ "issues": "https://github.com/thephpleague/mime-type-detection/issues",
+ "source": "https://github.com/thephpleague/mime-type-detection/tree/1.7.0"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/frankdejonge",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/league/flysystem",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2021-01-18T20:58:21+00:00"
+ },
+ {
+ "name": "maennchen/zipstream-php",
+ "version": "2.1.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/maennchen/ZipStream-PHP.git",
+ "reference": "c4c5803cc1f93df3d2448478ef79394a5981cc58"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/maennchen/ZipStream-PHP/zipball/c4c5803cc1f93df3d2448478ef79394a5981cc58",
+ "reference": "c4c5803cc1f93df3d2448478ef79394a5981cc58",
+ "shasum": ""
+ },
+ "require": {
+ "myclabs/php-enum": "^1.5",
+ "php": ">= 7.1",
+ "psr/http-message": "^1.0",
+ "symfony/polyfill-mbstring": "^1.0"
+ },
+ "require-dev": {
+ "ext-zip": "*",
+ "guzzlehttp/guzzle": ">= 6.3",
+ "mikey179/vfsstream": "^1.6",
+ "phpunit/phpunit": ">= 7.5"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "ZipStream\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Paul Duncan",
+ "email": "pabs@pablotron.org"
+ },
+ {
+ "name": "Jonatan Männchen",
+ "email": "jonatan@maennchen.ch"
+ },
+ {
+ "name": "Jesse Donat",
+ "email": "donatj@gmail.com"
+ },
+ {
+ "name": "András Kolesár",
+ "email": "kolesar@kolesar.hu"
+ }
+ ],
+ "description": "ZipStream is a library for dynamically streaming dynamic zip files from PHP without writing to the disk at all on the server.",
+ "keywords": [
+ "stream",
+ "zip"
+ ],
+ "support": {
+ "issues": "https://github.com/maennchen/ZipStream-PHP/issues",
+ "source": "https://github.com/maennchen/ZipStream-PHP/tree/master"
+ },
+ "funding": [
+ {
+ "url": "https://opencollective.com/zipstream",
+ "type": "open_collective"
+ }
+ ],
+ "time": "2020-05-30T13:11:16+00:00"
+ },
+ {
+ "name": "markbaker/complex",
+ "version": "2.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/MarkBaker/PHPComplex.git",
+ "reference": "9999f1432fae467bc93c53f357105b4c31bb994c"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/MarkBaker/PHPComplex/zipball/9999f1432fae467bc93c53f357105b4c31bb994c",
+ "reference": "9999f1432fae467bc93c53f357105b4c31bb994c",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.2 || ^8.0"
+ },
+ "require-dev": {
+ "dealerdirect/phpcodesniffer-composer-installer": "^0.7.0",
+ "phpcompatibility/php-compatibility": "^9.0",
+ "phpdocumentor/phpdocumentor": "2.*",
+ "phploc/phploc": "^4.0",
+ "phpmd/phpmd": "2.*",
+ "phpunit/phpunit": "^7.0 || ^8.0 || ^9.3",
+ "sebastian/phpcpd": "^4.0",
+ "squizlabs/php_codesniffer": "^3.4"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Complex\\": "classes/src/"
+ },
+ "files": [
+ "classes/src/functions/abs.php",
+ "classes/src/functions/acos.php",
+ "classes/src/functions/acosh.php",
+ "classes/src/functions/acot.php",
+ "classes/src/functions/acoth.php",
+ "classes/src/functions/acsc.php",
+ "classes/src/functions/acsch.php",
+ "classes/src/functions/argument.php",
+ "classes/src/functions/asec.php",
+ "classes/src/functions/asech.php",
+ "classes/src/functions/asin.php",
+ "classes/src/functions/asinh.php",
+ "classes/src/functions/atan.php",
+ "classes/src/functions/atanh.php",
+ "classes/src/functions/conjugate.php",
+ "classes/src/functions/cos.php",
+ "classes/src/functions/cosh.php",
+ "classes/src/functions/cot.php",
+ "classes/src/functions/coth.php",
+ "classes/src/functions/csc.php",
+ "classes/src/functions/csch.php",
+ "classes/src/functions/exp.php",
+ "classes/src/functions/inverse.php",
+ "classes/src/functions/ln.php",
+ "classes/src/functions/log2.php",
+ "classes/src/functions/log10.php",
+ "classes/src/functions/negative.php",
+ "classes/src/functions/pow.php",
+ "classes/src/functions/rho.php",
+ "classes/src/functions/sec.php",
+ "classes/src/functions/sech.php",
+ "classes/src/functions/sin.php",
+ "classes/src/functions/sinh.php",
+ "classes/src/functions/sqrt.php",
+ "classes/src/functions/tan.php",
+ "classes/src/functions/tanh.php",
+ "classes/src/functions/theta.php",
+ "classes/src/operations/add.php",
+ "classes/src/operations/subtract.php",
+ "classes/src/operations/multiply.php",
+ "classes/src/operations/divideby.php",
+ "classes/src/operations/divideinto.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Mark Baker",
+ "email": "mark@lange.demon.co.uk"
+ }
+ ],
+ "description": "PHP Class for working with complex numbers",
+ "homepage": "https://github.com/MarkBaker/PHPComplex",
+ "keywords": [
+ "complex",
+ "mathematics"
+ ],
+ "support": {
+ "issues": "https://github.com/MarkBaker/PHPComplex/issues",
+ "source": "https://github.com/MarkBaker/PHPComplex/tree/PHP8"
+ },
+ "time": "2020-08-26T10:42:07+00:00"
+ },
+ {
+ "name": "markbaker/matrix",
+ "version": "2.1.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/MarkBaker/PHPMatrix.git",
+ "reference": "361c0f545c3172ee26c3d596a0aa03f0cef65e6a"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/MarkBaker/PHPMatrix/zipball/361c0f545c3172ee26c3d596a0aa03f0cef65e6a",
+ "reference": "361c0f545c3172ee26c3d596a0aa03f0cef65e6a",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.1 || ^8.0"
+ },
+ "require-dev": {
+ "dealerdirect/phpcodesniffer-composer-installer": "^0.7.0",
+ "phpcompatibility/php-compatibility": "^9.0",
+ "phpdocumentor/phpdocumentor": "2.*",
+ "phploc/phploc": "^4.0",
+ "phpmd/phpmd": "2.*",
+ "phpunit/phpunit": "^7.0 || ^8.0 || ^9.3",
+ "sebastian/phpcpd": "^4.0",
+ "squizlabs/php_codesniffer": "^3.4"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Matrix\\": "classes/src/"
+ },
+ "files": [
+ "classes/src/Functions/adjoint.php",
+ "classes/src/Functions/antidiagonal.php",
+ "classes/src/Functions/cofactors.php",
+ "classes/src/Functions/determinant.php",
+ "classes/src/Functions/diagonal.php",
+ "classes/src/Functions/identity.php",
+ "classes/src/Functions/inverse.php",
+ "classes/src/Functions/minors.php",
+ "classes/src/Functions/trace.php",
+ "classes/src/Functions/transpose.php",
+ "classes/src/Operations/add.php",
+ "classes/src/Operations/directsum.php",
+ "classes/src/Operations/subtract.php",
+ "classes/src/Operations/multiply.php",
+ "classes/src/Operations/divideby.php",
+ "classes/src/Operations/divideinto.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Mark Baker",
+ "email": "mark@demon-angel.eu"
+ }
+ ],
+ "description": "PHP Class for working with matrices",
+ "homepage": "https://github.com/MarkBaker/PHPMatrix",
+ "keywords": [
+ "mathematics",
+ "matrix",
+ "vector"
+ ],
+ "support": {
+ "issues": "https://github.com/MarkBaker/PHPMatrix/issues",
+ "source": "https://github.com/MarkBaker/PHPMatrix/tree/2.1.2"
+ },
+ "time": "2021-01-23T16:37:31+00:00"
+ },
+ {
+ "name": "mtdowling/jmespath.php",
+ "version": "2.6.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/jmespath/jmespath.php.git",
+ "reference": "42dae2cbd13154083ca6d70099692fef8ca84bfb"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/jmespath/jmespath.php/zipball/42dae2cbd13154083ca6d70099692fef8ca84bfb",
+ "reference": "42dae2cbd13154083ca6d70099692fef8ca84bfb",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^5.4 || ^7.0 || ^8.0",
+ "symfony/polyfill-mbstring": "^1.17"
+ },
+ "require-dev": {
+ "composer/xdebug-handler": "^1.4",
+ "phpunit/phpunit": "^4.8.36 || ^7.5.15"
+ },
+ "bin": [
+ "bin/jp.php"
+ ],
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.6-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "JmesPath\\": "src/"
+ },
+ "files": [
+ "src/JmesPath.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Michael Dowling",
+ "email": "mtdowling@gmail.com",
+ "homepage": "https://github.com/mtdowling"
+ }
+ ],
+ "description": "Declaratively specify how to extract elements from a JSON document",
+ "keywords": [
+ "json",
+ "jsonpath"
+ ],
+ "support": {
+ "issues": "https://github.com/jmespath/jmespath.php/issues",
+ "source": "https://github.com/jmespath/jmespath.php/tree/2.6.0"
+ },
+ "time": "2020-07-31T21:01:56+00:00"
+ },
+ {
+ "name": "myclabs/php-enum",
+ "version": "1.8.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/myclabs/php-enum.git",
+ "reference": "46cf3d8498b095bd33727b13fd5707263af99421"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/myclabs/php-enum/zipball/46cf3d8498b095bd33727b13fd5707263af99421",
+ "reference": "46cf3d8498b095bd33727b13fd5707263af99421",
+ "shasum": ""
+ },
+ "require": {
+ "ext-json": "*",
+ "php": "^7.3 || ^8.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^9.5",
+ "squizlabs/php_codesniffer": "1.*",
+ "vimeo/psalm": "^4.5.1"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "MyCLabs\\Enum\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "PHP Enum contributors",
+ "homepage": "https://github.com/myclabs/php-enum/graphs/contributors"
+ }
+ ],
+ "description": "PHP Enum implementation",
+ "homepage": "http://github.com/myclabs/php-enum",
+ "keywords": [
+ "enum"
+ ],
+ "support": {
+ "issues": "https://github.com/myclabs/php-enum/issues",
+ "source": "https://github.com/myclabs/php-enum/tree/1.8.0"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/mnapoli",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/myclabs/php-enum",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2021-02-15T16:11:48+00:00"
+ },
+ {
+ "name": "phpoffice/phpspreadsheet",
+ "version": "1.17.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/PHPOffice/PhpSpreadsheet.git",
+ "reference": "c55269cb06911575a126dc225a05c0e4626e5fb4"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/PHPOffice/PhpSpreadsheet/zipball/c55269cb06911575a126dc225a05c0e4626e5fb4",
+ "reference": "c55269cb06911575a126dc225a05c0e4626e5fb4",
+ "shasum": ""
+ },
+ "require": {
+ "ext-ctype": "*",
+ "ext-dom": "*",
+ "ext-fileinfo": "*",
+ "ext-gd": "*",
+ "ext-iconv": "*",
+ "ext-libxml": "*",
+ "ext-mbstring": "*",
+ "ext-simplexml": "*",
+ "ext-xml": "*",
+ "ext-xmlreader": "*",
+ "ext-xmlwriter": "*",
+ "ext-zip": "*",
+ "ext-zlib": "*",
+ "ezyang/htmlpurifier": "^4.13",
+ "maennchen/zipstream-php": "^2.1",
+ "markbaker/complex": "^1.5||^2.0",
+ "markbaker/matrix": "^1.2||^2.0",
+ "php": "^7.2||^8.0",
+ "psr/http-client": "^1.0",
+ "psr/http-factory": "^1.0",
+ "psr/simple-cache": "^1.0"
+ },
+ "require-dev": {
+ "dompdf/dompdf": "^0.8.5",
+ "friendsofphp/php-cs-fixer": "^2.18",
+ "jpgraph/jpgraph": "^4.0",
+ "mpdf/mpdf": "^8.0",
+ "phpcompatibility/php-compatibility": "^9.3",
+ "phpunit/phpunit": "^8.5||^9.3",
+ "squizlabs/php_codesniffer": "^3.5",
+ "tecnickcom/tcpdf": "^6.3"
+ },
+ "suggest": {
+ "dompdf/dompdf": "Option for rendering PDF with PDF Writer (doesn't yet support PHP8)",
+ "jpgraph/jpgraph": "Option for rendering charts, or including charts with PDF or HTML Writers",
+ "mpdf/mpdf": "Option for rendering PDF with PDF Writer",
+ "tecnickcom/tcpdf": "Option for rendering PDF with PDF Writer (doesn't yet support PHP8)"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "PhpOffice\\PhpSpreadsheet\\": "src/PhpSpreadsheet"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Maarten Balliauw",
+ "homepage": "https://blog.maartenballiauw.be"
+ },
+ {
+ "name": "Mark Baker",
+ "homepage": "https://markbakeruk.net"
+ },
+ {
+ "name": "Franck Lefevre",
+ "homepage": "https://rootslabs.net"
+ },
+ {
+ "name": "Erik Tilt"
+ },
+ {
+ "name": "Adrien Crivelli"
+ }
+ ],
+ "description": "PHPSpreadsheet - Read, Create and Write Spreadsheet documents in PHP - Spreadsheet engine",
+ "homepage": "https://github.com/PHPOffice/PhpSpreadsheet",
+ "keywords": [
+ "OpenXML",
+ "excel",
+ "gnumeric",
+ "ods",
+ "php",
+ "spreadsheet",
+ "xls",
+ "xlsx"
+ ],
+ "support": {
+ "issues": "https://github.com/PHPOffice/PhpSpreadsheet/issues",
+ "source": "https://github.com/PHPOffice/PhpSpreadsheet/tree/1.17.1"
+ },
+ "time": "2021-03-02T17:54:11+00:00"
+ },
+ {
+ "name": "pimple/pimple",
+ "version": "v3.4.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/silexphp/Pimple.git",
+ "reference": "86406047271859ffc13424a048541f4531f53601"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/silexphp/Pimple/zipball/86406047271859ffc13424a048541f4531f53601",
+ "reference": "86406047271859ffc13424a048541f4531f53601",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.2.5",
+ "psr/container": "^1.1"
+ },
+ "require-dev": {
+ "symfony/phpunit-bridge": "^5.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.4.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-0": {
+ "Pimple": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ }
+ ],
+ "description": "Pimple, a simple Dependency Injection Container",
+ "homepage": "https://pimple.symfony.com",
+ "keywords": [
+ "container",
+ "dependency injection"
+ ],
+ "support": {
+ "source": "https://github.com/silexphp/Pimple/tree/v3.4.0"
+ },
+ "time": "2021-03-06T08:28:00+00:00"
+ },
+ {
+ "name": "psr/cache",
+ "version": "1.0.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/php-fig/cache.git",
+ "reference": "d11b50ad223250cf17b86e38383413f5a6764bf8"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/php-fig/cache/zipball/d11b50ad223250cf17b86e38383413f5a6764bf8",
+ "reference": "d11b50ad223250cf17b86e38383413f5a6764bf8",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Psr\\Cache\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "PHP-FIG",
+ "homepage": "http://www.php-fig.org/"
+ }
+ ],
+ "description": "Common interface for caching libraries",
+ "keywords": [
+ "cache",
+ "psr",
+ "psr-6"
+ ],
+ "support": {
+ "source": "https://github.com/php-fig/cache/tree/master"
+ },
+ "time": "2016-08-06T20:24:11+00:00"
+ },
+ {
+ "name": "psr/container",
+ "version": "1.1.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/php-fig/container.git",
+ "reference": "8622567409010282b7aeebe4bb841fe98b58dcaf"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/php-fig/container/zipball/8622567409010282b7aeebe4bb841fe98b58dcaf",
+ "reference": "8622567409010282b7aeebe4bb841fe98b58dcaf",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.2.0"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Psr\\Container\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "PHP-FIG",
+ "homepage": "https://www.php-fig.org/"
+ }
+ ],
+ "description": "Common Container Interface (PHP FIG PSR-11)",
+ "homepage": "https://github.com/php-fig/container",
+ "keywords": [
+ "PSR-11",
+ "container",
+ "container-interface",
+ "container-interop",
+ "psr"
+ ],
+ "support": {
+ "issues": "https://github.com/php-fig/container/issues",
+ "source": "https://github.com/php-fig/container/tree/1.1.1"
+ },
+ "time": "2021-03-05T17:36:06+00:00"
+ },
+ {
+ "name": "psr/http-client",
+ "version": "1.0.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/php-fig/http-client.git",
+ "reference": "2dfb5f6c5eff0e91e20e913f8c5452ed95b86621"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/php-fig/http-client/zipball/2dfb5f6c5eff0e91e20e913f8c5452ed95b86621",
+ "reference": "2dfb5f6c5eff0e91e20e913f8c5452ed95b86621",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.0 || ^8.0",
+ "psr/http-message": "^1.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Psr\\Http\\Client\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "PHP-FIG",
+ "homepage": "http://www.php-fig.org/"
+ }
+ ],
+ "description": "Common interface for HTTP clients",
+ "homepage": "https://github.com/php-fig/http-client",
+ "keywords": [
+ "http",
+ "http-client",
+ "psr",
+ "psr-18"
+ ],
+ "support": {
+ "source": "https://github.com/php-fig/http-client/tree/master"
+ },
+ "time": "2020-06-29T06:28:15+00:00"
+ },
+ {
+ "name": "psr/http-factory",
+ "version": "1.0.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/php-fig/http-factory.git",
+ "reference": "12ac7fcd07e5b077433f5f2bee95b3a771bf61be"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/php-fig/http-factory/zipball/12ac7fcd07e5b077433f5f2bee95b3a771bf61be",
+ "reference": "12ac7fcd07e5b077433f5f2bee95b3a771bf61be",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.0.0",
+ "psr/http-message": "^1.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Psr\\Http\\Message\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "PHP-FIG",
+ "homepage": "http://www.php-fig.org/"
+ }
+ ],
+ "description": "Common interfaces for PSR-7 HTTP message factories",
+ "keywords": [
+ "factory",
+ "http",
+ "message",
+ "psr",
+ "psr-17",
+ "psr-7",
+ "request",
+ "response"
+ ],
+ "support": {
+ "source": "https://github.com/php-fig/http-factory/tree/master"
+ },
+ "time": "2019-04-30T12:38:16+00:00"
+ },
+ {
+ "name": "psr/http-message",
+ "version": "1.0.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/php-fig/http-message.git",
+ "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363",
+ "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Psr\\Http\\Message\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "PHP-FIG",
+ "homepage": "http://www.php-fig.org/"
+ }
+ ],
+ "description": "Common interface for HTTP messages",
+ "homepage": "https://github.com/php-fig/http-message",
+ "keywords": [
+ "http",
+ "http-message",
+ "psr",
+ "psr-7",
+ "request",
+ "response"
+ ],
+ "support": {
+ "source": "https://github.com/php-fig/http-message/tree/master"
+ },
+ "time": "2016-08-06T14:39:51+00:00"
+ },
+ {
+ "name": "psr/log",
+ "version": "1.1.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/php-fig/log.git",
+ "reference": "0f73288fd15629204f9d42b7055f72dacbe811fc"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/php-fig/log/zipball/0f73288fd15629204f9d42b7055f72dacbe811fc",
+ "reference": "0f73288fd15629204f9d42b7055f72dacbe811fc",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.1.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Psr\\Log\\": "Psr/Log/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "PHP-FIG",
+ "homepage": "http://www.php-fig.org/"
+ }
+ ],
+ "description": "Common interface for logging libraries",
+ "homepage": "https://github.com/php-fig/log",
+ "keywords": [
+ "log",
+ "psr",
+ "psr-3"
+ ],
+ "support": {
+ "source": "https://github.com/php-fig/log/tree/1.1.3"
+ },
+ "time": "2020-03-23T09:12:05+00:00"
+ },
+ {
+ "name": "psr/simple-cache",
+ "version": "1.0.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/php-fig/simple-cache.git",
+ "reference": "408d5eafb83c57f6365a3ca330ff23aa4a5fa39b"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/php-fig/simple-cache/zipball/408d5eafb83c57f6365a3ca330ff23aa4a5fa39b",
+ "reference": "408d5eafb83c57f6365a3ca330ff23aa4a5fa39b",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Psr\\SimpleCache\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "PHP-FIG",
+ "homepage": "http://www.php-fig.org/"
+ }
+ ],
+ "description": "Common interfaces for simple caching",
+ "keywords": [
+ "cache",
+ "caching",
+ "psr",
+ "psr-16",
+ "simple-cache"
+ ],
+ "support": {
+ "source": "https://github.com/php-fig/simple-cache/tree/master"
+ },
+ "time": "2017-10-23T01:57:42+00:00"
+ },
+ {
+ "name": "ralouphie/getallheaders",
+ "version": "3.0.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/ralouphie/getallheaders.git",
+ "reference": "120b605dfeb996808c31b6477290a714d356e822"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/120b605dfeb996808c31b6477290a714d356e822",
+ "reference": "120b605dfeb996808c31b6477290a714d356e822",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.6"
+ },
+ "require-dev": {
+ "php-coveralls/php-coveralls": "^2.1",
+ "phpunit/phpunit": "^5 || ^6.5"
+ },
+ "type": "library",
+ "autoload": {
+ "files": [
+ "src/getallheaders.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Ralph Khattar",
+ "email": "ralph.khattar@gmail.com"
+ }
+ ],
+ "description": "A polyfill for getallheaders.",
+ "support": {
+ "issues": "https://github.com/ralouphie/getallheaders/issues",
+ "source": "https://github.com/ralouphie/getallheaders/tree/develop"
+ },
+ "time": "2019-03-08T08:55:37+00:00"
+ },
+ {
+ "name": "songshenzong/support",
+ "version": "2.0.5",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/songshenzong/support.git",
+ "reference": "34973c04ffcf226e503f1c3a69d30ac49f7621f6"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/songshenzong/support/zipball/34973c04ffcf226e503f1c3a69d30ac49f7621f6",
+ "reference": "34973c04ffcf226e503f1c3a69d30ac49f7621f6",
+ "shasum": ""
+ },
+ "require": {
+ "danielstjules/stringy": "^3.1",
+ "ext-json": "*",
+ "ext-simplexml": "*",
+ "ext-xml": "*",
+ "php": ">=5.5"
+ },
+ "require-dev": {
+ "laravel/framework": "^5.8",
+ "phpunit/phpunit": "^4.8.35|^5.4.3"
+ },
+ "type": "library",
+ "extra": {
+ "laravel": {
+ "providers": [
+ "Songshenzong\\Support\\StringsServiceProvider"
+ ],
+ "aliases": {
+ "Strings": "Songshenzong\\Support\\StringsFacade"
+ }
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Songshenzong\\Support\\": "src/"
+ },
+ "files": [
+ "src/StringsHelpers.php",
+ "src/BashEchoHelpers.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Songshenzong",
+ "email": "i@songshenzong.com"
+ }
+ ],
+ "description": "The Songshenzong Support package.",
+ "homepage": "http://songshenzong.com",
+ "keywords": [
+ "laravel",
+ "support",
+ "tools",
+ "web"
+ ],
+ "support": {
+ "issues": "https://github.com/songshenzong/support/issues",
+ "source": "https://github.com/songshenzong/support"
+ },
+ "time": "2019-08-29T01:59:12+00:00"
+ },
+ {
+ "name": "symfony/deprecation-contracts",
+ "version": "v2.4.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/deprecation-contracts.git",
+ "reference": "5f38c8804a9e97d23e0c8d63341088cd8a22d627"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/5f38c8804a9e97d23e0c8d63341088cd8a22d627",
+ "reference": "5f38c8804a9e97d23e0c8d63341088cd8a22d627",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.1"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "2.4-dev"
+ },
+ "thanks": {
+ "name": "symfony/contracts",
+ "url": "https://github.com/symfony/contracts"
+ }
+ },
+ "autoload": {
+ "files": [
+ "function.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "A generic function and convention to trigger deprecation notices",
+ "homepage": "https://symfony.com",
+ "support": {
+ "source": "https://github.com/symfony/deprecation-contracts/tree/v2.4.0"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2021-03-23T23:28:01+00:00"
+ },
+ {
+ "name": "symfony/options-resolver",
+ "version": "v5.2.4",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/options-resolver.git",
+ "reference": "5d0f633f9bbfcf7ec642a2b5037268e61b0a62ce"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/options-resolver/zipball/5d0f633f9bbfcf7ec642a2b5037268e61b0a62ce",
+ "reference": "5d0f633f9bbfcf7ec642a2b5037268e61b0a62ce",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.2.5",
+ "symfony/deprecation-contracts": "^2.1",
+ "symfony/polyfill-php73": "~1.0",
+ "symfony/polyfill-php80": "^1.15"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\OptionsResolver\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Provides an improved replacement for the array_replace PHP function",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "config",
+ "configuration",
+ "options"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/options-resolver/tree/v5.2.4"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2021-01-27T12:56:27+00:00"
+ },
+ {
+ "name": "symfony/polyfill-ctype",
+ "version": "v1.22.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/polyfill-ctype.git",
+ "reference": "c6c942b1ac76c82448322025e084cadc56048b4e"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/c6c942b1ac76c82448322025e084cadc56048b4e",
+ "reference": "c6c942b1ac76c82448322025e084cadc56048b4e",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.1"
+ },
+ "suggest": {
+ "ext-ctype": "For best performance"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "1.22-dev"
+ },
+ "thanks": {
+ "name": "symfony/polyfill",
+ "url": "https://github.com/symfony/polyfill"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Polyfill\\Ctype\\": ""
+ },
+ "files": [
+ "bootstrap.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Gert de Pagter",
+ "email": "BackEndTea@gmail.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony polyfill for ctype functions",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "compatibility",
+ "ctype",
+ "polyfill",
+ "portable"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/polyfill-ctype/tree/v1.22.1"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2021-01-07T16:49:33+00:00"
+ },
+ {
+ "name": "symfony/polyfill-intl-grapheme",
+ "version": "v1.22.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/polyfill-intl-grapheme.git",
+ "reference": "5601e09b69f26c1828b13b6bb87cb07cddba3170"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/5601e09b69f26c1828b13b6bb87cb07cddba3170",
+ "reference": "5601e09b69f26c1828b13b6bb87cb07cddba3170",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.1"
+ },
+ "suggest": {
+ "ext-intl": "For best performance"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "1.22-dev"
+ },
+ "thanks": {
+ "name": "symfony/polyfill",
+ "url": "https://github.com/symfony/polyfill"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Polyfill\\Intl\\Grapheme\\": ""
+ },
+ "files": [
+ "bootstrap.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony polyfill for intl's grapheme_* functions",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "compatibility",
+ "grapheme",
+ "intl",
+ "polyfill",
+ "portable",
+ "shim"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.22.1"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2021-01-22T09:19:47+00:00"
+ },
+ {
+ "name": "symfony/polyfill-intl-normalizer",
+ "version": "v1.22.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/polyfill-intl-normalizer.git",
+ "reference": "43a0283138253ed1d48d352ab6d0bdb3f809f248"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/43a0283138253ed1d48d352ab6d0bdb3f809f248",
+ "reference": "43a0283138253ed1d48d352ab6d0bdb3f809f248",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.1"
+ },
+ "suggest": {
+ "ext-intl": "For best performance"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "1.22-dev"
+ },
+ "thanks": {
+ "name": "symfony/polyfill",
+ "url": "https://github.com/symfony/polyfill"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Polyfill\\Intl\\Normalizer\\": ""
+ },
+ "files": [
+ "bootstrap.php"
+ ],
+ "classmap": [
+ "Resources/stubs"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony polyfill for intl's Normalizer class and related functions",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "compatibility",
+ "intl",
+ "normalizer",
+ "polyfill",
+ "portable",
+ "shim"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.22.1"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2021-01-22T09:19:47+00:00"
+ },
+ {
+ "name": "symfony/polyfill-mbstring",
+ "version": "v1.22.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/polyfill-mbstring.git",
+ "reference": "5232de97ee3b75b0360528dae24e73db49566ab1"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/5232de97ee3b75b0360528dae24e73db49566ab1",
+ "reference": "5232de97ee3b75b0360528dae24e73db49566ab1",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.1"
+ },
+ "suggest": {
+ "ext-mbstring": "For best performance"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "1.22-dev"
+ },
+ "thanks": {
+ "name": "symfony/polyfill",
+ "url": "https://github.com/symfony/polyfill"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Polyfill\\Mbstring\\": ""
+ },
+ "files": [
+ "bootstrap.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony polyfill for the Mbstring extension",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "compatibility",
+ "mbstring",
+ "polyfill",
+ "portable",
+ "shim"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.22.1"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2021-01-22T09:19:47+00:00"
+ },
+ {
+ "name": "symfony/polyfill-php73",
+ "version": "v1.22.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/polyfill-php73.git",
+ "reference": "a678b42e92f86eca04b7fa4c0f6f19d097fb69e2"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/a678b42e92f86eca04b7fa4c0f6f19d097fb69e2",
+ "reference": "a678b42e92f86eca04b7fa4c0f6f19d097fb69e2",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.1"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "1.22-dev"
+ },
+ "thanks": {
+ "name": "symfony/polyfill",
+ "url": "https://github.com/symfony/polyfill"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Polyfill\\Php73\\": ""
+ },
+ "files": [
+ "bootstrap.php"
+ ],
+ "classmap": [
+ "Resources/stubs"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony polyfill backporting some PHP 7.3+ features to lower PHP versions",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "compatibility",
+ "polyfill",
+ "portable",
+ "shim"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/polyfill-php73/tree/v1.22.1"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2021-01-07T16:49:33+00:00"
+ },
+ {
+ "name": "symfony/polyfill-php80",
+ "version": "v1.22.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/polyfill-php80.git",
+ "reference": "dc3063ba22c2a1fd2f45ed856374d79114998f91"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/dc3063ba22c2a1fd2f45ed856374d79114998f91",
+ "reference": "dc3063ba22c2a1fd2f45ed856374d79114998f91",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.1"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "1.22-dev"
+ },
+ "thanks": {
+ "name": "symfony/polyfill",
+ "url": "https://github.com/symfony/polyfill"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Polyfill\\Php80\\": ""
+ },
+ "files": [
+ "bootstrap.php"
+ ],
+ "classmap": [
+ "Resources/stubs"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Ion Bazan",
+ "email": "ion.bazan@gmail.com"
+ },
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "compatibility",
+ "polyfill",
+ "portable",
+ "shim"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/polyfill-php80/tree/v1.22.1"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2021-01-07T16:49:33+00:00"
+ },
+ {
+ "name": "symfony/property-access",
+ "version": "v5.2.4",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/property-access.git",
+ "reference": "3af8ed262bd3217512a13b023981fe68f36ad5f3"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/property-access/zipball/3af8ed262bd3217512a13b023981fe68f36ad5f3",
+ "reference": "3af8ed262bd3217512a13b023981fe68f36ad5f3",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.2.5",
+ "symfony/deprecation-contracts": "^2.1",
+ "symfony/polyfill-php80": "^1.15",
+ "symfony/property-info": "^5.2"
+ },
+ "require-dev": {
+ "symfony/cache": "^4.4|^5.0"
+ },
+ "suggest": {
+ "psr/cache-implementation": "To cache access methods."
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\PropertyAccess\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Provides functions to read and write from/to an object or array using a simple string notation",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "access",
+ "array",
+ "extraction",
+ "index",
+ "injection",
+ "object",
+ "property",
+ "property path",
+ "reflection"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/property-access/tree/v5.2.4"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2021-01-27T10:15:41+00:00"
+ },
+ {
+ "name": "symfony/property-info",
+ "version": "v5.2.4",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/property-info.git",
+ "reference": "7185bbc74e6f49c3f1b5936b4d9e4ca133921189"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/property-info/zipball/7185bbc74e6f49c3f1b5936b4d9e4ca133921189",
+ "reference": "7185bbc74e6f49c3f1b5936b4d9e4ca133921189",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.2.5",
+ "symfony/deprecation-contracts": "^2.1",
+ "symfony/polyfill-php80": "^1.15",
+ "symfony/string": "^5.1"
+ },
+ "conflict": {
+ "phpdocumentor/reflection-docblock": "<3.2.2",
+ "phpdocumentor/type-resolver": "<1.4.0",
+ "symfony/dependency-injection": "<4.4"
+ },
+ "require-dev": {
+ "doctrine/annotations": "^1.10.4",
+ "phpdocumentor/reflection-docblock": "^3.0|^4.0|^5.0",
+ "symfony/cache": "^4.4|^5.0",
+ "symfony/dependency-injection": "^4.4|^5.0",
+ "symfony/serializer": "^4.4|^5.0"
+ },
+ "suggest": {
+ "phpdocumentor/reflection-docblock": "To use the PHPDoc",
+ "psr/cache-implementation": "To cache results",
+ "symfony/doctrine-bridge": "To use Doctrine metadata",
+ "symfony/serializer": "To use Serializer metadata"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\PropertyInfo\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Kévin Dunglas",
+ "email": "dunglas@gmail.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Extracts information about PHP class' properties using metadata of popular sources",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "doctrine",
+ "phpdoc",
+ "property",
+ "symfony",
+ "type",
+ "validator"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/property-info/tree/v5.2.4"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2021-02-17T15:24:54+00:00"
+ },
+ {
+ "name": "symfony/string",
+ "version": "v5.2.6",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/string.git",
+ "reference": "ad0bd91bce2054103f5eaa18ebeba8d3bc2a0572"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/string/zipball/ad0bd91bce2054103f5eaa18ebeba8d3bc2a0572",
+ "reference": "ad0bd91bce2054103f5eaa18ebeba8d3bc2a0572",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.2.5",
+ "symfony/polyfill-ctype": "~1.8",
+ "symfony/polyfill-intl-grapheme": "~1.0",
+ "symfony/polyfill-intl-normalizer": "~1.0",
+ "symfony/polyfill-mbstring": "~1.0",
+ "symfony/polyfill-php80": "~1.15"
+ },
+ "require-dev": {
+ "symfony/error-handler": "^4.4|^5.0",
+ "symfony/http-client": "^4.4|^5.0",
+ "symfony/translation-contracts": "^1.1|^2",
+ "symfony/var-exporter": "^4.4|^5.0"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\String\\": ""
+ },
+ "files": [
+ "Resources/functions.php"
+ ],
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Provides an object-oriented API to strings and deals with bytes, UTF-8 code points and grapheme clusters in a unified way",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "grapheme",
+ "i18n",
+ "string",
+ "unicode",
+ "utf-8",
+ "utf8"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/string/tree/v5.2.6"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2021-03-17T17:12:15+00:00"
+ },
+ {
+ "name": "topthink/framework",
+ "version": "v6.0.8",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/top-think/framework.git",
+ "reference": "4789343672aef06d571d556da369c0e156609bce"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/top-think/framework/zipball/4789343672aef06d571d556da369c0e156609bce",
+ "reference": "4789343672aef06d571d556da369c0e156609bce",
+ "shasum": ""
+ },
+ "require": {
+ "ext-json": "*",
+ "ext-mbstring": "*",
+ "league/flysystem": "^1.0",
+ "league/flysystem-cached-adapter": "^1.0",
+ "php": ">=7.1.0",
+ "psr/container": "~1.0",
+ "psr/log": "~1.0",
+ "psr/simple-cache": "^1.0",
+ "topthink/think-helper": "^3.1.1",
+ "topthink/think-orm": "^2.0"
+ },
+ "require-dev": {
+ "mikey179/vfsstream": "^1.6",
+ "mockery/mockery": "^1.2",
+ "phpunit/phpunit": "^7.0"
+ },
+ "type": "library",
+ "autoload": {
+ "files": [],
+ "psr-4": {
+ "think\\": "src/think/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "Apache-2.0"
+ ],
+ "authors": [
+ {
+ "name": "liu21st",
+ "email": "liu21st@gmail.com"
+ },
+ {
+ "name": "yunwuxin",
+ "email": "448901948@qq.com"
+ }
+ ],
+ "description": "The ThinkPHP Framework.",
+ "homepage": "http://thinkphp.cn/",
+ "keywords": [
+ "framework",
+ "orm",
+ "thinkphp"
+ ],
+ "support": {
+ "issues": "https://github.com/top-think/framework/issues",
+ "source": "https://github.com/top-think/framework/tree/v6.0.8"
+ },
+ "time": "2021-04-27T00:41:08+00:00"
+ },
+ {
+ "name": "topthink/think-helper",
+ "version": "v3.1.4",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/top-think/think-helper.git",
+ "reference": "c28d37743bda4a0455286ca85b17b5791d626e10"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/top-think/think-helper/zipball/c28d37743bda4a0455286ca85b17b5791d626e10",
+ "reference": "c28d37743bda4a0455286ca85b17b5791d626e10",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.1.0"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "think\\": "src"
+ },
+ "files": [
+ "src/helper.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "Apache-2.0"
+ ],
+ "authors": [
+ {
+ "name": "yunwuxin",
+ "email": "448901948@qq.com"
+ }
+ ],
+ "description": "The ThinkPHP6 Helper Package",
+ "support": {
+ "issues": "https://github.com/top-think/think-helper/issues",
+ "source": "https://github.com/top-think/think-helper/tree/3.0"
+ },
+ "time": "2019-11-08T08:01:10+00:00"
+ },
+ {
+ "name": "topthink/think-orm",
+ "version": "v2.0.40",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/top-think/think-orm.git",
+ "reference": "1119d979b850849f3725856460cf108eec1c3eb8"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/top-think/think-orm/zipball/1119d979b850849f3725856460cf108eec1c3eb8",
+ "reference": "1119d979b850849f3725856460cf108eec1c3eb8",
+ "shasum": ""
+ },
+ "require": {
+ "ext-json": "*",
+ "ext-pdo": "*",
+ "php": ">=7.1.0",
+ "psr/log": "~1.0",
+ "psr/simple-cache": "^1.0",
+ "topthink/think-helper": "^3.1"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^7|^8|^9.5"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "think\\": "src"
+ },
+ "files": [
+ "stubs/load_stubs.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "Apache-2.0"
+ ],
+ "authors": [
+ {
+ "name": "liu21st",
+ "email": "liu21st@gmail.com"
+ }
+ ],
+ "description": "think orm",
+ "keywords": [
+ "database",
+ "orm"
+ ],
+ "support": {
+ "issues": "https://github.com/top-think/think-orm/issues",
+ "source": "https://github.com/top-think/think-orm/tree/v2.0.40"
+ },
+ "time": "2021-04-19T13:29:37+00:00"
+ },
+ {
+ "name": "topthink/think-template",
+ "version": "v2.0.8",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/top-think/think-template.git",
+ "reference": "abfc293f74f9ef5127b5c416310a01fe42e59368"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/top-think/think-template/zipball/abfc293f74f9ef5127b5c416310a01fe42e59368",
+ "reference": "abfc293f74f9ef5127b5c416310a01fe42e59368",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.1.0",
+ "psr/simple-cache": "^1.0"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "think\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "Apache-2.0"
+ ],
+ "authors": [
+ {
+ "name": "liu21st",
+ "email": "liu21st@gmail.com"
+ }
+ ],
+ "description": "the php template engine",
+ "support": {
+ "issues": "https://github.com/top-think/think-template/issues",
+ "source": "https://github.com/top-think/think-template/tree/v2.0.8"
+ },
+ "time": "2020-12-10T07:52:03+00:00"
+ },
+ {
+ "name": "topthink/think-view",
+ "version": "v1.0.14",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/top-think/think-view.git",
+ "reference": "edce0ae2c9551ab65f9e94a222604b0dead3576d"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/top-think/think-view/zipball/edce0ae2c9551ab65f9e94a222604b0dead3576d",
+ "reference": "edce0ae2c9551ab65f9e94a222604b0dead3576d",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.1.0",
+ "topthink/think-template": "^2.0"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "think\\view\\driver\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "Apache-2.0"
+ ],
+ "authors": [
+ {
+ "name": "liu21st",
+ "email": "liu21st@gmail.com"
+ }
+ ],
+ "description": "thinkphp template driver",
+ "support": {
+ "issues": "https://github.com/top-think/think-view/issues",
+ "source": "https://github.com/top-think/think-view/tree/v1.0.14"
+ },
+ "time": "2019-11-06T11:40:13+00:00"
+ },
+ {
+ "name": "xin/container",
+ "version": "2.0.1",
+ "source": {
+ "type": "git",
+ "url": "https://gitee.com/liuxiaojinla/php-container",
+ "reference": "97bb67f87dd851545938a1f2fe0ffbd379e3ff81"
+ },
+ "require": {
+ "ext-ctype": "*",
+ "ext-iconv": "*",
+ "ext-json": "*",
+ "ext-libxml": "*",
+ "ext-mbstring": "*",
+ "ext-openssl": "*",
+ "ext-simplexml": "*",
+ "psr/container": "^1.0",
+ "xin/helper": "^1.0"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "xin\\container\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "Apache-2.0"
+ ],
+ "authors": [
+ {
+ "name": "晋",
+ "email": "657306123@qq.com"
+ }
+ ],
+ "description": "严格基于PSR11规范实现基础的容器和依赖注入",
+ "time": "2019-10-21T03:51:25+00:00"
+ },
+ {
+ "name": "xin/helper",
+ "version": "1.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://gitee.com/liuxiaojinla/php-helper",
+ "reference": "02a58132dae2aea2d1c0b8e66f55125969224747"
+ },
+ "require": {
+ "ext-ctype": "*",
+ "ext-iconv": "*",
+ "ext-json": "*",
+ "ext-libxml": "*",
+ "ext-mbstring": "*",
+ "ext-openssl": "*",
+ "ext-simplexml": "*"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "xin\\helper\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "Apache-2.0"
+ ],
+ "authors": [
+ {
+ "name": "晋",
+ "email": "1540175452@qq.com"
+ }
+ ],
+ "description": "PHP项目日常开发必备基础库,数组工具类、字符串工具类、数字工具类、函数工具类、服务器工具类、加密工具类",
+ "time": "2019-06-22T08:28:23+00:00"
+ }
+ ],
+ "packages-dev": [
+ {
+ "name": "symfony/polyfill-php72",
+ "version": "v1.22.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/polyfill-php72.git",
+ "reference": "cc6e6f9b39fe8075b3dabfbaf5b5f645ae1340c9"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/cc6e6f9b39fe8075b3dabfbaf5b5f645ae1340c9",
+ "reference": "cc6e6f9b39fe8075b3dabfbaf5b5f645ae1340c9",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.1"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "1.22-dev"
+ },
+ "thanks": {
+ "name": "symfony/polyfill",
+ "url": "https://github.com/symfony/polyfill"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Polyfill\\Php72\\": ""
+ },
+ "files": [
+ "bootstrap.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony polyfill backporting some PHP 7.2+ features to lower PHP versions",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "compatibility",
+ "polyfill",
+ "portable",
+ "shim"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/polyfill-php72/tree/v1.22.1"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2021-01-07T16:49:33+00:00"
+ },
+ {
+ "name": "symfony/var-dumper",
+ "version": "v4.4.21",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/var-dumper.git",
+ "reference": "0da0e174f728996f5d5072d6a9f0a42259dbc806"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/var-dumper/zipball/0da0e174f728996f5d5072d6a9f0a42259dbc806",
+ "reference": "0da0e174f728996f5d5072d6a9f0a42259dbc806",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.1.3",
+ "symfony/polyfill-mbstring": "~1.0",
+ "symfony/polyfill-php72": "~1.5",
+ "symfony/polyfill-php80": "^1.15"
+ },
+ "conflict": {
+ "phpunit/phpunit": "<4.8.35|<5.4.3,>=5.0",
+ "symfony/console": "<3.4"
+ },
+ "require-dev": {
+ "ext-iconv": "*",
+ "symfony/console": "^3.4|^4.0|^5.0",
+ "symfony/process": "^4.4|^5.0",
+ "twig/twig": "^1.43|^2.13|^3.0.4"
+ },
+ "suggest": {
+ "ext-iconv": "To convert non-UTF-8 strings to UTF-8 (or symfony/polyfill-iconv in case ext-iconv cannot be used).",
+ "ext-intl": "To show region name in time zone dump",
+ "symfony/console": "To use the ServerDumpCommand and/or the bin/var-dump-server script"
+ },
+ "bin": [
+ "Resources/bin/var-dump-server"
+ ],
+ "type": "library",
+ "autoload": {
+ "files": [
+ "Resources/functions/dump.php"
+ ],
+ "psr-4": {
+ "Symfony\\Component\\VarDumper\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Provides mechanisms for walking through any arbitrary PHP variable",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "debug",
+ "dump"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/var-dumper/tree/v4.4.21"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2021-03-27T19:49:03+00:00"
+ },
+ {
+ "name": "topthink/think-trace",
+ "version": "v1.4",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/top-think/think-trace.git",
+ "reference": "9a9fa8f767b6c66c5a133ad21ca1bc96ad329444"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/top-think/think-trace/zipball/9a9fa8f767b6c66c5a133ad21ca1bc96ad329444",
+ "reference": "9a9fa8f767b6c66c5a133ad21ca1bc96ad329444",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.1.0",
+ "topthink/framework": "^6.0.0"
+ },
+ "type": "library",
+ "extra": {
+ "think": {
+ "services": [
+ "think\\trace\\Service"
+ ],
+ "config": {
+ "trace": "src/config.php"
+ }
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "think\\trace\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "Apache-2.0"
+ ],
+ "authors": [
+ {
+ "name": "liu21st",
+ "email": "liu21st@gmail.com"
+ }
+ ],
+ "description": "thinkphp debug trace",
+ "support": {
+ "issues": "https://github.com/top-think/think-trace/issues",
+ "source": "https://github.com/top-think/think-trace/tree/v1.4"
+ },
+ "time": "2020-06-29T05:27:28+00:00"
+ }
+ ],
+ "aliases": [],
+ "minimum-stability": "stable",
+ "stability-flags": [],
+ "prefer-stable": false,
+ "prefer-lowest": false,
+ "platform": {
+ "php": ">=7.1.0"
+ },
+ "platform-dev": [],
+ "plugin-api-version": "2.0.0"
+}
diff --git a/serve/config/app.php b/serve/config/app.php
new file mode 100644
index 0000000..3bba167
--- /dev/null
+++ b/serve/config/app.php
@@ -0,0 +1,36 @@
+ Env::get('app.host', ''),
+ // 应用的命名空间
+ 'app_namespace' => '',
+ // 是否启用路由
+ 'with_route' => true,
+ // 是否启用事件
+ 'with_event' => true,
+ // 默认应用
+ 'default_app' => 'index',
+ // 默认时区
+ 'default_timezone' => 'Asia/Shanghai',
+
+ // 应用映射(自动多应用模式有效)
+ 'app_map' => [],
+ // 域名绑定(自动多应用模式有效)
+ 'domain_bind' => [],
+ // 禁止URL访问的应用列表(自动多应用模式有效)
+ 'deny_app_list' => [],
+
+ // 异常页面的模板文件
+ 'exception_tmpl' => app()->getThinkPath() . 'tpl/think_exception.tpl',
+
+ // 错误显示信息,非调试模式有效
+ 'error_message' => '页面错误!请稍后再试~',
+ // 显示错误信息
+ 'show_error_msg' => false,
+];
diff --git a/serve/config/cache.php b/serve/config/cache.php
new file mode 100644
index 0000000..65e8150
--- /dev/null
+++ b/serve/config/cache.php
@@ -0,0 +1,30 @@
+ Env::get('cache.driver', 'file'),
+
+ // 缓存连接方式配置
+ 'stores' => [
+ 'file' => [
+ // 驱动方式
+ 'type' => 'File',
+ // 缓存保存目录
+ 'path' => '',
+ // 缓存前缀
+ 'prefix' => '',
+ // 缓存有效期
+ 'expire' => 2*60*60,
+ // 缓存标签前缀
+ 'tag_prefix' => 'tag:',
+ // 序列化机制 例如 ['serialize', 'unserialize']
+ 'serialize' => [],
+ ],
+ // 更多的缓存连接
+ ],
+];
diff --git a/serve/config/captcha.php b/serve/config/captcha.php
new file mode 100644
index 0000000..9bbf529
--- /dev/null
+++ b/serve/config/captcha.php
@@ -0,0 +1,39 @@
+ 5,
+ // 验证码字符集合
+ 'codeSet' => '2345678abcdefhijkmnpqrstuvwxyzABCDEFGHJKLMNPQRTUVWXY',
+ // 验证码过期时间
+ 'expire' => 1800,
+ // 是否使用中文验证码
+ 'useZh' => false,
+ // 是否使用算术验证码
+ 'math' => false,
+ // 是否使用背景图
+ 'useImgBg' => false,
+ //验证码字符大小
+ 'fontSize' => 25,
+ // 是否使用混淆曲线
+ 'useCurve' => true,
+ //是否添加杂点
+ 'useNoise' => true,
+ // 验证码字体 不设置则随机
+ 'fontttf' => '',
+ //背景颜色
+ 'bg' => [243, 251, 254],
+ // 验证码图片高度
+ 'imageH' => 0,
+ // 验证码图片宽度
+ 'imageW' => 0,
+
+ // 添加额外的验证码设置
+ // verify => [
+ // 'length'=>4,
+ // ...
+ //],
+];
diff --git a/serve/config/console.php b/serve/config/console.php
new file mode 100644
index 0000000..a818a98
--- /dev/null
+++ b/serve/config/console.php
@@ -0,0 +1,9 @@
+ [
+ ],
+];
diff --git a/serve/config/cookie.php b/serve/config/cookie.php
new file mode 100644
index 0000000..bde814c
--- /dev/null
+++ b/serve/config/cookie.php
@@ -0,0 +1,21 @@
+ 0,
+ // cookie 保存路径
+ 'path' => '/',
+ // cookie 有效域名
+ 'domain' => '',
+ // cookie 启用安全传输
+ 'secure' => true,
+ // httponly设置
+ 'httponly' => false,
+ // 是否使用 setcookie
+ 'setcookie' => true,
+ // 是否使用 samesite
+ // Chrome|CORS|PHP7.3+
+ 'samesite' => 'None'
+];
diff --git a/serve/config/filesystem.php b/serve/config/filesystem.php
new file mode 100644
index 0000000..bac2e0f
--- /dev/null
+++ b/serve/config/filesystem.php
@@ -0,0 +1,35 @@
+ Env::get('filesystem.driver', 'local'),
+ // 磁盘列表
+ 'disks' => [
+ 'local' => [
+ 'type' => 'local',
+ 'root' => app()->getRuntimePath() . 'storage',
+ ],
+ 'public' => [
+ // 磁盘类型
+ 'type' => 'local',
+ // 磁盘路径
+ 'root' => app()->getRootPath() . 'public/storage',
+ // 磁盘路径对应的外部URL路径
+ 'url' => '/storage',
+ // 可见性
+ 'visibility' => 'public',
+ ],
+ 'upload' => [
+ // 磁盘类型
+ 'type' => 'local',
+ // 磁盘路径
+ 'root' => app()->getRootPath() . 'static/upload',
+ // 磁盘路径对应的外部URL路径
+ 'url' => 'static/upload',
+ // 可见性
+ 'visibility' => 'public',
+ ]
+ ],
+];
diff --git a/serve/config/lang.php b/serve/config/lang.php
new file mode 100644
index 0000000..33232bd
--- /dev/null
+++ b/serve/config/lang.php
@@ -0,0 +1,27 @@
+ Env::get('lang.default_lang', 'zh-cn'),
+ // 允许的语言列表
+ 'allow_lang_list' => [],
+ // 多语言自动侦测变量名
+ 'detect_var' => 'lang',
+ // 是否使用Cookie记录
+ 'use_cookie' => true,
+ // 多语言cookie变量
+ 'cookie_var' => 'think_lang',
+ // 扩展语言包
+ 'extend_list' => [],
+ // Accept-Language转义为对应语言包名称
+ 'accept_language' => [
+ 'zh-hans-cn' => 'zh-cn',
+ ],
+ // 是否支持语言分组
+ 'allow_group' => false,
+];
diff --git a/serve/config/log.php b/serve/config/log.php
new file mode 100644
index 0000000..5f7afcb
--- /dev/null
+++ b/serve/config/log.php
@@ -0,0 +1,46 @@
+ Env::get('log.channel', 'file'),
+ // 日志记录级别
+ 'level' => [],
+ // 日志类型记录的通道 ['error'=>'email',...]
+ 'type_channel' => [],
+ // 关闭全局日志写入
+ 'close' => false,
+ // 全局日志处理 支持闭包
+ 'processor' => null,
+
+ // 日志通道列表
+ 'channels' => [
+ 'file' => [
+ // 日志记录方式
+ 'type' => 'File',
+ // 日志保存目录
+ 'path' => '',
+ // 单文件日志写入
+ 'single' => false,
+ // 独立日志级别
+ 'apart_level' => [],
+ // 最大日志文件数量
+ 'max_files' => 0,
+ // 使用JSON格式记录
+ 'json' => false,
+ // 日志处理
+ 'processor' => null,
+ // 关闭通道日志写入
+ 'close' => false,
+ // 日志输出格式化
+ 'format' => '[%s][%s] %s',
+ // 是否实时写入
+ 'realtime_write' => false,
+ ],
+ // 其它日志通道配置
+ ],
+
+];
diff --git a/serve/config/middleware.php b/serve/config/middleware.php
new file mode 100644
index 0000000..7e1972f
--- /dev/null
+++ b/serve/config/middleware.php
@@ -0,0 +1,8 @@
+ [],
+ // 优先级设置,此数组中的中间件会按照数组中的顺序优先执行
+ 'priority' => [],
+];
diff --git a/serve/config/route.php b/serve/config/route.php
new file mode 100644
index 0000000..955eeec
--- /dev/null
+++ b/serve/config/route.php
@@ -0,0 +1,45 @@
+ '/',
+ // URL伪静态后缀
+ 'url_html_suffix' => 'html',
+ // URL普通方式参数 用于自动生成
+ 'url_common_param' => true,
+ // 是否开启路由延迟解析
+ 'url_lazy_route' => false,
+ // 是否强制使用路由
+ 'url_route_must' => false,
+ // 合并路由规则
+ 'route_rule_merge' => false,
+ // 路由是否完全匹配
+ 'route_complete_match' => false,
+ // 访问控制器层名称
+ 'controller_layer' => 'controller',
+ // 空控制器名
+ 'empty_controller' => 'Error',
+ // 是否使用控制器后缀
+ 'controller_suffix' => false,
+ // 默认的路由变量规则
+ 'default_route_pattern' => '[\w\.]+',
+ // 是否开启请求缓存 true自动缓存 支持设置请求缓存规则
+ 'request_cache' => false,
+ // 请求缓存有效期
+ 'request_cache_expire' => null,
+ // 全局请求缓存排除规则
+ 'request_cache_except' => [],
+ // 默认控制器名
+ 'default_controller' => 'Index',
+ // 默认操作名
+ 'default_action' => 'index',
+ // 操作方法后缀
+ 'action_suffix' => '',
+ // 默认JSONP格式返回的处理方法
+ 'default_jsonp_handler' => 'jsonpReturn',
+ // 默认JSONP处理方法
+ 'var_jsonp_handler' => 'callback',
+];
diff --git a/serve/config/session.php b/serve/config/session.php
new file mode 100644
index 0000000..c1ef6e1
--- /dev/null
+++ b/serve/config/session.php
@@ -0,0 +1,19 @@
+ 'PHPSESSID',
+ // SESSION_ID的提交变量,解决flash上传跨域
+ 'var_session_id' => '',
+ // 驱动方式 支持file cache
+ 'type' => 'file',
+ // 存储连接标识 当type使用cache的时候有效
+ 'store' => null,
+ // 过期时间
+ 'expire' => 1440,
+ // 前缀
+ 'prefix' => '',
+];
diff --git a/serve/config/soft.php b/serve/config/soft.php
new file mode 100644
index 0000000..1b8f7a0
--- /dev/null
+++ b/serve/config/soft.php
@@ -0,0 +1,10 @@
+ 'erp',
+ 'edition' => 'develop',
+ 'version' => '7.4.1'
+];
\ No newline at end of file
diff --git a/serve/config/trace.php b/serve/config/trace.php
new file mode 100644
index 0000000..fad2392
--- /dev/null
+++ b/serve/config/trace.php
@@ -0,0 +1,10 @@
+ 'Html',
+ // 读取的日志通道名
+ 'channel' => '',
+];
diff --git a/serve/config/view.php b/serve/config/view.php
new file mode 100644
index 0000000..01259a0
--- /dev/null
+++ b/serve/config/view.php
@@ -0,0 +1,25 @@
+ 'Think',
+ // 默认模板渲染规则 1 解析为小写+下划线 2 全部转换小写 3 保持操作方法
+ 'auto_rule' => 1,
+ // 模板目录名
+ 'view_dir_name' => 'view',
+ // 模板后缀
+ 'view_suffix' => 'html',
+ // 模板文件名分隔符
+ 'view_depr' => DIRECTORY_SEPARATOR,
+ // 模板引擎普通标签开始标记
+ 'tpl_begin' => '{',
+ // 模板引擎普通标签结束标记
+ 'tpl_end' => '}',
+ // 标签库标签开始标记
+ 'taglib_begin' => '{',
+ // 标签库标签结束标记
+ 'taglib_end' => '}',
+];
diff --git a/serve/extend/org/BakSql.php b/serve/extend/org/BakSql.php
new file mode 100644
index 0000000..963377f
--- /dev/null
+++ b/serve/extend/org/BakSql.php
@@ -0,0 +1,325 @@
+config = $config;
+ $this->begin = microtime(true);
+ header("Content-type: text/html;charset=utf-8");
+ $this->connect();
+ }
+ //首次进行pdo连接
+ private function connect() {
+ try{
+ $this->handler =new \PDO("{$this->config['type']}:host={$this->config['hostname']};port={$this->config['hostport']};dbname={$this->config['database']};",
+ $this->config['username'],
+ $this->config['password'],
+ array(
+ \PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES {$this->config['charset']};",
+ \PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION,
+ \PDO::ATTR_DEFAULT_FETCH_MODE => \PDO::FETCH_ASSOC
+ ));
+ }catch (PDOException $e) {
+ die ("Error!: " . $e->getMessage() . "
");
+ }
+ }
+ /**
+ * 查询
+ * @param string $sql
+ * @return mixed
+ */
+ private function query($sql = '')
+ {
+ $stmt = $this->handler->query($sql);
+ $stmt->setFetchMode(\PDO::FETCH_NUM);
+ $list = $stmt->fetchAll();
+ return $list;
+ }
+ /**
+ * 获取全部表
+ * @param string $dbName
+ * @return array
+ */
+ private function get_dbname($dbName = '*') {
+ $sql = 'SHOW TABLES';
+ $list = $this->query($sql);
+ $tables = array();
+ foreach ($list as $value)
+ {
+ $tables[] = $value[0];
+ }
+ return $tables;
+ }
+ /**
+ * 获取表定义语句
+ * @param string $table
+ * @return mixed
+ */
+ private function get_dbhead($table = '')
+ {
+ $sql = "SHOW CREATE TABLE `{$table}`";
+ $ddl = $this->query($sql)[0][1] . ';';
+ return $ddl;
+ }
+ /**
+ * 获取表数据
+ * @param string $table
+ * @return mixed
+ */
+ private function get_dbdata($table = '')
+ {
+ $sql = "SHOW COLUMNS FROM `{$table}`";
+ $list = $this->query($sql);
+ //字段
+ $columns = '';
+ //需要返回的SQL
+ $query = '';
+ foreach ($list as $value)
+ {
+ $columns .= "`{$value[0]}`,";
+ }
+ $columns = substr($columns, 0, -1);
+ $data = $this->query("SELECT * FROM `{$table}`");
+ foreach ($data as $value)
+ {
+ $dataSql = '';
+ foreach ($value as $v)
+ {
+ $dataSql .= "'".addslashes($v)."',";
+ }
+ $dataSql = substr($dataSql, 0, -1);
+ $query .= "INSERT INTO `{$table}` ({$columns}) VALUES ({$dataSql});\r\n";
+ }
+ return $query;
+ }
+ /**
+ * 写入文件
+ * @param array $tables
+ * @param array $ddl
+ * @param array $data
+ */
+ private function writeToFile($tables = array(), $ddl = array(), $data = array())
+ {
+ $str = "/*\r\nMySQL Database Backup Tools - NODCLOUD.COM\r\n";
+ $str .= "Server:{$this->config['hostname']}:{$this->config['hostport']}\r\n";
+ $str .= "Database:{$this->config['database']}\r\n";
+ $str .= "Data:" . date('Y-m-d H:i:s', time()) . "\r\n*/\r\n";
+ $str .= "SET NAMES utf8;\r\n";
+ $str .= "SET FOREIGN_KEY_CHECKS=0;\r\n";
+ $str .= "SET sql_mode = 'NO_AUTO_VALUE_ON_ZERO';\r\n";
+ $i = 0;
+ foreach ($tables as $table)
+ {
+ $str .= "-- ----------------------------\r\n";
+ $str .= "-- Table structure for {$table}\r\n";
+ $str .= "-- ----------------------------\r\n";
+ $str .= "DROP TABLE IF EXISTS `{$table}`;\r\n";
+ $str .= $ddl[$i] . "\r\n";
+ $str .= "-- ----------------------------\r\n";
+ $str .= "-- Records of {$table}\r\n";
+ $str .= "-- ----------------------------\r\n";
+ $str .= $data[$i] . "\r\n";
+ $i++;
+ }
+ if(!file_exists($this->config['path'])){mkdir($this->config['path']);}
+ return file_put_contents($this->config['path'].$this->config['sqlbakname'], $str) ? 'success' : 'error';
+ }
+ /**
+ * 设置要备份的表
+ * @param array $tables
+ */
+ private function setTables($tables = array())
+ {
+ if (!empty($tables) && is_array($tables))
+ {
+ //备份指定表
+ $this->tables = $tables;
+ }
+ else
+ {
+ //备份全部表
+ $this->tables = $this->get_dbname();
+ }
+ }
+ /**
+ * 备份
+ * @param array $tables
+ * @return bool
+ */
+ public function backup($tables = array())
+ {
+ //存储表定义语句的数组
+ $ddl = array();
+ //存储数据的数组
+ $data = array();
+ $this->setTables($tables);
+ if (!empty($this->tables))
+ {
+ foreach ($this->tables as $table)
+ {
+ $ddl[] = $this->get_dbhead($table);
+ $data[] = $this->get_dbdata($table);
+ }
+
+ //开始写入
+ return $this->writeToFile($this->tables, $ddl, $data);
+ }
+ else
+ {
+ $this->error = '数据库中没有表!';
+ return false;
+ }
+ }
+ /**
+ * 错误信息
+ * @return mixed
+ */
+ public function getError()
+ {
+ return $this->error;
+ }
+ //还原数据库
+ public function restore($filename = '')
+ {
+ $path=$this->config['path'].$filename;
+ if (!file_exists($path))
+ {
+ $this->error('SQL文件不存在!');
+ return false;
+ }
+ else
+ {
+ $sql = $this->parseSQL($path);
+ try
+ {
+ $this->handler->exec($sql);
+ return 'success';
+ }
+ catch (PDOException $e)
+ {
+ $this->error = $e->getMessage();
+ return false;
+ }
+ }
+ }
+
+ /**
+ * 解析SQL文件为SQL语句数组
+ * @param string $path
+ * @return array|mixed|string
+ */
+ private function parseSQL($path = '')
+ {
+ $sql = file_get_contents($path);
+ $sql = explode("\r\n", $sql);
+ //先消除--注释
+ $sql = array_filter($sql, function ($data)
+ {
+ if (empty($data) || preg_match('/^--.*/', $data))
+ {
+ return false;
+ }
+ else
+ {
+ return true;
+ }
+ });
+ $sql = implode('', $sql);
+ //删除/**/注释
+ $sql = preg_replace('/\/\*.*\*\//', '', $sql);
+ return $sql;
+ }
+ /**
+ * 下载备份
+ * @param string $fileName
+ * @return array|mixed|string
+ */
+ public function downloadFile($fileName) {
+ $fileName=$this->config['path'].$fileName;
+ if (file_exists($fileName)){
+ ob_end_clean();
+ header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
+ header('Content-Description: File Transfer');
+ header('Content-Type: application/octet-stream');
+ header('Content-Length: ' . filesize($fileName));
+ header('Content-Disposition: attachment; filename=' . basename($fileName));
+ readfile($fileName);
+ }else{
+ $this->error="文件有错误!";
+ }
+
+ }
+ /**
+ * 获取文件是时间
+ * @param string $file
+ * @return string
+ */
+ private function getfiletime($file){
+ $path=$this->config['path'].$file;
+ $a = filemtime($path);
+ $time = date("Y-m-d H:i:s", $a);
+ return $time;
+ }
+ /**
+ * 获取文件是大小
+ * @param string $file
+ * @return string
+ */
+ private function getfilesize($file){
+ $perms=stat($this->config['path'].$file);
+ $size = $perms['size'];
+ $a = ['B', 'KB', 'MB', 'GB', 'TB'];
+ $pos = 0;
+ while ($size >= 1024) {
+ $size /= 1024;
+ $pos++;
+ }
+ return round($size, 2). $a[$pos];
+ }
+
+ /**
+ * 获取文件列表
+ * @param string $Order 级别
+ * @return array
+ */
+ public function get_filelist($Order = 0) {
+ $FilePath=$this->config['path'];
+ $FilePath = opendir($FilePath);
+ $FileAndFolderAyy=array();
+ $i=1;
+ while (false !== ($filename = readdir($FilePath))) {
+ if ($filename!="." && $filename!=".."){
+ $i++;
+ $FileAndFolderAyy[$i]['name'] = $filename;
+ $FileAndFolderAyy[$i]['time'] = $this->getfiletime($filename);
+ $FileAndFolderAyy[$i]['size'] = $this->getfilesize($filename);
+ }
+ }
+ $Order == 0 ? sort($FileAndFolderAyy) : rsort($FileAndFolderAyy);
+ return array_reverse($FileAndFolderAyy);//返回反转数组
+ }
+ public function delfilename($filename){
+ $path=$this->config['path'].$filename;
+ if (@unlink($path)) {return 'success';}
+ }
+}
+?>
\ No newline at end of file
diff --git a/serve/extend/org/Captcha.php b/serve/extend/org/Captcha.php
new file mode 100644
index 0000000..d4e1b97
--- /dev/null
+++ b/serve/extend/org/Captcha.php
@@ -0,0 +1,139 @@
+join("",$code),
+ 'data'=>"data:image/png;base64,".base64_encode($imageData)
+ ];
+ }
+
+ /**
+ * 画一条由两条连在一起构成的随机正弦函数曲线作干扰线(你可以改成更帅的曲线函数)
+ *
+ * 高中的数学公式咋都忘了涅,写出来
+ * 正弦型函数解析式:y=Asin(ωx+φ)+b
+ * 各常数值对函数图像的影响:
+ * A:决定峰值(即纵向拉伸压缩的倍数)
+ * b:表示波形在Y轴的位置关系或纵向移动距离(上加下减)
+ * φ:决定波形与X轴位置关系或横向移动距离(左加右减)
+ * ω:决定周期(最小正周期T=2π/∣ω∣)
+ *
+ */
+ protected static function _writeCurve() {
+ $A = mt_rand(1, self::$imageH/2); // 振幅
+ $b = mt_rand(-self::$imageH/4, self::$imageH/4); // Y轴方向偏移量
+ $f = mt_rand(-self::$imageH/4, self::$imageH/4); // X轴方向偏移量
+ $T = mt_rand(self::$imageH*1.5, self::$imageL*2); // 周期
+ $w = (2* M_PI)/$T;
+ $px1 = 0; // 曲线横坐标起始位置
+ $px2 = mt_rand(self::$imageL/2, self::$imageL * 0.667); // 曲线横坐标结束位置
+ for ($px=$px1; $px<=$px2; $px=$px+ 0.9) {
+ if ($w!=0) {
+ $py = $A * sin($w*$px + $f)+ $b + self::$imageH/2; // y = Asin(ωx+φ) + b
+ $i = (int) ((self::$fontSize - 6)/4);
+ while ($i > 0) {
+ imagesetpixel(self::$_image, $px + $i, $py + $i, self::$_color); // 这里画像素点比imagettftext和imagestring性能要好很多
+ $i--;
+ }
+ }
+ }
+ $A = mt_rand(1, self::$imageH/2); // 振幅
+ $f = mt_rand(-self::$imageH/4, self::$imageH/4); // X轴方向偏移量
+ $T = mt_rand(self::$imageH*1.5, self::$imageL*2); // 周期
+ $w = (2* M_PI)/$T;
+ $b = $py - $A * sin($w*$px + $f) - self::$imageH/2;
+ $px1 = $px2;
+ $px2 = self::$imageL;
+ for ($px=$px1; $px<=$px2; $px=$px+ 0.9) {
+ if ($w!=0) {
+ $py = $A * sin($w*$px + $f)+ $b + self::$imageH/2; // y = Asin(ωx+φ) + b
+ $i = (int) ((self::$fontSize - 8)/4);
+ while ($i > 0) {
+ imagesetpixel(self::$_image, $px + $i, $py + $i, self::$_color); // 这里(while)循环画像素点比imagettftext和imagestring用字体大小一次画出(不用这while循环)性能要好很多
+ $i--;
+ }
+ }
+ }
+ }
+
+ /**
+ * 画杂点
+ * 往图片上写不同颜色的字母或数字
+ */
+ protected static function _writeNoise() {
+ for($i = 0; $i < 10; $i++){
+ //杂点颜色
+ $noiseColor = imagecolorallocate(
+ self::$_image,
+ mt_rand(150,225),
+ mt_rand(150,225),
+ mt_rand(150,225)
+ );
+ for($j = 0; $j < 5; $j++) {
+ // 绘杂点
+ imagestring(
+ self::$_image,
+ 5,
+ mt_rand(-10, self::$imageL),
+ mt_rand(-10, self::$imageH),
+ self::$codeSet[mt_rand(0, 27)], // 杂点文本为随机的字母或数字
+ $noiseColor
+ );
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/serve/extend/org/Core.php b/serve/extend/org/Core.php
new file mode 100644
index 0000000..e69de29
diff --git a/serve/extend/org/Math.php b/serve/extend/org/Math.php
new file mode 100644
index 0000000..d521d4a
--- /dev/null
+++ b/serve/extend/org/Math.php
@@ -0,0 +1,57 @@
+base=$number;
+ return $this;
+ }
+ //加法运算
+ public function add($number) {
+ $this->base=bcadd($this->base,$number);
+ return $this;
+ }
+ //减法运算
+ public function sub($number) {
+ $this->base=bcsub($this->base,$number);
+ return $this;
+ }
+ //乘法运算
+ public function mul($number) {
+ $this->base=bcmul($this->base,$number);
+ return $this;
+ }
+ //除法运算
+ public function div($number) {
+ $this->base=bcdiv($this->base,$number);
+ return $this;
+ }
+ //取余运算
+ public function mod($number) {
+ $this->base=bcmod($this->base,$number);
+ return $this;
+ }
+ //四舍五入
+ public function round($digit) {
+ $this->base=round($this->base,$digit);
+ return $this;
+ }
+ //四舍五入
+ public function abs() {
+ $this->base=abs($this->base);
+ return $this;
+ }
+ //返回结果
+ public function done() {
+ return floatval($this->base);
+ }
+}
diff --git a/serve/extend/org/Search.php b/serve/extend/org/Search.php
new file mode 100644
index 0000000..80acc34
--- /dev/null
+++ b/serve/extend/org/Search.php
@@ -0,0 +1,90 @@
+source=$source;
+ return $this;
+ }
+
+ //搜索条件
+ //[['key|key1','=|<>|in|like|between','val']]
+ public function where($condition,$retain=false) {
+ $recode=[];
+ foreach ($this->source as $sourcekey=>$sourceVo) {
+ $state=true;
+ foreach ($condition as $conditionVo){
+ //处理多层键名
+ $row=$this->arraySeek($sourceVo,$conditionVo[0]);
+ //条件判断
+ if($conditionVo[1]=='='){
+ //相等判断
+ $row==$conditionVo[2]||($state=false);
+ }elseif($conditionVo[1]=='<>'){
+ //不相等判断
+ $row==$conditionVo[2]&&($state=false);
+ }elseif($conditionVo[1]=='in'){
+ //包含判断
+ in_array($row,$conditionVo[2])||($state=false);
+ }elseif($conditionVo[1]=='like'){
+ //模糊匹配判断
+ strstr($row,$conditionVo[2])==false&&($state=false);
+ }elseif($conditionVo[1]=='between'){
+ //区间判断
+ ($row>=$conditionVo[2][0] && $row<=$conditionVo[2][1])||($state=false);
+ }else{
+ die('匹配规则失败!');
+ }
+ }
+ if($state){
+ $retain&&$sourceVo['rowKey']=$sourcekey;
+ $recode[]=$sourceVo;
+ }
+ }
+ $this->source=$recode;
+ return $this;
+ }
+ //处理数据
+ public function loop($fun){
+ foreach ($this->source as $key=>$vo) {
+ $this->source[$key]=$fun($vo,$key);
+ }
+ return $this;
+ }
+
+ //单组数据
+ public function find() {
+ return empty($this->source)?[]:$this->source[0];
+ }
+
+ //多组数据
+ public function select() {
+ return $this->source;
+ }
+
+ //数据统计
+ public function count() {
+ return count($this->source);
+ }
+
+ //多层键名匹配
+ private function arraySeek($data,$rule){
+ $recode=$data;
+ is_array($rule)||($rule=explode('|',$rule));
+ foreach ($rule as $ruleVo) {
+ if(is_array($recode) && isset($recode[$ruleVo])){
+ $recode=$recode[$ruleVo];
+ }else{
+ $recode='';
+ break;
+ }
+ }
+ return $recode;
+ }
+}
diff --git a/serve/extend/org/Tree.php b/serve/extend/org/Tree.php
new file mode 100644
index 0000000..89a9b7a
--- /dev/null
+++ b/serve/extend/org/Tree.php
@@ -0,0 +1,40 @@
+ &$v) {
+ if(!empty($v['sub'])){
+ $v['sub']=self::sort($v['sub'],$cols);
+ }
+ $sort[$k]=$v[$cols];
+ }
+ if(isset($sort))
+ array_multisort($sort,SORT_ASC,$arr);
+ return $arr;
+ }
+ //横向分类树
+ static public function hTree($arr,$pid=0){
+ foreach($arr as $k => $v){
+ if($v['pid']==$pid){
+ $v['sub']=self::hTree($arr,$v['id']);
+ $data[]=$v;
+ }
+ }
+ return isset($data)?$data:[];
+ }
+ //纵向分类树
+ static public function vTree($arr,$pid=0,$state=true){
+ static $data=[];
+ $state&&$data=[];
+ foreach($arr as $k => $v){
+ if($v['pid']==$pid){
+ $data[]=$v;
+ self::vTree($arr,$v['id'],false);
+ }
+ }
+ return $data;
+ }
+}
\ No newline at end of file
diff --git a/serve/extend/org/ZhToPy.php b/serve/extend/org/ZhToPy.php
new file mode 100644
index 0000000..276e5e8
--- /dev/null
+++ b/serve/extend/org/ZhToPy.php
@@ -0,0 +1,50 @@
+'yi','乁'=>'yi','乂'=>'yi','义'=>'yi','乙'=>'yi','亄'=>'yi','亦'=>'yi','亿'=>'yi','仡'=>'yi','以'=>'yi','仪'=>'yi','伇'=>'yi','伊'=>'yi','伿'=>'yi','佁'=>'yi','佚'=>'yi','佾'=>'yi','侇'=>'yi','依'=>'yi','俋'=>'yi','倚'=>'yi','偯'=>'yi','儀'=>'yi','億'=>'yi','兿'=>'yi','冝'=>'yi','刈'=>'yi','劓'=>'yi','劮'=>'yi','勚'=>'yi','勩'=>'yi','匇'=>'yi','匜'=>'yi','医'=>'yi','吚'=>'yi','呓'=>'yi','呭'=>'yi','呹'=>'yi','咦'=>'yi','咿'=>'yi','唈'=>'yi','噫'=>'yi','囈'=>'yi','圛'=>'yi','圯'=>'yi','坄'=>'yi','垼'=>'yi','埶'=>'yi','埸'=>'yi','墿'=>'yi','壱'=>'yi','壹'=>'yi','夁'=>'yi','夷'=>'yi','奕'=>'yi','妷'=>'yi','姨'=>'yi','媐'=>'yi','嫕'=>'yi','嫛'=>'yi','嬄'=>'yi','嬑'=>'yi','嬟'=>'yi','宐'=>'yi','宜'=>'yi','宧'=>'yi','寱'=>'yi','寲'=>'yi','屹'=>'yi','峄'=>'yi','峓'=>'yi','崺'=>'yi','嶧'=>'yi','嶬'=>'yi','嶷'=>'yi','已'=>'yi','巸'=>'yi','帟'=>'yi','帠'=>'yi','幆'=>'yi','庡'=>'yi','廙'=>'yi','异'=>'yi','弈'=>'yi','弋'=>'yi','弌'=>'yi','弬'=>'yi','彛'=>'yi','彜'=>'yi','彝'=>'yi','彞'=>'yi','役'=>'yi','忆'=>'yi','忔'=>'yi','怈'=>'yi','怡'=>'yi','怿'=>'yi','恞'=>'yi','悒'=>'yi','悘'=>'yi','悥'=>'yi','意'=>'yi','憶'=>'yi','懌'=>'yi','懿'=>'yi','扅'=>'yi','扆'=>'yi','抑'=>'yi','挹'=>'yi','揖'=>'yi','撎'=>'yi','攺'=>'yi','敡'=>'yi','敼'=>'yi','斁'=>'yi','旑'=>'yi','旖'=>'yi','易'=>'yi','晹'=>'yi','暆'=>'yi','曀'=>'yi','曎'=>'yi','曵'=>'yi','杙'=>'yi','杝'=>'yi','枍'=>'yi','枻'=>'yi','柂'=>'yi','栘'=>'yi','栧'=>'yi','栺'=>'yi','桋'=>'yi','棭'=>'yi','椅'=>'yi','椬'=>'yi','椸'=>'yi','榏'=>'yi','槸'=>'yi','檍'=>'yi','檥'=>'yi','檹'=>'yi','欭'=>'yi','欹'=>'yi','歝'=>'yi','殔'=>'yi','殪'=>'yi','殹'=>'yi','毅'=>'yi','毉'=>'yi','沂'=>'yi','沶'=>'yi','泆'=>'yi','洢'=>'yi','浂'=>'yi','浥'=>'yi','浳'=>'yi','湙'=>'yi','溢'=>'yi','漪'=>'yi','潩'=>'yi','澺'=>'yi','瀷'=>'yi','炈'=>'yi','焲'=>'yi','熠'=>'yi','熤'=>'yi','熪'=>'yi','熼'=>'yi','燚'=>'yi','燡'=>'yi','燱'=>'yi','狋'=>'yi','猗'=>'yi','獈'=>'yi','玴'=>'yi','瑿'=>'yi','瓵'=>'yi','畩'=>'yi','異'=>'yi','疑'=>'yi','疫'=>'yi','痍'=>'yi','痬'=>'yi','瘗'=>'yi','瘞'=>'yi','瘱'=>'yi','癔'=>'yi','益'=>'yi','眙'=>'yi','瞖'=>'yi','矣'=>'yi','礒'=>'yi','祎'=>'yi','禕'=>'yi','秇'=>'yi','移'=>'yi','稦'=>'yi','穓'=>'yi','竩'=>'yi','笖'=>'yi','簃'=>'yi','籎'=>'yi','縊'=>'yi','繄'=>'yi','繶'=>'yi','繹'=>'yi','绎'=>'yi','缢'=>'yi','羛'=>'yi','羠'=>'yi','義'=>'yi','羿'=>'yi','翊'=>'yi','翌'=>'yi','翳'=>'yi','翼'=>'yi','耴'=>'yi','肄'=>'yi','肊'=>'yi','胰'=>'yi','膉'=>'yi','臆'=>'yi','舣'=>'yi','艗'=>'yi','艤'=>'yi','艺'=>'yi','芅'=>'yi','苅'=>'yi','苡'=>'yi','苢'=>'yi','荑'=>'yi','萓'=>'yi','萟'=>'yi','蓺'=>'yi','薏'=>'yi','藙'=>'yi','藝'=>'yi','蘙'=>'yi','虉'=>'yi','蚁'=>'yi','蛜'=>'yi','蛡'=>'yi','蛦'=>'yi','蜴'=>'yi','螔'=>'yi','螘'=>'yi','螠'=>'yi','蟻'=>'yi','衣'=>'yi','衤'=>'yi','衪'=>'yi','衵'=>'yi','袘'=>'yi','袣'=>'yi','裔'=>'yi','裛'=>'yi','褹'=>'yi','襼'=>'yi','觺'=>'yi','訲'=>'yi','訳'=>'yi','詍'=>'yi','詒'=>'yi','詣'=>'yi','誃'=>'yi','誼'=>'yi','謻'=>'yi','譩'=>'yi','譯'=>'yi','議'=>'yi','讉'=>'yi','讛'=>'yi','议'=>'yi','译'=>'yi','诒'=>'yi','诣'=>'yi','谊'=>'yi','豙'=>'yi','豛'=>'yi','豷'=>'yi','貖'=>'yi','貤'=>'yi','貽'=>'yi','贀'=>'yi','贻'=>'yi','跇'=>'yi','跠'=>'yi','軼'=>'yi','輢'=>'yi','轙'=>'yi','轶'=>'yi','辷'=>'yi','迆'=>'yi','迤'=>'yi','迻'=>'yi','逘'=>'yi','逸'=>'yi','遗'=>'yi','遺'=>'yi','邑'=>'yi','郼'=>'yi','酏'=>'yi','醫'=>'yi','醳'=>'yi','醷'=>'yi','釔'=>'yi','釴'=>'yi','鈘'=>'yi','鈠'=>'yi','鉯'=>'yi','銥'=>'yi','鎰'=>'yi','鏔'=>'yi','鐿'=>'yi','钇'=>'yi','铱'=>'yi','镒'=>'yi','镱'=>'yi','阣'=>'yi','陭'=>'yi','隿'=>'yi','霬'=>'yi','靾'=>'yi','頉'=>'yi','頤'=>'yi','頥'=>'yi','顊'=>'yi','顗'=>'yi','颐'=>'yi','飴'=>'yi','饐'=>'yi','饴'=>'yi','駅'=>'yi','驛'=>'yi','驿'=>'yi','骮'=>'yi','鮧'=>'yi','鮨'=>'yi','鯣'=>'yi','鳦'=>'yi','鶂'=>'yi','鶃'=>'yi','鶍'=>'yi','鷁'=>'yi','鷊'=>'yi','鷖'=>'yi','鷧'=>'yi','鷾'=>'yi','鸃'=>'yi','鹝'=>'yi','鹢'=>'yi','鹥'=>'yi','黓'=>'yi','黟'=>'yi','黳'=>'yi','齮'=>'yi','齸'=>'yi','㐹'=>'yi','㑊'=>'yi','㑜'=>'yi','㑥'=>'yi','㓷'=>'yi','㔴'=>'yi','㕥'=>'yi','㖂'=>'yi','㘁'=>'yi','㘈'=>'yi','㘊'=>'yi','㘦'=>'yi','㙠'=>'yi','㙯'=>'yi','㚤'=>'yi','㚦'=>'yi','㛕'=>'yi','㜋'=>'yi','㜒'=>'yi','㝖'=>'yi','㞔'=>'yi','㠯'=>'yi','㡫'=>'yi','㡼'=>'yi','㢞'=>'yi','㣂'=>'yi','㣻'=>'yi','㥴'=>'yi','㦉'=>'yi','㦤'=>'yi','㦾'=>'yi','㩘'=>'yi','㫊'=>'yi','㰘'=>'yi','㰝'=>'yi','㰻'=>'yi','㱅'=>'yi','㱲'=>'yi','㲼'=>'yi','㳑'=>'yi','㴁'=>'yi','㴒'=>'yi','㵝'=>'yi','㵩'=>'yi','㶠'=>'yi','㹓'=>'yi','㹭'=>'yi','㺿'=>'yi','㽈'=>'yi','䄁'=>'yi','䄬'=>'yi','䄿'=>'yi','䆿'=>'yi','䇩'=>'yi','䇵'=>'yi','䉨'=>'yi','䋚'=>'yi','䋵'=>'yi','䌻'=>'yi','䎈'=>'yi','䐅'=>'yi','䐖'=>'yi','䓃'=>'yi','䓈'=>'yi','䓹'=>'yi','䔬'=>'yi','䕍'=>'yi','䖁'=>'yi','䖊'=>'yi','䗑'=>'yi','䗟'=>'yi','䗷'=>'yi','䘝'=>'yi','䘸'=>'yi','䝘'=>'yi','䝝'=>'yi','䝯'=>'yi','䞅'=>'yi','䢃'=>'yi','䣧'=>'yi','䦴'=>'yi','䧧'=>'yi','䩟'=>'yi','䬁'=>'yi','䬥'=>'yi','䬮'=>'yi','䭂'=>'yi','䭇'=>'yi','䭞'=>'yi','䭿'=>'yi','䮊'=>'yi','䯆'=>'yi','䰙'=>'yi','䱌'=>'yi','䱒'=>'yi','䲑'=>'yi','䴊'=>'yi','䴬'=>'yi','丁'=>'ding','仃'=>'ding','叮'=>'ding','啶'=>'ding','奵'=>'ding','定'=>'ding','嵿'=>'ding','帄'=>'ding','忊'=>'ding','椗'=>'ding','玎'=>'ding','甼'=>'ding','疔'=>'ding','盯'=>'ding','矴'=>'ding','碇'=>'ding','碠'=>'ding','磸'=>'ding','耵'=>'ding','聢'=>'ding','聣'=>'ding','腚'=>'ding','萣'=>'ding','薡'=>'ding','訂'=>'ding','订'=>'ding','酊'=>'ding','釘'=>'ding','錠'=>'ding','鐤'=>'ding','钉'=>'ding','锭'=>'ding','靪'=>'ding','頂'=>'ding','顁'=>'ding','顶'=>'ding','飣'=>'ding','饤'=>'ding','鼎'=>'ding','鼑'=>'ding','㝎'=>'ding','㫀'=>'ding','㴿'=>'ding','㼗'=>'ding','丂'=>'kao','尻'=>'kao','拷'=>'kao','攷'=>'kao','栲'=>'kao','洘'=>'kao','烤'=>'kao','犒'=>'kao','考'=>'kao','銬'=>'kao','铐'=>'kao','靠'=>'kao','髛'=>'kao','鮳'=>'kao','鯌'=>'kao','鲓'=>'kao','䐧'=>'kao','䯪'=>'kao','七'=>'qi','乞'=>'qi','亓'=>'qi','亝'=>'qi','企'=>'qi','倛'=>'qi','僛'=>'qi','其'=>'qi','凄'=>'qi','剘'=>'qi','启'=>'qi','呇'=>'qi','呮'=>'qi','咠'=>'qi','唘'=>'qi','唭'=>'qi','啓'=>'qi','啔'=>'qi','啟'=>'qi','嘁'=>'qi','噐'=>'qi','器'=>'qi','圻'=>'qi','埼'=>'qi','夡'=>'qi','奇'=>'qi','契'=>'qi','妻'=>'qi','娸'=>'qi','婍'=>'qi','屺'=>'qi','岂'=>'qi','岐'=>'qi','岓'=>'qi','崎'=>'qi','嵜'=>'qi','帺'=>'qi','弃'=>'qi','忯'=>'qi','恓'=>'qi','悽'=>'qi','愒'=>'qi','愭'=>'qi','慼'=>'qi','慽'=>'qi','憇'=>'qi','憩'=>'qi','懠'=>'qi','戚'=>'qi','捿'=>'qi','掑'=>'qi','摖'=>'qi','斉'=>'qi','斊'=>'qi','旂'=>'qi','旗'=>'qi','晵'=>'qi','暣'=>'qi','朞'=>'qi','期'=>'qi','杞'=>'qi','柒'=>'qi','栔'=>'qi','栖'=>'qi','桤'=>'qi','桼'=>'qi','棄'=>'qi','棊'=>'qi','棋'=>'qi','棨'=>'qi','棲'=>'qi','榿'=>'qi','槭'=>'qi','檱'=>'qi','櫀'=>'qi','欫'=>'qi','欺'=>'qi','歧'=>'qi','气'=>'qi','気'=>'qi','氣'=>'qi','汔'=>'qi','汽'=>'qi','沏'=>'qi','泣'=>'qi','淇'=>'qi','淒'=>'qi','渏'=>'qi','湆'=>'qi','湇'=>'qi','漆'=>'qi','濝'=>'qi','炁'=>'qi','猉'=>'qi','玂'=>'qi','玘'=>'qi','琦'=>'qi','琪'=>'qi','璂'=>'qi','甈'=>'qi','畦'=>'qi','疧'=>'qi','盀'=>'qi','盵'=>'qi','矵'=>'qi','砌'=>'qi','碁'=>'qi','碕'=>'qi','碛'=>'qi','碶'=>'qi','磎'=>'qi','磜'=>'qi','磧'=>'qi','磩'=>'qi','礘'=>'qi','祁'=>'qi','祇'=>'qi','祈'=>'qi','祺'=>'qi','禥'=>'qi','竒'=>'qi','簯'=>'qi','簱'=>'qi','籏'=>'qi','粸'=>'qi','紪'=>'qi','綥'=>'qi','綦'=>'qi','綨'=>'qi','綮'=>'qi','綺'=>'qi','緀'=>'qi','緕'=>'qi','纃'=>'qi','绮'=>'qi','缼'=>'qi','罊'=>'qi','耆'=>'qi','肵'=>'qi','脐'=>'qi','臍'=>'qi','艩'=>'qi','芑'=>'qi','芞'=>'qi','芪'=>'qi','荠'=>'qi','萁'=>'qi','萋'=>'qi','葺'=>'qi','蕲'=>'qi','薺'=>'qi','藄'=>'qi','蘄'=>'qi','蚑'=>'qi','蚔'=>'qi','蚚'=>'qi','蛴'=>'qi','蜝'=>'qi','蜞'=>'qi','螧'=>'qi','蟿'=>'qi','蠐'=>'qi','裿'=>'qi','褀'=>'qi','褄'=>'qi','訖'=>'qi','諆'=>'qi','諬'=>'qi','諿'=>'qi','讫'=>'qi','豈'=>'qi','起'=>'qi','跂'=>'qi','踑'=>'qi','踦'=>'qi','蹊'=>'qi','軝'=>'qi','迄'=>'qi','迉'=>'qi','邔'=>'qi','郪'=>'qi','釮'=>'qi','錡'=>'qi','鏚'=>'qi','锜'=>'qi','闙'=>'qi','霋'=>'qi','頎'=>'qi','颀'=>'qi','騎'=>'qi','騏'=>'qi','騹'=>'qi','骐'=>'qi','骑'=>'qi','鬐'=>'qi','鬾'=>'qi','鬿'=>'qi','魌'=>'qi','魕'=>'qi','鯕'=>'qi','鰭'=>'qi','鲯'=>'qi','鳍'=>'qi','鵸'=>'qi','鶀'=>'qi','鶈'=>'qi','麒'=>'qi','麡'=>'qi','齊'=>'qi','齐'=>'qi','㒅'=>'qi','㓞'=>'qi','㜎'=>'qi','㞓'=>'qi','㞚'=>'qi','㟓'=>'qi','㟚'=>'qi','㟢'=>'qi','㣬'=>'qi','㥓'=>'qi','㩩'=>'qi','㩽'=>'qi','㫓'=>'qi','㮑'=>'qi','㯦'=>'qi','㼤'=>'qi','㾨'=>'qi','䀈'=>'qi','䀙'=>'qi','䁈'=>'qi','䁉'=>'qi','䄎'=>'qi','䄢'=>'qi','䄫'=>'qi','䅤'=>'qi','䅲'=>'qi','䉝'=>'qi','䉻'=>'qi','䋯'=>'qi','䌌'=>'qi','䎢'=>'qi','䏅'=>'qi','䏌'=>'qi','䏠'=>'qi','䏿'=>'qi','䐡'=>'qi','䑴'=>'qi','䒗'=>'qi','䒻'=>'qi','䓅'=>'qi','䔇'=>'qi','䙄'=>'qi','䚉'=>'qi','䚍'=>'qi','䛴'=>'qi','䞚'=>'qi','䟄'=>'qi','䟚'=>'qi','䡋'=>'qi','䡔'=>'qi','䢀'=>'qi','䧘'=>'qi','䧵'=>'qi','䩓'=>'qi','䫔'=>'qi','䬣'=>'qi','䭫'=>'qi','䭬'=>'qi','䭶'=>'qi','䭼'=>'qi','䰇'=>'qi','䰴'=>'qi','䱈'=>'qi','䲬'=>'qi','䳢'=>'qi','䶒'=>'qi','䶞'=>'qi','丄'=>'shang','上'=>'shang','仩'=>'shang','伤'=>'shang','傷'=>'shang','商'=>'shang','垧'=>'shang','墒'=>'shang','尙'=>'shang','尚'=>'shang','恦'=>'shang','愓'=>'shang','慯'=>'shang','扄'=>'shang','晌'=>'shang','殇'=>'shang','殤'=>'shang','滳'=>'shang','漡'=>'shang','熵'=>'shang','緔'=>'shang','绱'=>'shang','蔏'=>'shang','螪'=>'shang','裳'=>'shang','觞'=>'shang','觴'=>'shang','謪'=>'shang','賞'=>'shang','赏'=>'shang','鑜'=>'shang','鬺'=>'shang','䬕'=>'shang','丅'=>'xia','下'=>'xia','侠'=>'xia','俠'=>'xia','傄'=>'xia','匣'=>'xia','厦'=>'xia','吓'=>'xia','呷'=>'xia','嚇'=>'xia','圷'=>'xia','夏'=>'xia','夓'=>'xia','峡'=>'xia','峽'=>'xia','廈'=>'xia','懗'=>'xia','搳'=>'xia','敮'=>'xia','暇'=>'xia','柙'=>'xia','梺'=>'xia','溊'=>'xia','炠'=>'xia','烚'=>'xia','煆'=>'xia','狎'=>'xia','狭'=>'xia','狹'=>'xia','珨'=>'xia','瑕'=>'xia','疜'=>'xia','疨'=>'xia','睱'=>'xia','瞎'=>'xia','硖'=>'xia','硤'=>'xia','碬'=>'xia','磍'=>'xia','祫'=>'xia','笚'=>'xia','筪'=>'xia','縀'=>'xia','縖'=>'xia','罅'=>'xia','翈'=>'xia','舝'=>'xia','舺'=>'xia','蕸'=>'xia','虾'=>'xia','蝦'=>'xia','諕'=>'xia','谺'=>'xia','赮'=>'xia','轄'=>'xia','辖'=>'xia','遐'=>'xia','鍜'=>'xia','鎋'=>'xia','鏬'=>'xia','閕'=>'xia','閜'=>'xia','陜'=>'xia','陿'=>'xia','霞'=>'xia','颬'=>'xia','騢'=>'xia','魻'=>'xia','鰕'=>'xia','鶷'=>'xia','黠'=>'xia','㗇'=>'xia','㗿'=>'xia','㘡'=>'xia','㙤'=>'xia','㰺'=>'xia','㽠'=>'xia','䖎'=>'xia','䖖'=>'xia','䘥'=>'xia','䛅'=>'xia','䦖'=>'xia','䪗'=>'xia','䫗'=>'xia','丆'=>'mu','亩'=>'mu','仫'=>'mu','凩'=>'mu','募'=>'mu','坶'=>'mu','墓'=>'mu','墲'=>'mu','姆'=>'mu','娒'=>'mu','峔'=>'mu','幕'=>'mu','幙'=>'mu','慔'=>'mu','慕'=>'mu','拇'=>'mu','旀'=>'mu','暮'=>'mu','木'=>'mu','椧'=>'mu','楘'=>'mu','樢'=>'mu','母'=>'mu','毣'=>'mu','毪'=>'mu','氁'=>'mu','沐'=>'mu','炑'=>'mu','牡'=>'mu','牧'=>'mu','牳'=>'mu','狇'=>'mu','獏'=>'mu','畆'=>'mu','畒'=>'mu','畝'=>'mu','畞'=>'mu','畮'=>'mu','目'=>'mu','睦'=>'mu','砪'=>'mu','穆'=>'mu','胟'=>'mu','艒'=>'mu','苜'=>'mu','莯'=>'mu','萺'=>'mu','蚞'=>'mu','踇'=>'mu','鉧'=>'mu','鉬'=>'mu','钼'=>'mu','雮'=>'mu','霂'=>'mu','鞪'=>'mu','㒇'=>'mu','㜈'=>'mu','㣎'=>'mu','㧅'=>'mu','㾇'=>'mu','䀲'=>'mu','䊾'=>'mu','䑵'=>'mu','䥈'=>'mu','䧔'=>'mu','䱯'=>'mu','万'=>'wan','丸'=>'wan','乛'=>'wan','倇'=>'wan','刓'=>'wan','剜'=>'wan','卍'=>'wan','卐'=>'wan','唍'=>'wan','埦'=>'wan','塆'=>'wan','壪'=>'wan','妧'=>'wan','婉'=>'wan','婠'=>'wan','完'=>'wan','宛'=>'wan','岏'=>'wan','帵'=>'wan','弯'=>'wan','彎'=>'wan','忨'=>'wan','惋'=>'wan','抏'=>'wan','挽'=>'wan','捖'=>'wan','捥'=>'wan','晚'=>'wan','晩'=>'wan','晼'=>'wan','杤'=>'wan','梚'=>'wan','椀'=>'wan','汍'=>'wan','涴'=>'wan','湾'=>'wan','潫'=>'wan','灣'=>'wan','烷'=>'wan','玩'=>'wan','琓'=>'wan','琬'=>'wan','畹'=>'wan','皖'=>'wan','盌'=>'wan','睕'=>'wan','碗'=>'wan','笂'=>'wan','紈'=>'wan','綩'=>'wan','綰'=>'wan','纨'=>'wan','绾'=>'wan','翫'=>'wan','脘'=>'wan','腕'=>'wan','芄'=>'wan','莞'=>'wan','菀'=>'wan','萬'=>'wan','薍'=>'wan','蜿'=>'wan','豌'=>'wan','貦'=>'wan','贃'=>'wan','贎'=>'wan','踠'=>'wan','輓'=>'wan','邜'=>'wan','鋄'=>'wan','鋔'=>'wan','錽'=>'wan','鍐'=>'wan','鎫'=>'wan','頑'=>'wan','顽'=>'wan','㜶'=>'wan','㝴'=>'wan','㸘'=>'wan','㽜'=>'wan','㿸'=>'wan','䂺'=>'wan','䅋'=>'wan','䖤'=>'wan','䗕'=>'wan','䘼'=>'wan','䛷'=>'wan','䝹'=>'wan','䥑'=>'wan','䩊'=>'wan','䯈'=>'wan','䳃'=>'wan','丈'=>'zhang','仉'=>'zhang','仗'=>'zhang','傽'=>'zhang','墇'=>'zhang','嫜'=>'zhang','嶂'=>'zhang','帐'=>'zhang','帳'=>'zhang','幛'=>'zhang','幥'=>'zhang','张'=>'zhang','弡'=>'zhang','張'=>'zhang','彰'=>'zhang','慞'=>'zhang','扙'=>'zhang','掌'=>'zhang','暲'=>'zhang','杖'=>'zhang','樟'=>'zhang','涨'=>'zhang','涱'=>'zhang','漲'=>'zhang','漳'=>'zhang','獐'=>'zhang','璋'=>'zhang','痮'=>'zhang','瘬'=>'zhang','瘴'=>'zhang','瞕'=>'zhang','礃'=>'zhang','章'=>'zhang','粀'=>'zhang','粻'=>'zhang','胀'=>'zhang','脹'=>'zhang','蔁'=>'zhang','蟑'=>'zhang','賬'=>'zhang','账'=>'zhang','遧'=>'zhang','鄣'=>'zhang','鏱'=>'zhang','鐣'=>'zhang','障'=>'zhang','鞝'=>'zhang','餦'=>'zhang','騿'=>'zhang','鱆'=>'zhang','麞'=>'zhang','㕩'=>'zhang','㙣'=>'zhang','㽴'=>'zhang','䍤'=>'zhang','三'=>'san','伞'=>'san','俕'=>'san','傘'=>'san','厁'=>'san','叁'=>'san','壭'=>'san','弎'=>'san','散'=>'san','橵'=>'san','毵'=>'san','毶'=>'san','毿'=>'san','犙'=>'san','糁'=>'san','糂'=>'san','糝'=>'san','糣'=>'san','糤'=>'san','繖'=>'san','鏒'=>'san','閐'=>'san','饊'=>'san','馓'=>'san','鬖'=>'san','㤾'=>'san','㧲'=>'san','㪔'=>'san','㪚'=>'san','䀐'=>'san','䉈'=>'san','䊉'=>'san','䫅'=>'san','䫩'=>'san',''=>'','丌'=>'ji','丮'=>'ji','乩'=>'ji','亟'=>'ji','亼'=>'ji','伋'=>'ji','伎'=>'ji','佶'=>'ji','偈'=>'ji','偮'=>'ji','僟'=>'ji','兾'=>'ji','冀'=>'ji','几'=>'ji','击'=>'ji','刉'=>'ji','刏'=>'ji','剂'=>'ji','剞'=>'ji','剤'=>'ji','劑'=>'ji','勣'=>'ji','卙'=>'ji','即'=>'ji','卽'=>'ji','及'=>'ji','叝'=>'ji','叽'=>'ji','吉'=>'ji','咭'=>'ji','哜'=>'ji','唧'=>'ji','喞'=>'ji','嗘'=>'ji','嘰'=>'ji','嚌'=>'ji','圾'=>'ji','坖'=>'ji','垍'=>'ji','基'=>'ji','塉'=>'ji','墍'=>'ji','墼'=>'ji','妀'=>'ji','妓'=>'ji','姞'=>'ji','姬'=>'ji','嫉'=>'ji','季'=>'ji','寂'=>'ji','寄'=>'ji','屐'=>'ji','岌'=>'ji','峜'=>'ji','嵆'=>'ji','嵇'=>'ji','嵴'=>'ji','嶯'=>'ji','己'=>'ji','幾'=>'ji','庴'=>'ji','廭'=>'ji','彐'=>'ji','彑'=>'ji','彶'=>'ji','徛'=>'ji','忌'=>'ji','忣'=>'ji','急'=>'ji','悸'=>'ji','惎'=>'ji','愱'=>'ji','憿'=>'ji','懻'=>'ji','戟'=>'ji','戢'=>'ji','技'=>'ji','挤'=>'ji','掎'=>'ji','揤'=>'ji','撃'=>'ji','撠'=>'ji','擊'=>'ji','擠'=>'ji','攲'=>'ji','敧'=>'ji','旡'=>'ji','既'=>'ji','旣'=>'ji','暨'=>'ji','暩'=>'ji','曁'=>'ji','机'=>'ji','极'=>'ji','枅'=>'ji','梞'=>'ji','棘'=>'ji','楖'=>'ji','楫'=>'ji','極'=>'ji','槉'=>'ji','槣'=>'ji','樭'=>'ji','機'=>'ji','橶'=>'ji','檕'=>'ji','檝'=>'ji','檵'=>'ji','櫅'=>'ji','殛'=>'ji','毄'=>'ji','汲'=>'ji','泲'=>'ji','洎'=>'ji','济'=>'ji','済'=>'ji','湒'=>'ji','漃'=>'ji','漈'=>'ji','潗'=>'ji','激'=>'ji','濈'=>'ji','濟'=>'ji','瀱'=>'ji','焏'=>'ji','犄'=>'ji','犱'=>'ji','狤'=>'ji','玑'=>'ji','璣'=>'ji','璾'=>'ji','畸'=>'ji','畿'=>'ji','疾'=>'ji','痵'=>'ji','瘠'=>'ji','癠'=>'ji','癪'=>'ji','皍'=>'ji','矶'=>'ji','磯'=>'ji','祭'=>'ji','禝'=>'ji','禨'=>'ji','积'=>'ji','稘'=>'ji','稩'=>'ji','稷'=>'ji','稽'=>'ji','穄'=>'ji','穊'=>'ji','積'=>'ji','穖'=>'ji','穧'=>'ji','笄'=>'ji','笈'=>'ji','筓'=>'ji','箕'=>'ji','箿'=>'ji','簊'=>'ji','籍'=>'ji','糭'=>'ji','紀'=>'ji','紒'=>'ji','級'=>'ji','継'=>'ji','緝'=>'ji','縘'=>'ji','績'=>'ji','繋'=>'ji','繫'=>'ji','繼'=>'ji','级'=>'ji','纪'=>'ji','继'=>'ji','绩'=>'ji','缉'=>'ji','罽'=>'ji','羁'=>'ji','羇'=>'ji','羈'=>'ji','耤'=>'ji','耭'=>'ji','肌'=>'ji','脊'=>'ji','脨'=>'ji','膌'=>'ji','臮'=>'ji','艥'=>'ji','芨'=>'ji','芰'=>'ji','芶'=>'ji','茍'=>'ji','萕'=>'ji','葪'=>'ji','蒺'=>'ji','蓟'=>'ji','蔇'=>'ji','蕀'=>'ji','蕺'=>'ji','薊'=>'ji','蘎'=>'ji','蘮'=>'ji','蘻'=>'ji','虀'=>'ji','虮'=>'ji','蝍'=>'ji','螏'=>'ji','蟣'=>'ji','裚'=>'ji','襀'=>'ji','襋'=>'ji','覉'=>'ji','覊'=>'ji','覬'=>'ji','觊'=>'ji','觙'=>'ji','觭'=>'ji','計'=>'ji','記'=>'ji','誋'=>'ji','諅'=>'ji','譏'=>'ji','譤'=>'ji','计'=>'ji','讥'=>'ji','记'=>'ji','谻'=>'ji','賫'=>'ji','賷'=>'ji','赍'=>'ji','趌'=>'ji','跡'=>'ji','跻'=>'ji','跽'=>'ji','踖'=>'ji','蹐'=>'ji','蹟'=>'ji','躋'=>'ji','躤'=>'ji','躸'=>'ji','輯'=>'ji','轚'=>'ji','辑'=>'ji','迹'=>'ji','郆'=>'ji','鄿'=>'ji','銈'=>'ji','銡'=>'ji','錤'=>'ji','鍓'=>'ji','鏶'=>'ji','鐖'=>'ji','鑇'=>'ji','鑙'=>'ji','际'=>'ji','際'=>'ji','隮'=>'ji','集'=>'ji','雞'=>'ji','雦'=>'ji','雧'=>'ji','霁'=>'ji','霵'=>'ji','霽'=>'ji','鞊'=>'ji','鞿'=>'ji','韲'=>'ji','飢'=>'ji','饑'=>'ji','饥'=>'ji','驥'=>'ji','骥'=>'ji','髻'=>'ji','魢'=>'ji','鮆'=>'ji','鯚'=>'ji','鯽'=>'ji','鰶'=>'ji','鰿'=>'ji','鱀'=>'ji','鱭'=>'ji','鱾'=>'ji','鲚'=>'ji','鲫'=>'ji','鳮'=>'ji','鵋'=>'ji','鶏'=>'ji','鶺'=>'ji','鷄'=>'ji','鷑'=>'ji','鸄'=>'ji','鸡'=>'ji','鹡'=>'ji','麂'=>'ji','齌'=>'ji','齎'=>'ji','齏'=>'ji','齑'=>'ji','㑧'=>'ji','㒫'=>'ji','㔕'=>'ji','㖢'=>'ji','㗊'=>'ji','㗱'=>'ji','㘍'=>'ji','㙨'=>'ji','㙫'=>'ji','㚡'=>'ji','㞃'=>'ji','㞆'=>'ji','㞛'=>'ji','㞦'=>'ji','㠍'=>'ji','㠎'=>'ji','㠖'=>'ji','㠱'=>'ji','㡇'=>'ji','㡭'=>'ji','㡮'=>'ji','㡶'=>'ji','㤂'=>'ji','㥍'=>'ji','㥛'=>'ji','㦸'=>'ji','㧀'=>'ji','㨈'=>'ji','㪠'=>'ji','㭰'=>'ji','㭲'=>'ji','㮟'=>'ji','㮨'=>'ji','㰟'=>'ji','㱞'=>'ji','㲅'=>'ji','㲺'=>'ji','㳵'=>'ji','㴉'=>'ji','㴕'=>'ji','㸄'=>'ji','㹄'=>'ji','㻑'=>'ji','㻷'=>'ji','㽺'=>'ji','㾊'=>'ji','㾒'=>'ji','㾵'=>'ji','䁒'=>'ji','䋟'=>'ji','䐀'=>'ji','䐕'=>'ji','䐚'=>'ji','䒁'=>'ji','䓫'=>'ji','䓽'=>'ji','䗁'=>'ji','䚐'=>'ji','䜞'=>'ji','䝸'=>'ji','䞘'=>'ji','䟌'=>'ji','䠏'=>'ji','䢋'=>'ji','䢳'=>'ji','䣢'=>'ji','䤒'=>'ji','䤠'=>'ji','䦇'=>'ji','䨖'=>'ji','䩯'=>'ji','䮺'=>'ji','䯂'=>'ji','䰏'=>'ji','䲯'=>'ji','䳭'=>'ji','䶓'=>'ji','䶩'=>'ji','不'=>'bu','佈'=>'bu','勏'=>'bu','卟'=>'bu','吥'=>'bu','咘'=>'bu','哺'=>'bu','埗'=>'bu','埠'=>'bu','峬'=>'bu','布'=>'bu','庯'=>'bu','廍'=>'bu','怖'=>'bu','悑'=>'bu','捗'=>'bu','晡'=>'bu','步'=>'bu','歨'=>'bu','歩'=>'bu','獛'=>'bu','瓿'=>'bu','篰'=>'bu','簿'=>'bu','荹'=>'bu','蔀'=>'bu','补'=>'bu','補'=>'bu','誧'=>'bu','踄'=>'bu','轐'=>'bu','逋'=>'bu','部'=>'bu','郶'=>'bu','醭'=>'bu','鈈'=>'bu','鈽'=>'bu','钚'=>'bu','钸'=>'bu','餔'=>'bu','餢'=>'bu','鳪'=>'bu','鵏'=>'bu','鸔'=>'bu','㘵'=>'bu','㙛'=>'bu','㚴'=>'bu','㨐'=>'bu','㳍'=>'bu','㻉'=>'bu','㾟'=>'bu','䀯'=>'bu','䊇'=>'bu','䋠'=>'bu','䍌'=>'bu','䏽'=>'bu','䑰'=>'bu','䒈'=>'bu','䝵'=>'bu','䪁'=>'bu','䪔'=>'bu','䬏'=>'bu','䳝'=>'bu','䴝'=>'bu','䴺'=>'bu','与'=>'yu','予'=>'yu','于'=>'yu','亐'=>'yu','伃'=>'yu','伛'=>'yu','余'=>'yu','俁'=>'yu','俞'=>'yu','俣'=>'yu','俼'=>'yu','偊'=>'yu','傴'=>'yu','儥'=>'yu','兪'=>'yu','匬'=>'yu','吁'=>'yu','唹'=>'yu','喅'=>'yu','喐'=>'yu','喩'=>'yu','喻'=>'yu','噊'=>'yu','噳'=>'yu','圄'=>'yu','圉'=>'yu','圫'=>'yu','域'=>'yu','堉'=>'yu','堣'=>'yu','堬'=>'yu','妤'=>'yu','妪'=>'yu','娛'=>'yu','娯'=>'yu','娱'=>'yu','媀'=>'yu','嫗'=>'yu','嬩'=>'yu','宇'=>'yu','寓'=>'yu','寙'=>'yu','屿'=>'yu','峪'=>'yu','峿'=>'yu','崳'=>'yu','嵎'=>'yu','嵛'=>'yu','嶎'=>'yu','嶼'=>'yu','庽'=>'yu','庾'=>'yu','彧'=>'yu','御'=>'yu','忬'=>'yu','悆'=>'yu','惐'=>'yu','愈'=>'yu','愉'=>'yu','愚'=>'yu','慾'=>'yu','懙'=>'yu','戫'=>'yu','扜'=>'yu','扵'=>'yu','挧'=>'yu','揄'=>'yu','敔'=>'yu','斔'=>'yu','斞'=>'yu','於'=>'yu','旟'=>'yu','昱'=>'yu','杅'=>'yu','栯'=>'yu','棛'=>'yu','棜'=>'yu','棫'=>'yu','楀'=>'yu','楡'=>'yu','楰'=>'yu','榆'=>'yu','櫲'=>'yu','欎'=>'yu','欝'=>'yu','欤'=>'yu','欲'=>'yu','歈'=>'yu','歟'=>'yu','歶'=>'yu','毓'=>'yu','浴'=>'yu','淢'=>'yu','淤'=>'yu','淯'=>'yu','渔'=>'yu','渝'=>'yu','湡'=>'yu','滪'=>'yu','漁'=>'yu','澞'=>'yu','澦'=>'yu','灪'=>'yu','焴'=>'yu','煜'=>'yu','燏'=>'yu','燠'=>'yu','爩'=>'yu','牏'=>'yu','狱'=>'yu','狳'=>'yu','獄'=>'yu','玉'=>'yu','玗'=>'yu','玙'=>'yu','琙'=>'yu','瑀'=>'yu','瑜'=>'yu','璵'=>'yu','畬'=>'yu','畭'=>'yu','瘀'=>'yu','瘉'=>'yu','瘐'=>'yu','癒'=>'yu','盂'=>'yu','盓'=>'yu','睮'=>'yu','矞'=>'yu','砡'=>'yu','硢'=>'yu','礇'=>'yu','礖'=>'yu','礜'=>'yu','祤'=>'yu','禦'=>'yu','禹'=>'yu','禺'=>'yu','秗'=>'yu','稢'=>'yu','稶'=>'yu','穥'=>'yu','穻'=>'yu','窬'=>'yu','窳'=>'yu','竽'=>'yu','箊'=>'yu','篽'=>'yu','籅'=>'yu','籞'=>'yu','籲'=>'yu','紆'=>'yu','緎'=>'yu','繘'=>'yu','纡'=>'yu','罭'=>'yu','羭'=>'yu','羽'=>'yu','聿'=>'yu','育'=>'yu','腴'=>'yu','臾'=>'yu','舁'=>'yu','舆'=>'yu','與'=>'yu','艅'=>'yu','芋'=>'yu','芌'=>'yu','茟'=>'yu','茰'=>'yu','荢'=>'yu','萭'=>'yu','萮'=>'yu','萸'=>'yu','蒮'=>'yu','蓣'=>'yu','蓹'=>'yu','蕍'=>'yu','蕷'=>'yu','薁'=>'yu','蘌'=>'yu','蘛'=>'yu','虞'=>'yu','虶'=>'yu','蜟'=>'yu','蜮'=>'yu','蝓'=>'yu','螸'=>'yu','衧'=>'yu','袬'=>'yu','裕'=>'yu','褕'=>'yu','覦'=>'yu','觎'=>'yu','誉'=>'yu','語'=>'yu','諛'=>'yu','諭'=>'yu','謣'=>'yu','譽'=>'yu','语'=>'yu','谀'=>'yu','谕'=>'yu','豫'=>'yu','貐'=>'yu','踰'=>'yu','軉'=>'yu','輍'=>'yu','輿'=>'yu','轝'=>'yu','迃'=>'yu','逳'=>'yu','逾'=>'yu','遇'=>'yu','遹'=>'yu','邘'=>'yu','郁'=>'yu','鄅'=>'yu','酑'=>'yu','醧'=>'yu','釪'=>'yu','鈺'=>'yu','銉'=>'yu','鋊'=>'yu','鋙'=>'yu','錥'=>'yu','鍝'=>'yu','鐭'=>'yu','钰'=>'yu','铻'=>'yu','閾'=>'yu','阈'=>'yu','陓'=>'yu','隃'=>'yu','隅'=>'yu','隩'=>'yu','雓'=>'yu','雨'=>'yu','雩'=>'yu','霱'=>'yu','預'=>'yu','预'=>'yu','飫'=>'yu','餘'=>'yu','饇'=>'yu','饫'=>'yu','馀'=>'yu','馭'=>'yu','騟'=>'yu','驈'=>'yu','驭'=>'yu','骬'=>'yu','髃'=>'yu','鬰'=>'yu','鬱'=>'yu','鬻'=>'yu','魊'=>'yu','魚'=>'yu','魣'=>'yu','鮽'=>'yu','鯲'=>'yu','鰅'=>'yu','鱊'=>'yu','鱼'=>'yu','鳿'=>'yu','鴥'=>'yu','鴧'=>'yu','鴪'=>'yu','鵒'=>'yu','鷠'=>'yu','鷸'=>'yu','鸆'=>'yu','鸒'=>'yu','鹆'=>'yu','鹬'=>'yu','麌'=>'yu','齬'=>'yu','龉'=>'yu','㑨'=>'yu','㒁'=>'yu','㒜'=>'yu','㔱'=>'yu','㙑'=>'yu','㚥'=>'yu','㝢'=>'yu','㠘'=>'yu','㠨'=>'yu','㡰'=>'yu','㣃'=>'yu','㤤'=>'yu','㥔'=>'yu','㥚'=>'yu','㥥'=>'yu','㦛'=>'yu','㪀'=>'yu','㬂'=>'yu','㬰'=>'yu','㲾'=>'yu','㳚'=>'yu','㳛'=>'yu','㶛'=>'yu','㷒'=>'yu','㺄'=>'yu','㺞'=>'yu','㺮'=>'yu','㼌'=>'yu','㼶'=>'yu','㽣'=>'yu','䁌'=>'yu','䁩'=>'yu','䂊'=>'yu','䂛'=>'yu','䃋'=>'yu','䄏'=>'yu','䄨'=>'yu','䆷'=>'yu','䈅'=>'yu','䉛'=>'yu','䋖'=>'yu','䍂'=>'yu','䍞'=>'yu','䏸'=>'yu','䐳'=>'yu','䔡'=>'yu','䖇'=>'yu','䗨'=>'yu','䘘'=>'yu','䘱'=>'yu','䛕'=>'yu','䜽'=>'yu','䢓'=>'yu','䢩'=>'yu','䣁'=>'yu','䥏'=>'yu','䨒'=>'yu','䨞'=>'yu','䩒'=>'yu','䬄'=>'yu','䮇'=>'yu','䮙'=>'yu','䰻'=>'yu','䱷'=>'yu','䲣'=>'yu','䴁'=>'yu','䵫'=>'yu','丏'=>'mian','俛'=>'mian','偭'=>'mian','免'=>'mian','冕'=>'mian','勉'=>'mian','勔'=>'mian','喕'=>'mian','娩'=>'mian','婂'=>'mian','媔'=>'mian','嬵'=>'mian','宀'=>'mian','愐'=>'mian','棉'=>'mian','檰'=>'mian','櫋'=>'mian','汅'=>'mian','沔'=>'mian','湎'=>'mian','眄'=>'mian','眠'=>'mian','矈'=>'mian','矊'=>'mian','矏'=>'mian','糆'=>'mian','綿'=>'mian','緜'=>'mian','緬'=>'mian','绵'=>'mian','缅'=>'mian','腼'=>'mian','臱'=>'mian','芇'=>'mian','葂'=>'mian','蝒'=>'mian','面'=>'mian','靣'=>'mian','鮸'=>'mian','麪'=>'mian','麫'=>'mian','麵'=>'mian','麺'=>'mian','黾'=>'mian','㒙'=>'mian','㛯'=>'mian','㝰'=>'mian','㤁'=>'mian','㬆'=>'mian','㮌'=>'mian','㰃'=>'mian','㴐'=>'mian','㻰'=>'mian','䀎'=>'mian','䃇'=>'mian','䏃'=>'mian','䤄'=>'mian','䫵'=>'mian','䰓'=>'mian','丐'=>'gai','乢'=>'gai','侅'=>'gai','匃'=>'gai','匄'=>'gai','垓'=>'gai','姟'=>'gai','峐'=>'gai','忋'=>'gai','戤'=>'gai','摡'=>'gai','改'=>'gai','晐'=>'gai','杚'=>'gai','概'=>'gai','槩'=>'gai','槪'=>'gai','溉'=>'gai','漑'=>'gai','瓂'=>'gai','畡'=>'gai','盖'=>'gai','祴'=>'gai','絠'=>'gai','絯'=>'gai','荄'=>'gai','葢'=>'gai','蓋'=>'gai','該'=>'gai','该'=>'gai','豥'=>'gai','賅'=>'gai','賌'=>'gai','赅'=>'gai','郂'=>'gai','鈣'=>'gai','鎅'=>'gai','钙'=>'gai','陔'=>'gai','隑'=>'gai','㕢'=>'gai','㧉'=>'gai','㮣'=>'gai','䏗'=>'gai','䪱'=>'gai','丑'=>'chou','丒'=>'chou','仇'=>'chou','侴'=>'chou','俦'=>'chou','偢'=>'chou','儔'=>'chou','吜'=>'chou','嬦'=>'chou','帱'=>'chou','幬'=>'chou','惆'=>'chou','愁'=>'chou','懤'=>'chou','抽'=>'chou','搊'=>'chou','杽'=>'chou','栦'=>'chou','椆'=>'chou','殠'=>'chou','燽'=>'chou','犨'=>'chou','犫'=>'chou','畴'=>'chou','疇'=>'chou','瘳'=>'chou','皗'=>'chou','瞅'=>'chou','矁'=>'chou','稠'=>'chou','筹'=>'chou','篘'=>'chou','籌'=>'chou','紬'=>'chou','絒'=>'chou','綢'=>'chou','绸'=>'chou','臭'=>'chou','臰'=>'chou','菗'=>'chou','薵'=>'chou','裯'=>'chou','詶'=>'chou','讎'=>'chou','讐'=>'chou','踌'=>'chou','躊'=>'chou','遚'=>'chou','酧'=>'chou','酬'=>'chou','醜'=>'chou','醻'=>'chou','雔'=>'chou','雠'=>'chou','魗'=>'chou','㐜'=>'chou','㛶'=>'chou','㤽'=>'chou','㦞'=>'chou','㨶'=>'chou','㵞'=>'chou','㿧'=>'chou','䇺'=>'chou','䊭'=>'chou','䌧'=>'chou','䌷'=>'chou','䓓'=>'chou','䔏'=>'chou','䛬'=>'chou','䥒'=>'chou','䪮'=>'chou','䲖'=>'chou','专'=>'zhuan','僎'=>'zhuan','叀'=>'zhuan','啭'=>'zhuan','囀'=>'zhuan','堟'=>'zhuan','嫥'=>'zhuan','孨'=>'zhuan','専'=>'zhuan','專'=>'zhuan','撰'=>'zhuan','灷'=>'zhuan','瑑'=>'zhuan','瑼'=>'zhuan','甎'=>'zhuan','砖'=>'zhuan','磚'=>'zhuan','竱'=>'zhuan','篆'=>'zhuan','籑'=>'zhuan','縳'=>'zhuan','膞'=>'zhuan','蒃'=>'zhuan','蟤'=>'zhuan','襈'=>'zhuan','諯'=>'zhuan','譔'=>'zhuan','賺'=>'zhuan','赚'=>'zhuan','転'=>'zhuan','轉'=>'zhuan','转'=>'zhuan','鄟'=>'zhuan','顓'=>'zhuan','颛'=>'zhuan','饌'=>'zhuan','馔'=>'zhuan','鱄'=>'zhuan','䉵'=>'zhuan','䡱'=>'zhuan','且'=>'qie','倿'=>'qie','切'=>'qie','匧'=>'qie','厒'=>'qie','妾'=>'qie','怯'=>'qie','悏'=>'qie','惬'=>'qie','愜'=>'qie','挈'=>'qie','朅'=>'qie','洯'=>'qie','淁'=>'qie','癿'=>'qie','穕'=>'qie','窃'=>'qie','竊'=>'qie','笡'=>'qie','箧'=>'qie','篋'=>'qie','籡'=>'qie','緁'=>'qie','聺'=>'qie','苆'=>'qie','茄'=>'qie','藒'=>'qie','蛪'=>'qie','踥'=>'qie','鍥'=>'qie','鐑'=>'qie','锲'=>'qie','魥'=>'qie','鯜'=>'qie','㓶'=>'qie','㗫'=>'qie','㚗'=>'qie','㛍'=>'qie','㛙'=>'qie','㤲'=>'qie','㥦'=>'qie','㫸'=>'qie','㰰'=>'qie','㰼'=>'qie','㹤'=>'qie','㾀'=>'qie','㾜'=>'qie','䟙'=>'qie','䤿'=>'qie','䦧'=>'qie','䬊'=>'qie','丕'=>'pi','仳'=>'pi','伓'=>'pi','伾'=>'pi','僻'=>'pi','劈'=>'pi','匹'=>'pi','啤'=>'pi','噼'=>'pi','噽'=>'pi','嚊'=>'pi','嚭'=>'pi','圮'=>'pi','坯'=>'pi','埤'=>'pi','壀'=>'pi','媲'=>'pi','嫓'=>'pi','屁'=>'pi','岯'=>'pi','崥'=>'pi','庀'=>'pi','怶'=>'pi','悂'=>'pi','憵'=>'pi','批'=>'pi','披'=>'pi','抷'=>'pi','揊'=>'pi','擗'=>'pi','旇'=>'pi','朇'=>'pi','枇'=>'pi','椑'=>'pi','榌'=>'pi','毗'=>'pi','毘'=>'pi','毞'=>'pi','淠'=>'pi','渒'=>'pi','潎'=>'pi','澼'=>'pi','炋'=>'pi','焷'=>'pi','狉'=>'pi','狓'=>'pi','琵'=>'pi','甓'=>'pi','疈'=>'pi','疲'=>'pi','痞'=>'pi','癖'=>'pi','皮'=>'pi','睤'=>'pi','睥'=>'pi','砒'=>'pi','磇'=>'pi','礔'=>'pi','礕'=>'pi','秛'=>'pi','秠'=>'pi','笓'=>'pi','篺'=>'pi','簲'=>'pi','紕'=>'pi','纰'=>'pi','罴'=>'pi','羆'=>'pi','翍'=>'pi','耚'=>'pi','肶'=>'pi','脴'=>'pi','脾'=>'pi','腗'=>'pi','膍'=>'pi','芘'=>'pi','苉'=>'pi','蚍'=>'pi','蚽'=>'pi','蜱'=>'pi','螷'=>'pi','蠯'=>'pi','諀'=>'pi','譬'=>'pi','豼'=>'pi','豾'=>'pi','貔'=>'pi','邳'=>'pi','郫'=>'pi','釽'=>'pi','鈚'=>'pi','鈹'=>'pi','鉟'=>'pi','銔'=>'pi','銢'=>'pi','錃'=>'pi','錍'=>'pi','铍'=>'pi','闢'=>'pi','阰'=>'pi','陴'=>'pi','隦'=>'pi','霹'=>'pi','駓'=>'pi','髬'=>'pi','魮'=>'pi','魾'=>'pi','鮍'=>'pi','鲏'=>'pi','鴄'=>'pi','鵧'=>'pi','鷿'=>'pi','鸊'=>'pi','鼙'=>'pi','㔥'=>'pi','㨽'=>'pi','㯅'=>'pi','㿙'=>'pi','䏘'=>'pi','䑀'=>'pi','䑄'=>'pi','䚰'=>'pi','䚹'=>'pi','䠘'=>'pi','䡟'=>'pi','䤏'=>'pi','䤨'=>'pi','䫌'=>'pi','䰦'=>'pi','䴙'=>'pi','世'=>'shi','丗'=>'shi','乨'=>'shi','亊'=>'shi','事'=>'shi','什'=>'shi','仕'=>'shi','佦'=>'shi','使'=>'shi','侍'=>'shi','兘'=>'shi','兙'=>'shi','冟'=>'shi','势'=>'shi','勢'=>'shi','十'=>'shi','卋'=>'shi','叓'=>'shi','史'=>'shi','呞'=>'shi','呩'=>'shi','嗜'=>'shi','噬'=>'shi','埘'=>'shi','塒'=>'shi','士'=>'shi','失'=>'shi','奭'=>'shi','始'=>'shi','姼'=>'shi','嬕'=>'shi','实'=>'shi','実'=>'shi','室'=>'shi','宩'=>'shi','寔'=>'shi','實'=>'shi','尸'=>'shi','屍'=>'shi','屎'=>'shi','峕'=>'shi','崼'=>'shi','嵵'=>'shi','市'=>'shi','师'=>'shi','師'=>'shi','式'=>'shi','弑'=>'shi','弒'=>'shi','徥'=>'shi','忕'=>'shi','恀'=>'shi','恃'=>'shi','戺'=>'shi','拭'=>'shi','拾'=>'shi','揓'=>'shi','施'=>'shi','时'=>'shi','旹'=>'shi','是'=>'shi','昰'=>'shi','時'=>'shi','枾'=>'shi','柹'=>'shi','柿'=>'shi','栻'=>'shi','榁'=>'shi','榯'=>'shi','檡'=>'shi','氏'=>'shi','浉'=>'shi','湜'=>'shi','湤'=>'shi','湿'=>'shi','溡'=>'shi','溮'=>'shi','溼'=>'shi','澨'=>'shi','濕'=>'shi','炻'=>'shi','烒'=>'shi','煶'=>'shi','狮'=>'shi','獅'=>'shi','瑡'=>'shi','瓧'=>'shi','眂'=>'shi','眎'=>'shi','眡'=>'shi','睗'=>'shi','矢'=>'shi','石'=>'shi','示'=>'shi','礻'=>'shi','祏'=>'shi','竍'=>'shi','笶'=>'shi','笹'=>'shi','筮'=>'shi','箷'=>'shi','篒'=>'shi','簭'=>'shi','籂'=>'shi','籭'=>'shi','絁'=>'shi','舐'=>'shi','舓'=>'shi','莳'=>'shi','葹'=>'shi','蒒'=>'shi','蒔'=>'shi','蓍'=>'shi','虱'=>'shi','虲'=>'shi','蚀'=>'shi','蝕'=>'shi','蝨'=>'shi','螫'=>'shi','褆'=>'shi','褷'=>'shi','襫'=>'shi','襹'=>'shi','視'=>'shi','视'=>'shi','觢'=>'shi','試'=>'shi','詩'=>'shi','誓'=>'shi','諟'=>'shi','諡'=>'shi','謚'=>'shi','識'=>'shi','识'=>'shi','试'=>'shi','诗'=>'shi','谥'=>'shi','豕'=>'shi','貰'=>'shi','贳'=>'shi','軾'=>'shi','轼'=>'shi','辻'=>'shi','适'=>'shi','逝'=>'shi','遈'=>'shi','適'=>'shi','遾'=>'shi','邿'=>'shi','酾'=>'shi','釃'=>'shi','釈'=>'shi','释'=>'shi','釋'=>'shi','釶'=>'shi','鈰'=>'shi','鉂'=>'shi','鉃'=>'shi','鉇'=>'shi','鉐'=>'shi','鉽'=>'shi','銴'=>'shi','鍦'=>'shi','铈'=>'shi','食'=>'shi','飠'=>'shi','飾'=>'shi','餝'=>'shi','饣'=>'shi','饰'=>'shi','駛'=>'shi','驶'=>'shi','鮖'=>'shi','鯴'=>'shi','鰘'=>'shi','鰣'=>'shi','鰤'=>'shi','鲥'=>'shi','鲺'=>'shi','鳲'=>'shi','鳾'=>'shi','鶳'=>'shi','鸤'=>'shi','鼫'=>'shi','鼭'=>'shi','齛'=>'shi','㒾'=>'shi','㔺'=>'shi','㕜'=>'shi','㖷'=>'shi','㫑'=>'shi','㮶'=>'shi','㱁'=>'shi','㵓'=>'shi','㸷'=>'shi','㹝'=>'shi','㹬'=>'shi','㹷'=>'shi','䁺'=>'shi','䂖'=>'shi','䊓'=>'shi','䏡'=>'shi','䒨'=>'shi','䖨'=>'shi','䛈'=>'shi','䟗'=>'shi','䤱'=>'shi','䦠'=>'shi','䦹'=>'shi','䩃'=>'shi','䭄'=>'shi','䰄'=>'shi','䴓'=>'shi','䶡'=>'shi','丘'=>'qiu','丠'=>'qiu','俅'=>'qiu','叴'=>'qiu','唒'=>'qiu','囚'=>'qiu','坵'=>'qiu','媝'=>'qiu','寈'=>'qiu','崷'=>'qiu','巯'=>'qiu','巰'=>'qiu','恘'=>'qiu','扏'=>'qiu','搝'=>'qiu','朹'=>'qiu','梂'=>'qiu','楸'=>'qiu','殏'=>'qiu','毬'=>'qiu','求'=>'qiu','汓'=>'qiu','泅'=>'qiu','浗'=>'qiu','渞'=>'qiu','湭'=>'qiu','煪'=>'qiu','犰'=>'qiu','玌'=>'qiu','球'=>'qiu','璆'=>'qiu','皳'=>'qiu','盚'=>'qiu','秋'=>'qiu','秌'=>'qiu','穐'=>'qiu','篍'=>'qiu','糗'=>'qiu','紌'=>'qiu','絿'=>'qiu','緧'=>'qiu','肍'=>'qiu','莍'=>'qiu','萩'=>'qiu','蓲'=>'qiu','蘒'=>'qiu','虬'=>'qiu','虯'=>'qiu','蚯'=>'qiu','蛷'=>'qiu','蝤'=>'qiu','蝵'=>'qiu','蟗'=>'qiu','蠤'=>'qiu','裘'=>'qiu','觓'=>'qiu','觩'=>'qiu','訄'=>'qiu','訅'=>'qiu','賕'=>'qiu','赇'=>'qiu','趥'=>'qiu','逎'=>'qiu','逑'=>'qiu','遒'=>'qiu','邱'=>'qiu','酋'=>'qiu','醔'=>'qiu','釚'=>'qiu','釻'=>'qiu','銶'=>'qiu','鞦'=>'qiu','鞧'=>'qiu','鮂'=>'qiu','鯄'=>'qiu','鰌'=>'qiu','鰍'=>'qiu','鰽'=>'qiu','鱃'=>'qiu','鳅'=>'qiu','鵭'=>'qiu','鶖'=>'qiu','鹙'=>'qiu','鼽'=>'qiu','龝'=>'qiu','㐀'=>'qiu','㐤'=>'qiu','㕤'=>'qiu','㞗'=>'qiu','㟈'=>'qiu','㤹'=>'qiu','㥢'=>'qiu','㧨'=>'qiu','㭝'=>'qiu','㷕'=>'qiu','㺫'=>'qiu','㼒'=>'qiu','䆋'=>'qiu','䊵'=>'qiu','䎿'=>'qiu','䜪'=>'qiu','䞭'=>'qiu','䟬'=>'qiu','䟵'=>'qiu','䠗'=>'qiu','䣇'=>'qiu','䤛'=>'qiu','丙'=>'bing','並'=>'bing','仌'=>'bing','併'=>'bing','倂'=>'bing','偋'=>'bing','傡'=>'bing','兵'=>'bing','冫'=>'bing','冰'=>'bing','垪'=>'bing','寎'=>'bing','并'=>'bing','幷'=>'bing','庰'=>'bing','怲'=>'bing','抦'=>'bing','掤'=>'bing','摒'=>'bing','昞'=>'bing','昺'=>'bing','柄'=>'bing','栟'=>'bing','栤'=>'bing','梹'=>'bing','棅'=>'bing','檳'=>'bing','氷'=>'bing','炳'=>'bing','燷'=>'bing','病'=>'bing','眪'=>'bing','禀'=>'bing','秉'=>'bing','窉'=>'bing','竝'=>'bing','苪'=>'bing','蛃'=>'bing','誁'=>'bing','邴'=>'bing','鈵'=>'bing','鉼'=>'bing','鋲'=>'bing','陃'=>'bing','靐'=>'bing','鞆'=>'bing','餅'=>'bing','餠'=>'bing','饼'=>'bing','鮩'=>'bing','㓈'=>'bing','㨀'=>'bing','䈂'=>'bing','䋑'=>'bing','䓑'=>'bing','䗒'=>'bing','䴵'=>'bing','业'=>'ye','也'=>'ye','亪'=>'ye','亱'=>'ye','倻'=>'ye','偞'=>'ye','僷'=>'ye','冶'=>'ye','叶'=>'ye','吔'=>'ye','嘢'=>'ye','噎'=>'ye','嚈'=>'ye','埜'=>'ye','堨'=>'ye','墷'=>'ye','壄'=>'ye','夜'=>'ye','嶪'=>'ye','嶫'=>'ye','抴'=>'ye','捓'=>'ye','捙'=>'ye','掖'=>'ye','揶'=>'ye','擖'=>'ye','擛'=>'ye','擨'=>'ye','擪'=>'ye','擫'=>'ye','晔'=>'ye','暍'=>'ye','曄'=>'ye','曅'=>'ye','曗'=>'ye','曳'=>'ye','枼'=>'ye','枽'=>'ye','椰'=>'ye','楪'=>'ye','業'=>'ye','歋'=>'ye','殗'=>'ye','洂'=>'ye','液'=>'ye','漜'=>'ye','潱'=>'ye','澲'=>'ye','烨'=>'ye','燁'=>'ye','爗'=>'ye','爷'=>'ye','爺'=>'ye','皣'=>'ye','瞱'=>'ye','瞸'=>'ye','礏'=>'ye','耶'=>'ye','腋'=>'ye','葉'=>'ye','蠮'=>'ye','謁'=>'ye','谒'=>'ye','邺'=>'ye','鄓'=>'ye','鄴'=>'ye','野'=>'ye','釾'=>'ye','鋣'=>'ye','鍱'=>'ye','鎁'=>'ye','鎑'=>'ye','铘'=>'ye','靥'=>'ye','靨'=>'ye','頁'=>'ye','页'=>'ye','餣'=>'ye','饁'=>'ye','馌'=>'ye','驜'=>'ye','鵺'=>'ye','鸈'=>'ye','㐖'=>'ye','㖡'=>'ye','㖶'=>'ye','㗼'=>'ye','㙒'=>'ye','㙪'=>'ye','㝣'=>'ye','㥷'=>'ye','㩎'=>'ye','㪑'=>'ye','㱉'=>'ye','㸣'=>'ye','䈎'=>'ye','䓉'=>'ye','䤳'=>'ye','䤶'=>'ye','䥟'=>'ye','䥡'=>'ye','䥺'=>'ye','䧨'=>'ye','䭟'=>'ye','䲜'=>'ye','丛'=>'cong','从'=>'cong','匆'=>'cong','叢'=>'cong','囪'=>'cong','囱'=>'cong','婃'=>'cong','孮'=>'cong','従'=>'cong','徖'=>'cong','從'=>'cong','忩'=>'cong','怱'=>'cong','悤'=>'cong','悰'=>'cong','慒'=>'cong','憁'=>'cong','暰'=>'cong','枞'=>'cong','棇'=>'cong','楤'=>'cong','樅'=>'cong','樬'=>'cong','樷'=>'cong','欉'=>'cong','淙'=>'cong','漎'=>'cong','漗'=>'cong','潀'=>'cong','潈'=>'cong','潨'=>'cong','灇'=>'cong','焧'=>'cong','熜'=>'cong','爜'=>'cong','琮'=>'cong','瑽'=>'cong','璁'=>'cong','瞛'=>'cong','篵'=>'cong','緫'=>'cong','繱'=>'cong','聡'=>'cong','聦'=>'cong','聪'=>'cong','聰'=>'cong','苁'=>'cong','茐'=>'cong','葱'=>'cong','蓯'=>'cong','蔥'=>'cong','藂'=>'cong','蟌'=>'cong','誴'=>'cong','謥'=>'cong','賨'=>'cong','賩'=>'cong','鏦'=>'cong','騘'=>'cong','驄'=>'cong','骢'=>'cong','㼻'=>'cong','䉘'=>'cong','䕺'=>'cong','䧚'=>'cong','䳷'=>'cong','东'=>'dong','侗'=>'dong','倲'=>'dong','働'=>'dong','冬'=>'dong','冻'=>'dong','凍'=>'dong','动'=>'dong','動'=>'dong','咚'=>'dong','垌'=>'dong','埬'=>'dong','墥'=>'dong','姛'=>'dong','娻'=>'dong','嬞'=>'dong','岽'=>'dong','峒'=>'dong','峝'=>'dong','崠'=>'dong','崬'=>'dong','恫'=>'dong','懂'=>'dong','戙'=>'dong','挏'=>'dong','昸'=>'dong','東'=>'dong','栋'=>'dong','棟'=>'dong','氡'=>'dong','氭'=>'dong','洞'=>'dong','涷'=>'dong','湩'=>'dong','硐'=>'dong','笗'=>'dong','箽'=>'dong','胨'=>'dong','胴'=>'dong','腖'=>'dong','苳'=>'dong','菄'=>'dong','董'=>'dong','蕫'=>'dong','蝀'=>'dong','詷'=>'dong','諌'=>'dong','迵'=>'dong','霘'=>'dong','駧'=>'dong','鮗'=>'dong','鯟'=>'dong','鶇'=>'dong','鶫'=>'dong','鸫'=>'dong','鼕'=>'dong','㑈'=>'dong','㓊'=>'dong','㖦'=>'dong','㗢'=>'dong','㜱'=>'dong','㢥'=>'dong','㨂'=>'dong','㼯'=>'dong','䂢'=>'dong','䅍'=>'dong','䍶'=>'dong','䞒'=>'dong','䵔'=>'dong','丝'=>'si','乺'=>'si','亖'=>'si','伺'=>'si','似'=>'si','佀'=>'si','価'=>'si','俟'=>'si','俬'=>'si','儩'=>'si','兕'=>'si','凘'=>'si','厮'=>'si','厶'=>'si','司'=>'si','咝'=>'si','嗣'=>'si','嘶'=>'si','噝'=>'si','四'=>'si','姒'=>'si','娰'=>'si','媤'=>'si','孠'=>'si','寺'=>'si','巳'=>'si','廝'=>'si','思'=>'si','恖'=>'si','撕'=>'si','斯'=>'si','枱'=>'si','柶'=>'si','梩'=>'si','楒'=>'si','榹'=>'si','死'=>'si','汜'=>'si','泀'=>'si','泗'=>'si','泤'=>'si','洍'=>'si','涘'=>'si','澌'=>'si','瀃'=>'si','燍'=>'si','牭'=>'si','磃'=>'si','祀'=>'si','禗'=>'si','禠'=>'si','禩'=>'si','私'=>'si','竢'=>'si','笥'=>'si','糹'=>'si','絲'=>'si','緦'=>'si','纟'=>'si','缌'=>'si','罒'=>'si','罳'=>'si','耜'=>'si','肂'=>'si','肆'=>'si','蕬'=>'si','蕼'=>'si','虒'=>'si','蛳'=>'si','蜤'=>'si','螄'=>'si','螦'=>'si','蟖'=>'si','蟴'=>'si','覗'=>'si','貄'=>'si','釲'=>'si','鈻'=>'si','鉰'=>'si','銯'=>'si','鋖'=>'si','鍶'=>'si','鐁'=>'si','锶'=>'si','颸'=>'si','飔'=>'si','飤'=>'si','飼'=>'si','饲'=>'si','駟'=>'si','騃'=>'si','騦'=>'si','驷'=>'si','鷥'=>'si','鸶'=>'si','鼶'=>'si','㐌'=>'si','㕽'=>'si','㚶'=>'si','㣈'=>'si','㭒'=>'si','㸻'=>'si','㹑'=>'si','㾅'=>'si','䇃'=>'si','䎣'=>'si','䏤'=>'si','䦙'=>'si','丞'=>'cheng','乗'=>'cheng','乘'=>'cheng','侱'=>'cheng','偁'=>'cheng','呈'=>'cheng','城'=>'cheng','埕'=>'cheng','堘'=>'cheng','塍'=>'cheng','塖'=>'cheng','娍'=>'cheng','宬'=>'cheng','峸'=>'cheng','庱'=>'cheng','徎'=>'cheng','悜'=>'cheng','惩'=>'cheng','憆'=>'cheng','憕'=>'cheng','懲'=>'cheng','成'=>'cheng','承'=>'cheng','挰'=>'cheng','掁'=>'cheng','摚'=>'cheng','撐'=>'cheng','撑'=>'cheng','朾'=>'cheng','枨'=>'cheng','柽'=>'cheng','棖'=>'cheng','棦'=>'cheng','椉'=>'cheng','橕'=>'cheng','橙'=>'cheng','檉'=>'cheng','檙'=>'cheng','泟'=>'cheng','洆'=>'cheng','浾'=>'cheng','溗'=>'cheng','澂'=>'cheng','澄'=>'cheng','瀓'=>'cheng','爯'=>'cheng','牚'=>'cheng','珵'=>'cheng','珹'=>'cheng','琤'=>'cheng','畻'=>'cheng','睈'=>'cheng','瞠'=>'cheng','碀'=>'cheng','秤'=>'cheng','称'=>'cheng','程'=>'cheng','穪'=>'cheng','窚'=>'cheng','竀'=>'cheng','筬'=>'cheng','絾'=>'cheng','緽'=>'cheng','脀'=>'cheng','脭'=>'cheng','荿'=>'cheng','虰'=>'cheng','蛏'=>'cheng','蟶'=>'cheng','裎'=>'cheng','誠'=>'cheng','诚'=>'cheng','赪'=>'cheng','赬'=>'cheng','逞'=>'cheng','郕'=>'cheng','酲'=>'cheng','鋮'=>'cheng','鏳'=>'cheng','鏿'=>'cheng','鐺'=>'cheng','铖'=>'cheng','铛'=>'cheng','阷'=>'cheng','靗'=>'cheng','頳'=>'cheng','饓'=>'cheng','騁'=>'cheng','騬'=>'cheng','骋'=>'cheng','鯎'=>'cheng','㐼'=>'cheng','㞼'=>'cheng','㨃'=>'cheng','㲂'=>'cheng','㼩'=>'cheng','䀕'=>'cheng','䁎'=>'cheng','䄇'=>'cheng','䆑'=>'cheng','䆵'=>'cheng','䆸'=>'cheng','䇸'=>'cheng','䔲'=>'cheng','䗊'=>'cheng','䞓'=>'cheng','䧕'=>'cheng','䫆'=>'cheng','䮪'=>'cheng','丟'=>'diu','丢'=>'diu','銩'=>'diu','铥'=>'diu','颩'=>'diu','両'=>'liang','两'=>'liang','亮'=>'liang','俍'=>'liang','兩'=>'liang','凉'=>'liang','哴'=>'liang','唡'=>'liang','啢'=>'liang','喨'=>'liang','墚'=>'liang','掚'=>'liang','晾'=>'liang','梁'=>'liang','椋'=>'liang','樑'=>'liang','涼'=>'liang','湸'=>'liang','煷'=>'liang','簗'=>'liang','粮'=>'liang','粱'=>'liang','糧'=>'liang','綡'=>'liang','緉'=>'liang','脼'=>'liang','良'=>'liang','蜽'=>'liang','裲'=>'liang','諒'=>'liang','谅'=>'liang','踉'=>'liang','輌'=>'liang','輛'=>'liang','輬'=>'liang','辆'=>'liang','辌'=>'liang','量'=>'liang','鍄'=>'liang','魉'=>'liang','魎'=>'liang','㒳'=>'liang','㔝'=>'liang','㹁'=>'liang','䓣'=>'liang','䝶'=>'liang','䠃'=>'liang','䣼'=>'liang','䩫'=>'liang','䭪'=>'liang','丣'=>'you','亴'=>'you','优'=>'you','佑'=>'you','侑'=>'you','偤'=>'you','優'=>'you','卣'=>'you','又'=>'you','友'=>'you','右'=>'you','呦'=>'you','哊'=>'you','唀'=>'you','嚘'=>'you','囿'=>'you','姷'=>'you','孧'=>'you','宥'=>'you','尢'=>'you','尤'=>'you','峟'=>'you','峳'=>'you','幼'=>'you','幽'=>'you','庮'=>'you','忧'=>'you','怞'=>'you','怣'=>'you','怮'=>'you','悠'=>'you','憂'=>'you','懮'=>'you','攸'=>'you','斿'=>'you','有'=>'you','柚'=>'you','梄'=>'you','梎'=>'you','楢'=>'you','槱'=>'you','櫌'=>'you','櫾'=>'you','沋'=>'you','油'=>'you','泑'=>'you','浟'=>'you','游'=>'you','湵'=>'you','滺'=>'you','瀀'=>'you','牖'=>'you','牗'=>'you','牰'=>'you','犹'=>'you','狖'=>'you','猶'=>'you','猷'=>'you','由'=>'you','疣'=>'you','祐'=>'you','禉'=>'you','秞'=>'you','糿'=>'you','纋'=>'you','羐'=>'you','羑'=>'you','耰'=>'you','聈'=>'you','肬'=>'you','脜'=>'you','苃'=>'you','莜'=>'you','莠'=>'you','莤'=>'you','莸'=>'you','蒏'=>'you','蕕'=>'you','蚰'=>'you','蚴'=>'you','蜏'=>'you','蝣'=>'you','訧'=>'you','誘'=>'you','诱'=>'you','貁'=>'you','輏'=>'you','輶'=>'you','迂'=>'you','迶'=>'you','逌'=>'you','逰'=>'you','遊'=>'you','邎'=>'you','邮'=>'you','郵'=>'you','鄾'=>'you','酉'=>'you','酭'=>'you','釉'=>'you','鈾'=>'you','銪'=>'you','铀'=>'you','铕'=>'you','駀'=>'you','魷'=>'you','鮋'=>'you','鱿'=>'you','鲉'=>'you','麀'=>'you','黝'=>'you','鼬'=>'you','㒡'=>'you','㓜'=>'you','㕗'=>'you','㕱'=>'you','㘥'=>'you','㚭'=>'you','㛜'=>'you','㤑'=>'you','㫍'=>'you','㮋'=>'you','㰶'=>'you','㳺'=>'you','㹨'=>'you','㺠'=>'you','㻀'=>'you','㽕'=>'you','㾞'=>'you','䀁'=>'you','䅎'=>'you','䆜'=>'you','䑻'=>'you','䒴'=>'you','䖻'=>'you','䚃'=>'you','䛻'=>'you','䞥'=>'you','䢊'=>'you','䢟'=>'you','䬀'=>'you','䱂'=>'you','䳑'=>'you','严'=>'yan','乵'=>'yan','俨'=>'yan','偃'=>'yan','偐'=>'yan','偣'=>'yan','傿'=>'yan','儼'=>'yan','兖'=>'yan','兗'=>'yan','円'=>'yan','剦'=>'yan','匽'=>'yan','厌'=>'yan','厣'=>'yan','厭'=>'yan','厳'=>'yan','厴'=>'yan','咽'=>'yan','唁'=>'yan','喭'=>'yan','噞'=>'yan','嚥'=>'yan','嚴'=>'yan','堰'=>'yan','塩'=>'yan','墕'=>'yan','壛'=>'yan','壧'=>'yan','夵'=>'yan','奄'=>'yan','妍'=>'yan','妟'=>'yan','姲'=>'yan','姸'=>'yan','娫'=>'yan','娮'=>'yan','嫣'=>'yan','嬊'=>'yan','嬮'=>'yan','嬿'=>'yan','孍'=>'yan','宴'=>'yan','岩'=>'yan','崦'=>'yan','嵃'=>'yan','嵒'=>'yan','嵓'=>'yan','嶖'=>'yan','巌'=>'yan','巖'=>'yan','巗'=>'yan','巘'=>'yan','巚'=>'yan','延'=>'yan','弇'=>'yan','彥'=>'yan','彦'=>'yan','恹'=>'yan','愝'=>'yan','懕'=>'yan','戭'=>'yan','扊'=>'yan','抁'=>'yan','掞'=>'yan','掩'=>'yan','揅'=>'yan','揜'=>'yan','敥'=>'yan','昖'=>'yan','晏'=>'yan','暥'=>'yan','曕'=>'yan','曮'=>'yan','棪'=>'yan','椻'=>'yan','椼'=>'yan','楌'=>'yan','樮'=>'yan','檐'=>'yan','檿'=>'yan','櫩'=>'yan','欕'=>'yan','沇'=>'yan','沿'=>'yan','淹'=>'yan','渰'=>'yan','渷'=>'yan','湮'=>'yan','滟'=>'yan','演'=>'yan','漹'=>'yan','灎'=>'yan','灔'=>'yan','灧'=>'yan','灩'=>'yan','炎'=>'yan','烟'=>'yan','焉'=>'yan','焔'=>'yan','焰'=>'yan','焱'=>'yan','煙'=>'yan','熖'=>'yan','燄'=>'yan','燕'=>'yan','爓'=>'yan','牪'=>'yan','狿'=>'yan','猒'=>'yan','珚'=>'yan','琂'=>'yan','琰'=>'yan','甗'=>'yan','盐'=>'yan','眼'=>'yan','研'=>'yan','砚'=>'yan','硏'=>'yan','硯'=>'yan','硽'=>'yan','碞'=>'yan','礹'=>'yan','筵'=>'yan','篶'=>'yan','簷'=>'yan','綖'=>'yan','縯'=>'yan','罨'=>'yan','胭'=>'yan','腌'=>'yan','臙'=>'yan','艳'=>'yan','艶'=>'yan','艷'=>'yan','芫'=>'yan','莚'=>'yan','菸'=>'yan','萒'=>'yan','葕'=>'yan','蔅'=>'yan','虤'=>'yan','蜒'=>'yan','蝘'=>'yan','衍'=>'yan','裺'=>'yan','褗'=>'yan','覎'=>'yan','觃'=>'yan','觾'=>'yan','言'=>'yan','訁'=>'yan','訮'=>'yan','詽'=>'yan','諺'=>'yan','讌'=>'yan','讞'=>'yan','讠'=>'yan','谚'=>'yan','谳'=>'yan','豓'=>'yan','豔'=>'yan','贋'=>'yan','贗'=>'yan','贘'=>'yan','赝'=>'yan','躽'=>'yan','軅'=>'yan','遃'=>'yan','郔'=>'yan','郾'=>'yan','鄢'=>'yan','酀'=>'yan','酓'=>'yan','酽'=>'yan','醃'=>'yan','醶'=>'yan','醼'=>'yan','釅'=>'yan','閆'=>'yan','閹'=>'yan','閻'=>'yan','闫'=>'yan','阉'=>'yan','阎'=>'yan','隁'=>'yan','隒'=>'yan','雁'=>'yan','顏'=>'yan','顔'=>'yan','顩'=>'yan','颜'=>'yan','餍'=>'yan','饜'=>'yan','騐'=>'yan','験'=>'yan','騴'=>'yan','驗'=>'yan','驠'=>'yan','验'=>'yan','鬳'=>'yan','魇'=>'yan','魘'=>'yan','鰋'=>'yan','鳫'=>'yan','鴈'=>'yan','鴳'=>'yan','鶠'=>'yan','鷃'=>'yan','鷰'=>'yan','鹽'=>'yan','麙'=>'yan','麣'=>'yan','黡'=>'yan','黤'=>'yan','黫'=>'yan','黬'=>'yan','黭'=>'yan','黶'=>'yan','鼴'=>'yan','鼹'=>'yan','齞'=>'yan','齴'=>'yan','龑'=>'yan','㓧'=>'yan','㕣'=>'yan','㗴'=>'yan','㘖'=>'yan','㘙'=>'yan','㚧'=>'yan','㛪'=>'yan','㢂'=>'yan','㢛'=>'yan','㦔'=>'yan','㫃'=>'yan','㫟'=>'yan','㬫'=>'yan','㭺'=>'yan','㳂'=>'yan','㶄'=>'yan','㷔'=>'yan','㷳'=>'yan','㷼'=>'yan','㿕'=>'yan','㿼'=>'yan','䀋'=>'yan','䀽'=>'yan','䁙'=>'yan','䂩'=>'yan','䂴'=>'yan','䄋'=>'yan','䅧'=>'yan','䊙'=>'yan','䊻'=>'yan','䌪'=>'yan','䎦'=>'yan','䑍'=>'yan','䓂'=>'yan','䕾'=>'yan','䖗'=>'yan','䗡'=>'yan','䗺'=>'yan','䜩'=>'yan','䢥'=>'yan','䢭'=>'yan','䣍'=>'yan','䤷'=>'yan','䨄'=>'yan','䭘'=>'yan','䱲'=>'yan','䲓'=>'yan','䳛'=>'yan','䳺'=>'yan','䴏'=>'yan','䶮'=>'yan','丧'=>'sang','喪'=>'sang','嗓'=>'sang','搡'=>'sang','桑'=>'sang','桒'=>'sang','槡'=>'sang','磉'=>'sang','褬'=>'sang','鎟'=>'sang','顙'=>'sang','颡'=>'sang','䡦'=>'sang','䫙'=>'sang','丨'=>'gun','惃'=>'gun','棍'=>'gun','棞'=>'gun','滚'=>'gun','滾'=>'gun','璭'=>'gun','睔'=>'gun','睴'=>'gun','磙'=>'gun','緄'=>'gun','緷'=>'gun','绲'=>'gun','蓘'=>'gun','蔉'=>'gun','衮'=>'gun','袞'=>'gun','裷'=>'gun','謴'=>'gun','輥'=>'gun','辊'=>'gun','鮌'=>'gun','鯀'=>'gun','鲧'=>'gun','㙥'=>'gun','㫎'=>'gun','㯻'=>'gun','䃂'=>'gun','䎾'=>'gun','䜇'=>'gun','䵪'=>'gun','丩'=>'jiu','久'=>'jiu','乆'=>'jiu','九'=>'jiu','乣'=>'jiu','倃'=>'jiu','僦'=>'jiu','勼'=>'jiu','匓'=>'jiu','匛'=>'jiu','匶'=>'jiu','厩'=>'jiu','咎'=>'jiu','啾'=>'jiu','奺'=>'jiu','就'=>'jiu','廄'=>'jiu','廏'=>'jiu','廐'=>'jiu','慦'=>'jiu','揂'=>'jiu','揪'=>'jiu','揫'=>'jiu','摎'=>'jiu','救'=>'jiu','旧'=>'jiu','朻'=>'jiu','杦'=>'jiu','柩'=>'jiu','柾'=>'jiu','桕'=>'jiu','樛'=>'jiu','欍'=>'jiu','殧'=>'jiu','汣'=>'jiu','灸'=>'jiu','牞'=>'jiu','玖'=>'jiu','畂'=>'jiu','疚'=>'jiu','究'=>'jiu','糺'=>'jiu','糾'=>'jiu','紤'=>'jiu','纠'=>'jiu','臼'=>'jiu','舅'=>'jiu','舊'=>'jiu','舏'=>'jiu','萛'=>'jiu','赳'=>'jiu','酒'=>'jiu','镹'=>'jiu','阄'=>'jiu','韭'=>'jiu','韮'=>'jiu','鬏'=>'jiu','鬮'=>'jiu','鯦'=>'jiu','鳩'=>'jiu','鷲'=>'jiu','鸠'=>'jiu','鹫'=>'jiu','麔'=>'jiu','齨'=>'jiu','㠇'=>'jiu','㡱'=>'jiu','㧕'=>'jiu','㩆'=>'jiu','㲃'=>'jiu','㶭'=>'jiu','㺩'=>'jiu','㺵'=>'jiu','䅢'=>'jiu','䆒'=>'jiu','䊆'=>'jiu','䊘'=>'jiu','䓘'=>'jiu','䛮'=>'jiu','䡂'=>'jiu','䳎'=>'jiu','䳔'=>'jiu','个'=>'ge','佮'=>'ge','個'=>'ge','割'=>'ge','匌'=>'ge','各'=>'ge','呄'=>'ge','哥'=>'ge','哿'=>'ge','嗝'=>'ge','圪'=>'ge','塥'=>'ge','彁'=>'ge','愅'=>'ge','戈'=>'ge','戓'=>'ge','戨'=>'ge','挌'=>'ge','搁'=>'ge','搿'=>'ge','擱'=>'ge','敋'=>'ge','格'=>'ge','槅'=>'ge','櫊'=>'ge','歌'=>'ge','滆'=>'ge','滒'=>'ge','牫'=>'ge','牱'=>'ge','犵'=>'ge','獦'=>'ge','疙'=>'ge','硌'=>'ge','箇'=>'ge','紇'=>'ge','纥'=>'ge','肐'=>'ge','胳'=>'ge','膈'=>'ge','臵'=>'ge','舸'=>'ge','茖'=>'ge','葛'=>'ge','虼'=>'ge','蛒'=>'ge','蛤'=>'ge','袼'=>'ge','裓'=>'ge','觡'=>'ge','諽'=>'ge','謌'=>'ge','輵'=>'ge','轕'=>'ge','鉻'=>'ge','鎘'=>'ge','鎶'=>'ge','铬'=>'ge','镉'=>'ge','閣'=>'ge','閤'=>'ge','阁'=>'ge','隔'=>'ge','革'=>'ge','鞈'=>'ge','鞷'=>'ge','韐'=>'ge','韚'=>'ge','騔'=>'ge','骼'=>'ge','鬲'=>'ge','鮯'=>'ge','鰪'=>'ge','鴐'=>'ge','鴚'=>'ge','鴿'=>'ge','鸽'=>'ge','㗆'=>'ge','㝓'=>'ge','㠷'=>'ge','㦴'=>'ge','㨰'=>'ge','㪾'=>'ge','㵧'=>'ge','㷴'=>'ge','䆟'=>'ge','䈓'=>'ge','䐙'=>'ge','䕻'=>'ge','䗘'=>'ge','䘁'=>'ge','䛋'=>'ge','䛿'=>'ge','䢔'=>'ge','䧄'=>'ge','䨣'=>'ge','䩐'=>'ge','䪂'=>'ge','䪺'=>'ge','䫦'=>'ge','丫'=>'ya','亚'=>'ya','亜'=>'ya','亞'=>'ya','伢'=>'ya','俹'=>'ya','劜'=>'ya','厊'=>'ya','压'=>'ya','厓'=>'ya','呀'=>'ya','哑'=>'ya','唖'=>'ya','啞'=>'ya','圔'=>'ya','圠'=>'ya','垭'=>'ya','埡'=>'ya','堐'=>'ya','壓'=>'ya','娅'=>'ya','婭'=>'ya','孲'=>'ya','岈'=>'ya','崕'=>'ya','崖'=>'ya','庌'=>'ya','庘'=>'ya','押'=>'ya','挜'=>'ya','掗'=>'ya','揠'=>'ya','枒'=>'ya','桠'=>'ya','椏'=>'ya','氩'=>'ya','氬'=>'ya','涯'=>'ya','漄'=>'ya','牙'=>'ya','犽'=>'ya','猚'=>'ya','猰'=>'ya','玡'=>'ya','琊'=>'ya','瑘'=>'ya','疋'=>'ya','痖'=>'ya','瘂'=>'ya','睚'=>'ya','砑'=>'ya','稏'=>'ya','穵'=>'ya','窫'=>'ya','笌'=>'ya','聐'=>'ya','芽'=>'ya','蕥'=>'ya','蚜'=>'ya','衙'=>'ya','襾'=>'ya','訝'=>'ya','讶'=>'ya','迓'=>'ya','錏'=>'ya','鐚'=>'ya','铔'=>'ya','雅'=>'ya','鴉'=>'ya','鴨'=>'ya','鵶'=>'ya','鸦'=>'ya','鸭'=>'ya','齖'=>'ya','齾'=>'ya','㝞'=>'ya','㧎'=>'ya','㰳'=>'ya','㿿'=>'ya','䄰'=>'ya','䅉'=>'ya','䊦'=>'ya','䝟'=>'ya','䢝'=>'ya','䦪'=>'ya','䪵'=>'ya','䯉'=>'ya','䰲'=>'ya','䵝'=>'ya','丬'=>'zhuang','壮'=>'zhuang','壯'=>'zhuang','壵'=>'zhuang','妆'=>'zhuang','妝'=>'zhuang','娤'=>'zhuang','庄'=>'zhuang','庒'=>'zhuang','戅'=>'zhuang','撞'=>'zhuang','桩'=>'zhuang','梉'=>'zhuang','樁'=>'zhuang','湷'=>'zhuang','焋'=>'zhuang','状'=>'zhuang','狀'=>'zhuang','粧'=>'zhuang','糚'=>'zhuang','荘'=>'zhuang','莊'=>'zhuang','装'=>'zhuang','裝'=>'zhuang','中'=>'zhong','仲'=>'zhong','伀'=>'zhong','众'=>'zhong','偅'=>'zhong','冢'=>'zhong','刣'=>'zhong','喠'=>'zhong','堹'=>'zhong','塚'=>'zhong','妐'=>'zhong','妕'=>'zhong','媑'=>'zhong','尰'=>'zhong','幒'=>'zhong','彸'=>'zhong','忠'=>'zhong','柊'=>'zhong','歱'=>'zhong','汷'=>'zhong','泈'=>'zhong','炂'=>'zhong','煄'=>'zhong','狆'=>'zhong','瘇'=>'zhong','盅'=>'zhong','眾'=>'zhong','祌'=>'zhong','祍'=>'zhong','种'=>'zhong','種'=>'zhong','筗'=>'zhong','籦'=>'zhong','終'=>'zhong','终'=>'zhong','肿'=>'zhong','腫'=>'zhong','舯'=>'zhong','茽'=>'zhong','蔠'=>'zhong','蚛'=>'zhong','螤'=>'zhong','螽'=>'zhong','衆'=>'zhong','衳'=>'zhong','衶'=>'zhong','衷'=>'zhong','諥'=>'zhong','踵'=>'zhong','蹱'=>'zhong','迚'=>'zhong','重'=>'zhong','鈡'=>'zhong','鍾'=>'zhong','鐘'=>'zhong','钟'=>'zhong','锺'=>'zhong','鴤'=>'zhong','鼨'=>'zhong','㐺'=>'zhong','㣫'=>'zhong','㲴'=>'zhong','䱰'=>'zhong','丯'=>'jie','介'=>'jie','借'=>'jie','倢'=>'jie','偼'=>'jie','傑'=>'jie','刦'=>'jie','刧'=>'jie','刼'=>'jie','劫'=>'jie','劼'=>'jie','卩'=>'jie','卪'=>'jie','吤'=>'jie','喈'=>'jie','嗟'=>'jie','堦'=>'jie','堺'=>'jie','姐'=>'jie','婕'=>'jie','媎'=>'jie','媘'=>'jie','媫'=>'jie','嫅'=>'jie','孑'=>'jie','尐'=>'jie','屆'=>'jie','届'=>'jie','岊'=>'jie','岕'=>'jie','崨'=>'jie','嵥'=>'jie','嶻'=>'jie','巀'=>'jie','幯'=>'jie','庎'=>'jie','徣'=>'jie','忦'=>'jie','悈'=>'jie','戒'=>'jie','截'=>'jie','拮'=>'jie','捷'=>'jie','接'=>'jie','掲'=>'jie','揭'=>'jie','擑'=>'jie','擮'=>'jie','擳'=>'jie','斺'=>'jie','昅'=>'jie','杰'=>'jie','桀'=>'jie','桔'=>'jie','桝'=>'jie','椄'=>'jie','楐'=>'jie','楬'=>'jie','楶'=>'jie','榤'=>'jie','檞'=>'jie','櫭'=>'jie','毑'=>'jie','洁'=>'jie','湝'=>'jie','滐'=>'jie','潔'=>'jie','煯'=>'jie','犗'=>'jie','玠'=>'jie','琾'=>'jie','界'=>'jie','畍'=>'jie','疌'=>'jie','疖'=>'jie','疥'=>'jie','痎'=>'jie','癤'=>'jie','皆'=>'jie','睫'=>'jie','砎'=>'jie','碣'=>'jie','礍'=>'jie','秸'=>'jie','稭'=>'jie','竭'=>'jie','節'=>'jie','結'=>'jie','繲'=>'jie','结'=>'jie','羯'=>'jie','脻'=>'jie','节'=>'jie','芥'=>'jie','莭'=>'jie','菨'=>'jie','蓵'=>'jie','藉'=>'jie','蚧'=>'jie','蛣'=>'jie','蛶'=>'jie','蜐'=>'jie','蝔'=>'jie','蠘'=>'jie','蠞'=>'jie','蠽'=>'jie','街'=>'jie','衱'=>'jie','衸'=>'jie','袺'=>'jie','褯'=>'jie','解'=>'jie','觧'=>'jie','訐'=>'jie','詰'=>'jie','誡'=>'jie','誱'=>'jie','讦'=>'jie','诘'=>'jie','诫'=>'jie','踕'=>'jie','迼'=>'jie','鉣'=>'jie','鍻'=>'jie','阶'=>'jie','階'=>'jie','鞂'=>'jie','頡'=>'jie','颉'=>'jie','飷'=>'jie','骱'=>'jie','魝'=>'jie','魪'=>'jie','鮚'=>'jie','鲒'=>'jie','鶛'=>'jie','㑘'=>'jie','㓗'=>'jie','㓤'=>'jie','㔾'=>'jie','㘶'=>'jie','㛃'=>'jie','㝌'=>'jie','㝏'=>'jie','㞯'=>'jie','㠹'=>'jie','㦢'=>'jie','㨗'=>'jie','㨩'=>'jie','㮞'=>'jie','㮮'=>'jie','㸅'=>'jie','㾏'=>'jie','㿍'=>'jie','䀷'=>'jie','䀹'=>'jie','䁓'=>'jie','䂒'=>'jie','䂝'=>'jie','䂶'=>'jie','䅥'=>'jie','䇒'=>'jie','䌖'=>'jie','䔿'=>'jie','䕙'=>'jie','䗻'=>'jie','䛺'=>'jie','䣠'=>'jie','䥛'=>'jie','䯰'=>'jie','䰺'=>'jie','䱄'=>'jie','䲙'=>'jie','䲸'=>'jie','丰'=>'feng','仹'=>'feng','俸'=>'feng','偑'=>'feng','僼'=>'feng','冯'=>'feng','凤'=>'feng','凨'=>'feng','凬'=>'feng','凮'=>'feng','唪'=>'feng','堸'=>'feng','夆'=>'feng','奉'=>'feng','妦'=>'feng','寷'=>'feng','封'=>'feng','峯'=>'feng','峰'=>'feng','崶'=>'feng','捀'=>'feng','摓'=>'feng','枫'=>'feng','桻'=>'feng','楓'=>'feng','檒'=>'feng','沣'=>'feng','沨'=>'feng','浲'=>'feng','渢'=>'feng','湗'=>'feng','溄'=>'feng','灃'=>'feng','烽'=>'feng','焨'=>'feng','煈'=>'feng','犎'=>'feng','猦'=>'feng','琒'=>'feng','瓰'=>'feng','甮'=>'feng','疯'=>'feng','瘋'=>'feng','盽'=>'feng','砜'=>'feng','碸'=>'feng','篈'=>'feng','綘'=>'feng','縫'=>'feng','缝'=>'feng','艂'=>'feng','葑'=>'feng','蘕'=>'feng','蘴'=>'feng','蜂'=>'feng','覂'=>'feng','諷'=>'feng','讽'=>'feng','豐'=>'feng','賵'=>'feng','赗'=>'feng','逢'=>'feng','鄷'=>'feng','酆'=>'feng','鋒'=>'feng','鎽'=>'feng','鏠'=>'feng','锋'=>'feng','靊'=>'feng','風'=>'feng','飌'=>'feng','风'=>'feng','馮'=>'feng','鳯'=>'feng','鳳'=>'feng','鴌'=>'feng','麷'=>'feng','㡝'=>'feng','㦀'=>'feng','㵯'=>'feng','䏎'=>'feng','䙜'=>'feng','䟪'=>'feng','䩼'=>'feng','丱'=>'guan','倌'=>'guan','关'=>'guan','冠'=>'guan','卝'=>'guan','官'=>'guan','悹'=>'guan','悺'=>'guan','惯'=>'guan','慣'=>'guan','掼'=>'guan','摜'=>'guan','棺'=>'guan','樌'=>'guan','毌'=>'guan','泴'=>'guan','涫'=>'guan','潅'=>'guan','灌'=>'guan','爟'=>'guan','琯'=>'guan','瓘'=>'guan','痯'=>'guan','瘝'=>'guan','癏'=>'guan','盥'=>'guan','矔'=>'guan','礶'=>'guan','祼'=>'guan','窤'=>'guan','筦'=>'guan','管'=>'guan','罆'=>'guan','罐'=>'guan','舘'=>'guan','萖'=>'guan','蒄'=>'guan','覌'=>'guan','観'=>'guan','觀'=>'guan','观'=>'guan','貫'=>'guan','贯'=>'guan','躀'=>'guan','輨'=>'guan','遦'=>'guan','錧'=>'guan','鏆'=>'guan','鑵'=>'guan','関'=>'guan','闗'=>'guan','關'=>'guan','雚'=>'guan','館'=>'guan','馆'=>'guan','鰥'=>'guan','鱞'=>'guan','鱹'=>'guan','鳏'=>'guan','鳤'=>'guan','鸛'=>'guan','鹳'=>'guan','㮡'=>'guan','㴦'=>'guan','䌯'=>'guan','䎚'=>'guan','䏓'=>'guan','䗆'=>'guan','䗰'=>'guan','䘾'=>'guan','䙛'=>'guan','䙮'=>'guan','䝺'=>'guan','䦎'=>'guan','䩪'=>'guan','䪀'=>'guan','䲘'=>'guan','串'=>'chuan','传'=>'chuan','傳'=>'chuan','僢'=>'chuan','剶'=>'chuan','喘'=>'chuan','圌'=>'chuan','巛'=>'chuan','川'=>'chuan','暷'=>'chuan','椽'=>'chuan','歂'=>'chuan','氚'=>'chuan','汌'=>'chuan','猭'=>'chuan','玔'=>'chuan','瑏'=>'chuan','穿'=>'chuan','篅'=>'chuan','舛'=>'chuan','舡'=>'chuan','舩'=>'chuan','船'=>'chuan','荈'=>'chuan','賗'=>'chuan','輲'=>'chuan','遄'=>'chuan','釧'=>'chuan','钏'=>'chuan','镩'=>'chuan','鶨'=>'chuan','㯌'=>'chuan','㱛'=>'chuan','㼷'=>'chuan','䁣'=>'chuan','丳'=>'chan','产'=>'chan','僝'=>'chan','儃'=>'chan','儳'=>'chan','冁'=>'chan','刬'=>'chan','剗'=>'chan','剷'=>'chan','劖'=>'chan','嚵'=>'chan','囅'=>'chan','壥'=>'chan','婵'=>'chan','嬋'=>'chan','孱'=>'chan','嵼'=>'chan','巉'=>'chan','幝'=>'chan','幨'=>'chan','廛'=>'chan','忏'=>'chan','懴'=>'chan','懺'=>'chan','掺'=>'chan','搀'=>'chan','摌'=>'chan','摲'=>'chan','摻'=>'chan','攙'=>'chan','旵'=>'chan','梴'=>'chan','棎'=>'chan','欃'=>'chan','毚'=>'chan','浐'=>'chan','湹'=>'chan','滻'=>'chan','潹'=>'chan','潺'=>'chan','瀍'=>'chan','瀺'=>'chan','灛'=>'chan','煘'=>'chan','燀'=>'chan','獑'=>'chan','產'=>'chan','産'=>'chan','硟'=>'chan','磛'=>'chan','禅'=>'chan','禪'=>'chan','簅'=>'chan','緾'=>'chan','繟'=>'chan','繵'=>'chan','纏'=>'chan','纒'=>'chan','缠'=>'chan','羼'=>'chan','艬'=>'chan','蒇'=>'chan','蕆'=>'chan','蝉'=>'chan','蝊'=>'chan','蟬'=>'chan','蟾'=>'chan','裧'=>'chan','襜'=>'chan','覘'=>'chan','觇'=>'chan','誗'=>'chan','諂'=>'chan','譂'=>'chan','讇'=>'chan','讒'=>'chan','谄'=>'chan','谗'=>'chan','躔'=>'chan','辿'=>'chan','鄽'=>'chan','酁'=>'chan','醦'=>'chan','鋋'=>'chan','鋓'=>'chan','鏟'=>'chan','鑱'=>'chan','铲'=>'chan','镡'=>'chan','镵'=>'chan','閳'=>'chan','闡'=>'chan','阐'=>'chan','韂'=>'chan','顫'=>'chan','颤'=>'chan','饞'=>'chan','馋'=>'chan','㔆'=>'chan','㙴'=>'chan','㙻'=>'chan','㢆'=>'chan','㢟'=>'chan','㦃'=>'chan','㬄'=>'chan','㯆'=>'chan','㵌'=>'chan','㶣'=>'chan','㸥'=>'chan','㹌'=>'chan','㹽'=>'chan','㺥'=>'chan','䀡'=>'chan','䂁'=>'chan','䊲'=>'chan','䐮'=>'chan','䑎'=>'chan','䜛'=>'chan','䠨'=>'chan','䡪'=>'chan','䡲'=>'chan','䣑'=>'chan','䤘'=>'chan','䤫'=>'chan','䥀'=>'chan','䧯'=>'chan','䩶'=>'chan','䪜'=>'chan','䮭'=>'chan','䱿'=>'chan','䴼'=>'chan','䵐'=>'chan','临'=>'lin','亃'=>'lin','僯'=>'lin','凛'=>'lin','凜'=>'lin','厸'=>'lin','吝'=>'lin','啉'=>'lin','壣'=>'lin','崊'=>'lin','嶙'=>'lin','廩'=>'lin','廪'=>'lin','恡'=>'lin','悋'=>'lin','惏'=>'lin','懍'=>'lin','懔'=>'lin','拎'=>'lin','撛'=>'lin','斴'=>'lin','晽'=>'lin','暽'=>'lin','林'=>'lin','橉'=>'lin','檁'=>'lin','檩'=>'lin','淋'=>'lin','潾'=>'lin','澟'=>'lin','瀶'=>'lin','焛'=>'lin','燐'=>'lin','獜'=>'lin','琳'=>'lin','璘'=>'lin','甐'=>'lin','疄'=>'lin','痳'=>'lin','癛'=>'lin','癝'=>'lin','瞵'=>'lin','碄'=>'lin','磷'=>'lin','稟'=>'lin','箖'=>'lin','粦'=>'lin','粼'=>'lin','繗'=>'lin','翷'=>'lin','膦'=>'lin','臨'=>'lin','菻'=>'lin','蔺'=>'lin','藺'=>'lin','賃'=>'lin','赁'=>'lin','蹸'=>'lin','躏'=>'lin','躙'=>'lin','躪'=>'lin','轔'=>'lin','轥'=>'lin','辚'=>'lin','遴'=>'lin','邻'=>'lin','鄰'=>'lin','鏻'=>'lin','閵'=>'lin','隣'=>'lin','霖'=>'lin','顲'=>'lin','驎'=>'lin','鱗'=>'lin','鳞'=>'lin','麐'=>'lin','麟'=>'lin','㐭'=>'lin','㔂'=>'lin','㖁'=>'lin','㝝'=>'lin','㨆'=>'lin','㷠'=>'lin','䉮'=>'lin','䕲'=>'lin','䗲'=>'lin','䚬'=>'lin','䢯'=>'lin','䫐'=>'lin','䫰'=>'lin','䮼'=>'lin','丵'=>'zhuo','倬'=>'zhuo','劅'=>'zhuo','卓'=>'zhuo','叕'=>'zhuo','啄'=>'zhuo','啅'=>'zhuo','圴'=>'zhuo','妰'=>'zhuo','娺'=>'zhuo','彴'=>'zhuo','拙'=>'zhuo','捉'=>'zhuo','撯'=>'zhuo','擆'=>'zhuo','擢'=>'zhuo','斀'=>'zhuo','斫'=>'zhuo','斮'=>'zhuo','斱'=>'zhuo','斲'=>'zhuo','斵'=>'zhuo','晫'=>'zhuo','桌'=>'zhuo','梲'=>'zhuo','棁'=>'zhuo','棳'=>'zhuo','椓'=>'zhuo','槕'=>'zhuo','櫡'=>'zhuo','浊'=>'zhuo','浞'=>'zhuo','涿'=>'zhuo','濁'=>'zhuo','濯'=>'zhuo','灂'=>'zhuo','灼'=>'zhuo','炪'=>'zhuo','烵'=>'zhuo','犳'=>'zhuo','琢'=>'zhuo','琸'=>'zhuo','着'=>'zhuo','硺'=>'zhuo','禚'=>'zhuo','穛'=>'zhuo','穱'=>'zhuo','窡'=>'zhuo','窧'=>'zhuo','篧'=>'zhuo','籗'=>'zhuo','籱'=>'zhuo','罬'=>'zhuo','茁'=>'zhuo','蠗'=>'zhuo','蠿'=>'zhuo','諁'=>'zhuo','諑'=>'zhuo','謶'=>'zhuo','诼'=>'zhuo','酌'=>'zhuo','鋜'=>'zhuo','鐯'=>'zhuo','鐲'=>'zhuo','镯'=>'zhuo','鵫'=>'zhuo','鷟'=>'zhuo','㑁'=>'zhuo','㣿'=>'zhuo','㪬'=>'zhuo','㭬'=>'zhuo','㺟'=>'zhuo','䅵'=>'zhuo','䕴'=>'zhuo','䶂'=>'zhuo','丶'=>'zhu','主'=>'zhu','伫'=>'zhu','佇'=>'zhu','住'=>'zhu','侏'=>'zhu','劚'=>'zhu','助'=>'zhu','劯'=>'zhu','嘱'=>'zhu','囑'=>'zhu','坾'=>'zhu','墸'=>'zhu','壴'=>'zhu','孎'=>'zhu','宔'=>'zhu','屬'=>'zhu','嵀'=>'zhu','拄'=>'zhu','斸'=>'zhu','曯'=>'zhu','朱'=>'zhu','杼'=>'zhu','柱'=>'zhu','柷'=>'zhu','株'=>'zhu','槠'=>'zhu','樦'=>'zhu','橥'=>'zhu','櫧'=>'zhu','櫫'=>'zhu','欘'=>'zhu','殶'=>'zhu','泏'=>'zhu','注'=>'zhu','洙'=>'zhu','渚'=>'zhu','潴'=>'zhu','濐'=>'zhu','瀦'=>'zhu','灟'=>'zhu','炢'=>'zhu','炷'=>'zhu','烛'=>'zhu','煑'=>'zhu','煮'=>'zhu','燭'=>'zhu','爥'=>'zhu','猪'=>'zhu','珠'=>'zhu','疰'=>'zhu','瘃'=>'zhu','眝'=>'zhu','瞩'=>'zhu','矚'=>'zhu','砫'=>'zhu','硃'=>'zhu','祝'=>'zhu','祩'=>'zhu','秼'=>'zhu','窋'=>'zhu','竚'=>'zhu','竹'=>'zhu','竺'=>'zhu','笁'=>'zhu','笜'=>'zhu','筑'=>'zhu','筯'=>'zhu','箸'=>'zhu','築'=>'zhu','篫'=>'zhu','紵'=>'zhu','紸'=>'zhu','絑'=>'zhu','纻'=>'zhu','罜'=>'zhu','羜'=>'zhu','翥'=>'zhu','舳'=>'zhu','芧'=>'zhu','苎'=>'zhu','苧'=>'zhu','茱'=>'zhu','茿'=>'zhu','莇'=>'zhu','著'=>'zhu','蓫'=>'zhu','藸'=>'zhu','蛀'=>'zhu','蛛'=>'zhu','蝫'=>'zhu','蠋'=>'zhu','蠩'=>'zhu','蠾'=>'zhu','袾'=>'zhu','註'=>'zhu','詝'=>'zhu','誅'=>'zhu','諸'=>'zhu','诛'=>'zhu','诸'=>'zhu','豬'=>'zhu','貯'=>'zhu','贮'=>'zhu','跓'=>'zhu','跦'=>'zhu','躅'=>'zhu','軴'=>'zhu','迬'=>'zhu','逐'=>'zhu','邾'=>'zhu','鉒'=>'zhu','銖'=>'zhu','鋳'=>'zhu','鑄'=>'zhu','钃'=>'zhu','铢'=>'zhu','铸'=>'zhu','陼'=>'zhu','霔'=>'zhu','飳'=>'zhu','馵'=>'zhu','駐'=>'zhu','駯'=>'zhu','驻'=>'zhu','鮢'=>'zhu','鯺'=>'zhu','鱁'=>'zhu','鴸'=>'zhu','麆'=>'zhu','麈'=>'zhu','鼄'=>'zhu','㑏'=>'zhu','㔉'=>'zhu','㝉'=>'zhu','㤖'=>'zhu','㧣'=>'zhu','㫂'=>'zhu','㵭'=>'zhu','㹥'=>'zhu','㺛'=>'zhu','㾻'=>'zhu','㿾'=>'zhu','䇡'=>'zhu','䇧'=>'zhu','䌵'=>'zhu','䍆'=>'zhu','䎷'=>'zhu','䐢'=>'zhu','䕽'=>'zhu','䘚'=>'zhu','䘢'=>'zhu','䝒'=>'zhu','䝬'=>'zhu','䟉'=>'zhu','䥮'=>'zhu','䬡'=>'zhu','䭖'=>'zhu','䮱'=>'zhu','䰞'=>'zhu','丷'=>'ha','哈'=>'ha','妎'=>'ha','鉿'=>'ha','铪'=>'ha','丹'=>'dan','亶'=>'dan','伔'=>'dan','但'=>'dan','僤'=>'dan','儋'=>'dan','刐'=>'dan','勯'=>'dan','匰'=>'dan','单'=>'dan','単'=>'dan','啖'=>'dan','啗'=>'dan','啿'=>'dan','單'=>'dan','嘾'=>'dan','噉'=>'dan','嚪'=>'dan','妉'=>'dan','媅'=>'dan','帎'=>'dan','弹'=>'dan','彈'=>'dan','惮'=>'dan','憚'=>'dan','憺'=>'dan','担'=>'dan','掸'=>'dan','撣'=>'dan','擔'=>'dan','旦'=>'dan','柦'=>'dan','殚'=>'dan','殫'=>'dan','氮'=>'dan','沊'=>'dan','泹'=>'dan','淡'=>'dan','澸'=>'dan','澹'=>'dan','狚'=>'dan','玬'=>'dan','瓭'=>'dan','甔'=>'dan','疍'=>'dan','疸'=>'dan','瘅'=>'dan','癉'=>'dan','癚'=>'dan','眈'=>'dan','砃'=>'dan','禫'=>'dan','窞'=>'dan','箪'=>'dan','簞'=>'dan','紞'=>'dan','耼'=>'dan','耽'=>'dan','聃'=>'dan','聸'=>'dan','胆'=>'dan','腅'=>'dan','膽'=>'dan','萏'=>'dan','蛋'=>'dan','蜑'=>'dan','衴'=>'dan','褝'=>'dan','襌'=>'dan','觛'=>'dan','訑'=>'dan','誕'=>'dan','诞'=>'dan','贉'=>'dan','躭'=>'dan','郸'=>'dan','鄲'=>'dan','酖'=>'dan','霮'=>'dan','頕'=>'dan','餤'=>'dan','饏'=>'dan','馾'=>'dan','駳'=>'dan','髧'=>'dan','鴠'=>'dan','黕'=>'dan','㔊'=>'dan','㕪'=>'dan','㗖'=>'dan','㡺'=>'dan','㫜'=>'dan','㱽'=>'dan','㲷'=>'dan','㵅'=>'dan','㺗'=>'dan','㽎'=>'dan','䃫'=>'dan','䄷'=>'dan','䉞'=>'dan','䉷'=>'dan','䨢'=>'dan','䨵'=>'dan','䩥'=>'dan','䭛'=>'dan','䮰'=>'dan','䱋'=>'dan','䳉'=>'dan','为'=>'wei','亹'=>'wei','伟'=>'wei','伪'=>'wei','位'=>'wei','偉'=>'wei','偎'=>'wei','偽'=>'wei','僞'=>'wei','儰'=>'wei','卫'=>'wei','危'=>'wei','厃'=>'wei','叞'=>'wei','味'=>'wei','唯'=>'wei','喂'=>'wei','喡'=>'wei','喴'=>'wei','囗'=>'wei','围'=>'wei','圍'=>'wei','圩'=>'wei','墛'=>'wei','壝'=>'wei','委'=>'wei','威'=>'wei','娓'=>'wei','媁'=>'wei','媙'=>'wei','媦'=>'wei','寪'=>'wei','尉'=>'wei','尾'=>'wei','峗'=>'wei','峞'=>'wei','崣'=>'wei','嵔'=>'wei','嵬'=>'wei','嶶'=>'wei','巍'=>'wei','帏'=>'wei','帷'=>'wei','幃'=>'wei','廆'=>'wei','徫'=>'wei','微'=>'wei','惟'=>'wei','愄'=>'wei','愇'=>'wei','慰'=>'wei','懀'=>'wei','捤'=>'wei','揋'=>'wei','揻'=>'wei','斖'=>'wei','昷'=>'wei','暐'=>'wei','未'=>'wei','桅'=>'wei','梶'=>'wei','椲'=>'wei','椳'=>'wei','楲'=>'wei','沩'=>'wei','洈'=>'wei','洧'=>'wei','浘'=>'wei','涠'=>'wei','渨'=>'wei','渭'=>'wei','湋'=>'wei','溈'=>'wei','溦'=>'wei','潍'=>'wei','潙'=>'wei','潿'=>'wei','濊'=>'wei','濰'=>'wei','濻'=>'wei','瀢'=>'wei','炜'=>'wei','為'=>'wei','烓'=>'wei','煀'=>'wei','煒'=>'wei','煟'=>'wei','煨'=>'wei','熭'=>'wei','燰'=>'wei','爲'=>'wei','犚'=>'wei','犩'=>'wei','猥'=>'wei','猬'=>'wei','玮'=>'wei','琟'=>'wei','瑋'=>'wei','璏'=>'wei','畏'=>'wei','痏'=>'wei','痿'=>'wei','癐'=>'wei','癓'=>'wei','硊'=>'wei','硙'=>'wei','碨'=>'wei','磑'=>'wei','維'=>'wei','緭'=>'wei','緯'=>'wei','縅'=>'wei','纬'=>'wei','维'=>'wei','罻'=>'wei','胃'=>'wei','腲'=>'wei','艉'=>'wei','芛'=>'wei','苇'=>'wei','苿'=>'wei','荱'=>'wei','菋'=>'wei','萎'=>'wei','葦'=>'wei','葨'=>'wei','葳'=>'wei','蒍'=>'wei','蓶'=>'wei','蔚'=>'wei','蔿'=>'wei','薇'=>'wei','薳'=>'wei','藯'=>'wei','蘶'=>'wei','蜲'=>'wei','蜼'=>'wei','蝛'=>'wei','蝟'=>'wei','螱'=>'wei','衛'=>'wei','衞'=>'wei','褽'=>'wei','覣'=>'wei','覹'=>'wei','詴'=>'wei','諉'=>'wei','謂'=>'wei','讆'=>'wei','讏'=>'wei','诿'=>'wei','谓'=>'wei','踓'=>'wei','躗'=>'wei','躛'=>'wei','軎'=>'wei','轊'=>'wei','违'=>'wei','逶'=>'wei','違'=>'wei','鄬'=>'wei','醀'=>'wei','錗'=>'wei','鍏'=>'wei','鍡'=>'wei','鏏'=>'wei','闈'=>'wei','闱'=>'wei','隇'=>'wei','隈'=>'wei','隗'=>'wei','霨'=>'wei','霺'=>'wei','霻'=>'wei','韋'=>'wei','韑'=>'wei','韙'=>'wei','韡'=>'wei','韦'=>'wei','韪'=>'wei','頠'=>'wei','颹'=>'wei','餧'=>'wei','餵'=>'wei','饖'=>'wei','骩'=>'wei','骪'=>'wei','骫'=>'wei','魏'=>'wei','鮇'=>'wei','鮠'=>'wei','鮪'=>'wei','鰃'=>'wei','鰄'=>'wei','鲔'=>'wei','鳂'=>'wei','鳚'=>'wei','㕒'=>'wei','㖐'=>'wei','㞇'=>'wei','㞑'=>'wei','㟪'=>'wei','㠕'=>'wei','㢻'=>'wei','㣲'=>'wei','㥜'=>'wei','㦣'=>'wei','㧑'=>'wei','㨊'=>'wei','㬙'=>'wei','㭏'=>'wei','㱬'=>'wei','㷉'=>'wei','䃬'=>'wei','䈧'=>'wei','䉠'=>'wei','䑊'=>'wei','䔺'=>'wei','䗽'=>'wei','䘙'=>'wei','䙿'=>'wei','䜅'=>'wei','䜜'=>'wei','䝐'=>'wei','䞔'=>'wei','䡺'=>'wei','䥩'=>'wei','䧦'=>'wei','䪋'=>'wei','䪘'=>'wei','䬐'=>'wei','䬑'=>'wei','䬿'=>'wei','䭳'=>'wei','䮹'=>'wei','䲁'=>'wei','䵋'=>'wei','䵳'=>'wei','丼'=>'jing','井'=>'jing','京'=>'jing','亰'=>'jing','俓'=>'jing','倞'=>'jing','傹'=>'jing','儆'=>'jing','兢'=>'jing','净'=>'jing','凈'=>'jing','刭'=>'jing','剄'=>'jing','坓'=>'jing','坕'=>'jing','坙'=>'jing','境'=>'jing','妌'=>'jing','婙'=>'jing','婛'=>'jing','婧'=>'jing','宑'=>'jing','巠'=>'jing','幜'=>'jing','弪'=>'jing','弳'=>'jing','径'=>'jing','徑'=>'jing','惊'=>'jing','憬'=>'jing','憼'=>'jing','敬'=>'jing','旌'=>'jing','旍'=>'jing','景'=>'jing','晶'=>'jing','暻'=>'jing','曔'=>'jing','桱'=>'jing','梷'=>'jing','橸'=>'jing','汫'=>'jing','汬'=>'jing','泾'=>'jing','浄'=>'jing','涇'=>'jing','淨'=>'jing','瀞'=>'jing','燝'=>'jing','燞'=>'jing','猄'=>'jing','獍'=>'jing','璄'=>'jing','璟'=>'jing','璥'=>'jing','痉'=>'jing','痙'=>'jing','睛'=>'jing','秔'=>'jing','稉'=>'jing','穽'=>'jing','竞'=>'jing','竟'=>'jing','竧'=>'jing','竫'=>'jing','競'=>'jing','竸'=>'jing','粳'=>'jing','精'=>'jing','経'=>'jing','經'=>'jing','经'=>'jing','聙'=>'jing','肼'=>'jing','胫'=>'jing','脛'=>'jing','腈'=>'jing','茎'=>'jing','荆'=>'jing','荊'=>'jing','莖'=>'jing','菁'=>'jing','蟼'=>'jing','誩'=>'jing','警'=>'jing','踁'=>'jing','迳'=>'jing','逕'=>'jing','鏡'=>'jing','镜'=>'jing','阱'=>'jing','靓'=>'jing','靖'=>'jing','静'=>'jing','靚'=>'jing','靜'=>'jing','頚'=>'jing','頸'=>'jing','颈'=>'jing','驚'=>'jing','鯨'=>'jing','鲸'=>'jing','鵛'=>'jing','鶁'=>'jing','鶄'=>'jing','麖'=>'jing','麠'=>'jing','鼱'=>'jing','㕋'=>'jing','㘫'=>'jing','㢣'=>'jing','㣏'=>'jing','㬌'=>'jing','㵾'=>'jing','㹵'=>'jing','䔔'=>'jing','䜘'=>'jing','䡖'=>'jing','䴖'=>'jing','䵞'=>'jing','丽'=>'li','例'=>'li','俐'=>'li','俚'=>'li','俪'=>'li','傈'=>'li','儮'=>'li','儷'=>'li','凓'=>'li','刕'=>'li','利'=>'li','剓'=>'li','剺'=>'li','劙'=>'li','力'=>'li','励'=>'li','勵'=>'li','历'=>'li','厉'=>'li','厘'=>'li','厤'=>'li','厯'=>'li','厲'=>'li','吏'=>'li','呖'=>'li','哩'=>'li','唎'=>'li','唳'=>'li','喱'=>'li','嚟'=>'li','嚦'=>'li','囄'=>'li','囇'=>'li','坜'=>'li','塛'=>'li','壢'=>'li','娌'=>'li','娳'=>'li','婯'=>'li','嫠'=>'li','孋'=>'li','孷'=>'li','屴'=>'li','岦'=>'li','峛'=>'li','峲'=>'li','巁'=>'li','廲'=>'li','悡'=>'li','悧'=>'li','悷'=>'li','慄'=>'li','戾'=>'li','搮'=>'li','攊'=>'li','攦'=>'li','攭'=>'li','斄'=>'li','暦'=>'li','曆'=>'li','曞'=>'li','朸'=>'li','李'=>'li','枥'=>'li','栃'=>'li','栎'=>'li','栗'=>'li','栛'=>'li','栵'=>'li','梨'=>'li','梸'=>'li','棃'=>'li','棙'=>'li','樆'=>'li','檪'=>'li','櫔'=>'li','櫟'=>'li','櫪'=>'li','欐'=>'li','欚'=>'li','歴'=>'li','歷'=>'li','氂'=>'li','沥'=>'li','沴'=>'li','浬'=>'li','涖'=>'li','溧'=>'li','漓'=>'li','澧'=>'li','濿'=>'li','瀝'=>'li','灕'=>'li','爄'=>'li','爏'=>'li','犁'=>'li','犂'=>'li','犛'=>'li','犡'=>'li','狸'=>'li','猁'=>'li','珕'=>'li','理'=>'li','琍'=>'li','瑮'=>'li','璃'=>'li','瓅'=>'li','瓈'=>'li','瓑'=>'li','瓥'=>'li','疠'=>'li','疬'=>'li','痢'=>'li','癘'=>'li','癧'=>'li','皪'=>'li','盠'=>'li','盭'=>'li','睝'=>'li','砅'=>'li','砺'=>'li','砾'=>'li','磿'=>'li','礪'=>'li','礫'=>'li','礰'=>'li','礼'=>'li','禮'=>'li','禲'=>'li','离'=>'li','秝'=>'li','穲'=>'li','立'=>'li','竰'=>'li','笠'=>'li','筣'=>'li','篥'=>'li','篱'=>'li','籬'=>'li','粒'=>'li','粝'=>'li','粴'=>'li','糎'=>'li','糲'=>'li','綟'=>'li','縭'=>'li','缡'=>'li','罹'=>'li','艃'=>'li','苈'=>'li','苙'=>'li','茘'=>'li','荔'=>'li','荲'=>'li','莅'=>'li','莉'=>'li','菞'=>'li','蒚'=>'li','蒞'=>'li','蓠'=>'li','蔾'=>'li','藜'=>'li','藶'=>'li','蘺'=>'li','蚸'=>'li','蛎'=>'li','蛠'=>'li','蜊'=>'li','蜧'=>'li','蟍'=>'li','蟸'=>'li','蠇'=>'li','蠡'=>'li','蠣'=>'li','蠫'=>'li','裏'=>'li','裡'=>'li','褵'=>'li','詈'=>'li','謧'=>'li','讈'=>'li','豊'=>'li','貍'=>'li','赲'=>'li','跞'=>'li','躒'=>'li','轢'=>'li','轣'=>'li','轹'=>'li','逦'=>'li','邌'=>'li','邐'=>'li','郦'=>'li','酈'=>'li','醨'=>'li','醴'=>'li','里'=>'li','釐'=>'li','鉝'=>'li','鋫'=>'li','鋰'=>'li','錅'=>'li','鏫'=>'li','鑗'=>'li','锂'=>'li','隶'=>'li','隷'=>'li','隸'=>'li','離'=>'li','雳'=>'li','靂'=>'li','靋'=>'li','驪'=>'li','骊'=>'li','鬁'=>'li','鯉'=>'li','鯏'=>'li','鯬'=>'li','鱧'=>'li','鱱'=>'li','鱺'=>'li','鲡'=>'li','鲤'=>'li','鳢'=>'li','鳨'=>'li','鴗'=>'li','鵹'=>'li','鷅'=>'li','鸝'=>'li','鹂'=>'li','麗'=>'li','麜'=>'li','黎'=>'li','黧'=>'li','㑦'=>'li','㒧'=>'li','㒿'=>'li','㓯'=>'li','㔏'=>'li','㕸'=>'li','㗚'=>'li','㘑'=>'li','㟳'=>'li','㠟'=>'li','㡂'=>'li','㤡'=>'li','㤦'=>'li','㦒'=>'li','㧰'=>'li','㬏'=>'li','㮚'=>'li','㯤'=>'li','㰀'=>'li','㰚'=>'li','㱹'=>'li','㴝'=>'li','㷰'=>'li','㸚'=>'li','㹈'=>'li','㺡'=>'li','㻎'=>'li','㻺'=>'li','㼖'=>'li','㽁'=>'li','㽝'=>'li','㾐'=>'li','㾖'=>'li','㿛'=>'li','㿨'=>'li','䁻'=>'li','䃯'=>'li','䄜'=>'li','䅄'=>'li','䅻'=>'li','䇐'=>'li','䉫'=>'li','䊍'=>'li','䊪'=>'li','䋥'=>'li','䍠'=>'li','䍦'=>'li','䍽'=>'li','䓞'=>'li','䔁'=>'li','䔆'=>'li','䔉'=>'li','䔣'=>'li','䔧'=>'li','䖥'=>'li','䖽'=>'li','䖿'=>'li','䗍'=>'li','䘈'=>'li','䙰'=>'li','䚕'=>'li','䟏'=>'li','䟐'=>'li','䡃'=>'li','䣓'=>'li','䣫'=>'li','䤙'=>'li','䤚'=>'li','䥶'=>'li','䧉'=>'li','䬅'=>'li','䬆'=>'li','䮋'=>'li','䮥'=>'li','䰛'=>'li','䰜'=>'li','䱘'=>'li','䲞'=>'li','䴄'=>'li','䴡'=>'li','䴻'=>'li','䵓'=>'li','䵩'=>'li','䶘'=>'li','举'=>'ju','侷'=>'ju','俱'=>'ju','倨'=>'ju','倶'=>'ju','僪'=>'ju','具'=>'ju','冣'=>'ju','凥'=>'ju','剧'=>'ju','劇'=>'ju','勮'=>'ju','匊'=>'ju','句'=>'ju','咀'=>'ju','圧'=>'ju','埧'=>'ju','埾'=>'ju','壉'=>'ju','姖'=>'ju','娵'=>'ju','婅'=>'ju','婮'=>'ju','寠'=>'ju','局'=>'ju','居'=>'ju','屦'=>'ju','屨'=>'ju','岠'=>'ju','崌'=>'ju','巈'=>'ju','巨'=>'ju','弆'=>'ju','怇'=>'ju','怚'=>'ju','惧'=>'ju','愳'=>'ju','懅'=>'ju','懼'=>'ju','抅'=>'ju','拒'=>'ju','拘'=>'ju','拠'=>'ju','挙'=>'ju','挶'=>'ju','捄'=>'ju','据'=>'ju','掬'=>'ju','據'=>'ju','擧'=>'ju','昛'=>'ju','梮'=>'ju','椇'=>'ju','椈'=>'ju','椐'=>'ju','榉'=>'ju','榘'=>'ju','橘'=>'ju','檋'=>'ju','櫸'=>'ju','欅'=>'ju','歫'=>'ju','毩'=>'ju','毱'=>'ju','沮'=>'ju','泃'=>'ju','泦'=>'ju','洰'=>'ju','涺'=>'ju','淗'=>'ju','湨'=>'ju','澽'=>'ju','炬'=>'ju','焗'=>'ju','焣'=>'ju','爠'=>'ju','犋'=>'ju','犑'=>'ju','狊'=>'ju','狙'=>'ju','琚'=>'ju','疽'=>'ju','痀'=>'ju','眗'=>'ju','瞿'=>'ju','矩'=>'ju','砠'=>'ju','秬'=>'ju','窭'=>'ju','窶'=>'ju','筥'=>'ju','簴'=>'ju','粔'=>'ju','粷'=>'ju','罝'=>'ju','耟'=>'ju','聚'=>'ju','聥'=>'ju','腒'=>'ju','舉'=>'ju','艍'=>'ju','苣'=>'ju','苴'=>'ju','莒'=>'ju','菊'=>'ju','蒟'=>'ju','蓻'=>'ju','蘜'=>'ju','虡'=>'ju','蚷'=>'ju','蜛'=>'ju','袓'=>'ju','裾'=>'ju','襷'=>'ju','詎'=>'ju','諊'=>'ju','讵'=>'ju','豦'=>'ju','貗'=>'ju','趄'=>'ju','趜'=>'ju','跔'=>'ju','跙'=>'ju','距'=>'ju','跼'=>'ju','踘'=>'ju','踞'=>'ju','踽'=>'ju','蹫'=>'ju','躆'=>'ju','躹'=>'ju','輂'=>'ju','遽'=>'ju','邭'=>'ju','郹'=>'ju','醵'=>'ju','鉅'=>'ju','鋦'=>'ju','鋸'=>'ju','鐻'=>'ju','钜'=>'ju','锔'=>'ju','锯'=>'ju','閰'=>'ju','陱'=>'ju','雎'=>'ju','鞠'=>'ju','鞫'=>'ju','颶'=>'ju','飓'=>'ju','駏'=>'ju','駒'=>'ju','駶'=>'ju','驧'=>'ju','驹'=>'ju','鮈'=>'ju','鮔'=>'ju','鴡'=>'ju','鵙'=>'ju','鵴'=>'ju','鶋'=>'ju','鶪'=>'ju','鼰'=>'ju','鼳'=>'ju','齟'=>'ju','龃'=>'ju','㘌'=>'ju','㘲'=>'ju','㜘'=>'ju','㞐'=>'ju','㞫'=>'ju','㠪'=>'ju','㥌'=>'ju','㨿'=>'ju','㩀'=>'ju','㩴'=>'ju','㬬'=>'ju','㮂'=>'ju','㳥'=>'ju','㽤'=>'ju','䃊'=>'ju','䄔'=>'ju','䅓'=>'ju','䆽'=>'ju','䈮'=>'ju','䋰'=>'ju','䏱'=>'ju','䕮'=>'ju','䗇'=>'ju','䛯'=>'ju','䜯'=>'ju','䡞'=>'ju','䢹'=>'ju','䣰'=>'ju','䤎'=>'ju','䪕'=>'ju','䰬'=>'ju','䱟'=>'ju','䱡'=>'ju','䴗'=>'ju','䵕'=>'ju','䶙'=>'ju','䶥'=>'ju','丿'=>'pie','嫳'=>'pie','撆'=>'pie','撇'=>'pie','暼'=>'pie','氕'=>'pie','瞥'=>'pie','苤'=>'pie','鐅'=>'pie','䥕'=>'pie','乀'=>'fu','付'=>'fu','伏'=>'fu','伕'=>'fu','俌'=>'fu','俘'=>'fu','俯'=>'fu','偩'=>'fu','傅'=>'fu','冨'=>'fu','冹'=>'fu','凫'=>'fu','刜'=>'fu','副'=>'fu','匐'=>'fu','呋'=>'fu','呒'=>'fu','咈'=>'fu','咐'=>'fu','哹'=>'fu','坿'=>'fu','垘'=>'fu','复'=>'fu','夫'=>'fu','妇'=>'fu','妋'=>'fu','姇'=>'fu','娐'=>'fu','婏'=>'fu','婦'=>'fu','媍'=>'fu','孚'=>'fu','孵'=>'fu','富'=>'fu','尃'=>'fu','岪'=>'fu','峊'=>'fu','巿'=>'fu','帗'=>'fu','幅'=>'fu','幞'=>'fu','府'=>'fu','弗'=>'fu','弣'=>'fu','彿'=>'fu','復'=>'fu','怤'=>'fu','怫'=>'fu','懯'=>'fu','扶'=>'fu','抚'=>'fu','拂'=>'fu','拊'=>'fu','捬'=>'fu','撫'=>'fu','敷'=>'fu','斧'=>'fu','旉'=>'fu','服'=>'fu','枎'=>'fu','枹'=>'fu','柎'=>'fu','柫'=>'fu','栿'=>'fu','桴'=>'fu','棴'=>'fu','椨'=>'fu','椱'=>'fu','榑'=>'fu','氟'=>'fu','泭'=>'fu','洑'=>'fu','浮'=>'fu','涪'=>'fu','滏'=>'fu','澓'=>'fu','炥'=>'fu','烰'=>'fu','焤'=>'fu','父'=>'fu','猤'=>'fu','玞'=>'fu','玸'=>'fu','琈'=>'fu','甫'=>'fu','甶'=>'fu','畉'=>'fu','畐'=>'fu','畗'=>'fu','癁'=>'fu','盙'=>'fu','砆'=>'fu','砩'=>'fu','祓'=>'fu','祔'=>'fu','福'=>'fu','禣'=>'fu','秿'=>'fu','稃'=>'fu','稪'=>'fu','竎'=>'fu','符'=>'fu','笰'=>'fu','筟'=>'fu','箙'=>'fu','簠'=>'fu','粰'=>'fu','糐'=>'fu','紨'=>'fu','紱'=>'fu','紼'=>'fu','絥'=>'fu','綍'=>'fu','綒'=>'fu','緮'=>'fu','縛'=>'fu','绂'=>'fu','绋'=>'fu','缚'=>'fu','罘'=>'fu','罦'=>'fu','翇'=>'fu','肤'=>'fu','胕'=>'fu','脯'=>'fu','腐'=>'fu','腑'=>'fu','腹'=>'fu','膚'=>'fu','艀'=>'fu','艴'=>'fu','芙'=>'fu','芣'=>'fu','芾'=>'fu','苻'=>'fu','茀'=>'fu','茯'=>'fu','荂'=>'fu','荴'=>'fu','莩'=>'fu','菔'=>'fu','萯'=>'fu','葍'=>'fu','蕧'=>'fu','虙'=>'fu','蚥'=>'fu','蚨'=>'fu','蚹'=>'fu','蛗'=>'fu','蜅'=>'fu','蜉'=>'fu','蝜'=>'fu','蝠'=>'fu','蝮'=>'fu','衭'=>'fu','袝'=>'fu','袱'=>'fu','複'=>'fu','褔'=>'fu','襆'=>'fu','襥'=>'fu','覄'=>'fu','覆'=>'fu','訃'=>'fu','詂'=>'fu','諨'=>'fu','讣'=>'fu','豧'=>'fu','負'=>'fu','賦'=>'fu','賻'=>'fu','负'=>'fu','赋'=>'fu','赙'=>'fu','赴'=>'fu','趺'=>'fu','跗'=>'fu','踾'=>'fu','輔'=>'fu','輹'=>'fu','輻'=>'fu','辅'=>'fu','辐'=>'fu','邞'=>'fu','郙'=>'fu','郛'=>'fu','鄜'=>'fu','酜'=>'fu','釜'=>'fu','釡'=>'fu','鈇'=>'fu','鉘'=>'fu','鉜'=>'fu','鍑'=>'fu','鍢'=>'fu','阜'=>'fu','阝'=>'fu','附'=>'fu','陚'=>'fu','韍'=>'fu','韨'=>'fu','颫'=>'fu','馥'=>'fu','駙'=>'fu','驸'=>'fu','髴'=>'fu','鬴'=>'fu','鮄'=>'fu','鮒'=>'fu','鮲'=>'fu','鰒'=>'fu','鲋'=>'fu','鳆'=>'fu','鳧'=>'fu','鳬'=>'fu','鳺'=>'fu','鴔'=>'fu','鵩'=>'fu','鶝'=>'fu','麩'=>'fu','麬'=>'fu','麱'=>'fu','麸'=>'fu','黻'=>'fu','黼'=>'fu','㓡'=>'fu','㕮'=>'fu','㙏'=>'fu','㚆'=>'fu','㚕'=>'fu','㜑'=>'fu','㟊'=>'fu','㠅'=>'fu','㤔'=>'fu','㤱'=>'fu','㪄'=>'fu','㫙'=>'fu','㬼'=>'fu','㳇'=>'fu','㵗'=>'fu','㽬'=>'fu','㾈'=>'fu','䂤'=>'fu','䃽'=>'fu','䋨'=>'fu','䋹'=>'fu','䌗'=>'fu','䌿'=>'fu','䍖'=>'fu','䎅'=>'fu','䑧'=>'fu','䒀'=>'fu','䒇'=>'fu','䓛'=>'fu','䔰'=>'fu','䕎'=>'fu','䗄'=>'fu','䘀'=>'fu','䘄'=>'fu','䘠'=>'fu','䝾'=>'fu','䞜'=>'fu','䞞'=>'fu','䞯'=>'fu','䞸'=>'fu','䟔'=>'fu','䟮'=>'fu','䠵'=>'fu','䡍'=>'fu','䦣'=>'fu','䧞'=>'fu','䨗'=>'fu','䨱'=>'fu','䩉'=>'fu','䪙'=>'fu','䫍'=>'fu','䫝'=>'fu','䭸'=>'fu','䮛'=>'fu','䯱'=>'fu','䯽'=>'fu','䵗'=>'fu','䵾'=>'fu','乃'=>'nai','倷'=>'nai','奈'=>'nai','奶'=>'nai','妳'=>'nai','嬭'=>'nai','孻'=>'nai','廼'=>'nai','摨'=>'nai','柰'=>'nai','氖'=>'nai','渿'=>'nai','熋'=>'nai','疓'=>'nai','耐'=>'nai','腉'=>'nai','艿'=>'nai','萘'=>'nai','螚'=>'nai','褦'=>'nai','迺'=>'nai','釢'=>'nai','錼'=>'nai','鼐'=>'nai','㮈'=>'nai','㮏'=>'nai','㲡'=>'nai','㾍'=>'nai','䍲'=>'nai','䘅'=>'nai','䯮'=>'nai','乄'=>'wu','乌'=>'wu','五'=>'wu','仵'=>'wu','伆'=>'wu','伍'=>'wu','侮'=>'wu','俉'=>'wu','倵'=>'wu','儛'=>'wu','兀'=>'wu','剭'=>'wu','务'=>'wu','務'=>'wu','勿'=>'wu','午'=>'wu','吳'=>'wu','吴'=>'wu','吾'=>'wu','呉'=>'wu','呜'=>'wu','唔'=>'wu','啎'=>'wu','嗚'=>'wu','圬'=>'wu','坞'=>'wu','塢'=>'wu','奦'=>'wu','妩'=>'wu','娪'=>'wu','娬'=>'wu','婺'=>'wu','嫵'=>'wu','寤'=>'wu','屋'=>'wu','屼'=>'wu','岉'=>'wu','嵍'=>'wu','嵨'=>'wu','巫'=>'wu','庑'=>'wu','廡'=>'wu','弙'=>'wu','忢'=>'wu','忤'=>'wu','怃'=>'wu','悞'=>'wu','悟'=>'wu','悮'=>'wu','憮'=>'wu','戊'=>'wu','扤'=>'wu','捂'=>'wu','摀'=>'wu','敄'=>'wu','无'=>'wu','旿'=>'wu','晤'=>'wu','杇'=>'wu','杌'=>'wu','梧'=>'wu','橆'=>'wu','歍'=>'wu','武'=>'wu','毋'=>'wu','汙'=>'wu','汚'=>'wu','污'=>'wu','洖'=>'wu','洿'=>'wu','浯'=>'wu','溩'=>'wu','潕'=>'wu','烏'=>'wu','焐'=>'wu','焑'=>'wu','無'=>'wu','熃'=>'wu','熓'=>'wu','物'=>'wu','牾'=>'wu','玝'=>'wu','珷'=>'wu','珸'=>'wu','瑦'=>'wu','璑'=>'wu','甒'=>'wu','痦'=>'wu','矹'=>'wu','碔'=>'wu','祦'=>'wu','禑'=>'wu','窏'=>'wu','窹'=>'wu','箼'=>'wu','粅'=>'wu','舞'=>'wu','芜'=>'wu','芴'=>'wu','茣'=>'wu','莁'=>'wu','蕪'=>'wu','蘁'=>'wu','蜈'=>'wu','螐'=>'wu','誈'=>'wu','誣'=>'wu','誤'=>'wu','诬'=>'wu','误'=>'wu','趶'=>'wu','躌'=>'wu','迕'=>'wu','逜'=>'wu','邬'=>'wu','郚'=>'wu','鄔'=>'wu','釫'=>'wu','鋈'=>'wu','錻'=>'wu','鎢'=>'wu','钨'=>'wu','阢'=>'wu','隖'=>'wu','雾'=>'wu','霚'=>'wu','霧'=>'wu','靰'=>'wu','騖'=>'wu','骛'=>'wu','鯃'=>'wu','鰞'=>'wu','鴮'=>'wu','鵐'=>'wu','鵡'=>'wu','鶩'=>'wu','鷡'=>'wu','鹀'=>'wu','鹉'=>'wu','鹜'=>'wu','鼯'=>'wu','鼿'=>'wu','齀'=>'wu','㐅'=>'wu','㐳'=>'wu','㑄'=>'wu','㡔'=>'wu','㬳'=>'wu','㵲'=>'wu','㷻'=>'wu','㹳'=>'wu','㻍'=>'wu','㽾'=>'wu','䃖'=>'wu','䍢'=>'wu','䎸'=>'wu','䑁'=>'wu','䒉'=>'wu','䛩'=>'wu','䟼'=>'wu','䡧'=>'wu','䦍'=>'wu','䦜'=>'wu','䫓'=>'wu','䮏'=>'wu','䳇'=>'wu','䳱'=>'wu','乇'=>'tuo','佗'=>'tuo','侂'=>'tuo','侻'=>'tuo','咃'=>'tuo','唾'=>'tuo','坨'=>'tuo','堶'=>'tuo','妥'=>'tuo','媠'=>'tuo','嫷'=>'tuo','岮'=>'tuo','庹'=>'tuo','彵'=>'tuo','托'=>'tuo','扡'=>'tuo','拓'=>'tuo','拕'=>'tuo','拖'=>'tuo','挩'=>'tuo','捝'=>'tuo','撱'=>'tuo','杔'=>'tuo','柁'=>'tuo','柝'=>'tuo','椭'=>'tuo','楕'=>'tuo','槖'=>'tuo','橐'=>'tuo','橢'=>'tuo','毤'=>'tuo','毻'=>'tuo','汑'=>'tuo','沰'=>'tuo','沱'=>'tuo','涶'=>'tuo','狏'=>'tuo','砣'=>'tuo','砤'=>'tuo','碢'=>'tuo','箨'=>'tuo','籜'=>'tuo','紽'=>'tuo','脫'=>'tuo','脱'=>'tuo','莌'=>'tuo','萚'=>'tuo','蘀'=>'tuo','袉'=>'tuo','袥'=>'tuo','託'=>'tuo','詑'=>'tuo','讬'=>'tuo','跅'=>'tuo','跎'=>'tuo','踻'=>'tuo','迱'=>'tuo','酡'=>'tuo','陀'=>'tuo','陁'=>'tuo','飥'=>'tuo','饦'=>'tuo','馱'=>'tuo','馲'=>'tuo','駄'=>'tuo','駝'=>'tuo','駞'=>'tuo','騨'=>'tuo','驒'=>'tuo','驝'=>'tuo','驮'=>'tuo','驼'=>'tuo','魠'=>'tuo','鮀'=>'tuo','鰖'=>'tuo','鴕'=>'tuo','鵎'=>'tuo','鸵'=>'tuo','鼉'=>'tuo','鼍'=>'tuo','鼧'=>'tuo','㟎'=>'tuo','㸰'=>'tuo','㸱'=>'tuo','㼠'=>'tuo','㾃'=>'tuo','䍫'=>'tuo','䓕'=>'tuo','䡐'=>'tuo','䪑'=>'tuo','䭾'=>'tuo','䰿'=>'tuo','䲊'=>'tuo','䴱'=>'tuo','么'=>'me','嚒'=>'me','嚰'=>'me','庅'=>'me','濹'=>'me','癦'=>'me','乊'=>'ho','乥'=>'ho','之'=>'zhi','乿'=>'zhi','侄'=>'zhi','俧'=>'zhi','倁'=>'zhi','値'=>'zhi','值'=>'zhi','偫'=>'zhi','傂'=>'zhi','儨'=>'zhi','凪'=>'zhi','制'=>'zhi','劕'=>'zhi','劧'=>'zhi','卮'=>'zhi','厔'=>'zhi','只'=>'zhi','吱'=>'zhi','咫'=>'zhi','址'=>'zhi','坁'=>'zhi','坧'=>'zhi','垁'=>'zhi','埴'=>'zhi','執'=>'zhi','墆'=>'zhi','墌'=>'zhi','夂'=>'zhi','姪'=>'zhi','娡'=>'zhi','嬂'=>'zhi','寘'=>'zhi','峙'=>'zhi','崻'=>'zhi','巵'=>'zhi','帋'=>'zhi','帙'=>'zhi','帜'=>'zhi','幟'=>'zhi','庢'=>'zhi','庤'=>'zhi','廌'=>'zhi','彘'=>'zhi','徏'=>'zhi','徔'=>'zhi','徝'=>'zhi','志'=>'zhi','忮'=>'zhi','恉'=>'zhi','慹'=>'zhi','憄'=>'zhi','懥'=>'zhi','懫'=>'zhi','戠'=>'zhi','执'=>'zhi','扺'=>'zhi','扻'=>'zhi','抧'=>'zhi','挃'=>'zhi','指'=>'zhi','挚'=>'zhi','掷'=>'zhi','搘'=>'zhi','搱'=>'zhi','摭'=>'zhi','摯'=>'zhi','擲'=>'zhi','擿'=>'zhi','支'=>'zhi','旘'=>'zhi','旨'=>'zhi','晊'=>'zhi','智'=>'zhi','枝'=>'zhi','枳'=>'zhi','柣'=>'zhi','栀'=>'zhi','栉'=>'zhi','桎'=>'zhi','梔'=>'zhi','梽'=>'zhi','植'=>'zhi','椥'=>'zhi','榰'=>'zhi','槜'=>'zhi','樴'=>'zhi','櫍'=>'zhi','櫛'=>'zhi','止'=>'zhi','殖'=>'zhi','汁'=>'zhi','汥'=>'zhi','汦'=>'zhi','沚'=>'zhi','治'=>'zhi','洔'=>'zhi','洷'=>'zhi','淽'=>'zhi','滍'=>'zhi','滞'=>'zhi','滯'=>'zhi','漐'=>'zhi','潌'=>'zhi','潪'=>'zhi','瀄'=>'zhi','炙'=>'zhi','熫'=>'zhi','狾'=>'zhi','猘'=>'zhi','瓆'=>'zhi','瓡'=>'zhi','畤'=>'zhi','疐'=>'zhi','疷'=>'zhi','疻'=>'zhi','痔'=>'zhi','痣'=>'zhi','瘈'=>'zhi','直'=>'zhi','知'=>'zhi','砋'=>'zhi','礩'=>'zhi','祉'=>'zhi','祑'=>'zhi','祗'=>'zhi','祬'=>'zhi','禃'=>'zhi','禔'=>'zhi','禵'=>'zhi','秓'=>'zhi','秖'=>'zhi','秩'=>'zhi','秪'=>'zhi','秲'=>'zhi','秷'=>'zhi','稙'=>'zhi','稚'=>'zhi','稺'=>'zhi','穉'=>'zhi','窒'=>'zhi','筫'=>'zhi','紙'=>'zhi','紩'=>'zhi','絷'=>'zhi','綕'=>'zhi','緻'=>'zhi','縶'=>'zhi','織'=>'zhi','纸'=>'zhi','织'=>'zhi','置'=>'zhi','翐'=>'zhi','聀'=>'zhi','聁'=>'zhi','职'=>'zhi','職'=>'zhi','肢'=>'zhi','胑'=>'zhi','胝'=>'zhi','脂'=>'zhi','膣'=>'zhi','膱'=>'zhi','至'=>'zhi','致'=>'zhi','臸'=>'zhi','芖'=>'zhi','芝'=>'zhi','芷'=>'zhi','茋'=>'zhi','藢'=>'zhi','蘵'=>'zhi','蛭'=>'zhi','蜘'=>'zhi','螲'=>'zhi','蟙'=>'zhi','衹'=>'zhi','衼'=>'zhi','袟'=>'zhi','袠'=>'zhi','製'=>'zhi','襧'=>'zhi','覟'=>'zhi','觗'=>'zhi','觯'=>'zhi','觶'=>'zhi','訨'=>'zhi','誌'=>'zhi','謢'=>'zhi','豑'=>'zhi','豒'=>'zhi','豸'=>'zhi','貭'=>'zhi','質'=>'zhi','贄'=>'zhi','质'=>'zhi','贽'=>'zhi','趾'=>'zhi','跖'=>'zhi','跱'=>'zhi','踬'=>'zhi','踯'=>'zhi','蹠'=>'zhi','蹢'=>'zhi','躑'=>'zhi','躓'=>'zhi','軄'=>'zhi','軹'=>'zhi','輊'=>'zhi','轵'=>'zhi','轾'=>'zhi','郅'=>'zhi','酯'=>'zhi','釞'=>'zhi','銍'=>'zhi','鋕'=>'zhi','鑕'=>'zhi','铚'=>'zhi','锧'=>'zhi','阤'=>'zhi','阯'=>'zhi','陟'=>'zhi','隲'=>'zhi','隻'=>'zhi','雉'=>'zhi','馶'=>'zhi','馽'=>'zhi','駤'=>'zhi','騭'=>'zhi','騺'=>'zhi','驇'=>'zhi','骘'=>'zhi','鯯'=>'zhi','鳷'=>'zhi','鴙'=>'zhi','鴲'=>'zhi','鷙'=>'zhi','鸷'=>'zhi','黹'=>'zhi','鼅'=>'zhi','㕄'=>'zhi','㗌'=>'zhi','㗧'=>'zhi','㘉'=>'zhi','㙷'=>'zhi','㛿'=>'zhi','㜼'=>'zhi','㝂'=>'zhi','㣥'=>'zhi','㧻'=>'zhi','㨁'=>'zhi','㨖'=>'zhi','㮹'=>'zhi','㲛'=>'zhi','㴛'=>'zhi','䄺'=>'zhi','䅩'=>'zhi','䆈'=>'zhi','䇛'=>'zhi','䇽'=>'zhi','䉅'=>'zhi','䉜'=>'zhi','䌤'=>'zhi','䎺'=>'zhi','䏄'=>'zhi','䏯'=>'zhi','䐈'=>'zhi','䐭'=>'zhi','䑇'=>'zhi','䓌'=>'zhi','䕌'=>'zhi','䚦'=>'zhi','䛗'=>'zhi','䝷'=>'zhi','䞃'=>'zhi','䟈'=>'zhi','䡹'=>'zhi','䥍'=>'zhi','䦯'=>'zhi','䫕'=>'zhi','䬹'=>'zhi','䭁'=>'zhi','䱥'=>'zhi','䱨'=>'zhi','䳅'=>'zhi','䵂'=>'zhi','乍'=>'zha','偧'=>'zha','劄'=>'zha','厏'=>'zha','吒'=>'zha','咋'=>'zha','咤'=>'zha','哳'=>'zha','喳'=>'zha','奓'=>'zha','宱'=>'zha','扎'=>'zha','抯'=>'zha','挓'=>'zha','揸'=>'zha','搩'=>'zha','搾'=>'zha','摣'=>'zha','札'=>'zha','柤'=>'zha','柵'=>'zha','栅'=>'zha','楂'=>'zha','榨'=>'zha','樝'=>'zha','渣'=>'zha','溠'=>'zha','灹'=>'zha','炸'=>'zha','煠'=>'zha','牐'=>'zha','甴'=>'zha','痄'=>'zha','皶'=>'zha','皻'=>'zha','皼'=>'zha','眨'=>'zha','砟'=>'zha','箚'=>'zha','膪'=>'zha','苲'=>'zha','蚱'=>'zha','蚻'=>'zha','觰'=>'zha','詐'=>'zha','譇'=>'zha','譗'=>'zha','诈'=>'zha','踷'=>'zha','軋'=>'zha','轧'=>'zha','迊'=>'zha','醡'=>'zha','鍘'=>'zha','铡'=>'zha','閘'=>'zha','闸'=>'zha','霅'=>'zha','鮓'=>'zha','鮺'=>'zha','鲊'=>'zha','鲝'=>'zha','齄'=>'zha','齇'=>'zha','㒀'=>'zha','㡸'=>'zha','㱜'=>'zha','㴙'=>'zha','㷢'=>'zha','䋾'=>'zha','䕢'=>'zha','䖳'=>'zha','䛽'=>'zha','䞢'=>'zha','䥷'=>'zha','䵙'=>'zha','䵵'=>'zha','乎'=>'hu','乕'=>'hu','互'=>'hu','冱'=>'hu','冴'=>'hu','匢'=>'hu','匫'=>'hu','呼'=>'hu','唬'=>'hu','唿'=>'hu','喖'=>'hu','嘑'=>'hu','嘝'=>'hu','嚛'=>'hu','囫'=>'hu','垀'=>'hu','壶'=>'hu','壷'=>'hu','壺'=>'hu','婟'=>'hu','媩'=>'hu','嫭'=>'hu','嫮'=>'hu','寣'=>'hu','岵'=>'hu','帍'=>'hu','幠'=>'hu','弖'=>'hu','弧'=>'hu','忽'=>'hu','怙'=>'hu','恗'=>'hu','惚'=>'hu','戶'=>'hu','户'=>'hu','戸'=>'hu','戽'=>'hu','扈'=>'hu','抇'=>'hu','护'=>'hu','搰'=>'hu','摢'=>'hu','斛'=>'hu','昈'=>'hu','昒'=>'hu','曶'=>'hu','枑'=>'hu','楜'=>'hu','槲'=>'hu','槴'=>'hu','歑'=>'hu','汻'=>'hu','沍'=>'hu','沪'=>'hu','泘'=>'hu','浒'=>'hu','淴'=>'hu','湖'=>'hu','滬'=>'hu','滸'=>'hu','滹'=>'hu','瀫'=>'hu','烀'=>'hu','焀'=>'hu','煳'=>'hu','熩'=>'hu','狐'=>'hu','猢'=>'hu','琥'=>'hu','瑚'=>'hu','瓠'=>'hu','瓳'=>'hu','祜'=>'hu','笏'=>'hu','箎'=>'hu','箶'=>'hu','簄'=>'hu','粐'=>'hu','糊'=>'hu','絗'=>'hu','綔'=>'hu','縠'=>'hu','胡'=>'hu','膴'=>'hu','芐'=>'hu','苸'=>'hu','萀'=>'hu','葫'=>'hu','蔛'=>'hu','蔰'=>'hu','虍'=>'hu','虎'=>'hu','虖'=>'hu','虝'=>'hu','蝴'=>'hu','螜'=>'hu','衚'=>'hu','觳'=>'hu','謼'=>'hu','護'=>'hu','軤'=>'hu','轷'=>'hu','鄠'=>'hu','醐'=>'hu','錿'=>'hu','鍙'=>'hu','鍸'=>'hu','雐'=>'hu','雽'=>'hu','韄'=>'hu','頀'=>'hu','頶'=>'hu','餬'=>'hu','鬍'=>'hu','魱'=>'hu','鯱'=>'hu','鰗'=>'hu','鱯'=>'hu','鳠'=>'hu','鳸'=>'hu','鶘'=>'hu','鶦'=>'hu','鶮'=>'hu','鸌'=>'hu','鹕'=>'hu','鹱'=>'hu','㕆'=>'hu','㗅'=>'hu','㦿'=>'hu','㨭'=>'hu','㪶'=>'hu','㫚'=>'hu','㯛'=>'hu','㸦'=>'hu','㹱'=>'hu','㺉'=>'hu','㾰'=>'hu','㿥'=>'hu','䁫'=>'hu','䇘'=>'hu','䈸'=>'hu','䉉'=>'hu','䉿'=>'hu','䊀'=>'hu','䍓'=>'hu','䎁'=>'hu','䔯'=>'hu','䕶'=>'hu','䗂'=>'hu','䚛'=>'hu','䛎'=>'hu','䞱'=>'hu','䠒'=>'hu','䧼'=>'hu','䨥'=>'hu','䨼'=>'hu','䩴'=>'hu','䪝'=>'hu','䭅'=>'hu','䭌'=>'hu','䭍'=>'hu','䮸'=>'hu','䲵'=>'hu','乏'=>'fa','伐'=>'fa','佱'=>'fa','傠'=>'fa','发'=>'fa','垡'=>'fa','姂'=>'fa','彂'=>'fa','栰'=>'fa','橃'=>'fa','沷'=>'fa','法'=>'fa','灋'=>'fa','珐'=>'fa','琺'=>'fa','疺'=>'fa','発'=>'fa','發'=>'fa','瞂'=>'fa','砝'=>'fa','筏'=>'fa','罚'=>'fa','罰'=>'fa','罸'=>'fa','茷'=>'fa','藅'=>'fa','醗'=>'fa','鍅'=>'fa','閥'=>'fa','阀'=>'fa','髪'=>'fa','髮'=>'fa','㕹'=>'fa','㘺'=>'fa','㛲'=>'fa','䂲'=>'fa','䇅'=>'fa','䒥'=>'fa','䣹'=>'fa','乐'=>'le','仂'=>'le','勒'=>'le','叻'=>'le','忇'=>'le','扐'=>'le','楽'=>'le','樂'=>'le','氻'=>'le','泐'=>'le','玏'=>'le','砳'=>'le','竻'=>'le','簕'=>'le','艻'=>'le','阞'=>'le','韷'=>'le','餎'=>'le','饹'=>'le','鰳'=>'le','鳓'=>'le','㔹'=>'le','㖀'=>'le','㦡'=>'le','乑'=>'yin','乚'=>'yin','侌'=>'yin','冘'=>'yin','凐'=>'yin','印'=>'yin','吟'=>'yin','吲'=>'yin','唫'=>'yin','喑'=>'yin','噖'=>'yin','噾'=>'yin','嚚'=>'yin','囙'=>'yin','因'=>'yin','圁'=>'yin','垔'=>'yin','垠'=>'yin','垽'=>'yin','堙'=>'yin','夤'=>'yin','姻'=>'yin','婣'=>'yin','婬'=>'yin','寅'=>'yin','尹'=>'yin','峾'=>'yin','崟'=>'yin','崯'=>'yin','嶾'=>'yin','廕'=>'yin','廴'=>'yin','引'=>'yin','愔'=>'yin','慇'=>'yin','慭'=>'yin','憖'=>'yin','憗'=>'yin','懚'=>'yin','斦'=>'yin','朄'=>'yin','栶'=>'yin','檃'=>'yin','檭'=>'yin','檼'=>'yin','櫽'=>'yin','歅'=>'yin','殥'=>'yin','殷'=>'yin','氤'=>'yin','泿'=>'yin','洇'=>'yin','洕'=>'yin','淫'=>'yin','淾'=>'yin','湚'=>'yin','溵'=>'yin','滛'=>'yin','濥'=>'yin','濦'=>'yin','烎'=>'yin','犾'=>'yin','狺'=>'yin','猌'=>'yin','珢'=>'yin','璌'=>'yin','瘖'=>'yin','瘾'=>'yin','癊'=>'yin','癮'=>'yin','碒'=>'yin','磤'=>'yin','禋'=>'yin','秵'=>'yin','筃'=>'yin','粌'=>'yin','絪'=>'yin','緸'=>'yin','胤'=>'yin','苂'=>'yin','茚'=>'yin','茵'=>'yin','荫'=>'yin','荶'=>'yin','蒑'=>'yin','蔩'=>'yin','蔭'=>'yin','蘟'=>'yin','蚓'=>'yin','螾'=>'yin','蟫'=>'yin','裀'=>'yin','訔'=>'yin','訚'=>'yin','訡'=>'yin','誾'=>'yin','諲'=>'yin','讔'=>'yin','趛'=>'yin','鄞'=>'yin','酳'=>'yin','釿'=>'yin','鈏'=>'yin','鈝'=>'yin','銀'=>'yin','銦'=>'yin','铟'=>'yin','银'=>'yin','闉'=>'yin','阥'=>'yin','阴'=>'yin','陰'=>'yin','陻'=>'yin','隂'=>'yin','隐'=>'yin','隠'=>'yin','隱'=>'yin','霒'=>'yin','霠'=>'yin','霪'=>'yin','靷'=>'yin','鞇'=>'yin','音'=>'yin','韾'=>'yin','飮'=>'yin','飲'=>'yin','饮'=>'yin','駰'=>'yin','骃'=>'yin','鮣'=>'yin','鷣'=>'yin','齗'=>'yin','齦'=>'yin','龂'=>'yin','龈'=>'yin','㐆'=>'yin','㕂'=>'yin','㖗'=>'yin','㙬'=>'yin','㝙'=>'yin','㞤'=>'yin','㡥'=>'yin','㣧'=>'yin','㥯'=>'yin','㥼'=>'yin','㦩'=>'yin','㧈'=>'yin','㪦'=>'yin','㱃'=>'yin','㴈'=>'yin','㸒'=>'yin','㹜'=>'yin','㹞'=>'yin','㼉'=>'yin','㾙'=>'yin','䇙'=>'yin','䌥'=>'yin','䒡'=>'yin','䓄'=>'yin','䕃'=>'yin','䖜'=>'yin','䚿'=>'yin','䡛'=>'yin','䤃'=>'yin','䤺'=>'yin','䨸'=>'yin','䪩'=>'yin','䲟'=>'yin','乒'=>'ping','俜'=>'ping','凭'=>'ping','凴'=>'ping','呯'=>'ping','坪'=>'ping','塀'=>'ping','娦'=>'ping','屏'=>'ping','屛'=>'ping','岼'=>'ping','帡'=>'ping','帲'=>'ping','幈'=>'ping','平'=>'ping','慿'=>'ping','憑'=>'ping','枰'=>'ping','檘'=>'ping','洴'=>'ping','涄'=>'ping','淜'=>'ping','焩'=>'ping','玶'=>'ping','瓶'=>'ping','甁'=>'ping','甹'=>'ping','砯'=>'ping','竮'=>'ping','箳'=>'ping','簈'=>'ping','缾'=>'ping','聠'=>'ping','艵'=>'ping','苹'=>'ping','荓'=>'ping','萍'=>'ping','蓱'=>'ping','蘋'=>'ping','蚲'=>'ping','蛢'=>'ping','評'=>'ping','评'=>'ping','軿'=>'ping','輧'=>'ping','郱'=>'ping','頩'=>'ping','鮃'=>'ping','鲆'=>'ping','㺸'=>'ping','㻂'=>'ping','䍈'=>'ping','䶄'=>'ping','乓'=>'pang','厐'=>'pang','嗙'=>'pang','嫎'=>'pang','庞'=>'pang','旁'=>'pang','汸'=>'pang','沗'=>'pang','滂'=>'pang','炐'=>'pang','篣'=>'pang','耪'=>'pang','肨'=>'pang','胖'=>'pang','胮'=>'pang','膖'=>'pang','舽'=>'pang','螃'=>'pang','蠭'=>'pang','覫'=>'pang','逄'=>'pang','雱'=>'pang','霶'=>'pang','髈'=>'pang','鰟'=>'pang','鳑'=>'pang','龎'=>'pang','龐'=>'pang','㜊'=>'pang','㤶'=>'pang','㥬'=>'pang','㫄'=>'pang','䅭'=>'pang','䒍'=>'pang','䨦'=>'pang','䮾'=>'pang','乔'=>'qiao','侨'=>'qiao','俏'=>'qiao','僑'=>'qiao','僺'=>'qiao','劁'=>'qiao','喬'=>'qiao','嘺'=>'qiao','墝'=>'qiao','墽'=>'qiao','嫶'=>'qiao','峭'=>'qiao','嵪'=>'qiao','巧'=>'qiao','帩'=>'qiao','幧'=>'qiao','悄'=>'qiao','愀'=>'qiao','憔'=>'qiao','撬'=>'qiao','撽'=>'qiao','敲'=>'qiao','桥'=>'qiao','槗'=>'qiao','樵'=>'qiao','橇'=>'qiao','橋'=>'qiao','殼'=>'qiao','燆'=>'qiao','犞'=>'qiao','癄'=>'qiao','睄'=>'qiao','瞧'=>'qiao','硗'=>'qiao','硚'=>'qiao','碻'=>'qiao','磽'=>'qiao','礄'=>'qiao','窍'=>'qiao','竅'=>'qiao','繑'=>'qiao','繰'=>'qiao','缲'=>'qiao','翘'=>'qiao','翹'=>'qiao','荍'=>'qiao','荞'=>'qiao','菬'=>'qiao','蕎'=>'qiao','藮'=>'qiao','誚'=>'qiao','譙'=>'qiao','诮'=>'qiao','谯'=>'qiao','趫'=>'qiao','趬'=>'qiao','跷'=>'qiao','踍'=>'qiao','蹺'=>'qiao','蹻'=>'qiao','躈'=>'qiao','郻'=>'qiao','鄗'=>'qiao','鄡'=>'qiao','鄥'=>'qiao','釥'=>'qiao','鍫'=>'qiao','鍬'=>'qiao','鐈'=>'qiao','鐰'=>'qiao','锹'=>'qiao','陗'=>'qiao','鞒'=>'qiao','鞘'=>'qiao','鞩'=>'qiao','鞽'=>'qiao','韒'=>'qiao','頝'=>'qiao','顦'=>'qiao','骹'=>'qiao','髚'=>'qiao','髜'=>'qiao','㚁'=>'qiao','㚽'=>'qiao','㝯'=>'qiao','㡑'=>'qiao','㢗'=>'qiao','㤍'=>'qiao','㪣'=>'qiao','㴥'=>'qiao','䀉'=>'qiao','䃝'=>'qiao','䆻'=>'qiao','䇌'=>'qiao','䎗'=>'qiao','䩌'=>'qiao','䱁'=>'qiao','䲾'=>'qiao','乖'=>'guai','叏'=>'guai','夬'=>'guai','怪'=>'guai','恠'=>'guai','拐'=>'guai','枴'=>'guai','柺'=>'guai','箉'=>'guai','㧔'=>'guai','㷇'=>'guai','㽇'=>'guai','䂯'=>'guai','䊽'=>'guai','乜'=>'mie','吀'=>'mie','咩'=>'mie','哶'=>'mie','孭'=>'mie','幭'=>'mie','懱'=>'mie','搣'=>'mie','櫗'=>'mie','滅'=>'mie','瀎'=>'mie','灭'=>'mie','瓱'=>'mie','篾'=>'mie','蔑'=>'mie','薎'=>'mie','蠛'=>'mie','衊'=>'mie','覕'=>'mie','鑖'=>'mie','鱴'=>'mie','鴓'=>'mie','㒝'=>'mie','䁾'=>'mie','䈼'=>'mie','䘊'=>'mie','䩏'=>'mie','习'=>'xi','係'=>'xi','俙'=>'xi','傒'=>'xi','僖'=>'xi','兮'=>'xi','凞'=>'xi','匸'=>'xi','卌'=>'xi','卥'=>'xi','厀'=>'xi','吸'=>'xi','呬'=>'xi','咥'=>'xi','唏'=>'xi','唽'=>'xi','喜'=>'xi','嘻'=>'xi','噏'=>'xi','嚱'=>'xi','塈'=>'xi','壐'=>'xi','夕'=>'xi','奚'=>'xi','娭'=>'xi','媳'=>'xi','嬆'=>'xi','嬉'=>'xi','屃'=>'xi','屖'=>'xi','屗'=>'xi','屣'=>'xi','嵠'=>'xi','嶍'=>'xi','巇'=>'xi','希'=>'xi','席'=>'xi','徆'=>'xi','徙'=>'xi','徚'=>'xi','徯'=>'xi','忚'=>'xi','忥'=>'xi','怬'=>'xi','怸'=>'xi','恄'=>'xi','息'=>'xi','悉'=>'xi','悕'=>'xi','惁'=>'xi','惜'=>'xi','慀'=>'xi','憘'=>'xi','憙'=>'xi','戏'=>'xi','戯'=>'xi','戱'=>'xi','戲'=>'xi','扸'=>'xi','昔'=>'xi','晞'=>'xi','晰'=>'xi','晳'=>'xi','暿'=>'xi','曦'=>'xi','杫'=>'xi','析'=>'xi','枲'=>'xi','桸'=>'xi','椞'=>'xi','椺'=>'xi','榽'=>'xi','槢'=>'xi','樨'=>'xi','橀'=>'xi','橲'=>'xi','檄'=>'xi','欯'=>'xi','欷'=>'xi','歖'=>'xi','歙'=>'xi','歚'=>'xi','氥'=>'xi','汐'=>'xi','洗'=>'xi','浠'=>'xi','淅'=>'xi','渓'=>'xi','溪'=>'xi','滊'=>'xi','漇'=>'xi','漝'=>'xi','潝'=>'xi','潟'=>'xi','澙'=>'xi','烯'=>'xi','焁'=>'xi','焈'=>'xi','焟'=>'xi','焬'=>'xi','煕'=>'xi','熂'=>'xi','熄'=>'xi','熈'=>'xi','熙'=>'xi','熹'=>'xi','熺'=>'xi','熻'=>'xi','燨'=>'xi','爔'=>'xi','牺'=>'xi','犀'=>'xi','犔'=>'xi','犠'=>'xi','犧'=>'xi','狶'=>'xi','玺'=>'xi','琋'=>'xi','璽'=>'xi','瘜'=>'xi','皙'=>'xi','盻'=>'xi','睎'=>'xi','瞦'=>'xi','矖'=>'xi','矽'=>'xi','硒'=>'xi','磶'=>'xi','礂'=>'xi','禊'=>'xi','禧'=>'xi','稀'=>'xi','稧'=>'xi','穸'=>'xi','窸'=>'xi','粞'=>'xi','系'=>'xi','細'=>'xi','綌'=>'xi','緆'=>'xi','縰'=>'xi','繥'=>'xi','纚'=>'xi','细'=>'xi','绤'=>'xi','羲'=>'xi','習'=>'xi','翕'=>'xi','翖'=>'xi','肸'=>'xi','肹'=>'xi','膝'=>'xi','舄'=>'xi','舾'=>'xi','莃'=>'xi','菥'=>'xi','葈'=>'xi','葸'=>'xi','蒠'=>'xi','蒵'=>'xi','蓆'=>'xi','蓰'=>'xi','蕮'=>'xi','薂'=>'xi','虩'=>'xi','蜥'=>'xi','蝷'=>'xi','螅'=>'xi','螇'=>'xi','蟋'=>'xi','蟢'=>'xi','蠵'=>'xi','衋'=>'xi','袭'=>'xi','襲'=>'xi','西'=>'xi','覀'=>'xi','覡'=>'xi','覤'=>'xi','觋'=>'xi','觹'=>'xi','觽'=>'xi','觿'=>'xi','誒'=>'xi','諰'=>'xi','謑'=>'xi','謵'=>'xi','譆'=>'xi','诶'=>'xi','谿'=>'xi','豀'=>'xi','豨'=>'xi','豯'=>'xi','貕'=>'xi','赥'=>'xi','赩'=>'xi','趇'=>'xi','趘'=>'xi','蹝'=>'xi','躧'=>'xi','郄'=>'xi','郋'=>'xi','郗'=>'xi','郤'=>'xi','鄎'=>'xi','酅'=>'xi','醯'=>'xi','釳'=>'xi','釸'=>'xi','鈢'=>'xi','銑'=>'xi','錫'=>'xi','鎴'=>'xi','鏭'=>'xi','鑴'=>'xi','铣'=>'xi','锡'=>'xi','闟'=>'xi','阋'=>'xi','隙'=>'xi','隟'=>'xi','隰'=>'xi','隵'=>'xi','雟'=>'xi','霫'=>'xi','霼'=>'xi','飁'=>'xi','餏'=>'xi','餙'=>'xi','餼'=>'xi','饩'=>'xi','饻'=>'xi','騱'=>'xi','騽'=>'xi','驨'=>'xi','鬩'=>'xi','鯑'=>'xi','鰼'=>'xi','鱚'=>'xi','鳛'=>'xi','鵗'=>'xi','鸂'=>'xi','黖'=>'xi','鼷'=>'xi','㑶'=>'xi','㔒'=>'xi','㗩'=>'xi','㙾'=>'xi','㚛'=>'xi','㞒'=>'xi','㠄'=>'xi','㣟'=>'xi','㤴'=>'xi','㤸'=>'xi','㥡'=>'xi','㦻'=>'xi','㩗'=>'xi','㭡'=>'xi','㳧'=>'xi','㵿'=>'xi','㸍'=>'xi','㹫'=>'xi','㽯'=>'xi','㿇'=>'xi','䀘'=>'xi','䂀'=>'xi','䈪'=>'xi','䊠'=>'xi','䏮'=>'xi','䐼'=>'xi','䓇'=>'xi','䙽'=>'xi','䚷'=>'xi','䛥'=>'xi','䜁'=>'xi','䢄'=>'xi','䧍'=>'xi','䨳'=>'xi','䩤'=>'xi','䫣'=>'xi','䮎'=>'xi','䲪'=>'xi','乡'=>'xiang','享'=>'xiang','亯'=>'xiang','佭'=>'xiang','像'=>'xiang','勨'=>'xiang','厢'=>'xiang','向'=>'xiang','响'=>'xiang','啌'=>'xiang','嚮'=>'xiang','姠'=>'xiang','嶑'=>'xiang','巷'=>'xiang','庠'=>'xiang','廂'=>'xiang','忀'=>'xiang','想'=>'xiang','晑'=>'xiang','曏'=>'xiang','栙'=>'xiang','楿'=>'xiang','橡'=>'xiang','欀'=>'xiang','湘'=>'xiang','珦'=>'xiang','瓖'=>'xiang','瓨'=>'xiang','相'=>'xiang','祥'=>'xiang','箱'=>'xiang','絴'=>'xiang','緗'=>'xiang','缃'=>'xiang','缿'=>'xiang','翔'=>'xiang','膷'=>'xiang','芗'=>'xiang','萫'=>'xiang','葙'=>'xiang','薌'=>'xiang','蚃'=>'xiang','蟓'=>'xiang','蠁'=>'xiang','襄'=>'xiang','襐'=>'xiang','詳'=>'xiang','详'=>'xiang','象'=>'xiang','跭'=>'xiang','郷'=>'xiang','鄉'=>'xiang','鄊'=>'xiang','鄕'=>'xiang','銄'=>'xiang','鐌'=>'xiang','鑲'=>'xiang','镶'=>'xiang','響'=>'xiang','項'=>'xiang','项'=>'xiang','飨'=>'xiang','餉'=>'xiang','饗'=>'xiang','饟'=>'xiang','饷'=>'xiang','香'=>'xiang','驤'=>'xiang','骧'=>'xiang','鮝'=>'xiang','鯗'=>'xiang','鱌'=>'xiang','鱜'=>'xiang','鱶'=>'xiang','鲞'=>'xiang','麘'=>'xiang','㐮'=>'xiang','㗽'=>'xiang','㟄'=>'xiang','㟟'=>'xiang','䊑'=>'xiang','䐟'=>'xiang','䔗'=>'xiang','䖮'=>'xiang','䜶'=>'xiang','䢽'=>'xiang','乤'=>'hai','亥'=>'hai','咍'=>'hai','嗐'=>'hai','嗨'=>'hai','嚡'=>'hai','塰'=>'hai','孩'=>'hai','害'=>'hai','氦'=>'hai','海'=>'hai','烸'=>'hai','胲'=>'hai','酼'=>'hai','醢'=>'hai','餀'=>'hai','饚'=>'hai','駭'=>'hai','駴'=>'hai','骇'=>'hai','骸'=>'hai','㜾'=>'hai','㤥'=>'hai','㦟'=>'hai','㧡'=>'hai','㨟'=>'hai','㺔'=>'hai','䇋'=>'hai','䠽'=>'hai','䯐'=>'hai','䱺'=>'hai','书'=>'shu','侸'=>'shu','倏'=>'shu','倐'=>'shu','儵'=>'shu','叔'=>'shu','咰'=>'shu','塾'=>'shu','墅'=>'shu','姝'=>'shu','婌'=>'shu','孰'=>'shu','尌'=>'shu','尗'=>'shu','属'=>'shu','庶'=>'shu','庻'=>'shu','怷'=>'shu','恕'=>'shu','戍'=>'shu','抒'=>'shu','掓'=>'shu','摅'=>'shu','攄'=>'shu','数'=>'shu','數'=>'shu','暏'=>'shu','暑'=>'shu','曙'=>'shu','書'=>'shu','朮'=>'shu','术'=>'shu','束'=>'shu','杸'=>'shu','枢'=>'shu','柕'=>'shu','树'=>'shu','梳'=>'shu','樞'=>'shu','樹'=>'shu','橾'=>'shu','殊'=>'shu','殳'=>'shu','毹'=>'shu','毺'=>'shu','沭'=>'shu','淑'=>'shu','漱'=>'shu','潄'=>'shu','潻'=>'shu','澍'=>'shu','濖'=>'shu','瀭'=>'shu','焂'=>'shu','熟'=>'shu','瑹'=>'shu','璹'=>'shu','疎'=>'shu','疏'=>'shu','癙'=>'shu','秫'=>'shu','竖'=>'shu','竪'=>'shu','籔'=>'shu','糬'=>'shu','紓'=>'shu','絉'=>'shu','綀'=>'shu','纾'=>'shu','署'=>'shu','腧'=>'shu','舒'=>'shu','荗'=>'shu','菽'=>'shu','蒁'=>'shu','蔬'=>'shu','薥'=>'shu','薯'=>'shu','藷'=>'shu','虪'=>'shu','蜀'=>'shu','蠴'=>'shu','術'=>'shu','裋'=>'shu','襡'=>'shu','襩'=>'shu','豎'=>'shu','贖'=>'shu','赎'=>'shu','跾'=>'shu','踈'=>'shu','軗'=>'shu','輸'=>'shu','输'=>'shu','述'=>'shu','鄃'=>'shu','鉥'=>'shu','錰'=>'shu','鏣'=>'shu','陎'=>'shu','鮛'=>'shu','鱪'=>'shu','鱰'=>'shu','鵨'=>'shu','鶐'=>'shu','鶑'=>'shu','鸀'=>'shu','黍'=>'shu','鼠'=>'shu','鼡'=>'shu','㒔'=>'shu','㛸'=>'shu','㜐'=>'shu','㟬'=>'shu','㣽'=>'shu','㯮'=>'shu','㳆'=>'shu','㶖'=>'shu','㷂'=>'shu','㻿'=>'shu','㽰'=>'shu','㾁'=>'shu','䃞'=>'shu','䆝'=>'shu','䉀'=>'shu','䎉'=>'shu','䘤'=>'shu','䜹'=>'shu','䝂'=>'shu','䝪'=>'shu','䞖'=>'shu','䠱'=>'shu','䢤'=>'shu','䩱'=>'shu','䩳'=>'shu','䴰'=>'shu','乧'=>'dou','兜'=>'dou','兠'=>'dou','剅'=>'dou','吺'=>'dou','唗'=>'dou','抖'=>'dou','斗'=>'dou','斣'=>'dou','枓'=>'dou','梪'=>'dou','橷'=>'dou','毭'=>'dou','浢'=>'dou','痘'=>'dou','窦'=>'dou','竇'=>'dou','篼'=>'dou','脰'=>'dou','艔'=>'dou','荳'=>'dou','蔸'=>'dou','蚪'=>'dou','豆'=>'dou','逗'=>'dou','郖'=>'dou','酘'=>'dou','鈄'=>'dou','鋀'=>'dou','钭'=>'dou','閗'=>'dou','闘'=>'dou','阧'=>'dou','陡'=>'dou','餖'=>'dou','饾'=>'dou','鬥'=>'dou','鬦'=>'dou','鬪'=>'dou','鬬'=>'dou','鬭'=>'dou','㛒'=>'dou','㞳'=>'dou','㢄'=>'dou','㨮'=>'dou','㪷'=>'dou','㷆'=>'dou','䄈'=>'dou','䕆'=>'dou','䕱'=>'dou','䛠'=>'dou','䬦'=>'dou','乪'=>'nang','儾'=>'nang','嚢'=>'nang','囊'=>'nang','囔'=>'nang','擃'=>'nang','攮'=>'nang','曩'=>'nang','欜'=>'nang','灢'=>'nang','蠰'=>'nang','饢'=>'nang','馕'=>'nang','鬞'=>'nang','齉'=>'nang','㒄'=>'nang','㶞'=>'nang','䂇'=>'nang','乫'=>'kai','凯'=>'kai','凱'=>'kai','剀'=>'kai','剴'=>'kai','勓'=>'kai','嘅'=>'kai','垲'=>'kai','塏'=>'kai','奒'=>'kai','开'=>'kai','忾'=>'kai','恺'=>'kai','愷'=>'kai','愾'=>'kai','慨'=>'kai','揩'=>'kai','暟'=>'kai','楷'=>'kai','欬'=>'kai','炌'=>'kai','炏'=>'kai','烗'=>'kai','蒈'=>'kai','衉'=>'kai','輆'=>'kai','鍇'=>'kai','鎎'=>'kai','鎧'=>'kai','鐦'=>'kai','铠'=>'kai','锎'=>'kai','锴'=>'kai','開'=>'kai','闓'=>'kai','闿'=>'kai','颽'=>'kai','㡁'=>'kai','㲉'=>'kai','䁗'=>'kai','䐩'=>'kai','䒓'=>'kai','䡷'=>'kai','乬'=>'keng','劥'=>'keng','厼'=>'keng','吭'=>'keng','唟'=>'keng','坈'=>'keng','坑'=>'keng','巪'=>'keng','怾'=>'keng','挳'=>'keng','牼'=>'keng','硁'=>'keng','硜'=>'keng','硻'=>'keng','誙'=>'keng','銵'=>'keng','鍞'=>'keng','鏗'=>'keng','铿'=>'keng','䡰'=>'keng','乭'=>'ting','亭'=>'ting','侹'=>'ting','停'=>'ting','厅'=>'ting','厛'=>'ting','听'=>'ting','圢'=>'ting','娗'=>'ting','婷'=>'ting','嵉'=>'ting','庁'=>'ting','庭'=>'ting','廰'=>'ting','廳'=>'ting','廷'=>'ting','挺'=>'ting','桯'=>'ting','梃'=>'ting','楟'=>'ting','榳'=>'ting','汀'=>'ting','涏'=>'ting','渟'=>'ting','濎'=>'ting','烃'=>'ting','烴'=>'ting','烶'=>'ting','珽'=>'ting','町'=>'ting','筳'=>'ting','綎'=>'ting','耓'=>'ting','聤'=>'ting','聴'=>'ting','聼'=>'ting','聽'=>'ting','脡'=>'ting','艇'=>'ting','艈'=>'ting','艼'=>'ting','莛'=>'ting','葶'=>'ting','蜓'=>'ting','蝏'=>'ting','誔'=>'ting','諪'=>'ting','邒'=>'ting','鋌'=>'ting','铤'=>'ting','閮'=>'ting','霆'=>'ting','鞓'=>'ting','頲'=>'ting','颋'=>'ting','鼮'=>'ting','㹶'=>'ting','䋼'=>'ting','䗴'=>'ting','䦐'=>'ting','䱓'=>'ting','䵺'=>'ting','乮'=>'mo','劘'=>'mo','劰'=>'mo','嗼'=>'mo','嚤'=>'mo','嚩'=>'mo','圽'=>'mo','塻'=>'mo','墨'=>'mo','妺'=>'mo','嫫'=>'mo','嫼'=>'mo','寞'=>'mo','尛'=>'mo','帓'=>'mo','帞'=>'mo','怽'=>'mo','懡'=>'mo','抹'=>'mo','摩'=>'mo','摸'=>'mo','摹'=>'mo','擵'=>'mo','昩'=>'mo','暯'=>'mo','末'=>'mo','枺'=>'mo','模'=>'mo','橅'=>'mo','歾'=>'mo','歿'=>'mo','殁'=>'mo','沫'=>'mo','漠'=>'mo','爅'=>'mo','瘼'=>'mo','皌'=>'mo','眜'=>'mo','眽'=>'mo','眿'=>'mo','瞐'=>'mo','瞙'=>'mo','砞'=>'mo','磨'=>'mo','礳'=>'mo','秣'=>'mo','粖'=>'mo','糢'=>'mo','絈'=>'mo','縸'=>'mo','纆'=>'mo','耱'=>'mo','膜'=>'mo','茉'=>'mo','莈'=>'mo','莫'=>'mo','蓦'=>'mo','藦'=>'mo','蘑'=>'mo','蛨'=>'mo','蟔'=>'mo','袹'=>'mo','謨'=>'mo','謩'=>'mo','譕'=>'mo','谟'=>'mo','貃'=>'mo','貊'=>'mo','貘'=>'mo','銆'=>'mo','鏌'=>'mo','镆'=>'mo','陌'=>'mo','靺'=>'mo','饃'=>'mo','饝'=>'mo','馍'=>'mo','驀'=>'mo','髍'=>'mo','魔'=>'mo','魩'=>'mo','魹'=>'mo','麼'=>'mo','麽'=>'mo','麿'=>'mo','默'=>'mo','黙'=>'mo','㱄'=>'mo','㱳'=>'mo','㷬'=>'mo','㷵'=>'mo','㹮'=>'mo','䁼'=>'mo','䁿'=>'mo','䃺'=>'mo','䉑'=>'mo','䏞'=>'mo','䒬'=>'mo','䘃'=>'mo','䜆'=>'mo','䩋'=>'mo','䬴'=>'mo','䮬'=>'mo','䯢'=>'mo','䱅'=>'mo','䳮'=>'mo','䴲'=>'mo','乯'=>'ou','偶'=>'ou','吘'=>'ou','呕'=>'ou','嘔'=>'ou','噢'=>'ou','塸'=>'ou','夞'=>'ou','怄'=>'ou','慪'=>'ou','櫙'=>'ou','欧'=>'ou','歐'=>'ou','殴'=>'ou','毆'=>'ou','毮'=>'ou','沤'=>'ou','漚'=>'ou','熰'=>'ou','瓯'=>'ou','甌'=>'ou','筽'=>'ou','耦'=>'ou','腢'=>'ou','膒'=>'ou','蕅'=>'ou','藕'=>'ou','藲'=>'ou','謳'=>'ou','讴'=>'ou','鏂'=>'ou','鞰'=>'ou','鴎'=>'ou','鷗'=>'ou','鸥'=>'ou','齵'=>'ou','㒖'=>'ou','㛏'=>'ou','㼴'=>'ou','䌂'=>'ou','䌔'=>'ou','䚆'=>'ou','䯚'=>'ou','买'=>'mai','佅'=>'mai','劢'=>'mai','勱'=>'mai','卖'=>'mai','嘪'=>'mai','埋'=>'mai','売'=>'mai','脈'=>'mai','脉'=>'mai','荬'=>'mai','蕒'=>'mai','薶'=>'mai','衇'=>'mai','買'=>'mai','賣'=>'mai','迈'=>'mai','邁'=>'mai','霡'=>'mai','霢'=>'mai','霾'=>'mai','鷶'=>'mai','麥'=>'mai','麦'=>'mai','㜥'=>'mai','㼮'=>'mai','䁲'=>'mai','䈿'=>'mai','䘑'=>'mai','䚑'=>'mai','䜕'=>'mai','䨪'=>'mai','䨫'=>'mai','䮮'=>'mai','乱'=>'luan','亂'=>'luan','卵'=>'luan','圝'=>'luan','圞'=>'luan','奱'=>'luan','孌'=>'luan','孪'=>'luan','孿'=>'luan','峦'=>'luan','巒'=>'luan','挛'=>'luan','攣'=>'luan','曫'=>'luan','栾'=>'luan','欒'=>'luan','滦'=>'luan','灓'=>'luan','灤'=>'luan','癴'=>'luan','癵'=>'luan','羉'=>'luan','脔'=>'luan','臠'=>'luan','虊'=>'luan','釠'=>'luan','銮'=>'luan','鑾'=>'luan','鵉'=>'luan','鸞'=>'luan','鸾'=>'luan','㝈'=>'luan','㡩'=>'luan','㱍'=>'luan','䖂'=>'luan','䜌'=>'luan','乲'=>'cai','倸'=>'cai','偲'=>'cai','埰'=>'cai','婇'=>'cai','寀'=>'cai','彩'=>'cai','戝'=>'cai','才'=>'cai','採'=>'cai','材'=>'cai','棌'=>'cai','猜'=>'cai','睬'=>'cai','綵'=>'cai','縩'=>'cai','纔'=>'cai','菜'=>'cai','蔡'=>'cai','裁'=>'cai','財'=>'cai','财'=>'cai','跴'=>'cai','踩'=>'cai','采'=>'cai','㒲'=>'cai','㥒'=>'cai','䌨'=>'cai','䌽'=>'cai','䐆'=>'cai','䣋'=>'cai','䰂'=>'cai','䴭'=>'cai','乳'=>'ru','侞'=>'ru','儒'=>'ru','入'=>'ru','嗕'=>'ru','嚅'=>'ru','如'=>'ru','媷'=>'ru','嬬'=>'ru','孺'=>'ru','嶿'=>'ru','帤'=>'ru','扖'=>'ru','擩'=>'ru','曘'=>'ru','杁'=>'ru','桇'=>'ru','汝'=>'ru','洳'=>'ru','渪'=>'ru','溽'=>'ru','濡'=>'ru','燸'=>'ru','筎'=>'ru','縟'=>'ru','繻'=>'ru','缛'=>'ru','肗'=>'ru','茹'=>'ru','蒘'=>'ru','蓐'=>'ru','蕠'=>'ru','薷'=>'ru','蠕'=>'ru','袽'=>'ru','褥'=>'ru','襦'=>'ru','辱'=>'ru','込'=>'ru','邚'=>'ru','鄏'=>'ru','醹'=>'ru','銣'=>'ru','铷'=>'ru','顬'=>'ru','颥'=>'ru','鱬'=>'ru','鳰'=>'ru','鴑'=>'ru','鴽'=>'ru','㦺'=>'ru','㨎'=>'ru','㹘'=>'ru','䋈'=>'ru','䰰'=>'ru','乴'=>'xue','吷'=>'xue','坹'=>'xue','学'=>'xue','學'=>'xue','岤'=>'xue','峃'=>'xue','嶨'=>'xue','怴'=>'xue','斈'=>'xue','桖'=>'xue','樰'=>'xue','泧'=>'xue','泶'=>'xue','澩'=>'xue','瀥'=>'xue','烕'=>'xue','燢'=>'xue','狘'=>'xue','疦'=>'xue','疶'=>'xue','穴'=>'xue','膤'=>'xue','艝'=>'xue','茓'=>'xue','蒆'=>'xue','薛'=>'xue','血'=>'xue','袕'=>'xue','觷'=>'xue','謔'=>'xue','谑'=>'xue','趐'=>'xue','踅'=>'xue','轌'=>'xue','辥'=>'xue','雤'=>'xue','雪'=>'xue','靴'=>'xue','鞾'=>'xue','鱈'=>'xue','鳕'=>'xue','鷽'=>'xue','鸴'=>'xue','㖸'=>'xue','㞽'=>'xue','㡜'=>'xue','㧒'=>'xue','㶅'=>'xue','㿱'=>'xue','䎀'=>'xue','䤕'=>'xue','䨮'=>'xue','䫻'=>'xue','䫼'=>'xue','䬂'=>'xue','䭥'=>'xue','䱑'=>'xue','乶'=>'peng','倗'=>'peng','傰'=>'peng','剻'=>'peng','匉'=>'peng','喸'=>'peng','嘭'=>'peng','堋'=>'peng','塜'=>'peng','塳'=>'peng','巼'=>'peng','弸'=>'peng','彭'=>'peng','怦'=>'peng','恲'=>'peng','憉'=>'peng','抨'=>'peng','挷'=>'peng','捧'=>'peng','掽'=>'peng','搒'=>'peng','朋'=>'peng','梈'=>'peng','棚'=>'peng','椖'=>'peng','椪'=>'peng','槰'=>'peng','樥'=>'peng','泙'=>'peng','浌'=>'peng','淎'=>'peng','漨'=>'peng','漰'=>'peng','澎'=>'peng','烹'=>'peng','熢'=>'peng','皏'=>'peng','砰'=>'peng','硑'=>'peng','硼'=>'peng','碰'=>'peng','磞'=>'peng','稝'=>'peng','竼'=>'peng','篷'=>'peng','纄'=>'peng','胓'=>'peng','膨'=>'peng','芃'=>'peng','莑'=>'peng','蓬'=>'peng','蟚'=>'peng','蟛'=>'peng','踫'=>'peng','軯'=>'peng','輣'=>'peng','錋'=>'peng','鑝'=>'peng','閛'=>'peng','闏'=>'peng','韸'=>'peng','韼'=>'peng','駍'=>'peng','騯'=>'peng','髼'=>'peng','鬅'=>'peng','鬔'=>'peng','鵬'=>'peng','鹏'=>'peng','㛔'=>'peng','㥊'=>'peng','㼞'=>'peng','䄘'=>'peng','䡫'=>'peng','䰃'=>'peng','䴶'=>'peng','乷'=>'sha','倽'=>'sha','傻'=>'sha','儍'=>'sha','刹'=>'sha','唦'=>'sha','唼'=>'sha','啥'=>'sha','喢'=>'sha','帹'=>'sha','挱'=>'sha','杀'=>'sha','榝'=>'sha','樧'=>'sha','歃'=>'sha','殺'=>'sha','沙'=>'sha','煞'=>'sha','猀'=>'sha','痧'=>'sha','砂'=>'sha','硰'=>'sha','箑'=>'sha','粆'=>'sha','紗'=>'sha','繌'=>'sha','繺'=>'sha','纱'=>'sha','翜'=>'sha','翣'=>'sha','莎'=>'sha','萐'=>'sha','蔱'=>'sha','裟'=>'sha','鎩'=>'sha','铩'=>'sha','閯'=>'sha','閷'=>'sha','霎'=>'sha','魦'=>'sha','鯊'=>'sha','鯋'=>'sha','鲨'=>'sha','㚫'=>'sha','㛼'=>'sha','㰱'=>'sha','䈉'=>'sha','䝊'=>'sha','䮜'=>'sha','䵘'=>'sha','䶎'=>'sha','乸'=>'na','吶'=>'na','呐'=>'na','哪'=>'na','嗱'=>'na','妠'=>'na','娜'=>'na','拏'=>'na','拿'=>'na','挐'=>'na','捺'=>'na','笝'=>'na','納'=>'na','纳'=>'na','肭'=>'na','蒳'=>'na','衲'=>'na','袦'=>'na','誽'=>'na','豽'=>'na','貀'=>'na','軜'=>'na','那'=>'na','鈉'=>'na','鎿'=>'na','钠'=>'na','镎'=>'na','雫'=>'na','靹'=>'na','魶'=>'na','㗙'=>'na','㨥'=>'na','㴸'=>'na','䀑'=>'na','䅞'=>'na','䇣'=>'na','䇱'=>'na','䈫'=>'na','䎎'=>'na','䏧'=>'na','䖓'=>'na','䖧'=>'na','䛔'=>'na','䟜'=>'na','䪏'=>'na','䫱'=>'na','䱹'=>'na','乹'=>'qian','乾'=>'qian','仟'=>'qian','仱'=>'qian','伣'=>'qian','佥'=>'qian','俔'=>'qian','倩'=>'qian','偂'=>'qian','傔'=>'qian','僉'=>'qian','儙'=>'qian','凵'=>'qian','刋'=>'qian','前'=>'qian','千'=>'qian','嗛'=>'qian','圱'=>'qian','圲'=>'qian','堑'=>'qian','塹'=>'qian','墘'=>'qian','壍'=>'qian','奷'=>'qian','婜'=>'qian','媊'=>'qian','嬱'=>'qian','孯'=>'qian','岍'=>'qian','岒'=>'qian','嵌'=>'qian','嵰'=>'qian','忴'=>'qian','悓'=>'qian','悭'=>'qian','愆'=>'qian','慊'=>'qian','慳'=>'qian','扦'=>'qian','扲'=>'qian','拑'=>'qian','拪'=>'qian','掔'=>'qian','掮'=>'qian','揵'=>'qian','搴'=>'qian','摼'=>'qian','撁'=>'qian','攐'=>'qian','攑'=>'qian','攓'=>'qian','杄'=>'qian','棈'=>'qian','椠'=>'qian','榩'=>'qian','槏'=>'qian','槧'=>'qian','橬'=>'qian','檶'=>'qian','櫏'=>'qian','欠'=>'qian','欦'=>'qian','歉'=>'qian','歬'=>'qian','汘'=>'qian','汧'=>'qian','浅'=>'qian','淺'=>'qian','潛'=>'qian','潜'=>'qian','濳'=>'qian','灊'=>'qian','牵'=>'qian','牽'=>'qian','皘'=>'qian','竏'=>'qian','签'=>'qian','箝'=>'qian','箞'=>'qian','篏'=>'qian','篟'=>'qian','簽'=>'qian','籖'=>'qian','籤'=>'qian','粁'=>'qian','綪'=>'qian','縴'=>'qian','繾'=>'qian','缱'=>'qian','羬'=>'qian','肷'=>'qian','膁'=>'qian','臤'=>'qian','芊'=>'qian','芡'=>'qian','茜'=>'qian','茾'=>'qian','荨'=>'qian','蒨'=>'qian','蔳'=>'qian','蕁'=>'qian','虔'=>'qian','蚈'=>'qian','蜸'=>'qian','褰'=>'qian','諐'=>'qian','謙'=>'qian','譴'=>'qian','谦'=>'qian','谴'=>'qian','谸'=>'qian','軡'=>'qian','輤'=>'qian','迁'=>'qian','遣'=>'qian','遷'=>'qian','釺'=>'qian','鈆'=>'qian','鈐'=>'qian','鉆'=>'qian','鉗'=>'qian','鉛'=>'qian','銭'=>'qian','錢'=>'qian','鎆'=>'qian','鏲'=>'qian','鐱'=>'qian','鑓'=>'qian','钎'=>'qian','钤'=>'qian','钱'=>'qian','钳'=>'qian','铅'=>'qian','阡'=>'qian','雃'=>'qian','韆'=>'qian','顅'=>'qian','騚'=>'qian','騝'=>'qian','騫'=>'qian','骞'=>'qian','鬜'=>'qian','鬝'=>'qian','鰬'=>'qian','鵮'=>'qian','鹐'=>'qian','黔'=>'qian','黚'=>'qian','㐸'=>'qian','㜞'=>'qian','㟻'=>'qian','㡨'=>'qian','㦮'=>'qian','㧄'=>'qian','㨜'=>'qian','㩮'=>'qian','㯠'=>'qian','㸫'=>'qian','䁮'=>'qian','䈤'=>'qian','䈴'=>'qian','䊴'=>'qian','䍉'=>'qian','䖍'=>'qian','䥅'=>'qian','䦲'=>'qian','䨿'=>'qian','䪈'=>'qian','䫡'=>'qian','䭤'=>'qian','乻'=>'er','二'=>'er','仒'=>'er','佴'=>'er','侕'=>'er','儿'=>'er','児'=>'er','兒'=>'er','刵'=>'er','咡'=>'er','唲'=>'er','尒'=>'er','尓'=>'er','尔'=>'er','峏'=>'er','弍'=>'er','弐'=>'er','旕'=>'er','栭'=>'er','栮'=>'er','樲'=>'er','毦'=>'er','洏'=>'er','洱'=>'er','爾'=>'er','珥'=>'er','粫'=>'er','而'=>'er','耏'=>'er','耳'=>'er','聏'=>'er','胹'=>'er','荋'=>'er','薾'=>'er','衈'=>'er','袻'=>'er','誀'=>'er','貮'=>'er','貳'=>'er','贰'=>'er','趰'=>'er','輀'=>'er','轜'=>'er','迩'=>'er','邇'=>'er','鉺'=>'er','铒'=>'er','陑'=>'er','隭'=>'er','餌'=>'er','饵'=>'er','駬'=>'er','髵'=>'er','鮞'=>'er','鲕'=>'er','鴯'=>'er','鸸'=>'er','㒃'=>'er','㖇'=>'er','㚷'=>'er','㛅'=>'er','㜨'=>'er','㢽'=>'er','㧫'=>'er','㮕'=>'er','䋙'=>'er','䋩'=>'er','䌺'=>'er','䎟'=>'er','䎠'=>'er','䎶'=>'er','䏪'=>'er','䣵'=>'er','䮘'=>'er','乼'=>'cui','伜'=>'cui','倅'=>'cui','催'=>'cui','凗'=>'cui','啐'=>'cui','啛'=>'cui','墔'=>'cui','崔'=>'cui','嶉'=>'cui','忰'=>'cui','悴'=>'cui','慛'=>'cui','摧'=>'cui','榱'=>'cui','槯'=>'cui','毳'=>'cui','淬'=>'cui','漼'=>'cui','焠'=>'cui','獕'=>'cui','璀'=>'cui','疩'=>'cui','瘁'=>'cui','皠'=>'cui','磪'=>'cui','竁'=>'cui','粹'=>'cui','紣'=>'cui','綷'=>'cui','縗'=>'cui','缞'=>'cui','翆'=>'cui','翠'=>'cui','脃'=>'cui','脆'=>'cui','膬'=>'cui','膵'=>'cui','臎'=>'cui','萃'=>'cui','襊'=>'cui','趡'=>'cui','鏙'=>'cui','顇'=>'cui','㝮'=>'cui','㥞'=>'cui','㧘'=>'cui','㯔'=>'cui','㯜'=>'cui','㱖'=>'cui','㳃'=>'cui','㵏'=>'cui','㷃'=>'cui','㷪'=>'cui','䂱'=>'cui','䃀'=>'cui','䄟'=>'cui','䆊'=>'cui','䊫'=>'cui','䧽'=>'cui','乽'=>'ceng','噌'=>'ceng','层'=>'ceng','層'=>'ceng','岾'=>'ceng','嶒'=>'ceng','猠'=>'ceng','硛'=>'ceng','硳'=>'ceng','竲'=>'ceng','蹭'=>'ceng','驓'=>'ceng','㣒'=>'ceng','㬝'=>'ceng','䁬'=>'ceng','䉕'=>'ceng','亀'=>'gui','佹'=>'gui','刽'=>'gui','刿'=>'gui','劊'=>'gui','劌'=>'gui','匦'=>'gui','匭'=>'gui','厬'=>'gui','圭'=>'gui','垝'=>'gui','妫'=>'gui','姽'=>'gui','媯'=>'gui','嫢'=>'gui','嬀'=>'gui','宄'=>'gui','嶲'=>'gui','巂'=>'gui','帰'=>'gui','庋'=>'gui','庪'=>'gui','归'=>'gui','恑'=>'gui','摫'=>'gui','撌'=>'gui','攰'=>'gui','攱'=>'gui','昋'=>'gui','晷'=>'gui','柜'=>'gui','桂'=>'gui','椝'=>'gui','椢'=>'gui','槶'=>'gui','槻'=>'gui','槼'=>'gui','櫃'=>'gui','櫷'=>'gui','歸'=>'gui','氿'=>'gui','湀'=>'gui','溎'=>'gui','炅'=>'gui','珪'=>'gui','瑰'=>'gui','璝'=>'gui','瓌'=>'gui','癸'=>'gui','皈'=>'gui','瞆'=>'gui','瞡'=>'gui','瞶'=>'gui','硅'=>'gui','祪'=>'gui','禬'=>'gui','窐'=>'gui','筀'=>'gui','簂'=>'gui','簋'=>'gui','胿'=>'gui','膭'=>'gui','茥'=>'gui','蓕'=>'gui','蛫'=>'gui','蟡'=>'gui','袿'=>'gui','襘'=>'gui','規'=>'gui','规'=>'gui','觤'=>'gui','詭'=>'gui','诡'=>'gui','貴'=>'gui','贵'=>'gui','跪'=>'gui','軌'=>'gui','轨'=>'gui','邽'=>'gui','郌'=>'gui','閨'=>'gui','闺'=>'gui','陒'=>'gui','鞼'=>'gui','騩'=>'gui','鬶'=>'gui','鬹'=>'gui','鬼'=>'gui','鮭'=>'gui','鱖'=>'gui','鱥'=>'gui','鲑'=>'gui','鳜'=>'gui','龜'=>'gui','龟'=>'gui','㔳'=>'gui','㙺'=>'gui','㧪'=>'gui','㨳'=>'gui','㩻'=>'gui','㪈'=>'gui','㲹'=>'gui','㸵'=>'gui','䁛'=>'gui','䇈'=>'gui','䌆'=>'gui','䍯'=>'gui','䍷'=>'gui','䐴'=>'gui','䖯'=>'gui','䙆'=>'gui','䝿'=>'gui','䞈'=>'gui','䞨'=>'gui','䠩'=>'gui','䣀'=>'gui','䤥'=>'gui','䯣'=>'gui','䰎'=>'gui','䳏'=>'gui','亁'=>'gan','仠'=>'gan','倝'=>'gan','凎'=>'gan','凲'=>'gan','坩'=>'gan','尲'=>'gan','尴'=>'gan','尶'=>'gan','尷'=>'gan','干'=>'gan','幹'=>'gan','忓'=>'gan','感'=>'gan','擀'=>'gan','攼'=>'gan','敢'=>'gan','旰'=>'gan','杆'=>'gan','柑'=>'gan','桿'=>'gan','榦'=>'gan','橄'=>'gan','檊'=>'gan','汵'=>'gan','泔'=>'gan','淦'=>'gan','漧'=>'gan','澉'=>'gan','灨'=>'gan','玕'=>'gan','甘'=>'gan','疳'=>'gan','皯'=>'gan','盰'=>'gan','矸'=>'gan','秆'=>'gan','稈'=>'gan','竿'=>'gan','笴'=>'gan','筸'=>'gan','簳'=>'gan','粓'=>'gan','紺'=>'gan','绀'=>'gan','肝'=>'gan','芉'=>'gan','苷'=>'gan','衦'=>'gan','詌'=>'gan','贛'=>'gan','赣'=>'gan','赶'=>'gan','趕'=>'gan','迀'=>'gan','酐'=>'gan','骭'=>'gan','魐'=>'gan','鱤'=>'gan','鳡'=>'gan','鳱'=>'gan','㺂'=>'gan','䃭'=>'gan','䇞'=>'gan','䔈'=>'gan','䤗'=>'gan','䯎'=>'gan','䲺'=>'gan','䵟'=>'gan','亅'=>'jue','倔'=>'jue','傕'=>'jue','决'=>'jue','刔'=>'jue','劂'=>'jue','勪'=>'jue','厥'=>'jue','噘'=>'jue','噱'=>'jue','妜'=>'jue','孒'=>'jue','孓'=>'jue','屩'=>'jue','屫'=>'jue','崛'=>'jue','嶡'=>'jue','嶥'=>'jue','彏'=>'jue','憠'=>'jue','憰'=>'jue','戄'=>'jue','抉'=>'jue','挗'=>'jue','捔'=>'jue','掘'=>'jue','撅'=>'jue','撧'=>'jue','攫'=>'jue','斍'=>'jue','桷'=>'jue','橛'=>'jue','橜'=>'jue','欔'=>'jue','欮'=>'jue','殌'=>'jue','氒'=>'jue','決'=>'jue','泬'=>'jue','潏'=>'jue','灍'=>'jue','焆'=>'jue','熦'=>'jue','爑'=>'jue','爝'=>'jue','爴'=>'jue','爵'=>'jue','獗'=>'jue','玃'=>'jue','玦'=>'jue','玨'=>'jue','珏'=>'jue','瑴'=>'jue','瘚'=>'jue','矍'=>'jue','矡'=>'jue','砄'=>'jue','絕'=>'jue','絶'=>'jue','绝'=>'jue','臄'=>'jue','芵'=>'jue','蕝'=>'jue','蕨'=>'jue','虳'=>'jue','蚗'=>'jue','蟨'=>'jue','蟩'=>'jue','覐'=>'jue','覚'=>'jue','覺'=>'jue','觉'=>'jue','觖'=>'jue','觼'=>'jue','訣'=>'jue','譎'=>'jue','诀'=>'jue','谲'=>'jue','貜'=>'jue','赽'=>'jue','趉'=>'jue','趹'=>'jue','蹶'=>'jue','蹷'=>'jue','躩'=>'jue','逫'=>'jue','鈌'=>'jue','鐍'=>'jue','鐝'=>'jue','钁'=>'jue','镢'=>'jue','镼'=>'jue','駃'=>'jue','鴂'=>'jue','鴃'=>'jue','鶌'=>'jue','鷢'=>'jue','龣'=>'jue','㓸'=>'jue','㔃'=>'jue','㔢'=>'jue','㟲'=>'jue','㤜'=>'jue','㩱'=>'jue','㭈'=>'jue','㭾'=>'jue','㰐'=>'jue','㵐'=>'jue','㷾'=>'jue','㸕'=>'jue','㹟'=>'jue','㻕'=>'jue','䀗'=>'jue','䁷'=>'jue','䆕'=>'jue','䆢'=>'jue','䇶'=>'jue','䋉'=>'jue','䍊'=>'jue','䏐'=>'jue','䏣'=>'jue','䐘'=>'jue','䖼'=>'jue','䘿'=>'jue','䙠'=>'jue','䝌'=>'jue','䞵'=>'jue','䞷'=>'jue','䟾'=>'jue','䠇'=>'jue','䡈'=>'jue','䦆'=>'jue','䦼'=>'jue','了'=>'liao','僚'=>'liao','嘹'=>'liao','嫽'=>'liao','寥'=>'liao','寮'=>'liao','尞'=>'liao','尥'=>'liao','尦'=>'liao','屪'=>'liao','嵺'=>'liao','嶚'=>'liao','嶛'=>'liao','廖'=>'liao','廫'=>'liao','憀'=>'liao','憭'=>'liao','撂'=>'liao','撩'=>'liao','敹'=>'liao','料'=>'liao','暸'=>'liao','漻'=>'liao','潦'=>'liao','炓'=>'liao','燎'=>'liao','爎'=>'liao','爒'=>'liao','獠'=>'liao','璙'=>'liao','疗'=>'liao','療'=>'liao','瞭'=>'liao','窷'=>'liao','竂'=>'liao','簝'=>'liao','繚'=>'liao','缭'=>'liao','聊'=>'liao','膋'=>'liao','膫'=>'liao','蓼'=>'liao','蟟'=>'liao','豂'=>'liao','賿'=>'liao','蹘'=>'liao','蹽'=>'liao','辽'=>'liao','遼'=>'liao','鄝'=>'liao','釕'=>'liao','鐐'=>'liao','钌'=>'liao','镣'=>'liao','镽'=>'liao','飉'=>'liao','髎'=>'liao','鷯'=>'liao','鹩'=>'liao','㙩'=>'liao','㝋'=>'liao','㡻'=>'liao','㵳'=>'liao','㶫'=>'liao','㺒'=>'liao','䄦'=>'liao','䉼'=>'liao','䍡'=>'liao','䎆'=>'liao','䑠'=>'liao','䜍'=>'liao','䜮'=>'liao','䝀'=>'liao','䢧'=>'liao','䨅'=>'liao','䩍'=>'liao','亇'=>'ma','傌'=>'ma','吗'=>'ma','唛'=>'ma','嗎'=>'ma','嘛'=>'ma','嘜'=>'ma','妈'=>'ma','媽'=>'ma','嫲'=>'ma','嬤'=>'ma','嬷'=>'ma','杩'=>'ma','榪'=>'ma','溤'=>'ma','犘'=>'ma','犸'=>'ma','獁'=>'ma','玛'=>'ma','瑪'=>'ma','痲'=>'ma','睰'=>'ma','码'=>'ma','碼'=>'ma','礣'=>'ma','祃'=>'ma','禡'=>'ma','罵'=>'ma','蔴'=>'ma','蚂'=>'ma','螞'=>'ma','蟆'=>'ma','蟇'=>'ma','遤'=>'ma','鎷'=>'ma','閁'=>'ma','馬'=>'ma','駡'=>'ma','马'=>'ma','骂'=>'ma','鬕'=>'ma','鰢'=>'ma','鷌'=>'ma','麻'=>'ma','㐷'=>'ma','㑻'=>'ma','㜫'=>'ma','㦄'=>'ma','㨸'=>'ma','㾺'=>'ma','䗫'=>'ma','䣕'=>'ma','䣖'=>'ma','䯦'=>'ma','䳸'=>'ma','争'=>'zheng','佂'=>'zheng','凧'=>'zheng','埩'=>'zheng','塣'=>'zheng','姃'=>'zheng','媜'=>'zheng','峥'=>'zheng','崝'=>'zheng','崢'=>'zheng','帧'=>'zheng','幀'=>'zheng','征'=>'zheng','徰'=>'zheng','徴'=>'zheng','徵'=>'zheng','怔'=>'zheng','愸'=>'zheng','抍'=>'zheng','拯'=>'zheng','挣'=>'zheng','掙'=>'zheng','掟'=>'zheng','揁'=>'zheng','撜'=>'zheng','政'=>'zheng','整'=>'zheng','晸'=>'zheng','正'=>'zheng','氶'=>'zheng','炡'=>'zheng','烝'=>'zheng','爭'=>'zheng','狰'=>'zheng','猙'=>'zheng','症'=>'zheng','癥'=>'zheng','眐'=>'zheng','睁'=>'zheng','睜'=>'zheng','筝'=>'zheng','箏'=>'zheng','篜'=>'zheng','糽'=>'zheng','聇'=>'zheng','蒸'=>'zheng','証'=>'zheng','諍'=>'zheng','證'=>'zheng','证'=>'zheng','诤'=>'zheng','踭'=>'zheng','郑'=>'zheng','鄭'=>'zheng','鉦'=>'zheng','錚'=>'zheng','钲'=>'zheng','铮'=>'zheng','鬇'=>'zheng','鴊'=>'zheng','㡠'=>'zheng','㡧'=>'zheng','㱏'=>'zheng','㽀'=>'zheng','䂻'=>'zheng','䈣'=>'zheng','䛫'=>'zheng','䡕'=>'zheng','䥌'=>'zheng','䥭'=>'zheng','䦛'=>'zheng','䦶'=>'zheng','亍'=>'chu','俶'=>'chu','傗'=>'chu','储'=>'chu','儊'=>'chu','儲'=>'chu','処'=>'chu','出'=>'chu','刍'=>'chu','初'=>'chu','厨'=>'chu','嘼'=>'chu','埱'=>'chu','处'=>'chu','岀'=>'chu','幮'=>'chu','廚'=>'chu','怵'=>'chu','憷'=>'chu','懨'=>'chu','拀'=>'chu','搋'=>'chu','搐'=>'chu','摴'=>'chu','敊'=>'chu','斶'=>'chu','杵'=>'chu','椘'=>'chu','楚'=>'chu','楮'=>'chu','榋'=>'chu','樗'=>'chu','橱'=>'chu','橻'=>'chu','檚'=>'chu','櫉'=>'chu','櫥'=>'chu','欪'=>'chu','歜'=>'chu','滀'=>'chu','滁'=>'chu','濋'=>'chu','犓'=>'chu','珿'=>'chu','琡'=>'chu','璴'=>'chu','矗'=>'chu','础'=>'chu','礎'=>'chu','禇'=>'chu','竌'=>'chu','竐'=>'chu','篨'=>'chu','絀'=>'chu','绌'=>'chu','耡'=>'chu','臅'=>'chu','芻'=>'chu','蒢'=>'chu','蒭'=>'chu','蕏'=>'chu','處'=>'chu','蜍'=>'chu','蟵'=>'chu','褚'=>'chu','触'=>'chu','觸'=>'chu','諔'=>'chu','豖'=>'chu','豠'=>'chu','貙'=>'chu','趎'=>'chu','踀'=>'chu','蹰'=>'chu','躇'=>'chu','躕'=>'chu','鄐'=>'chu','鉏'=>'chu','鋤'=>'chu','锄'=>'chu','閦'=>'chu','除'=>'chu','雏'=>'chu','雛'=>'chu','鶵'=>'chu','黜'=>'chu','齣'=>'chu','齭'=>'chu','齼'=>'chu','㔘'=>'chu','㕏'=>'chu','㕑'=>'chu','㗰'=>'chu','㙇'=>'chu','㡡'=>'chu','㤕'=>'chu','㤘'=>'chu','㶆'=>'chu','㹼'=>'chu','㼥'=>'chu','䅳'=>'chu','䊰'=>'chu','䎝'=>'chu','䎤'=>'chu','䖏'=>'chu','䙕'=>'chu','䙘'=>'chu','䜴'=>'chu','䟞'=>'chu','䟣'=>'chu','䠂'=>'chu','䠧'=>'chu','䦌'=>'chu','䧁'=>'chu','䮞'=>'chu','亏'=>'kui','傀'=>'kui','刲'=>'kui','匮'=>'kui','匱'=>'kui','卼'=>'kui','喟'=>'kui','喹'=>'kui','嘳'=>'kui','夔'=>'kui','奎'=>'kui','媿'=>'kui','嬇'=>'kui','尯'=>'kui','岿'=>'kui','巋'=>'kui','巙'=>'kui','悝'=>'kui','愦'=>'kui','愧'=>'kui','憒'=>'kui','戣'=>'kui','揆'=>'kui','晆'=>'kui','暌'=>'kui','楏'=>'kui','楑'=>'kui','樻'=>'kui','櫆'=>'kui','欳'=>'kui','殨'=>'kui','溃'=>'kui','潰'=>'kui','煃'=>'kui','盔'=>'kui','睽'=>'kui','磈'=>'kui','窥'=>'kui','窺'=>'kui','篑'=>'kui','簣'=>'kui','籄'=>'kui','聧'=>'kui','聩'=>'kui','聭'=>'kui','聵'=>'kui','葵'=>'kui','蒉'=>'kui','蒊'=>'kui','蕢'=>'kui','藈'=>'kui','蘬'=>'kui','蘷'=>'kui','虁'=>'kui','虧'=>'kui','蝰'=>'kui','謉'=>'kui','跬'=>'kui','蹞'=>'kui','躨'=>'kui','逵'=>'kui','鄈'=>'kui','鍨'=>'kui','鍷'=>'kui','鐀'=>'kui','鑎'=>'kui','闚'=>'kui','頄'=>'kui','頍'=>'kui','頯'=>'kui','顝'=>'kui','餽'=>'kui','饋'=>'kui','馈'=>'kui','馗'=>'kui','騤'=>'kui','骙'=>'kui','魁'=>'kui','㕟'=>'kui','㙓'=>'kui','㚝'=>'kui','㛻'=>'kui','㨒'=>'kui','䈐'=>'kui','䍪'=>'kui','䕚'=>'kui','䕫'=>'kui','䟸'=>'kui','䠑'=>'kui','䤆'=>'kui','䦱'=>'kui','䧶'=>'kui','䫥'=>'kui','䯓'=>'kui','䳫'=>'kui','云'=>'yun','伝'=>'yun','傊'=>'yun','允'=>'yun','勻'=>'yun','匀'=>'yun','呍'=>'yun','喗'=>'yun','囩'=>'yun','夽'=>'yun','奫'=>'yun','妘'=>'yun','孕'=>'yun','恽'=>'yun','惲'=>'yun','愠'=>'yun','愪'=>'yun','慍'=>'yun','抎'=>'yun','抣'=>'yun','昀'=>'yun','晕'=>'yun','暈'=>'yun','枟'=>'yun','橒'=>'yun','殒'=>'yun','殞'=>'yun','氲'=>'yun','氳'=>'yun','沄'=>'yun','涢'=>'yun','溳'=>'yun','澐'=>'yun','煴'=>'yun','熅'=>'yun','熉'=>'yun','熨'=>'yun','狁'=>'yun','玧'=>'yun','畇'=>'yun','眃'=>'yun','磒'=>'yun','秐'=>'yun','筼'=>'yun','篔'=>'yun','紜'=>'yun','緼'=>'yun','縕'=>'yun','縜'=>'yun','繧'=>'yun','纭'=>'yun','缊'=>'yun','耘'=>'yun','耺'=>'yun','腪'=>'yun','芸'=>'yun','荺'=>'yun','蒀'=>'yun','蒕'=>'yun','蒷'=>'yun','蕓'=>'yun','蕰'=>'yun','蕴'=>'yun','薀'=>'yun','藴'=>'yun','蘊'=>'yun','蝹'=>'yun','褞'=>'yun','賱'=>'yun','贇'=>'yun','赟'=>'yun','运'=>'yun','運'=>'yun','郓'=>'yun','郧'=>'yun','鄆'=>'yun','鄖'=>'yun','酝'=>'yun','醖'=>'yun','醞'=>'yun','鈗'=>'yun','鋆'=>'yun','阭'=>'yun','陨'=>'yun','隕'=>'yun','雲'=>'yun','霣'=>'yun','韗'=>'yun','韞'=>'yun','韫'=>'yun','韵'=>'yun','韻'=>'yun','頵'=>'yun','餫'=>'yun','馧'=>'yun','馻'=>'yun','齫'=>'yun','齳'=>'yun','㚃'=>'yun','㚺'=>'yun','㜏'=>'yun','㞌'=>'yun','㟦'=>'yun','䆬'=>'yun','䇖'=>'yun','䉙'=>'yun','䚋'=>'yun','䞫'=>'yun','䡝'=>'yun','䢵'=>'yun','䤞'=>'yun','䦾'=>'yun','䨶'=>'yun','䩵'=>'yun','䪳'=>'yun','䲰'=>'yun','䵴'=>'yun','亗'=>'sui','倠'=>'sui','哸'=>'sui','埣'=>'sui','夊'=>'sui','嬘'=>'sui','岁'=>'sui','嵗'=>'sui','旞'=>'sui','檖'=>'sui','歲'=>'sui','歳'=>'sui','浽'=>'sui','滖'=>'sui','澻'=>'sui','濉'=>'sui','瀡'=>'sui','煫'=>'sui','熣'=>'sui','燧'=>'sui','璲'=>'sui','瓍'=>'sui','眭'=>'sui','睟'=>'sui','睢'=>'sui','砕'=>'sui','碎'=>'sui','祟'=>'sui','禭'=>'sui','穂'=>'sui','穗'=>'sui','穟'=>'sui','粋'=>'sui','綏'=>'sui','繀'=>'sui','繐'=>'sui','繸'=>'sui','绥'=>'sui','脺'=>'sui','膸'=>'sui','芕'=>'sui','荽'=>'sui','荾'=>'sui','葰'=>'sui','虽'=>'sui','襚'=>'sui','誶'=>'sui','譢'=>'sui','谇'=>'sui','賥'=>'sui','遀'=>'sui','遂'=>'sui','邃'=>'sui','鐆'=>'sui','鐩'=>'sui','隋'=>'sui','随'=>'sui','隧'=>'sui','隨'=>'sui','雖'=>'sui','鞖'=>'sui','髄'=>'sui','髓'=>'sui','㒸'=>'sui','㞸'=>'sui','㴚'=>'sui','㵦'=>'sui','㻟'=>'sui','㻪'=>'sui','㻽'=>'sui','䅗'=>'sui','䉌'=>'sui','䍁'=>'sui','䔹'=>'sui','䜔'=>'sui','䠔'=>'sui','䡵'=>'sui','䢫'=>'sui','䥙'=>'sui','䭉'=>'sui','䯝'=>'sui','亘'=>'gen','哏'=>'gen','揯'=>'gen','搄'=>'gen','根'=>'gen','艮'=>'gen','茛'=>'gen','跟'=>'gen','㫔'=>'gen','㮓'=>'gen','䫀'=>'gen','亙'=>'geng','刯'=>'geng','哽'=>'geng','啹'=>'geng','喼'=>'geng','嗰'=>'geng','埂'=>'geng','堩'=>'geng','峺'=>'geng','庚'=>'geng','挭'=>'geng','掶'=>'geng','更'=>'geng','梗'=>'geng','椩'=>'geng','浭'=>'geng','焿'=>'geng','畊'=>'geng','絚'=>'geng','綆'=>'geng','緪'=>'geng','縆'=>'geng','绠'=>'geng','羮'=>'geng','羹'=>'geng','耕'=>'geng','耿'=>'geng','莄'=>'geng','菮'=>'geng','賡'=>'geng','赓'=>'geng','郠'=>'geng','骾'=>'geng','鯁'=>'geng','鲠'=>'geng','鶊'=>'geng','鹒'=>'geng','㾘'=>'geng','䋁'=>'geng','䌄'=>'geng','䱍'=>'geng','䱎'=>'geng','䱭'=>'geng','䱴'=>'geng','些'=>'xie','亵'=>'xie','伳'=>'xie','偕'=>'xie','偰'=>'xie','僁'=>'xie','写'=>'xie','冩'=>'xie','劦'=>'xie','勰'=>'xie','协'=>'xie','協'=>'xie','卨'=>'xie','卸'=>'xie','嗋'=>'xie','噧'=>'xie','垥'=>'xie','塮'=>'xie','夑'=>'xie','奊'=>'xie','娎'=>'xie','媟'=>'xie','寫'=>'xie','屑'=>'xie','屓'=>'xie','屟'=>'xie','屧'=>'xie','屭'=>'xie','峫'=>'xie','嶰'=>'xie','廨'=>'xie','徢'=>'xie','恊'=>'xie','愶'=>'xie','懈'=>'xie','拹'=>'xie','挟'=>'xie','挾'=>'xie','揳'=>'xie','携'=>'xie','撷'=>'xie','擕'=>'xie','擷'=>'xie','攜'=>'xie','斜'=>'xie','旪'=>'xie','暬'=>'xie','械'=>'xie','楔'=>'xie','榍'=>'xie','榭'=>'xie','歇'=>'xie','泄'=>'xie','泻'=>'xie','洩'=>'xie','渫'=>'xie','澥'=>'xie','瀉'=>'xie','瀣'=>'xie','灺'=>'xie','炧'=>'xie','炨'=>'xie','焎'=>'xie','熁'=>'xie','燮'=>'xie','燲'=>'xie','爕'=>'xie','猲'=>'xie','獬'=>'xie','瑎'=>'xie','祄'=>'xie','禼'=>'xie','糏'=>'xie','紲'=>'xie','絏'=>'xie','絜'=>'xie','絬'=>'xie','綊'=>'xie','緤'=>'xie','緳'=>'xie','纈'=>'xie','绁'=>'xie','缬'=>'xie','缷'=>'xie','翓'=>'xie','胁'=>'xie','脅'=>'xie','脇'=>'xie','脋'=>'xie','膎'=>'xie','薢'=>'xie','薤'=>'xie','藛'=>'xie','蝎'=>'xie','蝢'=>'xie','蟹'=>'xie','蠍'=>'xie','蠏'=>'xie','衺'=>'xie','褉'=>'xie','褻'=>'xie','襭'=>'xie','諧'=>'xie','謝'=>'xie','讗'=>'xie','谐'=>'xie','谢'=>'xie','躞'=>'xie','躠'=>'xie','邂'=>'xie','邪'=>'xie','鐷'=>'xie','鞋'=>'xie','鞢'=>'xie','鞵'=>'xie','韰'=>'xie','齂'=>'xie','齘'=>'xie','齥'=>'xie','龤'=>'xie','㒠'=>'xie','㓔'=>'xie','㔎'=>'xie','㕐'=>'xie','㖑'=>'xie','㖿'=>'xie','㙝'=>'xie','㙰'=>'xie','㝍'=>'xie','㞕'=>'xie','㣯'=>'xie','㣰'=>'xie','㥟'=>'xie','㦪'=>'xie','㨙'=>'xie','㨝'=>'xie','㩉'=>'xie','㩦'=>'xie','㩪'=>'xie','㭨'=>'xie','㰔'=>'xie','㰡'=>'xie','㳦'=>'xie','㳿'=>'xie','㴬'=>'xie','㴮'=>'xie','㴽'=>'xie','㸉'=>'xie','㽊'=>'xie','䉏'=>'xie','䉣'=>'xie','䊝'=>'xie','䔑'=>'xie','䕈'=>'xie','䕵'=>'xie','䙊'=>'xie','䙎'=>'xie','䙝'=>'xie','䚳'=>'xie','䚸'=>'xie','䡡'=>'xie','䢡'=>'xie','䥱'=>'xie','䥾'=>'xie','䦏'=>'xie','䦑'=>'xie','䩧'=>'xie','䭎'=>'xie','䲒'=>'xie','䵦'=>'xie','亠'=>'tou','偷'=>'tou','偸'=>'tou','头'=>'tou','妵'=>'tou','婾'=>'tou','媮'=>'tou','投'=>'tou','敨'=>'tou','斢'=>'tou','殕'=>'tou','紏'=>'tou','緰'=>'tou','蘣'=>'tou','透'=>'tou','鍮'=>'tou','頭'=>'tou','骰'=>'tou','黈'=>'tou','㓱'=>'tou','㖣'=>'tou','㡏'=>'tou','㢏'=>'tou','㪗'=>'tou','䞬'=>'tou','䟝'=>'tou','䱏'=>'tou','䵉'=>'tou','亡'=>'wang','亾'=>'wang','仼'=>'wang','兦'=>'wang','妄'=>'wang','尣'=>'wang','尩'=>'wang','尪'=>'wang','尫'=>'wang','彺'=>'wang','往'=>'wang','徃'=>'wang','忘'=>'wang','忹'=>'wang','惘'=>'wang','旺'=>'wang','暀'=>'wang','望'=>'wang','朢'=>'wang','枉'=>'wang','棢'=>'wang','汪'=>'wang','瀇'=>'wang','焹'=>'wang','王'=>'wang','盳'=>'wang','網'=>'wang','网'=>'wang','罔'=>'wang','莣'=>'wang','菵'=>'wang','蚟'=>'wang','蛧'=>'wang','蝄'=>'wang','誷'=>'wang','輞'=>'wang','辋'=>'wang','迋'=>'wang','魍'=>'wang','㑌'=>'wang','㓁'=>'wang','㲿'=>'wang','㳹'=>'wang','㴏'=>'wang','䋄'=>'wang','䋞'=>'wang','䛃'=>'wang','䤑'=>'wang','䰣'=>'wang','亢'=>'kang','伉'=>'kang','匟'=>'kang','囥'=>'kang','嫝'=>'kang','嵻'=>'kang','康'=>'kang','忼'=>'kang','慷'=>'kang','扛'=>'kang','抗'=>'kang','摃'=>'kang','槺'=>'kang','漮'=>'kang','炕'=>'kang','犺'=>'kang','砊'=>'kang','穅'=>'kang','粇'=>'kang','糠'=>'kang','躿'=>'kang','邟'=>'kang','鈧'=>'kang','鏮'=>'kang','钪'=>'kang','閌'=>'kang','闶'=>'kang','鱇'=>'kang','㰠'=>'kang','䡉'=>'kang','亣'=>'da','剳'=>'da','匒'=>'da','呾'=>'da','咑'=>'da','哒'=>'da','嗒'=>'da','噠'=>'da','垯'=>'da','墶'=>'da','大'=>'da','妲'=>'da','怛'=>'da','打'=>'da','搭'=>'da','撘'=>'da','橽'=>'da','沓'=>'da','溚'=>'da','炟'=>'da','燵'=>'da','畣'=>'da','瘩'=>'da','眔'=>'da','笪'=>'da','答'=>'da','繨'=>'da','羍'=>'da','耷'=>'da','荅'=>'da','荙'=>'da','薘'=>'da','蟽'=>'da','褡'=>'da','詚'=>'da','跶'=>'da','躂'=>'da','达'=>'da','迏'=>'da','迖'=>'da','逹'=>'da','達'=>'da','鎉'=>'da','鎝'=>'da','鐽'=>'da','靼'=>'da','鞑'=>'da','韃'=>'da','龖'=>'da','龘'=>'da','㙮'=>'da','㜓'=>'da','㟷'=>'da','㯚'=>'da','㾑'=>'da','㿯'=>'da','䃮'=>'da','䐊'=>'da','䑽'=>'da','䩢'=>'da','䳴'=>'da','䵣'=>'da','交'=>'jiao','佼'=>'jiao','侥'=>'jiao','僥'=>'jiao','僬'=>'jiao','儌'=>'jiao','剿'=>'jiao','劋'=>'jiao','勦'=>'jiao','叫'=>'jiao','呌'=>'jiao','嘂'=>'jiao','嘄'=>'jiao','嘦'=>'jiao','噍'=>'jiao','噭'=>'jiao','嚼'=>'jiao','姣'=>'jiao','娇'=>'jiao','嬌'=>'jiao','嬓'=>'jiao','孂'=>'jiao','峤'=>'jiao','峧'=>'jiao','嶕'=>'jiao','嶠'=>'jiao','嶣'=>'jiao','徼'=>'jiao','憍'=>'jiao','挍'=>'jiao','挢'=>'jiao','捁'=>'jiao','搅'=>'jiao','摷'=>'jiao','撟'=>'jiao','撹'=>'jiao','攪'=>'jiao','敎'=>'jiao','教'=>'jiao','敫'=>'jiao','敽'=>'jiao','敿'=>'jiao','斠'=>'jiao','晈'=>'jiao','暞'=>'jiao','曒'=>'jiao','椒'=>'jiao','櫵'=>'jiao','浇'=>'jiao','湫'=>'jiao','湬'=>'jiao','滘'=>'jiao','漖'=>'jiao','潐'=>'jiao','澆'=>'jiao','灚'=>'jiao','烄'=>'jiao','焦'=>'jiao','焳'=>'jiao','煍'=>'jiao','燋'=>'jiao','狡'=>'jiao','獥'=>'jiao','珓'=>'jiao','璬'=>'jiao','皎'=>'jiao','皦'=>'jiao','皭'=>'jiao','矫'=>'jiao','矯'=>'jiao','礁'=>'jiao','穚'=>'jiao','窌'=>'jiao','窖'=>'jiao','笅'=>'jiao','筊'=>'jiao','簥'=>'jiao','絞'=>'jiao','繳'=>'jiao','纐'=>'jiao','绞'=>'jiao','缴'=>'jiao','胶'=>'jiao','脚'=>'jiao','腳'=>'jiao','膠'=>'jiao','膲'=>'jiao','臫'=>'jiao','艽'=>'jiao','芁'=>'jiao','茭'=>'jiao','茮'=>'jiao','蕉'=>'jiao','藠'=>'jiao','虠'=>'jiao','蛟'=>'jiao','蟜'=>'jiao','蟭'=>'jiao','角'=>'jiao','訆'=>'jiao','譑'=>'jiao','譥'=>'jiao','賋'=>'jiao','趭'=>'jiao','跤'=>'jiao','踋'=>'jiao','較'=>'jiao','轇'=>'jiao','轎'=>'jiao','轿'=>'jiao','较'=>'jiao','郊'=>'jiao','酵'=>'jiao','醮'=>'jiao','釂'=>'jiao','鉸'=>'jiao','鐎'=>'jiao','铰'=>'jiao','餃'=>'jiao','饺'=>'jiao','驕'=>'jiao','骄'=>'jiao','鮫'=>'jiao','鱎'=>'jiao','鲛'=>'jiao','鵁'=>'jiao','鵤'=>'jiao','鷦'=>'jiao','鷮'=>'jiao','鹪'=>'jiao','㠐'=>'jiao','㩰'=>'jiao','㬭'=>'jiao','㭂'=>'jiao','㰾'=>'jiao','㳅'=>'jiao','㽱'=>'jiao','㽲'=>'jiao','䀊'=>'jiao','䁶'=>'jiao','䂃'=>'jiao','䆗'=>'jiao','䘨'=>'jiao','䚩'=>'jiao','䠛'=>'jiao','䣤'=>'jiao','䥞'=>'jiao','䪒'=>'jiao','䴔'=>'jiao','䴛'=>'jiao','亨'=>'heng','哼'=>'heng','啈'=>'heng','囍'=>'heng','堼'=>'heng','姮'=>'heng','恆'=>'heng','恒'=>'heng','悙'=>'heng','桁'=>'heng','横'=>'heng','橫'=>'heng','涥'=>'heng','烆'=>'heng','珩'=>'heng','胻'=>'heng','脝'=>'heng','蘅'=>'heng','衡'=>'heng','鑅'=>'heng','鴴'=>'heng','鵆'=>'heng','鸻'=>'heng','㔰'=>'heng','㶇'=>'heng','䄓'=>'heng','䒛'=>'heng','䬖'=>'heng','䬝'=>'heng','䯒'=>'heng','亲'=>'qin','侵'=>'qin','勤'=>'qin','吢'=>'qin','吣'=>'qin','唚'=>'qin','嗪'=>'qin','噙'=>'qin','坅'=>'qin','埁'=>'qin','媇'=>'qin','嫀'=>'qin','寑'=>'qin','寝'=>'qin','寢'=>'qin','寴'=>'qin','嵚'=>'qin','嶔'=>'qin','庈'=>'qin','懃'=>'qin','懄'=>'qin','抋'=>'qin','捦'=>'qin','揿'=>'qin','搇'=>'qin','撳'=>'qin','擒'=>'qin','斳'=>'qin','昑'=>'qin','梫'=>'qin','檎'=>'qin','欽'=>'qin','沁'=>'qin','溱'=>'qin','澿'=>'qin','瀙'=>'qin','珡'=>'qin','琴'=>'qin','琹'=>'qin','瘽'=>'qin','矝'=>'qin','禽'=>'qin','秦'=>'qin','笉'=>'qin','綅'=>'qin','耹'=>'qin','芩'=>'qin','芹'=>'qin','菣'=>'qin','菦'=>'qin','菳'=>'qin','藽'=>'qin','蚙'=>'qin','螓'=>'qin','螼'=>'qin','蠄'=>'qin','衾'=>'qin','親'=>'qin','誛'=>'qin','赺'=>'qin','赾'=>'qin','鈙'=>'qin','鋟'=>'qin','钦'=>'qin','锓'=>'qin','雂'=>'qin','靲'=>'qin','顉'=>'qin','駸'=>'qin','骎'=>'qin','鮼'=>'qin','鳹'=>'qin','㝲'=>'qin','㞬'=>'qin','㢙'=>'qin','㤈'=>'qin','㩒'=>'qin','㪁'=>'qin','㮗'=>'qin','㾛'=>'qin','䈜'=>'qin','䔷'=>'qin','䖌'=>'qin','䠴'=>'qin','䦦'=>'qin','亳'=>'bo','仢'=>'bo','伯'=>'bo','侼'=>'bo','僠'=>'bo','僰'=>'bo','勃'=>'bo','博'=>'bo','卜'=>'bo','啵'=>'bo','嚗'=>'bo','壆'=>'bo','孛'=>'bo','孹'=>'bo','嶓'=>'bo','帛'=>'bo','愽'=>'bo','懪'=>'bo','拨'=>'bo','挬'=>'bo','捕'=>'bo','搏'=>'bo','撥'=>'bo','播'=>'bo','擘'=>'bo','柭'=>'bo','桲'=>'bo','檗'=>'bo','欂'=>'bo','泊'=>'bo','波'=>'bo','浡'=>'bo','淿'=>'bo','渤'=>'bo','湐'=>'bo','煿'=>'bo','牔'=>'bo','犦'=>'bo','犻'=>'bo','狛'=>'bo','猼'=>'bo','玻'=>'bo','瓝'=>'bo','瓟'=>'bo','癶'=>'bo','癷'=>'bo','盋'=>'bo','砵'=>'bo','碆'=>'bo','磻'=>'bo','礡'=>'bo','礴'=>'bo','秡'=>'bo','箔'=>'bo','箥'=>'bo','簙'=>'bo','簸'=>'bo','糪'=>'bo','紴'=>'bo','缽'=>'bo','胉'=>'bo','脖'=>'bo','膊'=>'bo','舶'=>'bo','艊'=>'bo','苩'=>'bo','菠'=>'bo','葧'=>'bo','蔔'=>'bo','蘗'=>'bo','蚾'=>'bo','袚'=>'bo','袯'=>'bo','袰'=>'bo','襏'=>'bo','襮'=>'bo','譒'=>'bo','豰'=>'bo','跛'=>'bo','踣'=>'bo','蹳'=>'bo','郣'=>'bo','鈸'=>'bo','鉑'=>'bo','鉢'=>'bo','鋍'=>'bo','鎛'=>'bo','鑮'=>'bo','钵'=>'bo','钹'=>'bo','铂'=>'bo','镈'=>'bo','餑'=>'bo','餺'=>'bo','饽'=>'bo','馎'=>'bo','馛'=>'bo','馞'=>'bo','駁'=>'bo','駮'=>'bo','驋'=>'bo','驳'=>'bo','髆'=>'bo','髉'=>'bo','鮊'=>'bo','鱍'=>'bo','鲌'=>'bo','鵓'=>'bo','鹁'=>'bo','㖕'=>'bo','㗘'=>'bo','㝿'=>'bo','㟑'=>'bo','㧳'=>'bo','㩧'=>'bo','㩭'=>'bo','㪍'=>'bo','㬍'=>'bo','㬧'=>'bo','㱟'=>'bo','㴾'=>'bo','㶿'=>'bo','㹀'=>'bo','䂍'=>'bo','䊿'=>'bo','䍨'=>'bo','䍸'=>'bo','䑈'=>'bo','䒄'=>'bo','䗚'=>'bo','䙏'=>'bo','䞳'=>'bo','䟛'=>'bo','䢌'=>'bo','䥬'=>'bo','䪇'=>'bo','䪬'=>'bo','䫊'=>'bo','䬪'=>'bo','䭦'=>'bo','䭯'=>'bo','䮀'=>'bo','䮂'=>'bo','䯋'=>'bo','䰊'=>'bo','䶈'=>'bo','亷'=>'lian','僆'=>'lian','劆'=>'lian','匲'=>'lian','匳'=>'lian','嗹'=>'lian','噒'=>'lian','堜'=>'lian','奁'=>'lian','奩'=>'lian','娈'=>'lian','媡'=>'lian','嫾'=>'lian','嬚'=>'lian','帘'=>'lian','廉'=>'lian','怜'=>'lian','恋'=>'lian','慩'=>'lian','憐'=>'lian','戀'=>'lian','摙'=>'lian','敛'=>'lian','斂'=>'lian','梿'=>'lian','楝'=>'lian','槤'=>'lian','櫣'=>'lian','歛'=>'lian','殓'=>'lian','殮'=>'lian','浰'=>'lian','涟'=>'lian','湅'=>'lian','溓'=>'lian','漣'=>'lian','潋'=>'lian','澰'=>'lian','濂'=>'lian','濓'=>'lian','瀲'=>'lian','炼'=>'lian','煉'=>'lian','熑'=>'lian','燫'=>'lian','琏'=>'lian','瑓'=>'lian','璉'=>'lian','磏'=>'lian','稴'=>'lian','簾'=>'lian','籢'=>'lian','籨'=>'lian','練'=>'lian','縺'=>'lian','纞'=>'lian','练'=>'lian','羷'=>'lian','翴'=>'lian','联'=>'lian','聨'=>'lian','聫'=>'lian','聮'=>'lian','聯'=>'lian','脸'=>'lian','臁'=>'lian','臉'=>'lian','莲'=>'lian','萰'=>'lian','蓮'=>'lian','蔹'=>'lian','薕'=>'lian','蘝'=>'lian','蘞'=>'lian','螊'=>'lian','蠊'=>'lian','裢'=>'lian','裣'=>'lian','褳'=>'lian','襝'=>'lian','覝'=>'lian','謰'=>'lian','譧'=>'lian','蹥'=>'lian','连'=>'lian','連'=>'lian','鄻'=>'lian','錬'=>'lian','鍊'=>'lian','鎌'=>'lian','鏈'=>'lian','鐮'=>'lian','链'=>'lian','镰'=>'lian','鬑'=>'lian','鰊'=>'lian','鰱'=>'lian','鲢'=>'lian','㓎'=>'lian','㜃'=>'lian','㜕'=>'lian','㜻'=>'lian','㝺'=>'lian','㟀'=>'lian','㡘'=>'lian','㢘'=>'lian','㥕'=>'lian','㦁'=>'lian','㦑'=>'lian','㪘'=>'lian','㪝'=>'lian','㯬'=>'lian','㰈'=>'lian','㰸'=>'lian','㱨'=>'lian','㶌'=>'lian','㶑'=>'lian','㺦'=>'lian','㼑'=>'lian','㼓'=>'lian','㾾'=>'lian','䁠'=>'lian','䃛'=>'lian','䆂'=>'lian','䇜'=>'lian','䌞'=>'lian','䏈'=>'lian','䙺'=>'lian','䥥'=>'lian','䨬'=>'lian','䭑'=>'lian','亸'=>'duo','仛'=>'duo','凙'=>'duo','刴'=>'duo','剁'=>'duo','剟'=>'duo','剫'=>'duo','咄'=>'duo','哆'=>'duo','哚'=>'duo','喥'=>'duo','嚉'=>'duo','嚲'=>'duo','垛'=>'duo','垜'=>'duo','埵'=>'duo','堕'=>'duo','墮'=>'duo','墯'=>'duo','多'=>'duo','夛'=>'duo','夺'=>'duo','奪'=>'duo','尮'=>'duo','崜'=>'duo','嶞'=>'duo','惰'=>'duo','憜'=>'duo','挅'=>'duo','挆'=>'duo','掇'=>'duo','敓'=>'duo','敚'=>'duo','敠'=>'duo','敪'=>'duo','朵'=>'duo','朶'=>'duo','柮'=>'duo','桗'=>'duo','椯'=>'duo','毲'=>'duo','沲'=>'duo','痥'=>'duo','綞'=>'duo','缍'=>'duo','舵'=>'duo','茤'=>'duo','裰'=>'duo','趓'=>'duo','跢'=>'duo','跥'=>'duo','跺'=>'duo','踱'=>'duo','躱'=>'duo','躲'=>'duo','軃'=>'duo','鈬'=>'duo','鐸'=>'duo','铎'=>'duo','陊'=>'duo','陏'=>'duo','飿'=>'duo','饳'=>'duo','鬌'=>'duo','鮵'=>'duo','鵽'=>'duo','㔍'=>'duo','㖼'=>'duo','㙐'=>'duo','㛆'=>'duo','㛊'=>'duo','㣞'=>'duo','㥩'=>'duo','㧷'=>'duo','㻔'=>'duo','㻧'=>'duo','䅜'=>'duo','䍴'=>'duo','䐾'=>'duo','䑨'=>'duo','䒳'=>'duo','䙃'=>'duo','䙟'=>'duo','䙤'=>'duo','䠤'=>'duo','䤪'=>'duo','䤻'=>'duo','䩔'=>'duo','䩣'=>'duo','䫂'=>'duo','䯬'=>'duo','人'=>'ren','亻'=>'ren','仁'=>'ren','仞'=>'ren','仭'=>'ren','任'=>'ren','刃'=>'ren','刄'=>'ren','壬'=>'ren','妊'=>'ren','姙'=>'ren','屻'=>'ren','忈'=>'ren','忍'=>'ren','忎'=>'ren','恁'=>'ren','扨'=>'ren','朲'=>'ren','杒'=>'ren','栠'=>'ren','栣'=>'ren','梕'=>'ren','棯'=>'ren','牣'=>'ren','秂'=>'ren','秹'=>'ren','稔'=>'ren','紉'=>'ren','紝'=>'ren','絍'=>'ren','綛'=>'ren','纫'=>'ren','纴'=>'ren','肕'=>'ren','腍'=>'ren','芢'=>'ren','荏'=>'ren','荵'=>'ren','葚'=>'ren','衽'=>'ren','袵'=>'ren','訒'=>'ren','認'=>'ren','认'=>'ren','讱'=>'ren','躵'=>'ren','軔'=>'ren','轫'=>'ren','鈓'=>'ren','銋'=>'ren','靭'=>'ren','靱'=>'ren','韌'=>'ren','韧'=>'ren','飪'=>'ren','餁'=>'ren','饪'=>'ren','魜'=>'ren','鵀'=>'ren','㠴'=>'ren','㣼'=>'ren','㶵'=>'ren','㸾'=>'ren','䀼'=>'ren','䇮'=>'ren','䋕'=>'ren','䌾'=>'ren','䏕'=>'ren','䏰'=>'ren','䭃'=>'ren','䴦'=>'ren','亽'=>'ra','囕'=>'ra','罖'=>'ra','仄'=>'ze','伬'=>'ze','则'=>'ze','則'=>'ze','唶'=>'ze','啧'=>'ze','啫'=>'ze','嘖'=>'ze','夨'=>'ze','嫧'=>'ze','崱'=>'ze','帻'=>'ze','幘'=>'ze','庂'=>'ze','択'=>'ze','择'=>'ze','捑'=>'ze','擇'=>'ze','昃'=>'ze','昗'=>'ze','樍'=>'ze','歵'=>'ze','汄'=>'ze','沢'=>'ze','泎'=>'ze','泽'=>'ze','溭'=>'ze','澤'=>'ze','皟'=>'ze','瞔'=>'ze','矠'=>'ze','礋'=>'ze','稄'=>'ze','笮'=>'ze','箦'=>'ze','簀'=>'ze','耫'=>'ze','舴'=>'ze','蔶'=>'ze','蠌'=>'ze','襗'=>'ze','諎'=>'ze','謮'=>'ze','責'=>'ze','賾'=>'ze','责'=>'ze','赜'=>'ze','迮'=>'ze','鸅'=>'ze','齚'=>'ze','齰'=>'ze','㖽'=>'ze','㣱'=>'ze','㳁'=>'ze','㳻'=>'ze','䃎'=>'ze','䇥'=>'ze','䕉'=>'ze','䕪'=>'ze','䰹'=>'ze','䶦'=>'ze','仅'=>'jin','今'=>'jin','伒'=>'jin','侭'=>'jin','僅'=>'jin','僸'=>'jin','儘'=>'jin','兓'=>'jin','凚'=>'jin','劤'=>'jin','劲'=>'jin','勁'=>'jin','卺'=>'jin','厪'=>'jin','噤'=>'jin','嚍'=>'jin','埐'=>'jin','堇'=>'jin','堻'=>'jin','墐'=>'jin','壗'=>'jin','妗'=>'jin','嫤'=>'jin','嬧'=>'jin','寖'=>'jin','尽'=>'jin','嶜'=>'jin','巹'=>'jin','巾'=>'jin','廑'=>'jin','惍'=>'jin','慬'=>'jin','搢'=>'jin','斤'=>'jin','晉'=>'jin','晋'=>'jin','枃'=>'jin','槿'=>'jin','歏'=>'jin','殣'=>'jin','津'=>'jin','浕'=>'jin','浸'=>'jin','溍'=>'jin','漌'=>'jin','濅'=>'jin','濜'=>'jin','烬'=>'jin','煡'=>'jin','燼'=>'jin','珒'=>'jin','琎'=>'jin','琻'=>'jin','瑨'=>'jin','瑾'=>'jin','璡'=>'jin','璶'=>'jin','盡'=>'jin','矜'=>'jin','砛'=>'jin','祲'=>'jin','禁'=>'jin','筋'=>'jin','紟'=>'jin','紧'=>'jin','緊'=>'jin','縉'=>'jin','缙'=>'jin','荕'=>'jin','荩'=>'jin','菫'=>'jin','蓳'=>'jin','藎'=>'jin','衿'=>'jin','襟'=>'jin','覲'=>'jin','觐'=>'jin','觔'=>'jin','謹'=>'jin','谨'=>'jin','賮'=>'jin','贐'=>'jin','赆'=>'jin','近'=>'jin','进'=>'jin','進'=>'jin','金'=>'jin','釒'=>'jin','錦'=>'jin','钅'=>'jin','锦'=>'jin','靳'=>'jin','饉'=>'jin','馑'=>'jin','鹶'=>'jin','黅'=>'jin','齽'=>'jin','㝻'=>'jin','㨷'=>'jin','㬐'=>'jin','㬜'=>'jin','㯲'=>'jin','㯸'=>'jin','㰹'=>'jin','㱈'=>'jin','㴆'=>'jin','㶦'=>'jin','㶳'=>'jin','㹏'=>'jin','䀆'=>'jin','䆮'=>'jin','䋮'=>'jin','䌝'=>'jin','䐶'=>'jin','䑤'=>'jin','䒺'=>'jin','䖐'=>'jin','䗯'=>'jin','䝲'=>'jin','䤐'=>'jin','䥆'=>'jin','䫴'=>'jin','䭙'=>'jin','䶖'=>'jin','仆'=>'pu','僕'=>'pu','匍'=>'pu','噗'=>'pu','圃'=>'pu','圑'=>'pu','圤'=>'pu','埔'=>'pu','墣'=>'pu','巬'=>'pu','巭'=>'pu','扑'=>'pu','抪'=>'pu','撲'=>'pu','擈'=>'pu','攴'=>'pu','攵'=>'pu','普'=>'pu','暜'=>'pu','曝'=>'pu','朴'=>'pu','柨'=>'pu','樸'=>'pu','檏'=>'pu','氆'=>'pu','浦'=>'pu','溥'=>'pu','潽'=>'pu','濮'=>'pu','瀑'=>'pu','炇'=>'pu','烳'=>'pu','璞'=>'pu','痡'=>'pu','瞨'=>'pu','穙'=>'pu','纀'=>'pu','舖'=>'pu','舗'=>'pu','莆'=>'pu','菐'=>'pu','菩'=>'pu','葡'=>'pu','蒱'=>'pu','蒲'=>'pu','諩'=>'pu','譜'=>'pu','谱'=>'pu','贌'=>'pu','蹼'=>'pu','酺'=>'pu','鋪'=>'pu','鏷'=>'pu','鐠'=>'pu','铺'=>'pu','镤'=>'pu','镨'=>'pu','陠'=>'pu','駇'=>'pu','鯆'=>'pu','㒒'=>'pu','㬥'=>'pu','㯷'=>'pu','㲫'=>'pu','㹒'=>'pu','㺪'=>'pu','䈬'=>'pu','䈻'=>'pu','䑑'=>'pu','䔕'=>'pu','䗱'=>'pu','䧤'=>'pu','䲕'=>'pu','䴆'=>'pu','仈'=>'ba','八'=>'ba','叐'=>'ba','叭'=>'ba','吧'=>'ba','哵'=>'ba','坝'=>'ba','坺'=>'ba','垻'=>'ba','墢'=>'ba','壩'=>'ba','夿'=>'ba','妭'=>'ba','岜'=>'ba','巴'=>'ba','弝'=>'ba','扒'=>'ba','把'=>'ba','抜'=>'ba','拔'=>'ba','捌'=>'ba','朳'=>'ba','欛'=>'ba','灞'=>'ba','炦'=>'ba','爸'=>'ba','犮'=>'ba','玐'=>'ba','疤'=>'ba','癹'=>'ba','矲'=>'ba','笆'=>'ba','粑'=>'ba','紦'=>'ba','罢'=>'ba','罷'=>'ba','羓'=>'ba','耙'=>'ba','胈'=>'ba','芭'=>'ba','茇'=>'ba','菝'=>'ba','蚆'=>'ba','覇'=>'ba','詙'=>'ba','豝'=>'ba','跁'=>'ba','跋'=>'ba','軷'=>'ba','釛'=>'ba','釟'=>'ba','鈀'=>'ba','钯'=>'ba','霸'=>'ba','靶'=>'ba','颰'=>'ba','魃'=>'ba','魞'=>'ba','鮁'=>'ba','鲃'=>'ba','鲅'=>'ba','鼥'=>'ba','㔜'=>'ba','㖠'=>'ba','㞎'=>'ba','㧊'=>'ba','㶚'=>'ba','䃻'=>'ba','䆉'=>'ba','䇑'=>'ba','䎬'=>'ba','䟦'=>'ba','䥯'=>'ba','䩗'=>'ba','䩻'=>'ba','䰾'=>'ba','䱝'=>'ba','䳁'=>'ba','䳊'=>'ba','仍'=>'reng','扔'=>'reng','礽'=>'reng','芿'=>'reng','辸'=>'reng','陾'=>'reng','㭁'=>'reng','㺱'=>'reng','䄧'=>'reng','䚮'=>'reng','仏'=>'fo','佛'=>'fo','坲'=>'fo','梻'=>'fo','仐'=>'tao','匋'=>'tao','咷'=>'tao','啕'=>'tao','夲'=>'tao','套'=>'tao','嫍'=>'tao','幍'=>'tao','弢'=>'tao','慆'=>'tao','掏'=>'tao','搯'=>'tao','桃'=>'tao','梼'=>'tao','槄'=>'tao','檮'=>'tao','洮'=>'tao','涛'=>'tao','淘'=>'tao','滔'=>'tao','濤'=>'tao','瑫'=>'tao','畓'=>'tao','祹'=>'tao','絛'=>'tao','綯'=>'tao','縚'=>'tao','縧'=>'tao','绦'=>'tao','绹'=>'tao','萄'=>'tao','蜪'=>'tao','裪'=>'tao','討'=>'tao','詜'=>'tao','謟'=>'tao','讨'=>'tao','迯'=>'tao','逃'=>'tao','醄'=>'tao','鋾'=>'tao','錭'=>'tao','陶'=>'tao','鞀'=>'tao','鞉'=>'tao','鞱'=>'tao','韜'=>'tao','韬'=>'tao','飸'=>'tao','饀'=>'tao','饕'=>'tao','駣'=>'tao','騊'=>'tao','鼗'=>'tao','㚐'=>'tao','㹗'=>'tao','䚯'=>'tao','䚵'=>'tao','䬞'=>'tao','䵚'=>'tao','仑'=>'lun','伦'=>'lun','侖'=>'lun','倫'=>'lun','囵'=>'lun','圇'=>'lun','埨'=>'lun','婨'=>'lun','崘'=>'lun','崙'=>'lun','惀'=>'lun','抡'=>'lun','掄'=>'lun','棆'=>'lun','沦'=>'lun','淪'=>'lun','溣'=>'lun','碖'=>'lun','磮'=>'lun','稐'=>'lun','綸'=>'lun','纶'=>'lun','耣'=>'lun','腀'=>'lun','菕'=>'lun','蜦'=>'lun','論'=>'lun','论'=>'lun','踚'=>'lun','輪'=>'lun','轮'=>'lun','錀'=>'lun','陯'=>'lun','鯩'=>'lun','㖮'=>'lun','㷍'=>'lun','䈁'=>'lun','䑳'=>'lun','仓'=>'cang','仺'=>'cang','伧'=>'cang','倉'=>'cang','傖'=>'cang','凔'=>'cang','匨'=>'cang','嵢'=>'cang','欌'=>'cang','沧'=>'cang','滄'=>'cang','濸'=>'cang','獊'=>'cang','罉'=>'cang','舱'=>'cang','艙'=>'cang','苍'=>'cang','蒼'=>'cang','蔵'=>'cang','藏'=>'cang','螥'=>'cang','賶'=>'cang','鑶'=>'cang','鶬'=>'cang','鸧'=>'cang','㵴'=>'cang','㶓'=>'cang','䅮'=>'cang','䢢'=>'cang','仔'=>'zi','倳'=>'zi','兹'=>'zi','剚'=>'zi','吇'=>'zi','呰'=>'zi','咨'=>'zi','唨'=>'zi','啙'=>'zi','嗞'=>'zi','姉'=>'zi','姊'=>'zi','姕'=>'zi','姿'=>'zi','子'=>'zi','孖'=>'zi','字'=>'zi','孜'=>'zi','孳'=>'zi','孶'=>'zi','崰'=>'zi','嵫'=>'zi','恣'=>'zi','杍'=>'zi','栥'=>'zi','梓'=>'zi','椔'=>'zi','榟'=>'zi','橴'=>'zi','淄'=>'zi','渍'=>'zi','湽'=>'zi','滋'=>'zi','滓'=>'zi','漬'=>'zi','澬'=>'zi','牸'=>'zi','玆'=>'zi','眥'=>'zi','眦'=>'zi','矷'=>'zi','禌'=>'zi','秄'=>'zi','秭'=>'zi','秶'=>'zi','稵'=>'zi','笫'=>'zi','籽'=>'zi','粢'=>'zi','紎'=>'zi','紫'=>'zi','緇'=>'zi','缁'=>'zi','耔'=>'zi','胏'=>'zi','胔'=>'zi','胾'=>'zi','自'=>'zi','芓'=>'zi','茊'=>'zi','茡'=>'zi','茲'=>'zi','葘'=>'zi','虸'=>'zi','觜'=>'zi','訾'=>'zi','訿'=>'zi','諮'=>'zi','谘'=>'zi','貲'=>'zi','資'=>'zi','赀'=>'zi','资'=>'zi','赼'=>'zi','趑'=>'zi','趦'=>'zi','輜'=>'zi','輺'=>'zi','辎'=>'zi','鄑'=>'zi','釨'=>'zi','鈭'=>'zi','錙'=>'zi','鍿'=>'zi','鎡'=>'zi','锱'=>'zi','镃'=>'zi','頾'=>'zi','頿'=>'zi','髭'=>'zi','鯔'=>'zi','鰦'=>'zi','鲻'=>'zi','鶅'=>'zi','鼒'=>'zi','齍'=>'zi','齜'=>'zi','龇'=>'zi','㜽'=>'zi','㧗'=>'zi','㰣'=>'zi','㰷'=>'zi','㱴'=>'zi','㺭'=>'zi','䅆'=>'zi','䐉'=>'zi','䔂'=>'zi','䘣'=>'zi','他'=>'ta','侤'=>'ta','咜'=>'ta','嚃'=>'ta','嚺'=>'ta','塌'=>'ta','塔'=>'ta','墖'=>'ta','她'=>'ta','它'=>'ta','崉'=>'ta','挞'=>'ta','搨'=>'ta','撻'=>'ta','榙'=>'ta','榻'=>'ta','毾'=>'ta','涾'=>'ta','溻'=>'ta','澾'=>'ta','濌'=>'ta','牠'=>'ta','狧'=>'ta','獭'=>'ta','獺'=>'ta','祂'=>'ta','禢'=>'ta','褟'=>'ta','襨'=>'ta','誻'=>'ta','譶'=>'ta','趿'=>'ta','踏'=>'ta','蹋'=>'ta','蹹'=>'ta','躢'=>'ta','遝'=>'ta','遢'=>'ta','鉈'=>'ta','錔'=>'ta','铊'=>'ta','闒'=>'ta','闥'=>'ta','闼'=>'ta','阘'=>'ta','鞜'=>'ta','鞳'=>'ta','鮙'=>'ta','鰨'=>'ta','鳎'=>'ta','㒓'=>'ta','㗳'=>'ta','㛥'=>'ta','㣛'=>'ta','㣵'=>'ta','㧺'=>'ta','㭼'=>'ta','㯓'=>'ta','㳠'=>'ta','㳫'=>'ta','㹺'=>'ta','㺚'=>'ta','㿹'=>'ta','䂿'=>'ta','䈋'=>'ta','䈳'=>'ta','䌈'=>'ta','䍇'=>'ta','䍝'=>'ta','䎓'=>'ta','䑜'=>'ta','䓠'=>'ta','䜚'=>'ta','䵬'=>'ta','䶀'=>'ta','䶁'=>'ta','仙'=>'xian','仚'=>'xian','伭'=>'xian','佡'=>'xian','僊'=>'xian','僩'=>'xian','僲'=>'xian','僴'=>'xian','先'=>'xian','冼'=>'xian','县'=>'xian','咞'=>'xian','咸'=>'xian','哯'=>'xian','唌'=>'xian','啣'=>'xian','嘕'=>'xian','垷'=>'xian','奾'=>'xian','妶'=>'xian','姭'=>'xian','娊'=>'xian','娨'=>'xian','娴'=>'xian','娹'=>'xian','婱'=>'xian','嫌'=>'xian','嫺'=>'xian','嫻'=>'xian','嬐'=>'xian','孅'=>'xian','宪'=>'xian','尟'=>'xian','尠'=>'xian','屳'=>'xian','岘'=>'xian','峴'=>'xian','崄'=>'xian','嶮'=>'xian','幰'=>'xian','廯'=>'xian','弦'=>'xian','忺'=>'xian','憪'=>'xian','憲'=>'xian','憸'=>'xian','挦'=>'xian','掀'=>'xian','搟'=>'xian','撊'=>'xian','撏'=>'xian','攇'=>'xian','攕'=>'xian','显'=>'xian','晛'=>'xian','暹'=>'xian','杴'=>'xian','枮'=>'xian','橌'=>'xian','櫶'=>'xian','毨'=>'xian','氙'=>'xian','涀'=>'xian','涎'=>'xian','湺'=>'xian','澖'=>'xian','瀗'=>'xian','灦'=>'xian','烍'=>'xian','燹'=>'xian','狝'=>'xian','猃'=>'xian','献'=>'xian','獫'=>'xian','獮'=>'xian','獻'=>'xian','玁'=>'xian','现'=>'xian','珗'=>'xian','現'=>'xian','甉'=>'xian','痫'=>'xian','癇'=>'xian','癎'=>'xian','県'=>'xian','睍'=>'xian','硍'=>'xian','礥'=>'xian','祆'=>'xian','禒'=>'xian','秈'=>'xian','筅'=>'xian','箲'=>'xian','籼'=>'xian','粯'=>'xian','糮'=>'xian','絃'=>'xian','絤'=>'xian','綫'=>'xian','線'=>'xian','縣'=>'xian','繊'=>'xian','纎'=>'xian','纖'=>'xian','纤'=>'xian','线'=>'xian','缐'=>'xian','羡'=>'xian','羨'=>'xian','胘'=>'xian','腺'=>'xian','臔'=>'xian','臽'=>'xian','舷'=>'xian','苋'=>'xian','苮'=>'xian','莧'=>'xian','莶'=>'xian','薟'=>'xian','藓'=>'xian','藔'=>'xian','藖'=>'xian','蘚'=>'xian','蚬'=>'xian','蚿'=>'xian','蛝'=>'xian','蜆'=>'xian','衔'=>'xian','衘'=>'xian','褼'=>'xian','襳'=>'xian','誢'=>'xian','誸'=>'xian','諴'=>'xian','譣'=>'xian','豏'=>'xian','賢'=>'xian','贒'=>'xian','贤'=>'xian','赻'=>'xian','跣'=>'xian','跹'=>'xian','蹮'=>'xian','躚'=>'xian','輱'=>'xian','酰'=>'xian','醎'=>'xian','銛'=>'xian','銜'=>'xian','鋧'=>'xian','錎'=>'xian','鍁'=>'xian','鍂'=>'xian','鍌'=>'xian','鏾'=>'xian','鑦'=>'xian','铦'=>'xian','锨'=>'xian','閑'=>'xian','闲'=>'xian','限'=>'xian','陥'=>'xian','险'=>'xian','陷'=>'xian','険'=>'xian','險'=>'xian','霰'=>'xian','韅'=>'xian','韯'=>'xian','韱'=>'xian','顕'=>'xian','顯'=>'xian','餡'=>'xian','馅'=>'xian','馦'=>'xian','鮮'=>'xian','鱻'=>'xian','鲜'=>'xian','鶱'=>'xian','鷳'=>'xian','鷴'=>'xian','鷼'=>'xian','鹇'=>'xian','鹹'=>'xian','麲'=>'xian','鼸'=>'xian','㔵'=>'xian','㘅'=>'xian','㘋'=>'xian','㛾'=>'xian','㜪'=>'xian','㡉'=>'xian','㡾'=>'xian','㢺'=>'xian','㦓'=>'xian','㧋'=>'xian','㧥'=>'xian','㩈'=>'xian','㪇'=>'xian','㫫'=>'xian','㬎'=>'xian','㬗'=>'xian','㭠'=>'xian','㭹'=>'xian','㮭'=>'xian','㯀'=>'xian','㳄'=>'xian','㳭'=>'xian','㵪'=>'xian','㶍'=>'xian','㺌'=>'xian','㿅'=>'xian','䀏'=>'xian','䁂'=>'xian','䃱'=>'xian','䃸'=>'xian','䉯'=>'xian','䉳'=>'xian','䏹'=>'xian','䒸'=>'xian','䕔'=>'xian','䗾'=>'xian','䘆'=>'xian','䚚'=>'xian','䜢'=>'xian','䝨'=>'xian','䞁'=>'xian','䢾'=>'xian','䤼'=>'xian','䥪'=>'xian','䦥'=>'xian','䧋'=>'xian','䧟'=>'xian','䧮'=>'xian','䨘'=>'xian','䨷'=>'xian','䱤'=>'xian','䲗'=>'xian','䵇'=>'xian','䶟'=>'xian','䶢'=>'xian','仜'=>'hong','叿'=>'hong','吰'=>'hong','哄'=>'hong','嗊'=>'hong','嚝'=>'hong','垬'=>'hong','妅'=>'hong','娂'=>'hong','宏'=>'hong','宖'=>'hong','弘'=>'hong','彋'=>'hong','揈'=>'hong','撔'=>'hong','晎'=>'hong','汯'=>'hong','泓'=>'hong','洪'=>'hong','浤'=>'hong','渱'=>'hong','渹'=>'hong','潂'=>'hong','澋'=>'hong','澒'=>'hong','灴'=>'hong','烘'=>'hong','焢'=>'hong','玒'=>'hong','玜'=>'hong','硔'=>'hong','硡'=>'hong','竑'=>'hong','竤'=>'hong','篊'=>'hong','粠'=>'hong','紅'=>'hong','紘'=>'hong','紭'=>'hong','綋'=>'hong','红'=>'hong','纮'=>'hong','翃'=>'hong','翝'=>'hong','耾'=>'hong','苰'=>'hong','荭'=>'hong','葒'=>'hong','葓'=>'hong','蕻'=>'hong','薨'=>'hong','虹'=>'hong','訇'=>'hong','訌'=>'hong','讧'=>'hong','谹'=>'hong','谼'=>'hong','谾'=>'hong','軣'=>'hong','輷'=>'hong','轟'=>'hong','轰'=>'hong','鈜'=>'hong','鉷'=>'hong','銾'=>'hong','鋐'=>'hong','鍧'=>'hong','閎'=>'hong','閧'=>'hong','闀'=>'hong','闂'=>'hong','闳'=>'hong','霐'=>'hong','霟'=>'hong','鞃'=>'hong','鬨'=>'hong','魟'=>'hong','鴻'=>'hong','鸿'=>'hong','黉'=>'hong','黌'=>'hong','㖓'=>'hong','㢬'=>'hong','㬴'=>'hong','㶹'=>'hong','䀧'=>'hong','䂫'=>'hong','䃔'=>'hong','䆖'=>'hong','䉺'=>'hong','䍔'=>'hong','䜫'=>'hong','䞑'=>'hong','䡌'=>'hong','䡏'=>'hong','䧆'=>'hong','䨎'=>'hong','䩑'=>'hong','䪦'=>'hong','䫹'=>'hong','䫺'=>'hong','䲨'=>'hong','仝'=>'tong','佟'=>'tong','僮'=>'tong','勭'=>'tong','同'=>'tong','哃'=>'tong','嗵'=>'tong','囲'=>'tong','峂'=>'tong','庝'=>'tong','彤'=>'tong','恸'=>'tong','慟'=>'tong','憅'=>'tong','捅'=>'tong','晍'=>'tong','曈'=>'tong','朣'=>'tong','桐'=>'tong','桶'=>'tong','樋'=>'tong','橦'=>'tong','氃'=>'tong','浵'=>'tong','潼'=>'tong','炵'=>'tong','烔'=>'tong','熥'=>'tong','犝'=>'tong','狪'=>'tong','獞'=>'tong','痌'=>'tong','痛'=>'tong','眮'=>'tong','瞳'=>'tong','砼'=>'tong','秱'=>'tong','穜'=>'tong','童'=>'tong','筒'=>'tong','筩'=>'tong','粡'=>'tong','絧'=>'tong','統'=>'tong','綂'=>'tong','统'=>'tong','膧'=>'tong','茼'=>'tong','蓪'=>'tong','蚒'=>'tong','衕'=>'tong','赨'=>'tong','通'=>'tong','酮'=>'tong','鉖'=>'tong','鉵'=>'tong','銅'=>'tong','铜'=>'tong','餇'=>'tong','鮦'=>'tong','鲖'=>'tong','㛚'=>'tong','㠉'=>'tong','㠽'=>'tong','㣚'=>'tong','㣠'=>'tong','㤏'=>'tong','㪌'=>'tong','㮔'=>'tong','㸗'=>'tong','㼧'=>'tong','㼿'=>'tong','䂈'=>'tong','䆚'=>'tong','䆹'=>'tong','䮵'=>'tong','䳋'=>'tong','䴀'=>'tong','䶱'=>'tong','代'=>'dai','侢'=>'dai','傣'=>'dai','叇'=>'dai','呆'=>'dai','呔'=>'dai','垈'=>'dai','埭'=>'dai','岱'=>'dai','帒'=>'dai','带'=>'dai','帯'=>'dai','帶'=>'dai','廗'=>'dai','待'=>'dai','怠'=>'dai','懛'=>'dai','戴'=>'dai','曃'=>'dai','柋'=>'dai','歹'=>'dai','殆'=>'dai','汏'=>'dai','瀻'=>'dai','獃'=>'dai','玳'=>'dai','瑇'=>'dai','甙'=>'dai','簤'=>'dai','紿'=>'dai','緿'=>'dai','绐'=>'dai','艜'=>'dai','蚮'=>'dai','袋'=>'dai','襶'=>'dai','貸'=>'dai','贷'=>'dai','蹛'=>'dai','軑'=>'dai','軚'=>'dai','軩'=>'dai','轪'=>'dai','迨'=>'dai','逮'=>'dai','霴'=>'dai','靆'=>'dai','鮘'=>'dai','鴏'=>'dai','黛'=>'dai','黱'=>'dai','㐲'=>'dai','㞭'=>'dai','㫹'=>'dai','㯂'=>'dai','㶡'=>'dai','㻖'=>'dai','㿃'=>'dai','䈆'=>'dai','䒫'=>'dai','䚞'=>'dai','䚟'=>'dai','令'=>'ling','伶'=>'ling','凌'=>'ling','刢'=>'ling','另'=>'ling','呤'=>'ling','囹'=>'ling','坽'=>'ling','夌'=>'ling','姈'=>'ling','婈'=>'ling','孁'=>'ling','岭'=>'ling','岺'=>'ling','崚'=>'ling','嶺'=>'ling','彾'=>'ling','掕'=>'ling','昤'=>'ling','朎'=>'ling','柃'=>'ling','棂'=>'ling','櫺'=>'ling','欞'=>'ling','泠'=>'ling','淩'=>'ling','澪'=>'ling','瀮'=>'ling','灵'=>'ling','炩'=>'ling','燯'=>'ling','爧'=>'ling','狑'=>'ling','玲'=>'ling','琌'=>'ling','瓴'=>'ling','皊'=>'ling','砱'=>'ling','祾'=>'ling','秢'=>'ling','竛'=>'ling','笭'=>'ling','紷'=>'ling','綾'=>'ling','绫'=>'ling','羚'=>'ling','翎'=>'ling','聆'=>'ling','舲'=>'ling','苓'=>'ling','菱'=>'ling','蓤'=>'ling','蔆'=>'ling','蕶'=>'ling','蘦'=>'ling','蛉'=>'ling','衑'=>'ling','袊'=>'ling','裬'=>'ling','詅'=>'ling','跉'=>'ling','軨'=>'ling','輘'=>'ling','酃'=>'ling','醽'=>'ling','鈴'=>'ling','錂'=>'ling','铃'=>'ling','閝'=>'ling','阾'=>'ling','陵'=>'ling','零'=>'ling','霊'=>'ling','霗'=>'ling','霛'=>'ling','霝'=>'ling','靈'=>'ling','領'=>'ling','领'=>'ling','駖'=>'ling','魿'=>'ling','鯪'=>'ling','鲮'=>'ling','鴒'=>'ling','鸰'=>'ling','鹷'=>'ling','麢'=>'ling','齡'=>'ling','齢'=>'ling','龄'=>'ling','龗'=>'ling','㖫'=>'ling','㡵'=>'ling','㥄'=>'ling','㦭'=>'ling','㪮'=>'ling','㬡'=>'ling','㯪'=>'ling','㱥'=>'ling','㲆'=>'ling','㸳'=>'ling','㻏'=>'ling','㾉'=>'ling','䄥'=>'ling','䈊'=>'ling','䉁'=>'ling','䉖'=>'ling','䉹'=>'ling','䌢'=>'ling','䍅'=>'ling','䔖'=>'ling','䕘'=>'ling','䖅'=>'ling','䙥'=>'ling','䚖'=>'ling','䠲'=>'ling','䡼'=>'ling','䡿'=>'ling','䧙'=>'ling','䨩'=>'ling','䯍'=>'ling','䰱'=>'ling','䴇'=>'ling','䴒'=>'ling','䴫'=>'ling','仦'=>'chao','仯'=>'chao','吵'=>'chao','嘲'=>'chao','巐'=>'chao','巢'=>'chao','巣'=>'chao','弨'=>'chao','怊'=>'chao','抄'=>'chao','晁'=>'chao','朝'=>'chao','樔'=>'chao','欩'=>'chao','漅'=>'chao','潮'=>'chao','炒'=>'chao','焯'=>'chao','煼'=>'chao','牊'=>'chao','眧'=>'chao','窲'=>'chao','繛'=>'chao','罺'=>'chao','耖'=>'chao','觘'=>'chao','訬'=>'chao','謿'=>'chao','超'=>'chao','轈'=>'chao','鄛'=>'chao','鈔'=>'chao','钞'=>'chao','麨'=>'chao','鼂'=>'chao','鼌'=>'chao','㶤'=>'chao','㷅'=>'chao','䄻'=>'chao','䎐'=>'chao','䏚'=>'chao','䬤'=>'chao','䰫'=>'chao','仧'=>'chang','伥'=>'chang','倀'=>'chang','倡'=>'chang','偿'=>'chang','僘'=>'chang','償'=>'chang','兏'=>'chang','厂'=>'chang','厰'=>'chang','唱'=>'chang','嘗'=>'chang','嚐'=>'chang','场'=>'chang','場'=>'chang','塲'=>'chang','娼'=>'chang','嫦'=>'chang','尝'=>'chang','常'=>'chang','廠'=>'chang','徜'=>'chang','怅'=>'chang','悵'=>'chang','惝'=>'chang','敞'=>'chang','昌'=>'chang','昶'=>'chang','晿'=>'chang','暢'=>'chang','椙'=>'chang','氅'=>'chang','淐'=>'chang','猖'=>'chang','玚'=>'chang','琩'=>'chang','瑒'=>'chang','瑺'=>'chang','瓺'=>'chang','甞'=>'chang','畅'=>'chang','畼'=>'chang','肠'=>'chang','腸'=>'chang','膓'=>'chang','苌'=>'chang','菖'=>'chang','萇'=>'chang','蟐'=>'chang','裮'=>'chang','誯'=>'chang','鋹'=>'chang','鋿'=>'chang','錩'=>'chang','鏛'=>'chang','锠'=>'chang','長'=>'chang','镸'=>'chang','长'=>'chang','閶'=>'chang','阊'=>'chang','韔'=>'chang','鬯'=>'chang','鯧'=>'chang','鱨'=>'chang','鲳'=>'chang','鲿'=>'chang','鼚'=>'chang','㙊'=>'chang','㦂'=>'chang','㫤'=>'chang','䕋'=>'chang','䗅'=>'chang','䠀'=>'chang','䠆'=>'chang','䩨'=>'chang','䯴'=>'chang','仨'=>'sa','卅'=>'sa','摋'=>'sa','撒'=>'sa','栍'=>'sa','桬'=>'sa','櫒'=>'sa','洒'=>'sa','潵'=>'sa','灑'=>'sa','脎'=>'sa','萨'=>'sa','薩'=>'sa','訯'=>'sa','鈒'=>'sa','钑'=>'sa','隡'=>'sa','靸'=>'sa','颯'=>'sa','飒'=>'sa','馺'=>'sa','㒎'=>'sa','㪪'=>'sa','㳐'=>'sa','㽂'=>'sa','䊛'=>'sa','䘮'=>'sa','䙣'=>'sa','䬃'=>'sa','们'=>'men','們'=>'men','悶'=>'men','懑'=>'men','懣'=>'men','扪'=>'men','捫'=>'men','暪'=>'men','椚'=>'men','焖'=>'men','燜'=>'men','玣'=>'men','璊'=>'men','穈'=>'men','菛'=>'men','虋'=>'men','鍆'=>'men','钔'=>'men','門'=>'men','閅'=>'men','门'=>'men','闷'=>'men','㡈'=>'men','㥃'=>'men','㦖'=>'men','㨺'=>'men','㱪'=>'men','㵍'=>'men','䊟'=>'men','䝧'=>'men','䫒'=>'men','仮'=>'fan','凡'=>'fan','凢'=>'fan','凣'=>'fan','勫'=>'fan','匥'=>'fan','反'=>'fan','噃'=>'fan','墦'=>'fan','奿'=>'fan','嬎'=>'fan','嬏'=>'fan','嬔'=>'fan','帆'=>'fan','幡'=>'fan','忛'=>'fan','憣'=>'fan','払'=>'fan','旙'=>'fan','旛'=>'fan','杋'=>'fan','柉'=>'fan','梵'=>'fan','棥'=>'fan','樊'=>'fan','橎'=>'fan','氾'=>'fan','汎'=>'fan','泛'=>'fan','滼'=>'fan','瀪'=>'fan','瀿'=>'fan','烦'=>'fan','煩'=>'fan','燔'=>'fan','犯'=>'fan','犿'=>'fan','璠'=>'fan','畈'=>'fan','番'=>'fan','盕'=>'fan','矾'=>'fan','礬'=>'fan','笲'=>'fan','笵'=>'fan','範'=>'fan','籓'=>'fan','籵'=>'fan','緐'=>'fan','繁'=>'fan','繙'=>'fan','羳'=>'fan','翻'=>'fan','膰'=>'fan','舤'=>'fan','舧'=>'fan','范'=>'fan','蕃'=>'fan','薠'=>'fan','藩'=>'fan','蘩'=>'fan','蠜'=>'fan','襎'=>'fan','訉'=>'fan','販'=>'fan','贩'=>'fan','蹯'=>'fan','軓'=>'fan','軬'=>'fan','轓'=>'fan','辺'=>'fan','返'=>'fan','釩'=>'fan','鐇'=>'fan','钒'=>'fan','颿'=>'fan','飜'=>'fan','飯'=>'fan','飰'=>'fan','饭'=>'fan','鱕'=>'fan','鷭'=>'fan','㕨'=>'fan','㝃'=>'fan','㠶'=>'fan','㤆'=>'fan','㴀'=>'fan','㶗'=>'fan','㸋'=>'fan','㺕'=>'fan','㼝'=>'fan','㽹'=>'fan','䀀'=>'fan','䀟'=>'fan','䉊'=>'fan','䉒'=>'fan','䊩'=>'fan','䋣'=>'fan','䋦'=>'fan','䌓'=>'fan','䐪'=>'fan','䒠'=>'fan','䒦'=>'fan','䛀'=>'fan','䡊'=>'fan','䣲'=>'fan','䪛'=>'fan','䪤'=>'fan','䫶'=>'fan','䭵'=>'fan','䮳'=>'fan','仰'=>'yang','佒'=>'yang','佯'=>'yang','傟'=>'yang','养'=>'yang','劷'=>'yang','卬'=>'yang','咉'=>'yang','坱'=>'yang','垟'=>'yang','央'=>'yang','奍'=>'yang','姎'=>'yang','岟'=>'yang','崵'=>'yang','崸'=>'yang','徉'=>'yang','怏'=>'yang','恙'=>'yang','慃'=>'yang','懩'=>'yang','扬'=>'yang','抰'=>'yang','揚'=>'yang','攁'=>'yang','敭'=>'yang','旸'=>'yang','昜'=>'yang','暘'=>'yang','杨'=>'yang','柍'=>'yang','样'=>'yang','楊'=>'yang','楧'=>'yang','様'=>'yang','樣'=>'yang','殃'=>'yang','氜'=>'yang','氧'=>'yang','氱'=>'yang','泱'=>'yang','洋'=>'yang','漾'=>'yang','瀁'=>'yang','炀'=>'yang','炴'=>'yang','烊'=>'yang','煬'=>'yang','珜'=>'yang','疡'=>'yang','痒'=>'yang','瘍'=>'yang','癢'=>'yang','眏'=>'yang','眻'=>'yang','礢'=>'yang','禓'=>'yang','秧'=>'yang','紻'=>'yang','羊'=>'yang','羏'=>'yang','羕'=>'yang','羪'=>'yang','胦'=>'yang','蛘'=>'yang','詇'=>'yang','諹'=>'yang','軮'=>'yang','輰'=>'yang','鉠'=>'yang','鍈'=>'yang','鍚'=>'yang','鐊'=>'yang','钖'=>'yang','阦'=>'yang','阳'=>'yang','陽'=>'yang','雵'=>'yang','霷'=>'yang','鞅'=>'yang','颺'=>'yang','飏'=>'yang','養'=>'yang','駚'=>'yang','鰑'=>'yang','鴦'=>'yang','鴹'=>'yang','鸉'=>'yang','鸯'=>'yang','㔦'=>'yang','㟅'=>'yang','㨾'=>'yang','㬕'=>'yang','㺊'=>'yang','㿮'=>'yang','䁑'=>'yang','䇦'=>'yang','䑆'=>'yang','䒋'=>'yang','䖹'=>'yang','䬗'=>'yang','䬬'=>'yang','䬺'=>'yang','䭐'=>'yang','䵮'=>'yang','仴'=>'wo','倭'=>'wo','偓'=>'wo','卧'=>'wo','唩'=>'wo','喔'=>'wo','婐'=>'wo','婑'=>'wo','媉'=>'wo','幄'=>'wo','我'=>'wo','挝'=>'wo','捰'=>'wo','捾'=>'wo','握'=>'wo','撾'=>'wo','斡'=>'wo','楃'=>'wo','沃'=>'wo','涡'=>'wo','涹'=>'wo','渥'=>'wo','渦'=>'wo','濣'=>'wo','焥'=>'wo','猧'=>'wo','瓁'=>'wo','瞃'=>'wo','硪'=>'wo','窝'=>'wo','窩'=>'wo','肟'=>'wo','腛'=>'wo','臒'=>'wo','臥'=>'wo','莴'=>'wo','萵'=>'wo','蜗'=>'wo','蝸'=>'wo','踒'=>'wo','齷'=>'wo','龌'=>'wo','㠛'=>'wo','㦱'=>'wo','㧴'=>'wo','㱧'=>'wo','䁊'=>'wo','䠎'=>'wo','䰀'=>'wo','件'=>'jian','侟'=>'jian','俭'=>'jian','俴'=>'jian','倹'=>'jian','健'=>'jian','僭'=>'jian','儉'=>'jian','兼'=>'jian','冿'=>'jian','减'=>'jian','剑'=>'jian','剣'=>'jian','剪'=>'jian','剱'=>'jian','劍'=>'jian','劎'=>'jian','劒'=>'jian','劔'=>'jian','囏'=>'jian','囝'=>'jian','坚'=>'jian','堅'=>'jian','墹'=>'jian','奸'=>'jian','姦'=>'jian','姧'=>'jian','寋'=>'jian','尖'=>'jian','帴'=>'jian','幵'=>'jian','建'=>'jian','弿'=>'jian','彅'=>'jian','徤'=>'jian','惤'=>'jian','戋'=>'jian','戔'=>'jian','戩'=>'jian','戬'=>'jian','拣'=>'jian','挸'=>'jian','捡'=>'jian','揀'=>'jian','揃'=>'jian','搛'=>'jian','撿'=>'jian','擶'=>'jian','旔'=>'jian','暕'=>'jian','枧'=>'jian','柬'=>'jian','栫'=>'jian','梘'=>'jian','检'=>'jian','検'=>'jian','椷'=>'jian','椾'=>'jian','楗'=>'jian','榗'=>'jian','槛'=>'jian','樫'=>'jian','橺'=>'jian','檢'=>'jian','檻'=>'jian','櫼'=>'jian','歼'=>'jian','殱'=>'jian','殲'=>'jian','毽'=>'jian','洊'=>'jian','涧'=>'jian','渐'=>'jian','減'=>'jian','湔'=>'jian','湕'=>'jian','溅'=>'jian','漸'=>'jian','澗'=>'jian','濺'=>'jian','瀐'=>'jian','瀳'=>'jian','瀸'=>'jian','瀽'=>'jian','煎'=>'jian','熞'=>'jian','熸'=>'jian','牋'=>'jian','牮'=>'jian','犍'=>'jian','猏'=>'jian','玪'=>'jian','珔'=>'jian','瑊'=>'jian','瑐'=>'jian','监'=>'jian','監'=>'jian','睑'=>'jian','睷'=>'jian','瞯'=>'jian','瞷'=>'jian','瞼'=>'jian','硷'=>'jian','碊'=>'jian','碱'=>'jian','磵'=>'jian','礀'=>'jian','礆'=>'jian','礛'=>'jian','笕'=>'jian','笺'=>'jian','筧'=>'jian','简'=>'jian','箋'=>'jian','箭'=>'jian','篯'=>'jian','簡'=>'jian','籛'=>'jian','糋'=>'jian','絸'=>'jian','緘'=>'jian','縑'=>'jian','繝'=>'jian','繭'=>'jian','缄'=>'jian','缣'=>'jian','翦'=>'jian','聻'=>'jian','肩'=>'jian','腱'=>'jian','臶'=>'jian','舰'=>'jian','艦'=>'jian','艰'=>'jian','艱'=>'jian','茧'=>'jian','荐'=>'jian','菅'=>'jian','菺'=>'jian','葌'=>'jian','葏'=>'jian','葥'=>'jian','蒹'=>'jian','蕑'=>'jian','蕳'=>'jian','薦'=>'jian','藆'=>'jian','虃'=>'jian','螹'=>'jian','蠒'=>'jian','袸'=>'jian','裥'=>'jian','襇'=>'jian','襉'=>'jian','襺'=>'jian','見'=>'jian','覵'=>'jian','覸'=>'jian','见'=>'jian','詃'=>'jian','諓'=>'jian','諫'=>'jian','謇'=>'jian','謭'=>'jian','譼'=>'jian','譾'=>'jian','谏'=>'jian','谫'=>'jian','豜'=>'jian','豣'=>'jian','賎'=>'jian','賤'=>'jian','贱'=>'jian','趝'=>'jian','趼'=>'jian','跈'=>'jian','践'=>'jian','踐'=>'jian','踺'=>'jian','蹇'=>'jian','轞'=>'jian','釼'=>'jian','鉴'=>'jian','鋻'=>'jian','鍳'=>'jian','鍵'=>'jian','鏩'=>'jian','鐗'=>'jian','鐧'=>'jian','鑑'=>'jian','鑒'=>'jian','鑬'=>'jian','鑯'=>'jian','鑳'=>'jian','锏'=>'jian','键'=>'jian','閒'=>'jian','間'=>'jian','间'=>'jian','靬'=>'jian','鞬'=>'jian','鞯'=>'jian','韀'=>'jian','韉'=>'jian','餞'=>'jian','餰'=>'jian','饯'=>'jian','馢'=>'jian','鬋'=>'jian','鰎'=>'jian','鰔'=>'jian','鰜'=>'jian','鰹'=>'jian','鲣'=>'jian','鳒'=>'jian','鳽'=>'jian','鵳'=>'jian','鶼'=>'jian','鹣'=>'jian','鹸'=>'jian','鹻'=>'jian','鹼'=>'jian','麉'=>'jian','㓺'=>'jian','㔋'=>'jian','㔓'=>'jian','㣤'=>'jian','㦗'=>'jian','㨴'=>'jian','㨵'=>'jian','㯺'=>'jian','㰄'=>'jian','㳨'=>'jian','㶕'=>'jian','㺝'=>'jian','䄯'=>'jian','䅐'=>'jian','䇟'=>'jian','䉍'=>'jian','䛳'=>'jian','䟅'=>'jian','䟰'=>'jian','䤔'=>'jian','䥜'=>'jian','䧖'=>'jian','䩆'=>'jian','䬻'=>'jian','䭈'=>'jian','䭕'=>'jian','䭠'=>'jian','䮿'=>'jian','䯛'=>'jian','䯡'=>'jian','䵖'=>'jian','䵛'=>'jian','䵡'=>'jian','䵤'=>'jian','䶠'=>'jian','价'=>'jia','佳'=>'jia','假'=>'jia','傢'=>'jia','價'=>'jia','加'=>'jia','叚'=>'jia','唊'=>'jia','嗧'=>'jia','嘉'=>'jia','圿'=>'jia','埉'=>'jia','夹'=>'jia','夾'=>'jia','婽'=>'jia','嫁'=>'jia','宊'=>'jia','家'=>'jia','岬'=>'jia','幏'=>'jia','徦'=>'jia','恝'=>'jia','戛'=>'jia','戞'=>'jia','扴'=>'jia','抸'=>'jia','拁'=>'jia','斚'=>'jia','斝'=>'jia','架'=>'jia','枷'=>'jia','梜'=>'jia','椵'=>'jia','榎'=>'jia','榢'=>'jia','槚'=>'jia','檟'=>'jia','毠'=>'jia','泇'=>'jia','浃'=>'jia','浹'=>'jia','犌'=>'jia','猳'=>'jia','玾'=>'jia','珈'=>'jia','甲'=>'jia','痂'=>'jia','瘕'=>'jia','稼'=>'jia','笳'=>'jia','糘'=>'jia','耞'=>'jia','胛'=>'jia','脥'=>'jia','腵'=>'jia','荚'=>'jia','莢'=>'jia','葭'=>'jia','蛱'=>'jia','蛺'=>'jia','袈'=>'jia','袷'=>'jia','裌'=>'jia','豭'=>'jia','貑'=>'jia','賈'=>'jia','贾'=>'jia','跏'=>'jia','跲'=>'jia','迦'=>'jia','郏'=>'jia','郟'=>'jia','鉀'=>'jia','鉫'=>'jia','鋏'=>'jia','鎵'=>'jia','钾'=>'jia','铗'=>'jia','镓'=>'jia','頬'=>'jia','頰'=>'jia','颊'=>'jia','餄'=>'jia','駕'=>'jia','驾'=>'jia','鴶'=>'jia','鵊'=>'jia','麚'=>'jia','㕅'=>'jia','㪴'=>'jia','㮖'=>'jia','㼪'=>'jia','㿓'=>'jia','䀫'=>'jia','䁍'=>'jia','䑝'=>'jia','䕛'=>'jia','䛟'=>'jia','䩡'=>'jia','仸'=>'yao','倄'=>'yao','偠'=>'yao','傜'=>'yao','吆'=>'yao','咬'=>'yao','喓'=>'yao','嗂'=>'yao','垚'=>'yao','堯'=>'yao','夭'=>'yao','妖'=>'yao','姚'=>'yao','婹'=>'yao','媱'=>'yao','宎'=>'yao','尧'=>'yao','尭'=>'yao','岆'=>'yao','峣'=>'yao','崾'=>'yao','嶢'=>'yao','嶤'=>'yao','幺'=>'yao','徭'=>'yao','徺'=>'yao','愮'=>'yao','抭'=>'yao','揺'=>'yao','搖'=>'yao','摇'=>'yao','摿'=>'yao','暚'=>'yao','曜'=>'yao','曣'=>'yao','杳'=>'yao','枖'=>'yao','柼'=>'yao','楆'=>'yao','榚'=>'yao','榣'=>'yao','殀'=>'yao','殽'=>'yao','溔'=>'yao','烑'=>'yao','熎'=>'yao','燿'=>'yao','爻'=>'yao','狕'=>'yao','猺'=>'yao','獟'=>'yao','珧'=>'yao','瑤'=>'yao','瑶'=>'yao','眑'=>'yao','矅'=>'yao','磘'=>'yao','祅'=>'yao','穾'=>'yao','窅'=>'yao','窈'=>'yao','窑'=>'yao','窔'=>'yao','窯'=>'yao','窰'=>'yao','筄'=>'yao','繇'=>'yao','纅'=>'yao','耀'=>'yao','肴'=>'yao','腰'=>'yao','舀'=>'yao','艞'=>'yao','苭'=>'yao','药'=>'yao','葯'=>'yao','葽'=>'yao','蓔'=>'yao','薬'=>'yao','藥'=>'yao','蘨'=>'yao','袎'=>'yao','要'=>'yao','覞'=>'yao','訞'=>'yao','詏'=>'yao','謠'=>'yao','謡'=>'yao','讑'=>'yao','谣'=>'yao','軺'=>'yao','轺'=>'yao','遙'=>'yao','遥'=>'yao','邀'=>'yao','銚'=>'yao','鎐'=>'yao','鑰'=>'yao','闄'=>'yao','靿'=>'yao','顤'=>'yao','颻'=>'yao','飖'=>'yao','餆'=>'yao','餚'=>'yao','騕'=>'yao','鰩'=>'yao','鳐'=>'yao','鴁'=>'yao','鴢'=>'yao','鷂'=>'yao','鷕'=>'yao','鹞'=>'yao','鼼'=>'yao','齩'=>'yao','㔽'=>'yao','㝔'=>'yao','㞁'=>'yao','㟱'=>'yao','㢓'=>'yao','㨱'=>'yao','㫏'=>'yao','㫐'=>'yao','㮁'=>'yao','㴭'=>'yao','㵸'=>'yao','㿑'=>'yao','㿢'=>'yao','䁏'=>'yao','䁘'=>'yao','䂚'=>'yao','䆙'=>'yao','䆞'=>'yao','䉰'=>'yao','䋂'=>'yao','䋤'=>'yao','䌊'=>'yao','䌛'=>'yao','䍃'=>'yao','䑬'=>'yao','䔄'=>'yao','䖴'=>'yao','䙅'=>'yao','䚺'=>'yao','䚻'=>'yao','䢣'=>'yao','䬙'=>'yao','䴠'=>'yao','䶧'=>'yao','份'=>'fen','偾'=>'fen','僨'=>'fen','分'=>'fen','吩'=>'fen','坆'=>'fen','坋'=>'fen','坟'=>'fen','墳'=>'fen','奋'=>'fen','奮'=>'fen','妢'=>'fen','岎'=>'fen','帉'=>'fen','幩'=>'fen','弅'=>'fen','忿'=>'fen','愤'=>'fen','憤'=>'fen','昐'=>'fen','朆'=>'fen','枌'=>'fen','梤'=>'fen','棻'=>'fen','棼'=>'fen','橨'=>'fen','氛'=>'fen','汾'=>'fen','瀵'=>'fen','炃'=>'fen','焚'=>'fen','燌'=>'fen','燓'=>'fen','玢'=>'fen','瞓'=>'fen','秎'=>'fen','竕'=>'fen','粉'=>'fen','粪'=>'fen','糞'=>'fen','紛'=>'fen','纷'=>'fen','羒'=>'fen','羵'=>'fen','翂'=>'fen','肦'=>'fen','膹'=>'fen','芬'=>'fen','蒶'=>'fen','蕡'=>'fen','蚠'=>'fen','蚡'=>'fen','衯'=>'fen','訜'=>'fen','豮'=>'fen','豶'=>'fen','躮'=>'fen','轒'=>'fen','酚'=>'fen','鈖'=>'fen','鐼'=>'fen','隫'=>'fen','雰'=>'fen','餴'=>'fen','饙'=>'fen','馚'=>'fen','馩'=>'fen','魵'=>'fen','鱝'=>'fen','鲼'=>'fen','鳻'=>'fen','黂'=>'fen','黺'=>'fen','鼖'=>'fen','鼢'=>'fen','㖹'=>'fen','㥹'=>'fen','㮥'=>'fen','㷊'=>'fen','㸮'=>'fen','㿎'=>'fen','䩿'=>'fen','䯨'=>'fen','䴅'=>'fen','仾'=>'di','低'=>'di','俤'=>'di','偙'=>'di','僀'=>'di','厎'=>'di','呧'=>'di','唙'=>'di','啇'=>'di','啲'=>'di','嘀'=>'di','嚁'=>'di','地'=>'di','坔'=>'di','坻'=>'di','埊'=>'di','埞'=>'di','堤'=>'di','墑'=>'di','墬'=>'di','奃'=>'di','娣'=>'di','媂'=>'di','嫡'=>'di','嶳'=>'di','帝'=>'di','底'=>'di','廸'=>'di','弚'=>'di','弟'=>'di','弤'=>'di','彽'=>'di','怟'=>'di','慸'=>'di','抵'=>'di','拞'=>'di','掋'=>'di','摕'=>'di','敌'=>'di','敵'=>'di','旳'=>'di','杕'=>'di','枤'=>'di','柢'=>'di','梊'=>'di','梑'=>'di','棣'=>'di','氐'=>'di','涤'=>'di','滌'=>'di','滴'=>'di','焍'=>'di','牴'=>'di','狄'=>'di','玓'=>'di','甋'=>'di','眱'=>'di','睇'=>'di','砥'=>'di','碲'=>'di','磾'=>'di','祶'=>'di','禘'=>'di','笛'=>'di','第'=>'di','篴'=>'di','籴'=>'di','糴'=>'di','締'=>'di','缔'=>'di','羝'=>'di','翟'=>'di','聜'=>'di','肑'=>'di','腣'=>'di','苐'=>'di','苖'=>'di','荻'=>'di','菂'=>'di','菧'=>'di','蒂'=>'di','蔋'=>'di','蔐'=>'di','蔕'=>'di','藡'=>'di','蝃'=>'di','螮'=>'di','袛'=>'di','覿'=>'di','觌'=>'di','觝'=>'di','詆'=>'di','諦'=>'di','诋'=>'di','谛'=>'di','豴'=>'di','趆'=>'di','踶'=>'di','軧'=>'di','迪'=>'di','递'=>'di','逓'=>'di','遞'=>'di','遰'=>'di','邸'=>'di','釱'=>'di','鉪'=>'di','鍉'=>'di','鏑'=>'di','镝'=>'di','阺'=>'di','隄'=>'di','靮'=>'di','鞮'=>'di','頔'=>'di','馰'=>'di','骶'=>'di','髢'=>'di','魡'=>'di','鯳'=>'di','鸐'=>'di','㡳'=>'di','㢩'=>'di','㣙'=>'di','㦅'=>'di','㪆'=>'di','㭽'=>'di','㰅'=>'di','㹍'=>'di','㼵'=>'di','䀸'=>'di','䀿'=>'di','䂡'=>'di','䊮'=>'di','䍕'=>'di','䏑'=>'di','䑭'=>'di','䑯'=>'di','䞶'=>'di','䟡'=>'di','䢑'=>'di','䣌'=>'di','䧝'=>'di','䨀'=>'di','䨤'=>'di','䩘'=>'di','䩚'=>'di','䮤'=>'di','䯼'=>'di','䱃'=>'di','䱱'=>'di','䴞'=>'di','䵠'=>'di','䶍'=>'di','仿'=>'fang','倣'=>'fang','匚'=>'fang','坊'=>'fang','埅'=>'fang','堏'=>'fang','妨'=>'fang','彷'=>'fang','房'=>'fang','放'=>'fang','方'=>'fang','旊'=>'fang','昉'=>'fang','昘'=>'fang','枋'=>'fang','淓'=>'fang','牥'=>'fang','瓬'=>'fang','眆'=>'fang','紡'=>'fang','纺'=>'fang','肪'=>'fang','舫'=>'fang','芳'=>'fang','蚄'=>'fang','訪'=>'fang','访'=>'fang','趽'=>'fang','邡'=>'fang','鈁'=>'fang','錺'=>'fang','钫'=>'fang','防'=>'fang','髣'=>'fang','魴'=>'fang','鲂'=>'fang','鴋'=>'fang','鶭'=>'fang','㑂'=>'fang','㕫'=>'fang','㤃'=>'fang','㧍'=>'fang','㯐'=>'fang','䢍'=>'fang','䦈'=>'fang','䲱'=>'fang','伂'=>'pei','佩'=>'pei','俖'=>'pei','呸'=>'pei','培'=>'pei','姵'=>'pei','嶏'=>'pei','帔'=>'pei','怌'=>'pei','斾'=>'pei','旆'=>'pei','柸'=>'pei','毰'=>'pei','沛'=>'pei','浿'=>'pei','珮'=>'pei','笩'=>'pei','肧'=>'pei','胚'=>'pei','蓜'=>'pei','衃'=>'pei','裴'=>'pei','裵'=>'pei','賠'=>'pei','赔'=>'pei','轡'=>'pei','辔'=>'pei','配'=>'pei','醅'=>'pei','錇'=>'pei','锫'=>'pei','阫'=>'pei','陪'=>'pei','陫'=>'pei','霈'=>'pei','馷'=>'pei','㟝'=>'pei','㤄'=>'pei','㧩'=>'pei','㫲'=>'pei','㳈'=>'pei','䊃'=>'pei','䣙'=>'pei','䪹'=>'pei','䫠'=>'pei','䲹'=>'pei','伄'=>'diao','凋'=>'diao','刁'=>'diao','刟'=>'diao','叼'=>'diao','吊'=>'diao','奝'=>'diao','屌'=>'diao','弔'=>'diao','弴'=>'diao','彫'=>'diao','扚'=>'diao','掉'=>'diao','殦'=>'diao','汈'=>'diao','琱'=>'diao','瘹'=>'diao','瞗'=>'diao','碉'=>'diao','窎'=>'diao','窵'=>'diao','竨'=>'diao','簓'=>'diao','蓧'=>'diao','藋'=>'diao','虭'=>'diao','蛁'=>'diao','訋'=>'diao','調'=>'diao','调'=>'diao','貂'=>'diao','釣'=>'diao','鈟'=>'diao','銱'=>'diao','鋽'=>'diao','鑃'=>'diao','钓'=>'diao','铞'=>'diao','雕'=>'diao','雿'=>'diao','鮉'=>'diao','鯛'=>'diao','鲷'=>'diao','鳭'=>'diao','鵰'=>'diao','鼦'=>'diao','㒛'=>'diao','㪕'=>'diao','㹿'=>'diao','䂪'=>'diao','䂽'=>'diao','䉆'=>'diao','䔙'=>'diao','䠼'=>'diao','䵲'=>'diao','伅'=>'dun','吨'=>'dun','噸'=>'dun','囤'=>'dun','墩'=>'dun','墪'=>'dun','壿'=>'dun','庉'=>'dun','惇'=>'dun','憞'=>'dun','撉'=>'dun','撴'=>'dun','敦'=>'dun','橔'=>'dun','沌'=>'dun','潡'=>'dun','炖'=>'dun','燉'=>'dun','犜'=>'dun','獤'=>'dun','盹'=>'dun','盾'=>'dun','砘'=>'dun','碷'=>'dun','礅'=>'dun','腞'=>'dun','蜳'=>'dun','趸'=>'dun','踲'=>'dun','蹲'=>'dun','蹾'=>'dun','躉'=>'dun','逇'=>'dun','遁'=>'dun','遯'=>'dun','鈍'=>'dun','钝'=>'dun','頓'=>'dun','顿'=>'dun','驐'=>'dun','㬿'=>'dun','䤜'=>'dun','伈'=>'xin','伩'=>'xin','信'=>'xin','俽'=>'xin','噷'=>'xin','噺'=>'xin','囟'=>'xin','妡'=>'xin','嬜'=>'xin','孞'=>'xin','廞'=>'xin','心'=>'xin','忄'=>'xin','忻'=>'xin','惞'=>'xin','新'=>'xin','昕'=>'xin','杺'=>'xin','枔'=>'xin','欣'=>'xin','歆'=>'xin','潃'=>'xin','炘'=>'xin','焮'=>'xin','盺'=>'xin','脪'=>'xin','舋'=>'xin','芯'=>'xin','莘'=>'xin','薪'=>'xin','衅'=>'xin','訢'=>'xin','訫'=>'xin','軐'=>'xin','辛'=>'xin','邤'=>'xin','釁'=>'xin','鈊'=>'xin','鋅'=>'xin','鐔'=>'xin','鑫'=>'xin','锌'=>'xin','阠'=>'xin','顖'=>'xin','馨'=>'xin','馫'=>'xin','馸'=>'xin','鬵'=>'xin','㐰'=>'xin','㚯'=>'xin','㛛'=>'xin','㭄'=>'xin','䒖'=>'xin','䚱'=>'xin','䛨'=>'xin','䜗'=>'xin','䜣'=>'xin','䰼'=>'xin','伌'=>'ai','僾'=>'ai','凒'=>'ai','叆'=>'ai','哀'=>'ai','哎'=>'ai','唉'=>'ai','啀'=>'ai','嗌'=>'ai','嗳'=>'ai','嘊'=>'ai','噯'=>'ai','埃'=>'ai','塧'=>'ai','壒'=>'ai','娾'=>'ai','嫒'=>'ai','嬡'=>'ai','嵦'=>'ai','愛'=>'ai','懓'=>'ai','懝'=>'ai','挨'=>'ai','捱'=>'ai','敱'=>'ai','敳'=>'ai','昹'=>'ai','暧'=>'ai','曖'=>'ai','欸'=>'ai','毐'=>'ai','溰'=>'ai','溾'=>'ai','濭'=>'ai','爱'=>'ai','瑷'=>'ai','璦'=>'ai','癌'=>'ai','皑'=>'ai','皚'=>'ai','皧'=>'ai','瞹'=>'ai','矮'=>'ai','砹'=>'ai','硋'=>'ai','碍'=>'ai','礙'=>'ai','艾'=>'ai','蔼'=>'ai','薆'=>'ai','藹'=>'ai','譪'=>'ai','譺'=>'ai','賹'=>'ai','躷'=>'ai','鎄'=>'ai','鑀'=>'ai','锿'=>'ai','隘'=>'ai','霭'=>'ai','靄'=>'ai','靉'=>'ai','餲'=>'ai','馤'=>'ai','鱫'=>'ai','鴱'=>'ai','㑸'=>'ai','㕌'=>'ai','㗒'=>'ai','㗨'=>'ai','㘷'=>'ai','㝶'=>'ai','㢊'=>'ai','㤅'=>'ai','㱯'=>'ai','㿄'=>'ai','䀳'=>'ai','䅬'=>'ai','䑂'=>'ai','䔽'=>'ai','䝽'=>'ai','䠹'=>'ai','䨠'=>'ai','䬵'=>'ai','䶣'=>'ai','休'=>'xiu','俢'=>'xiu','修'=>'xiu','咻'=>'xiu','嗅'=>'xiu','岫'=>'xiu','庥'=>'xiu','朽'=>'xiu','樇'=>'xiu','溴'=>'xiu','滫'=>'xiu','烋'=>'xiu','烌'=>'xiu','珛'=>'xiu','琇'=>'xiu','璓'=>'xiu','秀'=>'xiu','糔'=>'xiu','綇'=>'xiu','綉'=>'xiu','繍'=>'xiu','繡'=>'xiu','绣'=>'xiu','羞'=>'xiu','脙'=>'xiu','脩'=>'xiu','臹'=>'xiu','苬'=>'xiu','螑'=>'xiu','袖'=>'xiu','裦'=>'xiu','褎'=>'xiu','褏'=>'xiu','貅'=>'xiu','銝'=>'xiu','銹'=>'xiu','鎀'=>'xiu','鏅'=>'xiu','鏥'=>'xiu','鏽'=>'xiu','锈'=>'xiu','飍'=>'xiu','饈'=>'xiu','馐'=>'xiu','髤'=>'xiu','髹'=>'xiu','鮴'=>'xiu','鵂'=>'xiu','鸺'=>'xiu','齅'=>'xiu','㗜'=>'xiu','㱙'=>'xiu','㾋'=>'xiu','伖'=>'nu','伮'=>'nu','傉'=>'nu','努'=>'nu','奴'=>'nu','孥'=>'nu','弩'=>'nu','怒'=>'nu','搙'=>'nu','砮'=>'nu','笯'=>'nu','胬'=>'nu','駑'=>'nu','驽'=>'nu','㚢'=>'nu','䢞'=>'nu','伙'=>'huo','佸'=>'huo','俰'=>'huo','剨'=>'huo','劐'=>'huo','吙'=>'huo','咟'=>'huo','嗀'=>'huo','嚄'=>'huo','嚯'=>'huo','嚿'=>'huo','夥'=>'huo','夻'=>'huo','奯'=>'huo','惑'=>'huo','或'=>'huo','捇'=>'huo','掝'=>'huo','擭'=>'huo','攉'=>'huo','旤'=>'huo','曤'=>'huo','檴'=>'huo','沎'=>'huo','活'=>'huo','湱'=>'huo','漷'=>'huo','濩'=>'huo','瀖'=>'huo','火'=>'huo','獲'=>'huo','癨'=>'huo','眓'=>'huo','矆'=>'huo','矐'=>'huo','祸'=>'huo','禍'=>'huo','秮'=>'huo','秳'=>'huo','穫'=>'huo','耠'=>'huo','耯'=>'huo','臛'=>'huo','艧'=>'huo','获'=>'huo','蒦'=>'huo','藿'=>'huo','蠖'=>'huo','謋'=>'huo','豁'=>'huo','貨'=>'huo','货'=>'huo','邩'=>'huo','鈥'=>'huo','鍃'=>'huo','鑊'=>'huo','钬'=>'huo','锪'=>'huo','镬'=>'huo','閄'=>'huo','雘'=>'huo','霍'=>'huo','靃'=>'huo','騞'=>'huo','㗲'=>'huo','㘞'=>'huo','㦜'=>'huo','㦯'=>'huo','㨯'=>'huo','㯉'=>'huo','㸌'=>'huo','䁨'=>'huo','䂄'=>'huo','䄀'=>'huo','䄆'=>'huo','䄑'=>'huo','䉟'=>'huo','䋭'=>'huo','䣶'=>'huo','䦚'=>'huo','䯏'=>'huo','䰥'=>'huo','会'=>'hui','佪'=>'hui','僡'=>'hui','儶'=>'hui','匯'=>'hui','卉'=>'hui','咴'=>'hui','哕'=>'hui','喙'=>'hui','嘒'=>'hui','噅'=>'hui','噕'=>'hui','噦'=>'hui','嚖'=>'hui','囘'=>'hui','回'=>'hui','囬'=>'hui','圚'=>'hui','婎'=>'hui','媈'=>'hui','孈'=>'hui','寭'=>'hui','屷'=>'hui','幑'=>'hui','廻'=>'hui','廽'=>'hui','彗'=>'hui','彙'=>'hui','彚'=>'hui','徻'=>'hui','徽'=>'hui','恚'=>'hui','恛'=>'hui','恢'=>'hui','恵'=>'hui','悔'=>'hui','惠'=>'hui','慧'=>'hui','憓'=>'hui','懳'=>'hui','拻'=>'hui','挥'=>'hui','揮'=>'hui','撝'=>'hui','晖'=>'hui','晦'=>'hui','暉'=>'hui','暳'=>'hui','會'=>'hui','桧'=>'hui','楎'=>'hui','槥'=>'hui','橞'=>'hui','檅'=>'hui','檓'=>'hui','檜'=>'hui','櫘'=>'hui','毀'=>'hui','毁'=>'hui','毇'=>'hui','汇'=>'hui','泋'=>'hui','洃'=>'hui','洄'=>'hui','浍'=>'hui','湏'=>'hui','滙'=>'hui','潓'=>'hui','澮'=>'hui','瀈'=>'hui','灰'=>'hui','灳'=>'hui','烠'=>'hui','烣'=>'hui','烩'=>'hui','烪'=>'hui','煇'=>'hui','燬'=>'hui','燴'=>'hui','獩'=>'hui','珲'=>'hui','琿'=>'hui','璤'=>'hui','璯'=>'hui','痐'=>'hui','瘣'=>'hui','睳'=>'hui','瞺'=>'hui','禈'=>'hui','秽'=>'hui','穢'=>'hui','篲'=>'hui','絵'=>'hui','繢'=>'hui','繪'=>'hui','绘'=>'hui','缋'=>'hui','翙'=>'hui','翚'=>'hui','翬'=>'hui','翽'=>'hui','芔'=>'hui','茴'=>'hui','荟'=>'hui','蔧'=>'hui','蕙'=>'hui','薈'=>'hui','薉'=>'hui','藱'=>'hui','虺'=>'hui','蚘'=>'hui','蛔'=>'hui','蛕'=>'hui','蜖'=>'hui','螝'=>'hui','蟪'=>'hui','袆'=>'hui','褘'=>'hui','詯'=>'hui','詼'=>'hui','誨'=>'hui','諱'=>'hui','譓'=>'hui','譭'=>'hui','譮'=>'hui','譿'=>'hui','讳'=>'hui','诙'=>'hui','诲'=>'hui','豗'=>'hui','賄'=>'hui','贿'=>'hui','輝'=>'hui','辉'=>'hui','迴'=>'hui','逥'=>'hui','鏸'=>'hui','鐬'=>'hui','闠'=>'hui','阓'=>'hui','隓'=>'hui','隳'=>'hui','靧'=>'hui','韢'=>'hui','頮'=>'hui','顪'=>'hui','餯'=>'hui','鮰'=>'hui','鰴'=>'hui','麾'=>'hui','㑰'=>'hui','㑹'=>'hui','㒑'=>'hui','㜇'=>'hui','㞧'=>'hui','㤬'=>'hui','㥣'=>'hui','㨤'=>'hui','㨹'=>'hui','㩓'=>'hui','㩨'=>'hui','㬩'=>'hui','㰥'=>'hui','㱱'=>'hui','㷄'=>'hui','㷐'=>'hui','㻅'=>'hui','䂕'=>'hui','䃣'=>'hui','䅏'=>'hui','䇻'=>'hui','䌇'=>'hui','䏨'=>'hui','䕇'=>'hui','䙌'=>'hui','䙡'=>'hui','䛛'=>'hui','䛼'=>'hui','䜋'=>'hui','䤧'=>'hui','䧥'=>'hui','䩈'=>'hui','䫭'=>'hui','伡'=>'che','俥'=>'che','偖'=>'che','勶'=>'che','唓'=>'che','坼'=>'che','奲'=>'che','屮'=>'che','彻'=>'che','徹'=>'che','扯'=>'che','掣'=>'che','撤'=>'che','撦'=>'che','澈'=>'che','烢'=>'che','烲'=>'che','爡'=>'che','瞮'=>'che','砗'=>'che','硨'=>'che','硩'=>'che','聅'=>'che','莗'=>'che','蛼'=>'che','車'=>'che','车'=>'che','迠'=>'che','頙'=>'che','㔭'=>'che','㥉'=>'che','㨋'=>'che','㬚'=>'che','㯙'=>'che','㱌'=>'che','㵃'=>'che','㵔'=>'che','㾝'=>'che','㿭'=>'che','䁤'=>'che','䋲'=>'che','䑲'=>'che','䒆'=>'che','䚢'=>'che','䛸'=>'che','䜠'=>'che','䞣'=>'che','䧪'=>'che','䨁'=>'che','䰩'=>'che','伨'=>'xun','侚'=>'xun','偱'=>'xun','勋'=>'xun','勛'=>'xun','勲'=>'xun','勳'=>'xun','卂'=>'xun','噀'=>'xun','噚'=>'xun','嚑'=>'xun','坃'=>'xun','埙'=>'xun','塤'=>'xun','壎'=>'xun','壦'=>'xun','奞'=>'xun','寻'=>'xun','尋'=>'xun','峋'=>'xun','巡'=>'xun','巽'=>'xun','廵'=>'xun','徇'=>'xun','循'=>'xun','恂'=>'xun','愻'=>'xun','揗'=>'xun','攳'=>'xun','旬'=>'xun','曛'=>'xun','杊'=>'xun','栒'=>'xun','桪'=>'xun','樳'=>'xun','殉'=>'xun','殾'=>'xun','毥'=>'xun','汛'=>'xun','洵'=>'xun','浔'=>'xun','潯'=>'xun','灥'=>'xun','焄'=>'xun','熏'=>'xun','燂'=>'xun','燅'=>'xun','燖'=>'xun','燻'=>'xun','爋'=>'xun','狥'=>'xun','獯'=>'xun','珣'=>'xun','璕'=>'xun','矄'=>'xun','窨'=>'xun','紃'=>'xun','纁'=>'xun','臐'=>'xun','荀'=>'xun','蔒'=>'xun','蕈'=>'xun','薫'=>'xun','薰'=>'xun','蘍'=>'xun','蟳'=>'xun','襑'=>'xun','訊'=>'xun','訓'=>'xun','訙'=>'xun','詢'=>'xun','训'=>'xun','讯'=>'xun','询'=>'xun','賐'=>'xun','迅'=>'xun','迿'=>'xun','逊'=>'xun','遜'=>'xun','鄩'=>'xun','醺'=>'xun','鑂'=>'xun','顨'=>'xun','馴'=>'xun','駨'=>'xun','驯'=>'xun','鱏'=>'xun','鱘'=>'xun','鲟'=>'xun','㜄'=>'xun','㝁'=>'xun','㢲'=>'xun','㨚'=>'xun','㰊'=>'xun','㰬'=>'xun','㽦'=>'xun','䋸'=>'xun','䑕'=>'xun','䖲'=>'xun','䙉'=>'xun','䛜'=>'xun','䞊'=>'xun','䭀'=>'xun','估'=>'gu','傦'=>'gu','僱'=>'gu','凅'=>'gu','古'=>'gu','咕'=>'gu','唂'=>'gu','唃'=>'gu','啒'=>'gu','嘏'=>'gu','固'=>'gu','堌'=>'gu','夃'=>'gu','姑'=>'gu','嫴'=>'gu','孤'=>'gu','尳'=>'gu','峠'=>'gu','崓'=>'gu','崮'=>'gu','怘'=>'gu','愲'=>'gu','扢'=>'gu','故'=>'gu','柧'=>'gu','梏'=>'gu','棝'=>'gu','榖'=>'gu','榾'=>'gu','橭'=>'gu','毂'=>'gu','汩'=>'gu','沽'=>'gu','泒'=>'gu','淈'=>'gu','濲'=>'gu','瀔'=>'gu','焸'=>'gu','牯'=>'gu','牿'=>'gu','痼'=>'gu','皷'=>'gu','盬'=>'gu','瞽'=>'gu','硲'=>'gu','祻'=>'gu','稒'=>'gu','穀'=>'gu','笟'=>'gu','箍'=>'gu','箛'=>'gu','篐'=>'gu','糓'=>'gu','縎'=>'gu','罛'=>'gu','罟'=>'gu','羖'=>'gu','股'=>'gu','脵'=>'gu','臌'=>'gu','菇'=>'gu','菰'=>'gu','蓇'=>'gu','薣'=>'gu','蛄'=>'gu','蛊'=>'gu','蛌'=>'gu','蠱'=>'gu','觚'=>'gu','詁'=>'gu','诂'=>'gu','谷'=>'gu','軱'=>'gu','軲'=>'gu','轂'=>'gu','轱'=>'gu','辜'=>'gu','逧'=>'gu','酤'=>'gu','鈲'=>'gu','鈷'=>'gu','錮'=>'gu','钴'=>'gu','锢'=>'gu','雇'=>'gu','頋'=>'gu','顧'=>'gu','顾'=>'gu','餶'=>'gu','馉'=>'gu','骨'=>'gu','鮕'=>'gu','鯝'=>'gu','鲴'=>'gu','鴣'=>'gu','鵠'=>'gu','鶻'=>'gu','鸪'=>'gu','鹄'=>'gu','鹘'=>'gu','鼓'=>'gu','鼔'=>'gu','㒴'=>'gu','㚉'=>'gu','㧽'=>'gu','㯏'=>'gu','㼋'=>'gu','㽽'=>'gu','㾶'=>'gu','䀇'=>'gu','䀜'=>'gu','䀦'=>'gu','䀰'=>'gu','䅽'=>'gu','䊺'=>'gu','䍍'=>'gu','䍛'=>'gu','䐨'=>'gu','䓢'=>'gu','䜼'=>'gu','䡩'=>'gu','䮩'=>'gu','䵻'=>'gu','䶜'=>'gu','伱'=>'ni','伲'=>'ni','你'=>'ni','倪'=>'ni','儗'=>'ni','儞'=>'ni','匿'=>'ni','坭'=>'ni','埿'=>'ni','堄'=>'ni','妮'=>'ni','婗'=>'ni','嫟'=>'ni','嬺'=>'ni','孴'=>'ni','尼'=>'ni','屔'=>'ni','屰'=>'ni','怩'=>'ni','惄'=>'ni','愵'=>'ni','抳'=>'ni','拟'=>'ni','掜'=>'ni','擬'=>'ni','旎'=>'ni','昵'=>'ni','晲'=>'ni','暱'=>'ni','柅'=>'ni','棿'=>'ni','檷'=>'ni','氼'=>'ni','泥'=>'ni','淣'=>'ni','溺'=>'ni','狔'=>'ni','猊'=>'ni','痆'=>'ni','眤'=>'ni','睨'=>'ni','秜'=>'ni','籾'=>'ni','縌'=>'ni','胒'=>'ni','腻'=>'ni','膩'=>'ni','臡'=>'ni','苨'=>'ni','薿'=>'ni','蚭'=>'ni','蜺'=>'ni','觬'=>'ni','貎'=>'ni','跜'=>'ni','輗'=>'ni','迡'=>'ni','逆'=>'ni','郳'=>'ni','鈮'=>'ni','鉨'=>'ni','鑈'=>'ni','铌'=>'ni','隬'=>'ni','霓'=>'ni','馜'=>'ni','鯢'=>'ni','鲵'=>'ni','麑'=>'ni','齯'=>'ni','㞾'=>'ni','㠜'=>'ni','㣇'=>'ni','㥾'=>'ni','㦐'=>'ni','㪒'=>'ni','㲻'=>'ni','㵫'=>'ni','㹸'=>'ni','䁥'=>'ni','䕥'=>'ni','䘌'=>'ni','䘦'=>'ni','䘽'=>'ni','䛏'=>'ni','䝚'=>'ni','䦵'=>'ni','䧇'=>'ni','䭲'=>'ni','䰯'=>'ni','䵑'=>'ni','䵒'=>'ni','伴'=>'ban','办'=>'ban','半'=>'ban','坂'=>'ban','姅'=>'ban','岅'=>'ban','怑'=>'ban','扮'=>'ban','扳'=>'ban','拌'=>'ban','搬'=>'ban','攽'=>'ban','斑'=>'ban','斒'=>'ban','昄'=>'ban','朌'=>'ban','板'=>'ban','湴'=>'ban','版'=>'ban','班'=>'ban','瓣'=>'ban','瓪'=>'ban','瘢'=>'ban','癍'=>'ban','秚'=>'ban','粄'=>'ban','絆'=>'ban','绊'=>'ban','舨'=>'ban','般'=>'ban','蝂'=>'ban','螁'=>'ban','螌'=>'ban','褩'=>'ban','辦'=>'ban','辬'=>'ban','鈑'=>'ban','鉡'=>'ban','钣'=>'ban','闆'=>'ban','阪'=>'ban','靽'=>'ban','頒'=>'ban','颁'=>'ban','魬'=>'ban','㚘'=>'ban','㩯'=>'ban','㪵'=>'ban','㸞'=>'ban','㺜'=>'ban','䉽'=>'ban','䕰'=>'ban','䬳'=>'ban','伵'=>'xu','侐'=>'xu','俆'=>'xu','偦'=>'xu','冔'=>'xu','勖'=>'xu','勗'=>'xu','卹'=>'xu','叙'=>'xu','呴'=>'xu','喣'=>'xu','嘘'=>'xu','噓'=>'xu','垿'=>'xu','墟'=>'xu','壻'=>'xu','姁'=>'xu','婿'=>'xu','媭'=>'xu','嬃'=>'xu','幁'=>'xu','序'=>'xu','徐'=>'xu','恤'=>'xu','慉'=>'xu','戌'=>'xu','揟'=>'xu','敍'=>'xu','敘'=>'xu','旭'=>'xu','旴'=>'xu','昫'=>'xu','暊'=>'xu','朂'=>'xu','栩'=>'xu','楈'=>'xu','槒'=>'xu','欨'=>'xu','欰'=>'xu','欻'=>'xu','歔'=>'xu','歘'=>'xu','殈'=>'xu','汿'=>'xu','沀'=>'xu','洫'=>'xu','湑'=>'xu','溆'=>'xu','漵'=>'xu','潊'=>'xu','烅'=>'xu','烼'=>'xu','煦'=>'xu','獝'=>'xu','珝'=>'xu','珬'=>'xu','畜'=>'xu','疞'=>'xu','盢'=>'xu','盨'=>'xu','盱'=>'xu','瞁'=>'xu','瞲'=>'xu','砉'=>'xu','稰'=>'xu','稸'=>'xu','窢'=>'xu','糈'=>'xu','絮'=>'xu','続'=>'xu','緒'=>'xu','緖'=>'xu','縃'=>'xu','續'=>'xu','绪'=>'xu','续'=>'xu','聟'=>'xu','胥'=>'xu','蒣'=>'xu','蓄'=>'xu','蓿'=>'xu','蕦'=>'xu','藇'=>'xu','藚'=>'xu','虗'=>'xu','虚'=>'xu','虛'=>'xu','蝑'=>'xu','訏'=>'xu','許'=>'xu','訹'=>'xu','詡'=>'xu','諝'=>'xu','譃'=>'xu','许'=>'xu','诩'=>'xu','谞'=>'xu','賉'=>'xu','鄦'=>'xu','酗'=>'xu','醑'=>'xu','銊'=>'xu','鑐'=>'xu','需'=>'xu','須'=>'xu','頊'=>'xu','须'=>'xu','顼'=>'xu','驉'=>'xu','鬚'=>'xu','魆'=>'xu','魖'=>'xu','鱮'=>'xu','㐨'=>'xu','㑔'=>'xu','㑯'=>'xu','㕛'=>'xu','㖅'=>'xu','㗵'=>'xu','㘧'=>'xu','㚜'=>'xu','㜅'=>'xu','㜿'=>'xu','㞊'=>'xu','㞰'=>'xu','㤢'=>'xu','㥠'=>'xu','㦽'=>'xu','㰲'=>'xu','㵰'=>'xu','㷦'=>'xu','㺷'=>'xu','㾥'=>'xu','䂆'=>'xu','䅡'=>'xu','䋶'=>'xu','䍱'=>'xu','䔓'=>'xu','䘏'=>'xu','䙒'=>'xu','䛙'=>'xu','䜡'=>'xu','䢕'=>'xu','䣱'=>'xu','䣴'=>'xu','䦗'=>'xu','䦽'=>'xu','䬔'=>'xu','䱛'=>'xu','䳳'=>'xu','伷'=>'zhou','侜'=>'zhou','僽'=>'zhou','冑'=>'zhou','周'=>'zhou','呪'=>'zhou','咒'=>'zhou','咮'=>'zhou','喌'=>'zhou','噣'=>'zhou','嚋'=>'zhou','妯'=>'zhou','婤'=>'zhou','宙'=>'zhou','州'=>'zhou','帚'=>'zhou','徟'=>'zhou','昼'=>'zhou','晝'=>'zhou','晭'=>'zhou','洀'=>'zhou','洲'=>'zhou','淍'=>'zhou','炿'=>'zhou','烐'=>'zhou','珘'=>'zhou','甃'=>'zhou','疛'=>'zhou','皱'=>'zhou','皺'=>'zhou','盩'=>'zhou','睭'=>'zhou','矪'=>'zhou','碡'=>'zhou','箒'=>'zhou','籀'=>'zhou','籒'=>'zhou','籕'=>'zhou','粙'=>'zhou','粥'=>'zhou','紂'=>'zhou','縐'=>'zhou','纣'=>'zhou','绉'=>'zhou','肘'=>'zhou','胄'=>'zhou','舟'=>'zhou','荮'=>'zhou','菷'=>'zhou','葤'=>'zhou','詋'=>'zhou','謅'=>'zhou','譸'=>'zhou','诌'=>'zhou','诪'=>'zhou','賙'=>'zhou','赒'=>'zhou','軸'=>'zhou','輈'=>'zhou','輖'=>'zhou','轴'=>'zhou','辀'=>'zhou','週'=>'zhou','郮'=>'zhou','酎'=>'zhou','銂'=>'zhou','霌'=>'zhou','駎'=>'zhou','駲'=>'zhou','騆'=>'zhou','驟'=>'zhou','骤'=>'zhou','鯞'=>'zhou','鵃'=>'zhou','鸼'=>'zhou','㑇'=>'zhou','㑳'=>'zhou','㔌'=>'zhou','㛩'=>'zhou','㥮'=>'zhou','㼙'=>'zhou','㾭'=>'zhou','䇠'=>'zhou','䈙'=>'zhou','䋓'=>'zhou','䎻'=>'zhou','䏲'=>'zhou','䐍'=>'zhou','䖞'=>'zhou','䛆'=>'zhou','䩜'=>'zhou','䶇'=>'zhou','伸'=>'shen','侁'=>'shen','侺'=>'shen','兟'=>'shen','呻'=>'shen','哂'=>'shen','堔'=>'shen','妽'=>'shen','姺'=>'shen','娠'=>'shen','婶'=>'shen','嬸'=>'shen','审'=>'shen','宷'=>'shen','審'=>'shen','屾'=>'shen','峷'=>'shen','弞'=>'shen','愼'=>'shen','慎'=>'shen','扟'=>'shen','抌'=>'shen','昚'=>'shen','曋'=>'shen','柛'=>'shen','椮'=>'shen','椹'=>'shen','榊'=>'shen','氠'=>'shen','沈'=>'shen','涁'=>'shen','深'=>'shen','渖'=>'shen','渗'=>'shen','滲'=>'shen','瀋'=>'shen','燊'=>'shen','珅'=>'shen','甚'=>'shen','甡'=>'shen','甧'=>'shen','申'=>'shen','瘆'=>'shen','瘮'=>'shen','眒'=>'shen','眘'=>'shen','瞫'=>'shen','矤'=>'shen','矧'=>'shen','砷'=>'shen','神'=>'shen','祳'=>'shen','穼'=>'shen','籶'=>'shen','籸'=>'shen','紳'=>'shen','绅'=>'shen','罙'=>'shen','罧'=>'shen','肾'=>'shen','胂'=>'shen','脤'=>'shen','腎'=>'shen','葠'=>'shen','蓡'=>'shen','蔘'=>'shen','薓'=>'shen','蜃'=>'shen','裑'=>'shen','覾'=>'shen','訠'=>'shen','訷'=>'shen','詵'=>'shen','諗'=>'shen','讅'=>'shen','诜'=>'shen','谂'=>'shen','谉'=>'shen','身'=>'shen','邥'=>'shen','鉮'=>'shen','鋠'=>'shen','頣'=>'shen','駪'=>'shen','魫'=>'shen','鯓'=>'shen','鯵'=>'shen','鰰'=>'shen','鰺'=>'shen','鲹'=>'shen','鵢'=>'shen','㔤'=>'shen','㜤'=>'shen','㥲'=>'shen','㰂'=>'shen','㰮'=>'shen','㵊'=>'shen','㵕'=>'shen','㾕'=>'shen','䆦'=>'shen','䰠'=>'shen','伹'=>'qu','佉'=>'qu','佢'=>'qu','刞'=>'qu','劬'=>'qu','匤'=>'qu','匷'=>'qu','区'=>'qu','區'=>'qu','厺'=>'qu','去'=>'qu','取'=>'qu','呿'=>'qu','坥'=>'qu','娶'=>'qu','屈'=>'qu','岖'=>'qu','岨'=>'qu','岴'=>'qu','嶇'=>'qu','忂'=>'qu','憈'=>'qu','戵'=>'qu','抾'=>'qu','敺'=>'qu','斪'=>'qu','曲'=>'qu','朐'=>'qu','朑'=>'qu','欋'=>'qu','氍'=>'qu','浀'=>'qu','淭'=>'qu','渠'=>'qu','灈'=>'qu','璖'=>'qu','璩'=>'qu','癯'=>'qu','磲'=>'qu','祛'=>'qu','竘'=>'qu','竬'=>'qu','筁'=>'qu','籧'=>'qu','粬'=>'qu','紶'=>'qu','絇'=>'qu','翑'=>'qu','翵'=>'qu','耝'=>'qu','胊'=>'qu','胠'=>'qu','臞'=>'qu','菃'=>'qu','葋'=>'qu','蕖'=>'qu','蘧'=>'qu','蛆'=>'qu','蛐'=>'qu','蝺'=>'qu','螶'=>'qu','蟝'=>'qu','蠷'=>'qu','蠼'=>'qu','衐'=>'qu','衢'=>'qu','袪'=>'qu','覰'=>'qu','覷'=>'qu','覻'=>'qu','觑'=>'qu','詓'=>'qu','詘'=>'qu','誳'=>'qu','诎'=>'qu','趋'=>'qu','趣'=>'qu','趨'=>'qu','躣'=>'qu','躯'=>'qu','軀'=>'qu','軥'=>'qu','迲'=>'qu','郥'=>'qu','鑺'=>'qu','閴'=>'qu','闃'=>'qu','阒'=>'qu','阹'=>'qu','駆'=>'qu','駈'=>'qu','驅'=>'qu','驱'=>'qu','髷'=>'qu','魼'=>'qu','鰸'=>'qu','鱋'=>'qu','鴝'=>'qu','鸜'=>'qu','鸲'=>'qu','麮'=>'qu','麯'=>'qu','麴'=>'qu','麹'=>'qu','黢'=>'qu','鼁'=>'qu','鼩'=>'qu','齲'=>'qu','龋'=>'qu','㖆'=>'qu','㜹'=>'qu','㠊'=>'qu','㣄'=>'qu','㧁'=>'qu','㫢'=>'qu','㯫'=>'qu','㰦'=>'qu','㲘'=>'qu','䀠'=>'qu','䁦'=>'qu','䂂'=>'qu','䋧'=>'qu','䒧'=>'qu','䝣'=>'qu','䞤'=>'qu','䟊'=>'qu','䠐'=>'qu','䵶'=>'qu','䶚'=>'qu','伻'=>'beng','嘣'=>'beng','埄'=>'beng','埲'=>'beng','塴'=>'beng','奟'=>'beng','崩'=>'beng','嵭'=>'beng','泵'=>'beng','琣'=>'beng','琫'=>'beng','甏'=>'beng','甭'=>'beng','痭'=>'beng','祊'=>'beng','絣'=>'beng','綳'=>'beng','繃'=>'beng','绷'=>'beng','菶'=>'beng','跰'=>'beng','蹦'=>'beng','迸'=>'beng','逬'=>'beng','鏰'=>'beng','镚'=>'beng','閍'=>'beng','鞛'=>'beng','㑟'=>'beng','㱶'=>'beng','㷯'=>'beng','䋽'=>'beng','䙀'=>'beng','䨻'=>'beng','䩬'=>'beng','䭰'=>'beng','䳞'=>'beng','伽'=>'ga','嘎'=>'ga','嘠'=>'ga','噶'=>'ga','尕'=>'ga','尜'=>'ga','尬'=>'ga','旮'=>'ga','玍'=>'ga','釓'=>'ga','錷'=>'ga','钆'=>'ga','魀'=>'ga','佃'=>'dian','傎'=>'dian','典'=>'dian','厧'=>'dian','唸'=>'dian','坫'=>'dian','垫'=>'dian','墊'=>'dian','壂'=>'dian','奌'=>'dian','奠'=>'dian','婝'=>'dian','婰'=>'dian','嵮'=>'dian','巅'=>'dian','巓'=>'dian','巔'=>'dian','店'=>'dian','惦'=>'dian','扂'=>'dian','掂'=>'dian','攧'=>'dian','敁'=>'dian','敟'=>'dian','椣'=>'dian','槙'=>'dian','橂'=>'dian','殿'=>'dian','淀'=>'dian','滇'=>'dian','澱'=>'dian','点'=>'dian','玷'=>'dian','琔'=>'dian','电'=>'dian','甸'=>'dian','瘨'=>'dian','癜'=>'dian','癫'=>'dian','癲'=>'dian','碘'=>'dian','磹'=>'dian','簟'=>'dian','蒧'=>'dian','蕇'=>'dian','蜔'=>'dian','踮'=>'dian','蹎'=>'dian','鈿'=>'dian','钿'=>'dian','阽'=>'dian','電'=>'dian','靛'=>'dian','顚'=>'dian','顛'=>'dian','颠'=>'dian','驔'=>'dian','點'=>'dian','齻'=>'dian','㓠'=>'dian','㚲'=>'dian','㝪'=>'dian','㞟'=>'dian','㥆'=>'dian','㵤'=>'dian','㶘'=>'dian','㸃'=>'dian','㼭'=>'dian','䍄'=>'dian','䓦'=>'dian','䟍'=>'dian','䧃'=>'dian','佄'=>'han','傼'=>'han','兯'=>'han','函'=>'han','凾'=>'han','厈'=>'han','含'=>'han','咁'=>'han','哻'=>'han','唅'=>'han','喊'=>'han','圅'=>'han','垾'=>'han','娢'=>'han','嫨'=>'han','寒'=>'han','屽'=>'han','崡'=>'han','嵅'=>'han','悍'=>'han','憨'=>'han','憾'=>'han','扞'=>'han','捍'=>'han','撖'=>'han','撼'=>'han','旱'=>'han','晗'=>'han','晘'=>'han','晥'=>'han','暵'=>'han','梒'=>'han','汉'=>'han','汗'=>'han','浛'=>'han','浫'=>'han','涆'=>'han','涵'=>'han','淊'=>'han','漢'=>'han','澏'=>'han','瀚'=>'han','焊'=>'han','焓'=>'han','熯'=>'han','爳'=>'han','猂'=>'han','琀'=>'han','甝'=>'han','皔'=>'han','睅'=>'han','筨'=>'han','罕'=>'han','翰'=>'han','肣'=>'han','莟'=>'han','菡'=>'han','蔊'=>'han','蘫'=>'han','虷'=>'han','蚶'=>'han','蛿'=>'han','蜬'=>'han','蜭'=>'han','螒'=>'han','譀'=>'han','谽'=>'han','豃'=>'han','邗'=>'han','邯'=>'han','酣'=>'han','釬'=>'han','銲'=>'han','鋎'=>'han','鋡'=>'han','閈'=>'han','闬'=>'han','雗'=>'han','韓'=>'han','韩'=>'han','頇'=>'han','頷'=>'han','顄'=>'han','顸'=>'han','颔'=>'han','馠'=>'han','馯'=>'han','駻'=>'han','鬫'=>'han','魽'=>'han','鶾'=>'han','鼾'=>'han','㑵'=>'han','㒈'=>'han','㖤'=>'han','㘎'=>'han','㘕'=>'han','㘚'=>'han','㙈'=>'han','㙔'=>'han','㙳'=>'han','㜦'=>'han','㟏'=>'han','㟔'=>'han','㢨'=>'han','㨔'=>'han','㪋'=>'han','㮀'=>'han','㲦'=>'han','㵄'=>'han','㵎'=>'han','㶰'=>'han','㸁'=>'han','㺖'=>'han','㼨'=>'han','㽉'=>'han','㽳'=>'han','䁔'=>'han','䈄'=>'han','䌍'=>'han','䍐'=>'han','䍑'=>'han','䎯'=>'han','䏷'=>'han','䐄'=>'han','䓍'=>'han','䓿'=>'han','䕿'=>'han','䖔'=>'han','䗙'=>'han','䘶'=>'han','䛞'=>'han','䤴'=>'han','䥁'=>'han','䧲'=>'han','䨡'=>'han','䫲'=>'han','䮧'=>'han','䶃'=>'han','佊'=>'bi','佖'=>'bi','俾'=>'bi','偪'=>'bi','匂'=>'bi','匕'=>'bi','吡'=>'bi','哔'=>'bi','啚'=>'bi','嗶'=>'bi','坒'=>'bi','堛'=>'bi','壁'=>'bi','夶'=>'bi','奰'=>'bi','妣'=>'bi','妼'=>'bi','婢'=>'bi','嬖'=>'bi','嬶'=>'bi','屄'=>'bi','币'=>'bi','幣'=>'bi','幤'=>'bi','庇'=>'bi','庳'=>'bi','廦'=>'bi','弊'=>'bi','弻'=>'bi','弼'=>'bi','彃'=>'bi','彼'=>'bi','必'=>'bi','怭'=>'bi','愊'=>'bi','愎'=>'bi','敝'=>'bi','斃'=>'bi','朼'=>'bi','枈'=>'bi','柀'=>'bi','柲'=>'bi','梐'=>'bi','楅'=>'bi','比'=>'bi','毕'=>'bi','毖'=>'bi','毙'=>'bi','毴'=>'bi','沘'=>'bi','湢'=>'bi','滗'=>'bi','滭'=>'bi','潷'=>'bi','濞'=>'bi','煏'=>'bi','熚'=>'bi','狴'=>'bi','獘'=>'bi','獙'=>'bi','珌'=>'bi','璧'=>'bi','畀'=>'bi','畁'=>'bi','畢'=>'bi','疕'=>'bi','疪'=>'bi','痹'=>'bi','痺'=>'bi','皀'=>'bi','皕'=>'bi','碧'=>'bi','禆'=>'bi','秕'=>'bi','稫'=>'bi','笔'=>'bi','筆'=>'bi','筚'=>'bi','箅'=>'bi','箆'=>'bi','篦'=>'bi','篳'=>'bi','粃'=>'bi','粊'=>'bi','綼'=>'bi','縪'=>'bi','繴'=>'bi','罼'=>'bi','聛'=>'bi','胇'=>'bi','腷'=>'bi','臂'=>'bi','舭'=>'bi','苾'=>'bi','荜'=>'bi','荸'=>'bi','萆'=>'bi','萞'=>'bi','蓖'=>'bi','蓽'=>'bi','蔽'=>'bi','薜'=>'bi','蜌'=>'bi','螕'=>'bi','袐'=>'bi','裨'=>'bi','襅'=>'bi','襞'=>'bi','襣'=>'bi','觱'=>'bi','詖'=>'bi','诐'=>'bi','豍'=>'bi','貏'=>'bi','貱'=>'bi','贔'=>'bi','赑'=>'bi','跸'=>'bi','蹕'=>'bi','躃'=>'bi','躄'=>'bi','辟'=>'bi','逼'=>'bi','避'=>'bi','邲'=>'bi','鄙'=>'bi','鄨'=>'bi','鄪'=>'bi','鉍'=>'bi','鎞'=>'bi','鏎'=>'bi','鐴'=>'bi','铋'=>'bi','閇'=>'bi','閉'=>'bi','閟'=>'bi','闭'=>'bi','陛'=>'bi','鞞'=>'bi','鞸'=>'bi','韠'=>'bi','飶'=>'bi','饆'=>'bi','馝'=>'bi','駜'=>'bi','驆'=>'bi','髀'=>'bi','髲'=>'bi','魓'=>'bi','鮅'=>'bi','鰏'=>'bi','鲾'=>'bi','鵖'=>'bi','鷝'=>'bi','鷩'=>'bi','鼊'=>'bi','鼻'=>'bi','㓖'=>'bi','㗉'=>'bi','㘠'=>'bi','㘩'=>'bi','㙄'=>'bi','㚰'=>'bi','㠲'=>'bi','㡀'=>'bi','㡙'=>'bi','㢰'=>'bi','㢶'=>'bi','㢸'=>'bi','㧙'=>'bi','㪏'=>'bi','㪤'=>'bi','㮰'=>'bi','㮿'=>'bi','㯇'=>'bi','㱸'=>'bi','㳼'=>'bi','㵥'=>'bi','㵨'=>'bi','㹃'=>'bi','㻫'=>'bi','㻶'=>'bi','㿫'=>'bi','䀣'=>'bi','䁹'=>'bi','䃾'=>'bi','䄶'=>'bi','䇷'=>'bi','䊧'=>'bi','䋔'=>'bi','䌟'=>'bi','䎵'=>'bi','䏢'=>'bi','䏶'=>'bi','䕗'=>'bi','䖩'=>'bi','䘡'=>'bi','䟆'=>'bi','䟤'=>'bi','䠋'=>'bi','䣥'=>'bi','䦘'=>'bi','䧗'=>'bi','䨆'=>'bi','䩛'=>'bi','䪐'=>'bi','䫁'=>'bi','䫾'=>'bi','䭮'=>'bi','䮡'=>'bi','䯗'=>'bi','䵄'=>'bi','佋'=>'zhao','兆'=>'zhao','召'=>'zhao','啁'=>'zhao','垗'=>'zhao','妱'=>'zhao','巶'=>'zhao','找'=>'zhao','招'=>'zhao','旐'=>'zhao','昭'=>'zhao','曌'=>'zhao','枛'=>'zhao','棹'=>'zhao','櫂'=>'zhao','沼'=>'zhao','炤'=>'zhao','照'=>'zhao','燳'=>'zhao','爫'=>'zhao','狣'=>'zhao','瑵'=>'zhao','盄'=>'zhao','瞾'=>'zhao','窼'=>'zhao','笊'=>'zhao','箌'=>'zhao','罀'=>'zhao','罩'=>'zhao','羄'=>'zhao','肁'=>'zhao','肇'=>'zhao','肈'=>'zhao','詔'=>'zhao','诏'=>'zhao','赵'=>'zhao','趙'=>'zhao','釗'=>'zhao','鉊'=>'zhao','鍣'=>'zhao','钊'=>'zhao','駋'=>'zhao','鮡'=>'zhao','㕚'=>'zhao','㡽'=>'zhao','㨄'=>'zhao','㷖'=>'zhao','㺐'=>'zhao','䃍'=>'zhao','䈃'=>'zhao','䈇'=>'zhao','䍜'=>'zhao','䍮'=>'zhao','䝖'=>'zhao','䮓'=>'zhao','佌'=>'ci','佽'=>'ci','偨'=>'ci','刺'=>'ci','刾'=>'ci','呲'=>'ci','嗭'=>'ci','垐'=>'ci','堲'=>'ci','嬨'=>'ci','庛'=>'ci','慈'=>'ci','朿'=>'ci','柌'=>'ci','栨'=>'ci','次'=>'ci','此'=>'ci','泚'=>'ci','濨'=>'ci','玼'=>'ci','珁'=>'ci','瓷'=>'ci','甆'=>'ci','疵'=>'ci','皉'=>'ci','磁'=>'ci','礠'=>'ci','祠'=>'ci','糍'=>'ci','絘'=>'ci','縒'=>'ci','茈'=>'ci','茦'=>'ci','茨'=>'ci','莿'=>'ci','薋'=>'ci','蛓'=>'ci','螆'=>'ci','蠀'=>'ci','詞'=>'ci','词'=>'ci','賜'=>'ci','赐'=>'ci','趀'=>'ci','跐'=>'ci','辝'=>'ci','辞'=>'ci','辤'=>'ci','辭'=>'ci','鈶'=>'ci','雌'=>'ci','飺'=>'ci','餈'=>'ci','骴'=>'ci','鴜'=>'ci','鶿'=>'ci','鷀'=>'ci','鹚'=>'ci','㓨'=>'ci','㘂'=>'ci','㘹'=>'ci','㞖'=>'ci','㠿'=>'ci','㡹'=>'ci','㢀'=>'ci','㤵'=>'ci','㩞'=>'ci','㹂'=>'ci','䂣'=>'ci','䆅'=>'ci','䈘'=>'ci','䓧'=>'ci','䖪'=>'ci','䗹'=>'ci','䛐'=>'ci','䦻'=>'ci','䧳'=>'ci','䨏'=>'ci','䭣'=>'ci','䯸'=>'ci','䰍'=>'ci','䲿'=>'ci','䳄'=>'ci','䳐'=>'ci','佐'=>'zuo','作'=>'zuo','侳'=>'zuo','做'=>'zuo','咗'=>'zuo','唑'=>'zuo','坐'=>'zuo','岝'=>'zuo','岞'=>'zuo','左'=>'zuo','座'=>'zuo','怍'=>'zuo','捽'=>'zuo','昨'=>'zuo','柞'=>'zuo','椊'=>'zuo','祚'=>'zuo','秨'=>'zuo','稓'=>'zuo','筰'=>'zuo','糳'=>'zuo','繓'=>'zuo','胙'=>'zuo','莋'=>'zuo','葃'=>'zuo','葄'=>'zuo','蓙'=>'zuo','袏'=>'zuo','鈼'=>'zuo','阼'=>'zuo','飵'=>'zuo','㑅'=>'zuo','㘀'=>'zuo','㘴'=>'zuo','㛗'=>'zuo','㝾'=>'zuo','㭮'=>'zuo','㸲'=>'zuo','䋏'=>'zuo','䎰'=>'zuo','䔘'=>'zuo','䝫'=>'zuo','䞰'=>'zuo','体'=>'ti','倜'=>'ti','偍'=>'ti','剃'=>'ti','剔'=>'ti','厗'=>'ti','啼'=>'ti','嗁'=>'ti','嚏'=>'ti','嚔'=>'ti','媞'=>'ti','屉'=>'ti','屜'=>'ti','崹'=>'ti','徲'=>'ti','悌'=>'ti','悐'=>'ti','惕'=>'ti','惖'=>'ti','惿'=>'ti','戻'=>'ti','挮'=>'ti','掦'=>'ti','提'=>'ti','揥'=>'ti','替'=>'ti','梯'=>'ti','楴'=>'ti','歒'=>'ti','殢'=>'ti','洟'=>'ti','涕'=>'ti','渧'=>'ti','漽'=>'ti','珶'=>'ti','瑅'=>'ti','瓋'=>'ti','碮'=>'ti','稊'=>'ti','籊'=>'ti','綈'=>'ti','緹'=>'ti','绨'=>'ti','缇'=>'ti','罤'=>'ti','蕛'=>'ti','薙'=>'ti','蝭'=>'ti','裼'=>'ti','褅'=>'ti','謕'=>'ti','趧'=>'ti','趯'=>'ti','踢'=>'ti','蹄'=>'ti','蹏'=>'ti','躰'=>'ti','軆'=>'ti','逖'=>'ti','逷'=>'ti','遆'=>'ti','醍'=>'ti','銻'=>'ti','鍗'=>'ti','鐟'=>'ti','锑'=>'ti','題'=>'ti','题'=>'ti','騠'=>'ti','骵'=>'ti','體'=>'ti','髰'=>'ti','鬀'=>'ti','鬄'=>'ti','鮷'=>'ti','鯷'=>'ti','鳀'=>'ti','鴺'=>'ti','鵜'=>'ti','鶗'=>'ti','鶙'=>'ti','鷈'=>'ti','鷉'=>'ti','鹈'=>'ti','㖒'=>'ti','㗣'=>'ti','㡗'=>'ti','㣢'=>'ti','㬱'=>'ti','㯩'=>'ti','䅠'=>'ti','䌡'=>'ti','䎮'=>'ti','䔶'=>'ti','䙗'=>'ti','䚣'=>'ti','䛱'=>'ti','䝰'=>'ti','䣡'=>'ti','䣽'=>'ti','䧅'=>'ti','䨑'=>'ti','䪆'=>'ti','䬾'=>'ti','䯜'=>'ti','䴘'=>'ti','䶏'=>'ti','䶑'=>'ti','佔'=>'zhan','偡'=>'zhan','占'=>'zhan','噡'=>'zhan','嫸'=>'zhan','展'=>'zhan','崭'=>'zhan','嶃'=>'zhan','嶄'=>'zhan','嶘'=>'zhan','嶦'=>'zhan','惉'=>'zhan','战'=>'zhan','戦'=>'zhan','戰'=>'zhan','拃'=>'zhan','搌'=>'zhan','斩'=>'zhan','斬'=>'zhan','旃'=>'zhan','旜'=>'zhan','栈'=>'zhan','栴'=>'zhan','桟'=>'zhan','棧'=>'zhan','榐'=>'zhan','橏'=>'zhan','毡'=>'zhan','氈'=>'zhan','氊'=>'zhan','沾'=>'zhan','湛'=>'zhan','澶'=>'zhan','琖'=>'zhan','皽'=>'zhan','盏'=>'zhan','盞'=>'zhan','瞻'=>'zhan','站'=>'zhan','粘'=>'zhan','綻'=>'zhan','绽'=>'zhan','菚'=>'zhan','薝'=>'zhan','蘸'=>'zhan','虥'=>'zhan','虦'=>'zhan','蛅'=>'zhan','覱'=>'zhan','詀'=>'zhan','詹'=>'zhan','譫'=>'zhan','讝'=>'zhan','谵'=>'zhan','趈'=>'zhan','蹍'=>'zhan','輚'=>'zhan','輾'=>'zhan','轏'=>'zhan','辗'=>'zhan','邅'=>'zhan','醆'=>'zhan','閚'=>'zhan','霑'=>'zhan','颭'=>'zhan','飐'=>'zhan','飦'=>'zhan','饘'=>'zhan','驏'=>'zhan','驙'=>'zhan','骣'=>'zhan','魙'=>'zhan','鱣'=>'zhan','鳣'=>'zhan','鸇'=>'zhan','鹯'=>'zhan','黵'=>'zhan','㞡'=>'zhan','㟞'=>'zhan','㠭'=>'zhan','㣶'=>'zhan','㺘'=>'zhan','㻵'=>'zhan','䁴'=>'zhan','䋎'=>'zhan','䎒'=>'zhan','䗃'=>'zhan','䘺'=>'zhan','䟋'=>'zhan','䡀'=>'zhan','䩅'=>'zhan','䪌'=>'zhan','䱠'=>'zhan','䱼'=>'zhan','何'=>'he','佫'=>'he','劾'=>'he','合'=>'he','呵'=>'he','咊'=>'he','和'=>'he','哬'=>'he','啝'=>'he','喝'=>'he','嗃'=>'he','嗬'=>'he','垎'=>'he','壑'=>'he','姀'=>'he','寉'=>'he','峆'=>'he','惒'=>'he','抲'=>'he','敆'=>'he','曷'=>'he','柇'=>'he','核'=>'he','楁'=>'he','欱'=>'he','毼'=>'he','河'=>'he','涸'=>'he','渮'=>'he','湼'=>'he','澕'=>'he','焃'=>'he','煂'=>'he','熆'=>'he','熇'=>'he','燺'=>'he','爀'=>'he','狢'=>'he','癋'=>'he','皬'=>'he','盇'=>'he','盉'=>'he','盍'=>'he','盒'=>'he','碋'=>'he','礉'=>'he','禾'=>'he','秴'=>'he','篕'=>'he','籺'=>'he','粭'=>'he','翮'=>'he','翯'=>'he','荷'=>'he','菏'=>'he','萂'=>'he','蚵'=>'he','螛'=>'he','蠚'=>'he','袔'=>'he','褐'=>'he','覈'=>'he','訶'=>'he','訸'=>'he','詥'=>'he','诃'=>'he','貈'=>'he','貉'=>'he','賀'=>'he','贺'=>'he','赫'=>'he','郃'=>'he','鉌'=>'he','鑉'=>'he','閡'=>'he','闔'=>'he','阂'=>'he','阖'=>'he','隺'=>'he','靍'=>'he','靎'=>'he','靏'=>'he','鞨'=>'he','頜'=>'he','颌'=>'he','饸'=>'he','魺'=>'he','鲄'=>'he','鶡'=>'he','鶴'=>'he','鸖'=>'he','鹖'=>'he','鹤'=>'he','麧'=>'he','齃'=>'he','齕'=>'he','龁'=>'he','龢'=>'he','㓭'=>'he','㔠'=>'he','㕡'=>'he','㕰'=>'he','㥺'=>'he','㦦'=>'he','㪉'=>'he','㬞'=>'he','㭘'=>'he','㭱'=>'he','㮝'=>'he','㮫'=>'he','㵑'=>'he','㷎'=>'he','㷤'=>'he','㹇'=>'he','㿣'=>'he','䃒'=>'he','䅂'=>'he','䎋'=>'he','䒩'=>'he','䓼'=>'he','䕣'=>'he','䚂'=>'he','䞦'=>'he','䢗'=>'he','䪚'=>'he','䫘'=>'he','䳚'=>'he','䳽'=>'he','䴳'=>'he','䵱'=>'he','䶅'=>'he','佘'=>'she','厍'=>'she','厙'=>'she','奢'=>'she','射'=>'she','弽'=>'she','慑'=>'she','慴'=>'she','懾'=>'she','捨'=>'she','摂'=>'she','摄'=>'she','摵'=>'she','攝'=>'she','檨'=>'she','欇'=>'she','涉'=>'she','涻'=>'she','渉'=>'she','滠'=>'she','灄'=>'she','猞'=>'she','畲'=>'she','社'=>'she','舌'=>'she','舍'=>'she','舎'=>'she','蔎'=>'she','虵'=>'she','蛇'=>'she','蛥'=>'she','蠂'=>'she','設'=>'she','设'=>'she','賒'=>'she','賖'=>'she','赊'=>'she','赦'=>'she','輋'=>'she','韘'=>'she','騇'=>'she','麝'=>'she','㒤'=>'she','㢵'=>'she','㭙'=>'she','㰒'=>'she','㴇'=>'she','䀅'=>'she','䁋'=>'she','䁯'=>'she','䂠'=>'she','䄕'=>'she','䌰'=>'she','䞌'=>'she','䠶'=>'she','䤮'=>'she','䬷'=>'she','䵥'=>'she','佝'=>'gou','冓'=>'gou','勾'=>'gou','坸'=>'gou','垢'=>'gou','够'=>'gou','夠'=>'gou','姤'=>'gou','媾'=>'gou','岣'=>'gou','彀'=>'gou','搆'=>'gou','撀'=>'gou','构'=>'gou','枸'=>'gou','構'=>'gou','沟'=>'gou','溝'=>'gou','煹'=>'gou','狗'=>'gou','玽'=>'gou','笱'=>'gou','篝'=>'gou','簼'=>'gou','緱'=>'gou','缑'=>'gou','耇'=>'gou','耈'=>'gou','耉'=>'gou','苟'=>'gou','茩'=>'gou','蚼'=>'gou','袧'=>'gou','褠'=>'gou','覯'=>'gou','觏'=>'gou','訽'=>'gou','詬'=>'gou','诟'=>'gou','豿'=>'gou','購'=>'gou','购'=>'gou','遘'=>'gou','鈎'=>'gou','鉤'=>'gou','钩'=>'gou','雊'=>'gou','鞲'=>'gou','韝'=>'gou','㗕'=>'gou','㜌'=>'gou','㝅'=>'gou','㝤'=>'gou','㨌'=>'gou','㳶'=>'gou','㺃'=>'gou','䃓'=>'gou','䝭'=>'gou','䞀'=>'gou','佞'=>'ning','侫'=>'ning','儜'=>'ning','凝'=>'ning','咛'=>'ning','嚀'=>'ning','嬣'=>'ning','宁'=>'ning','寍'=>'ning','寕'=>'ning','寗'=>'ning','寜'=>'ning','寧'=>'ning','拧'=>'ning','擰'=>'ning','柠'=>'ning','橣'=>'ning','檸'=>'ning','泞'=>'ning','澝'=>'ning','濘'=>'ning','狞'=>'ning','獰'=>'ning','甯'=>'ning','矃'=>'ning','聍'=>'ning','聹'=>'ning','薴'=>'ning','鑏'=>'ning','鬡'=>'ning','鸋'=>'ning','㝕'=>'ning','㣷'=>'ning','㲰'=>'ning','㿦'=>'ning','䔭'=>'ning','䗿'=>'ning','䭢'=>'ning','佣'=>'yong','俑'=>'yong','傛'=>'yong','傭'=>'yong','勇'=>'yong','勈'=>'yong','咏'=>'yong','喁'=>'yong','嗈'=>'yong','噰'=>'yong','埇'=>'yong','塎'=>'yong','墉'=>'yong','壅'=>'yong','嫞'=>'yong','嵱'=>'yong','庸'=>'yong','廱'=>'yong','彮'=>'yong','怺'=>'yong','恿'=>'yong','悀'=>'yong','惥'=>'yong','愑'=>'yong','愹'=>'yong','慂'=>'yong','慵'=>'yong','拥'=>'yong','擁'=>'yong','柡'=>'yong','栐'=>'yong','槦'=>'yong','永'=>'yong','泳'=>'yong','涌'=>'yong','湧'=>'yong','滽'=>'yong','澭'=>'yong','灉'=>'yong','牅'=>'yong','用'=>'yong','甬'=>'yong','痈'=>'yong','癕'=>'yong','癰'=>'yong','砽'=>'yong','硧'=>'yong','禜'=>'yong','臃'=>'yong','苚'=>'yong','蛹'=>'yong','詠'=>'yong','踊'=>'yong','踴'=>'yong','邕'=>'yong','郺'=>'yong','鄘'=>'yong','醟'=>'yong','銿'=>'yong','鏞'=>'yong','镛'=>'yong','雍'=>'yong','雝'=>'yong','顒'=>'yong','颙'=>'yong','饔'=>'yong','鯒'=>'yong','鰫'=>'yong','鱅'=>'yong','鲬'=>'yong','鳙'=>'yong','鷛'=>'yong','㐯'=>'yong','㙲'=>'yong','㝘'=>'yong','㞲'=>'yong','㦷'=>'yong','㶲'=>'yong','㷏'=>'yong','㽫'=>'yong','䗤'=>'yong','䞻'=>'yong','佤'=>'wa','劸'=>'wa','咓'=>'wa','哇'=>'wa','啘'=>'wa','嗗'=>'wa','嗢'=>'wa','娃'=>'wa','娲'=>'wa','媧'=>'wa','屲'=>'wa','徍'=>'wa','挖'=>'wa','搲'=>'wa','攨'=>'wa','洼'=>'wa','溛'=>'wa','漥'=>'wa','瓦'=>'wa','瓲'=>'wa','畖'=>'wa','砙'=>'wa','窊'=>'wa','窪'=>'wa','聉'=>'wa','腽'=>'wa','膃'=>'wa','蛙'=>'wa','袜'=>'wa','襪'=>'wa','邷'=>'wa','韈'=>'wa','韤'=>'wa','鼃'=>'wa','㧚'=>'wa','㰪'=>'wa','㼘'=>'wa','䎳'=>'wa','䚴'=>'wa','䠚'=>'wa','佧'=>'ka','卡'=>'ka','咔'=>'ka','咖'=>'ka','咯'=>'ka','喀'=>'ka','垰'=>'ka','胩'=>'ka','裃'=>'ka','鉲'=>'ka','佨'=>'bao','保'=>'bao','儤'=>'bao','剝'=>'bao','剥'=>'bao','勹'=>'bao','勽'=>'bao','包'=>'bao','堡'=>'bao','堢'=>'bao','報'=>'bao','媬'=>'bao','嫑'=>'bao','孢'=>'bao','宝'=>'bao','寚'=>'bao','寳'=>'bao','寶'=>'bao','忁'=>'bao','怉'=>'bao','报'=>'bao','抱'=>'bao','暴'=>'bao','曓'=>'bao','煲'=>'bao','爆'=>'bao','珤'=>'bao','窇'=>'bao','笣'=>'bao','緥'=>'bao','胞'=>'bao','苞'=>'bao','菢'=>'bao','萡'=>'bao','葆'=>'bao','蕔'=>'bao','薄'=>'bao','藵'=>'bao','虣'=>'bao','袌'=>'bao','褒'=>'bao','褓'=>'bao','襃'=>'bao','豹'=>'bao','賲'=>'bao','趵'=>'bao','鉋'=>'bao','鑤'=>'bao','铇'=>'bao','闁'=>'bao','雹'=>'bao','靌'=>'bao','靤'=>'bao','飹'=>'bao','飽'=>'bao','饱'=>'bao','駂'=>'bao','骲'=>'bao','髱'=>'bao','鮑'=>'bao','鲍'=>'bao','鳵'=>'bao','鴇'=>'bao','鸨'=>'bao','齙'=>'bao','龅'=>'bao','㙅'=>'bao','㙸'=>'bao','㫧'=>'bao','㲏'=>'bao','㲒'=>'bao','㵡'=>'bao','㻄'=>'bao','㿺'=>'bao','䈏'=>'bao','䎂'=>'bao','䤖'=>'bao','䥤'=>'bao','䨌'=>'bao','䨔'=>'bao','䪨'=>'bao','䭋'=>'bao','䳈'=>'bao','䳰'=>'bao','䴐'=>'bao','佬'=>'lao','僗'=>'lao','劳'=>'lao','労'=>'lao','勞'=>'lao','咾'=>'lao','哰'=>'lao','唠'=>'lao','嗠'=>'lao','嘮'=>'lao','姥'=>'lao','嫪'=>'lao','崂'=>'lao','嶗'=>'lao','恅'=>'lao','憥'=>'lao','憦'=>'lao','捞'=>'lao','撈'=>'lao','朥'=>'lao','栳'=>'lao','橑'=>'lao','橯'=>'lao','浶'=>'lao','涝'=>'lao','澇'=>'lao','烙'=>'lao','牢'=>'lao','狫'=>'lao','珯'=>'lao','痨'=>'lao','癆'=>'lao','硓'=>'lao','磱'=>'lao','窂'=>'lao','簩'=>'lao','粩'=>'lao','老'=>'lao','耂'=>'lao','耢'=>'lao','耮'=>'lao','荖'=>'lao','蛯'=>'lao','蟧'=>'lao','軂'=>'lao','轑'=>'lao','酪'=>'lao','醪'=>'lao','銠'=>'lao','鐒'=>'lao','铑'=>'lao','铹'=>'lao','顟'=>'lao','髝'=>'lao','鮱'=>'lao','㗦'=>'lao','㞠'=>'lao','㟉'=>'lao','㟙'=>'lao','㟹'=>'lao','㧯'=>'lao','㨓'=>'lao','䃕'=>'lao','䇭'=>'lao','䕩'=>'lao','䜎'=>'lao','䝁'=>'lao','䝤'=>'lao','䲏'=>'lao','䳓'=>'lao','䵏'=>'lao','佰'=>'bai','兡'=>'bai','呗'=>'bai','唄'=>'bai','庍'=>'bai','拜'=>'bai','拝'=>'bai','挀'=>'bai','捭'=>'bai','掰'=>'bai','摆'=>'bai','擺'=>'bai','敗'=>'bai','柏'=>'bai','栢'=>'bai','猈'=>'bai','瓸'=>'bai','白'=>'bai','百'=>'bai','稗'=>'bai','竡'=>'bai','粨'=>'bai','粺'=>'bai','絔'=>'bai','薭'=>'bai','襬'=>'bai','贁'=>'bai','败'=>'bai','鞁'=>'bai','韛'=>'bai','㗑'=>'bai','㗗'=>'bai','㠔'=>'bai','㼟'=>'bai','㼣'=>'bai','㿟'=>'bai','䒔'=>'bai','䙓'=>'bai','䢙'=>'bai','䳆'=>'bai','䴽'=>'bai','佲'=>'ming','冥'=>'ming','凕'=>'ming','名'=>'ming','命'=>'ming','姳'=>'ming','嫇'=>'ming','慏'=>'ming','掵'=>'ming','明'=>'ming','暝'=>'ming','朙'=>'ming','榠'=>'ming','洺'=>'ming','溟'=>'ming','猽'=>'ming','眀'=>'ming','眳'=>'ming','瞑'=>'ming','茗'=>'ming','蓂'=>'ming','螟'=>'ming','覭'=>'ming','詺'=>'ming','鄍'=>'ming','酩'=>'ming','銘'=>'ming','铭'=>'ming','鳴'=>'ming','鸣'=>'ming','㝠'=>'ming','㟰'=>'ming','㫥'=>'ming','䄙'=>'ming','䆨'=>'ming','䆩'=>'ming','䊅'=>'ming','䒌'=>'ming','䫤'=>'ming','佷'=>'hen','很'=>'hen','恨'=>'hen','拫'=>'hen','狠'=>'hen','痕'=>'hen','詪'=>'hen','鞎'=>'hen','㯊'=>'hen','䓳'=>'hen','佺'=>'quan','全'=>'quan','券'=>'quan','劝'=>'quan','勧'=>'quan','勸'=>'quan','啳'=>'quan','圈'=>'quan','圏'=>'quan','埢'=>'quan','姾'=>'quan','婘'=>'quan','孉'=>'quan','峑'=>'quan','巏'=>'quan','巻'=>'quan','恮'=>'quan','悛'=>'quan','惓'=>'quan','拳'=>'quan','搼'=>'quan','权'=>'quan','棬'=>'quan','椦'=>'quan','楾'=>'quan','権'=>'quan','權'=>'quan','汱'=>'quan','泉'=>'quan','洤'=>'quan','湶'=>'quan','烇'=>'quan','牶'=>'quan','牷'=>'quan','犈'=>'quan','犬'=>'quan','犭'=>'quan','瑔'=>'quan','甽'=>'quan','畎'=>'quan','痊'=>'quan','硂'=>'quan','筌'=>'quan','絟'=>'quan','綣'=>'quan','縓'=>'quan','绻'=>'quan','腃'=>'quan','荃'=>'quan','葲'=>'quan','虇'=>'quan','蜷'=>'quan','蠸'=>'quan','觠'=>'quan','詮'=>'quan','诠'=>'quan','跧'=>'quan','踡'=>'quan','輇'=>'quan','辁'=>'quan','醛'=>'quan','銓'=>'quan','鐉'=>'quan','铨'=>'quan','闎'=>'quan','韏'=>'quan','顴'=>'quan','颧'=>'quan','駩'=>'quan','騡'=>'quan','鬈'=>'quan','鰁'=>'quan','鳈'=>'quan','齤'=>'quan','㒰'=>'quan','㟨'=>'quan','㟫'=>'quan','䀬'=>'quan','䄐'=>'quan','䊎'=>'quan','䑏'=>'quan','䟒'=>'quan','䠰'=>'quan','佻'=>'tiao','嬥'=>'tiao','宨'=>'tiao','岧'=>'tiao','岹'=>'tiao','庣'=>'tiao','恌'=>'tiao','挑'=>'tiao','旫'=>'tiao','晀'=>'tiao','朓'=>'tiao','条'=>'tiao','條'=>'tiao','樤'=>'tiao','眺'=>'tiao','祒'=>'tiao','祧'=>'tiao','窕'=>'tiao','窱'=>'tiao','笤'=>'tiao','粜'=>'tiao','糶'=>'tiao','絩'=>'tiao','聎'=>'tiao','脁'=>'tiao','芀'=>'tiao','蓚'=>'tiao','蓨'=>'tiao','蜩'=>'tiao','螩'=>'tiao','覜'=>'tiao','誂'=>'tiao','趒'=>'tiao','跳'=>'tiao','迢'=>'tiao','鋚'=>'tiao','鎥'=>'tiao','铫'=>'tiao','鞗'=>'tiao','頫'=>'tiao','髫'=>'tiao','鯈'=>'tiao','鰷'=>'tiao','鲦'=>'tiao','齠'=>'tiao','龆'=>'tiao','㑿'=>'tiao','㟘'=>'tiao','㸠'=>'tiao','䎄'=>'tiao','䒒'=>'tiao','䖺'=>'tiao','䟭'=>'tiao','䠷'=>'tiao','䩦'=>'tiao','䯾'=>'tiao','䱔'=>'tiao','䳂'=>'tiao','侀'=>'xing','倖'=>'xing','兴'=>'xing','刑'=>'xing','哘'=>'xing','型'=>'xing','垶'=>'xing','塂'=>'xing','姓'=>'xing','娙'=>'xing','婞'=>'xing','嬹'=>'xing','幸'=>'xing','形'=>'xing','性'=>'xing','悻'=>'xing','惺'=>'xing','擤'=>'xing','星'=>'xing','曐'=>'xing','杏'=>'xing','洐'=>'xing','涬'=>'xing','煋'=>'xing','狌'=>'xing','猩'=>'xing','瑆'=>'xing','皨'=>'xing','睲'=>'xing','硎'=>'xing','箵'=>'xing','篂'=>'xing','緈'=>'xing','腥'=>'xing','臖'=>'xing','興'=>'xing','荇'=>'xing','莕'=>'xing','蛵'=>'xing','行'=>'xing','裄'=>'xing','觪'=>'xing','觲'=>'xing','謃'=>'xing','邢'=>'xing','郉'=>'xing','醒'=>'xing','鈃'=>'xing','鉶'=>'xing','銒'=>'xing','鋞'=>'xing','钘'=>'xing','铏'=>'xing','陉'=>'xing','陘'=>'xing','騂'=>'xing','骍'=>'xing','鮏'=>'xing','鯹'=>'xing','㐩'=>'xing','㓑'=>'xing','㓝'=>'xing','㝭'=>'xing','㣜'=>'xing','㨘'=>'xing','㮐'=>'xing','㼛'=>'xing','㼬'=>'xing','䁄'=>'xing','䂔'=>'xing','䓷'=>'xing','䛭'=>'xing','䣆'=>'xing','䤯'=>'xing','䰢'=>'xing','䳙'=>'xing','侃'=>'kan','偘'=>'kan','冚'=>'kan','刊'=>'kan','勘'=>'kan','坎'=>'kan','埳'=>'kan','堪'=>'kan','堿'=>'kan','塪'=>'kan','墈'=>'kan','崁'=>'kan','嵁'=>'kan','惂'=>'kan','戡'=>'kan','栞'=>'kan','欿'=>'kan','歁'=>'kan','看'=>'kan','瞰'=>'kan','矙'=>'kan','砍'=>'kan','磡'=>'kan','竷'=>'kan','莰'=>'kan','衎'=>'kan','輡'=>'kan','轁'=>'kan','轗'=>'kan','闞'=>'kan','阚'=>'kan','顑'=>'kan','龕'=>'kan','龛'=>'kan','㸝'=>'kan','䀍'=>'kan','䘓'=>'kan','䶫'=>'kan','來'=>'lai','俫'=>'lai','倈'=>'lai','唻'=>'lai','婡'=>'lai','崃'=>'lai','崍'=>'lai','庲'=>'lai','徕'=>'lai','徠'=>'lai','来'=>'lai','梾'=>'lai','棶'=>'lai','涞'=>'lai','淶'=>'lai','濑'=>'lai','瀨'=>'lai','瀬'=>'lai','猍'=>'lai','琜'=>'lai','癞'=>'lai','癩'=>'lai','睐'=>'lai','睞'=>'lai','筙'=>'lai','箂'=>'lai','籁'=>'lai','籟'=>'lai','莱'=>'lai','萊'=>'lai','藾'=>'lai','襰'=>'lai','賚'=>'lai','賴'=>'lai','赉'=>'lai','赖'=>'lai','逨'=>'lai','郲'=>'lai','錸'=>'lai','铼'=>'lai','頼'=>'lai','顂'=>'lai','騋'=>'lai','鯠'=>'lai','鵣'=>'lai','鶆'=>'lai','麳'=>'lai','㚓'=>'lai','㠣'=>'lai','㥎'=>'lai','㾢'=>'lai','䂾'=>'lai','䄤'=>'lai','䅘'=>'lai','䋱'=>'lai','䓶'=>'lai','䚅'=>'lai','䠭'=>'lai','䧒'=>'lai','䲚'=>'lai','侈'=>'chi','侙'=>'chi','俿'=>'chi','傺'=>'chi','勅'=>'chi','匙'=>'chi','卶'=>'chi','叱'=>'chi','叺'=>'chi','吃'=>'chi','呎'=>'chi','哧'=>'chi','啻'=>'chi','喫'=>'chi','嗤'=>'chi','噄'=>'chi','坘'=>'chi','垑'=>'chi','墀'=>'chi','妛'=>'chi','媸'=>'chi','尺'=>'chi','岻'=>'chi','弛'=>'chi','彨'=>'chi','彲'=>'chi','彳'=>'chi','恜'=>'chi','恥'=>'chi','慗'=>'chi','憏'=>'chi','懘'=>'chi','抶'=>'chi','拸'=>'chi','持'=>'chi','摛'=>'chi','攡'=>'chi','敕'=>'chi','斥'=>'chi','杘'=>'chi','欼'=>'chi','歭'=>'chi','歯'=>'chi','池'=>'chi','泜'=>'chi','淔'=>'chi','湁'=>'chi','漦'=>'chi','灻'=>'chi','炽'=>'chi','烾'=>'chi','熾'=>'chi','瓻'=>'chi','痓'=>'chi','痴'=>'chi','痸'=>'chi','瘛'=>'chi','癡'=>'chi','眵'=>'chi','瞝'=>'chi','竾'=>'chi','笞'=>'chi','筂'=>'chi','篪'=>'chi','粚'=>'chi','糦'=>'chi','絺'=>'chi','翄'=>'chi','翅'=>'chi','翤'=>'chi','翨'=>'chi','耛'=>'chi','耻'=>'chi','肔'=>'chi','胣'=>'chi','胵'=>'chi','腟'=>'chi','茌'=>'chi','荎'=>'chi','蚇'=>'chi','蚩'=>'chi','蚳'=>'chi','螭'=>'chi','袲'=>'chi','袳'=>'chi','裭'=>'chi','褫'=>'chi','訵'=>'chi','誺'=>'chi','謘'=>'chi','豉'=>'chi','貾'=>'chi','赤'=>'chi','赿'=>'chi','趍'=>'chi','趩'=>'chi','跮'=>'chi','踟'=>'chi','迟'=>'chi','迣'=>'chi','遅'=>'chi','遟'=>'chi','遫'=>'chi','遲'=>'chi','鉓'=>'chi','鉹'=>'chi','銐'=>'chi','雴'=>'chi','飭'=>'chi','饎'=>'chi','饬'=>'chi','馳'=>'chi','驰'=>'chi','魑'=>'chi','鴟'=>'chi','鵄'=>'chi','鶒'=>'chi','鷘'=>'chi','鸱'=>'chi','麶'=>'chi','黐'=>'chi','齒'=>'chi','齝'=>'chi','齿'=>'chi','㒆'=>'chi','㓼'=>'chi','㓾'=>'chi','㔑'=>'chi','㘜'=>'chi','㙜'=>'chi','㞴'=>'chi','㞿'=>'chi','㟂'=>'chi','㡿'=>'chi','㢁'=>'chi','㢋'=>'chi','㢮'=>'chi','㮛'=>'chi','㱀'=>'chi','㳏'=>'chi','㶴'=>'chi','㽚'=>'chi','䆍'=>'chi','䇼'=>'chi','䈕'=>'chi','䊼'=>'chi','䐤'=>'chi','䑛'=>'chi','䔟'=>'chi','䗖'=>'chi','䙙'=>'chi','䛂'=>'chi','䜄'=>'chi','䜵'=>'chi','䜻'=>'chi','䞾'=>'chi','䟷'=>'chi','䠠'=>'chi','䤲'=>'chi','䪧'=>'chi','䮈'=>'chi','䮻'=>'chi','䰡'=>'chi','䳵'=>'chi','䶔'=>'chi','䶵'=>'chi','侉'=>'kua','咵'=>'kua','垮'=>'kua','夸'=>'kua','姱'=>'kua','挎'=>'kua','晇'=>'kua','胯'=>'kua','舿'=>'kua','誇'=>'kua','跨'=>'kua','銙'=>'kua','骻'=>'kua','㐄'=>'kua','䋀'=>'kua','侊'=>'guang','俇'=>'guang','僙'=>'guang','光'=>'guang','咣'=>'guang','垙'=>'guang','姯'=>'guang','广'=>'guang','広'=>'guang','廣'=>'guang','撗'=>'guang','桄'=>'guang','欟'=>'guang','洸'=>'guang','灮'=>'guang','炗'=>'guang','炚'=>'guang','炛'=>'guang','烡'=>'guang','犷'=>'guang','獷'=>'guang','珖'=>'guang','硄'=>'guang','胱'=>'guang','臦'=>'guang','臩'=>'guang','茪'=>'guang','輄'=>'guang','逛'=>'guang','銧'=>'guang','黆'=>'guang','㫛'=>'guang','侎'=>'mi','冖'=>'mi','冞'=>'mi','冪'=>'mi','咪'=>'mi','嘧'=>'mi','塓'=>'mi','孊'=>'mi','宓'=>'mi','宻'=>'mi','密'=>'mi','峚'=>'mi','幂'=>'mi','幎'=>'mi','幦'=>'mi','弥'=>'mi','弭'=>'mi','彌'=>'mi','戂'=>'mi','擟'=>'mi','攠'=>'mi','敉'=>'mi','榓'=>'mi','樒'=>'mi','櫁'=>'mi','汨'=>'mi','沕'=>'mi','沵'=>'mi','泌'=>'mi','洣'=>'mi','淧'=>'mi','渳'=>'mi','滵'=>'mi','漞'=>'mi','濔'=>'mi','濗'=>'mi','瀰'=>'mi','灖'=>'mi','熐'=>'mi','爢'=>'mi','猕'=>'mi','獼'=>'mi','瓕'=>'mi','眫'=>'mi','眯'=>'mi','瞇'=>'mi','祕'=>'mi','祢'=>'mi','禰'=>'mi','秘'=>'mi','簚'=>'mi','米'=>'mi','粎'=>'mi','糜'=>'mi','糸'=>'mi','縻'=>'mi','羃'=>'mi','羋'=>'mi','脒'=>'mi','芈'=>'mi','葞'=>'mi','蒾'=>'mi','蔝'=>'mi','蔤'=>'mi','藌'=>'mi','蘼'=>'mi','蜜'=>'mi','蝆'=>'mi','袮'=>'mi','覓'=>'mi','覔'=>'mi','覛'=>'mi','觅'=>'mi','詸'=>'mi','謎'=>'mi','謐'=>'mi','谜'=>'mi','谧'=>'mi','踎'=>'mi','迷'=>'mi','醚'=>'mi','醾'=>'mi','醿'=>'mi','釄'=>'mi','銤'=>'mi','镾'=>'mi','靡'=>'mi','鸍'=>'mi','麊'=>'mi','麋'=>'mi','麛'=>'mi','鼏'=>'mi','㜆'=>'mi','㜷'=>'mi','㝥'=>'mi','㟜'=>'mi','㠧'=>'mi','㣆'=>'mi','㥝'=>'mi','㨠'=>'mi','㩢'=>'mi','㫘'=>'mi','㰽'=>'mi','㳴'=>'mi','㳽'=>'mi','㴵'=>'mi','㵋'=>'mi','㸏'=>'mi','㸓'=>'mi','䁇'=>'mi','䉾'=>'mi','䊳'=>'mi','䋛'=>'mi','䌏'=>'mi','䌐'=>'mi','䌕'=>'mi','䌘'=>'mi','䌩'=>'mi','䍘'=>'mi','䕳'=>'mi','䕷'=>'mi','䖑'=>'mi','䛉'=>'mi','䛑'=>'mi','䛧'=>'mi','䣾'=>'mi','䤉'=>'mi','䤍'=>'mi','䥸'=>'mi','䪾'=>'mi','䭧'=>'mi','䭩'=>'mi','䱊'=>'mi','䴢'=>'mi','侒'=>'an','俺'=>'an','儑'=>'an','唵'=>'an','啽'=>'an','垵'=>'an','埯'=>'an','堓'=>'an','婩'=>'an','媕'=>'an','安'=>'an','岸'=>'an','峖'=>'an','庵'=>'an','按'=>'an','揞'=>'an','晻'=>'an','暗'=>'an','案'=>'an','桉'=>'an','氨'=>'an','洝'=>'an','犴'=>'an','玵'=>'an','痷'=>'an','盦'=>'an','盫'=>'an','罯'=>'an','胺'=>'an','腤'=>'an','荌'=>'an','菴'=>'an','萻'=>'an','葊'=>'an','蓭'=>'an','誝'=>'an','諳'=>'an','谙'=>'an','豻'=>'an','貋'=>'an','銨'=>'an','錌'=>'an','铵'=>'an','闇'=>'an','隌'=>'an','雸'=>'an','鞌'=>'an','鞍'=>'an','韽'=>'an','馣'=>'an','鮟'=>'an','鵪'=>'an','鶕'=>'an','鹌'=>'an','黯'=>'an','㜝'=>'an','㟁'=>'an','㱘'=>'an','㸩'=>'an','㽢'=>'an','䁆'=>'an','䅁'=>'an','䅖'=>'an','䎏'=>'an','䎨'=>'an','䜙'=>'an','䬓'=>'an','䮗'=>'an','䯥'=>'an','侓'=>'lu','僇'=>'lu','剹'=>'lu','勎'=>'lu','勠'=>'lu','卢'=>'lu','卤'=>'lu','噜'=>'lu','嚕'=>'lu','嚧'=>'lu','圥'=>'lu','坴'=>'lu','垆'=>'lu','塶'=>'lu','塷'=>'lu','壚'=>'lu','娽'=>'lu','峍'=>'lu','庐'=>'lu','廘'=>'lu','廬'=>'lu','彔'=>'lu','录'=>'lu','戮'=>'lu','挔'=>'lu','捛'=>'lu','掳'=>'lu','摝'=>'lu','撸'=>'lu','擄'=>'lu','擼'=>'lu','攎'=>'lu','枦'=>'lu','栌'=>'lu','椂'=>'lu','樐'=>'lu','樚'=>'lu','橹'=>'lu','櫓'=>'lu','櫨'=>'lu','氇'=>'lu','氌'=>'lu','泸'=>'lu','淕'=>'lu','淥'=>'lu','渌'=>'lu','滷'=>'lu','漉'=>'lu','潞'=>'lu','澛'=>'lu','濾'=>'lu','瀂'=>'lu','瀘'=>'lu','炉'=>'lu','熝'=>'lu','爐'=>'lu','獹'=>'lu','玈'=>'lu','琭'=>'lu','璐'=>'lu','璷'=>'lu','瓐'=>'lu','甪'=>'lu','盝'=>'lu','盧'=>'lu','睩'=>'lu','矑'=>'lu','硉'=>'lu','硵'=>'lu','碌'=>'lu','磠'=>'lu','祿'=>'lu','禄'=>'lu','稑'=>'lu','穋'=>'lu','箓'=>'lu','簏'=>'lu','簬'=>'lu','簵'=>'lu','簶'=>'lu','籙'=>'lu','籚'=>'lu','粶'=>'lu','纑'=>'lu','罏'=>'lu','胪'=>'lu','膔'=>'lu','膟'=>'lu','臚'=>'lu','舮'=>'lu','舻'=>'lu','艣'=>'lu','艪'=>'lu','艫'=>'lu','芦'=>'lu','菉'=>'lu','蓾'=>'lu','蔍'=>'lu','蕗'=>'lu','蘆'=>'lu','虂'=>'lu','虏'=>'lu','虜'=>'lu','螰'=>'lu','蠦'=>'lu','觮'=>'lu','觻'=>'lu','賂'=>'lu','赂'=>'lu','趢'=>'lu','路'=>'lu','踛'=>'lu','蹗'=>'lu','輅'=>'lu','轆'=>'lu','轤'=>'lu','轳'=>'lu','辂'=>'lu','辘'=>'lu','逯'=>'lu','醁'=>'lu','鈩'=>'lu','錄'=>'lu','録'=>'lu','錴'=>'lu','鏀'=>'lu','鏕'=>'lu','鏴'=>'lu','鐪'=>'lu','鑥'=>'lu','鑪'=>'lu','镥'=>'lu','陆'=>'lu','陸'=>'lu','露'=>'lu','顱'=>'lu','颅'=>'lu','騄'=>'lu','騼'=>'lu','髗'=>'lu','魯'=>'lu','魲'=>'lu','鯥'=>'lu','鱸'=>'lu','鲁'=>'lu','鲈'=>'lu','鴼'=>'lu','鵦'=>'lu','鵱'=>'lu','鷺'=>'lu','鸕'=>'lu','鸬'=>'lu','鹭'=>'lu','鹵'=>'lu','鹿'=>'lu','麓'=>'lu','黸'=>'lu','㓐'=>'lu','㔪'=>'lu','㖨'=>'lu','㛬'=>'lu','㜙'=>'lu','㟤'=>'lu','㠠'=>'lu','㢚'=>'lu','㢳'=>'lu','㦇'=>'lu','㪐'=>'lu','㪖'=>'lu','㪭'=>'lu','㫽'=>'lu','㭔'=>'lu','㯝'=>'lu','㯟'=>'lu','㯭'=>'lu','㱺'=>'lu','㼾'=>'lu','㿖'=>'lu','䃙'=>'lu','䌒'=>'lu','䎑'=>'lu','䎼'=>'lu','䐂'=>'lu','䕡'=>'lu','䘵'=>'lu','䚄'=>'lu','䟿'=>'lu','䡎'=>'lu','䡜'=>'lu','䩮'=>'lu','䬛'=>'lu','䮉'=>'lu','䰕'=>'lu','䱚'=>'lu','䲐'=>'lu','䴪'=>'lu','侔'=>'mou','劺'=>'mou','哞'=>'mou','恈'=>'mou','某'=>'mou','桙'=>'mou','洠'=>'mou','牟'=>'mou','眸'=>'mou','瞴'=>'mou','蟱'=>'mou','謀'=>'mou','谋'=>'mou','鉾'=>'mou','鍪'=>'mou','鴾'=>'mou','麰'=>'mou','㭌'=>'mou','䍒'=>'mou','䏬'=>'mou','䗋'=>'mou','䥐'=>'mou','䱕'=>'mou','侘'=>'cha','偛'=>'cha','剎'=>'cha','叉'=>'cha','嗏'=>'cha','垞'=>'cha','奼'=>'cha','姹'=>'cha','察'=>'cha','岔'=>'cha','嵖'=>'cha','差'=>'cha','扠'=>'cha','扱'=>'cha','挿'=>'cha','插'=>'cha','揷'=>'cha','搽'=>'cha','杈'=>'cha','查'=>'cha','査'=>'cha','槎'=>'cha','檫'=>'cha','汊'=>'cha','猹'=>'cha','疀'=>'cha','碴'=>'cha','秅'=>'cha','紁'=>'cha','肞'=>'cha','臿'=>'cha','艖'=>'cha','芆'=>'cha','茬'=>'cha','茶'=>'cha','衩'=>'cha','褨'=>'cha','訍'=>'cha','詧'=>'cha','詫'=>'cha','诧'=>'cha','蹅'=>'cha','釵'=>'cha','銟'=>'cha','鍤'=>'cha','鎈'=>'cha','鑔'=>'cha','钗'=>'cha','锸'=>'cha','镲'=>'cha','靫'=>'cha','餷'=>'cha','馇'=>'cha','㛳'=>'cha','㢉'=>'cha','㢎'=>'cha','㢒'=>'cha','㣾'=>'cha','㤞'=>'cha','㪯'=>'cha','㫅'=>'cha','䁟'=>'cha','䆛'=>'cha','䊬'=>'cha','䑘'=>'cha','䒲'=>'cha','䓭'=>'cha','䕓'=>'cha','䟕'=>'cha','䡨'=>'cha','䤩'=>'cha','䰈'=>'cha','䲦'=>'cha','䶪'=>'cha','供'=>'gong','兝'=>'gong','兣'=>'gong','公'=>'gong','共'=>'gong','功'=>'gong','匑'=>'gong','匔'=>'gong','厷'=>'gong','唝'=>'gong','塨'=>'gong','宫'=>'gong','宮'=>'gong','工'=>'gong','巩'=>'gong','幊'=>'gong','廾'=>'gong','弓'=>'gong','恭'=>'gong','愩'=>'gong','慐'=>'gong','拱'=>'gong','拲'=>'gong','攻'=>'gong','杛'=>'gong','栱'=>'gong','汞'=>'gong','熕'=>'gong','珙'=>'gong','碽'=>'gong','篢'=>'gong','糼'=>'gong','羾'=>'gong','肱'=>'gong','蚣'=>'gong','觥'=>'gong','觵'=>'gong','貢'=>'gong','贑'=>'gong','贡'=>'gong','躬'=>'gong','躳'=>'gong','輁'=>'gong','鞏'=>'gong','髸'=>'gong','龏'=>'gong','龔'=>'gong','龚'=>'gong','㓋'=>'gong','㔶'=>'gong','㤨'=>'gong','㧬'=>'gong','㫒'=>'gong','㭟'=>'gong','㯯'=>'gong','㺬'=>'gong','㼦'=>'gong','䂬'=>'gong','䇨'=>'gong','䡗'=>'gong','䢚'=>'gong','侣'=>'lv','侶'=>'lv','儢'=>'lv','勴'=>'lv','吕'=>'lv','呂'=>'lv','哷'=>'lv','垏'=>'lv','寽'=>'lv','屡'=>'lv','屢'=>'lv','履'=>'lv','嵂'=>'lv','律'=>'lv','慮'=>'lv','旅'=>'lv','曥'=>'lv','梠'=>'lv','榈'=>'lv','櫖'=>'lv','櫚'=>'lv','氀'=>'lv','氯'=>'lv','滤'=>'lv','焒'=>'lv','爈'=>'lv','率'=>'lv','祣'=>'lv','稆'=>'lv','穞'=>'lv','穭'=>'lv','箻'=>'lv','絽'=>'lv','綠'=>'lv','緑'=>'lv','縷'=>'lv','繂'=>'lv','绿'=>'lv','缕'=>'lv','膂'=>'lv','膐'=>'lv','膢'=>'lv','葎'=>'lv','藘'=>'lv','虑'=>'lv','褛'=>'lv','褸'=>'lv','郘'=>'lv','鋁'=>'lv','鑢'=>'lv','铝'=>'lv','閭'=>'lv','闾'=>'lv','馿'=>'lv','驢'=>'lv','驴'=>'lv','鷜'=>'lv','㔧'=>'lv','㠥'=>'lv','㭚'=>'lv','㲶'=>'lv','㻲'=>'lv','㾔'=>'lv','䔞'=>'lv','䢖'=>'lv','䥨'=>'lv','侦'=>'zhen','侲'=>'zhen','偵'=>'zhen','圳'=>'zhen','塦'=>'zhen','姫'=>'zhen','嫃'=>'zhen','寊'=>'zhen','屒'=>'zhen','帪'=>'zhen','弫'=>'zhen','抮'=>'zhen','挋'=>'zhen','振'=>'zhen','揕'=>'zhen','搸'=>'zhen','敒'=>'zhen','敶'=>'zhen','斟'=>'zhen','昣'=>'zhen','朕'=>'zhen','枕'=>'zhen','栕'=>'zhen','栚'=>'zhen','桢'=>'zhen','桭'=>'zhen','楨'=>'zhen','榛'=>'zhen','槇'=>'zhen','樼'=>'zhen','殝'=>'zhen','浈'=>'zhen','湞'=>'zhen','潧'=>'zhen','澵'=>'zhen','獉'=>'zhen','珍'=>'zhen','珎'=>'zhen','瑧'=>'zhen','甄'=>'zhen','畛'=>'zhen','疹'=>'zhen','眕'=>'zhen','眞'=>'zhen','真'=>'zhen','眹'=>'zhen','砧'=>'zhen','碪'=>'zhen','祯'=>'zhen','禎'=>'zhen','禛'=>'zhen','稹'=>'zhen','箴'=>'zhen','籈'=>'zhen','紖'=>'zhen','紾'=>'zhen','絼'=>'zhen','縝'=>'zhen','縥'=>'zhen','纼'=>'zhen','缜'=>'zhen','聄'=>'zhen','胗'=>'zhen','臻'=>'zhen','萙'=>'zhen','葴'=>'zhen','蒖'=>'zhen','蓁'=>'zhen','薽'=>'zhen','蜄'=>'zhen','袗'=>'zhen','裖'=>'zhen','覙'=>'zhen','診'=>'zhen','誫'=>'zhen','诊'=>'zhen','貞'=>'zhen','賑'=>'zhen','贞'=>'zhen','赈'=>'zhen','軫'=>'zhen','轃'=>'zhen','轸'=>'zhen','辴'=>'zhen','遉'=>'zhen','酙'=>'zhen','針'=>'zhen','鉁'=>'zhen','鋴'=>'zhen','錱'=>'zhen','鍖'=>'zhen','鍼'=>'zhen','鎭'=>'zhen','鎮'=>'zhen','针'=>'zhen','镇'=>'zhen','阵'=>'zhen','陣'=>'zhen','震'=>'zhen','靕'=>'zhen','駗'=>'zhen','鬒'=>'zhen','鱵'=>'zhen','鴆'=>'zhen','鸩'=>'zhen','黮'=>'zhen','黰'=>'zhen','㐱'=>'zhen','㓄'=>'zhen','㣀'=>'zhen','㪛'=>'zhen','㮳'=>'zhen','㯢'=>'zhen','㴨'=>'zhen','䂦'=>'zhen','䂧'=>'zhen','䊶'=>'zhen','䏖'=>'zhen','䑐'=>'zhen','䝩'=>'zhen','䟴'=>'zhen','䨯'=>'zhen','䪴'=>'zhen','䫬'=>'zhen','䲴'=>'zhen','䳲'=>'zhen','侧'=>'ce','側'=>'ce','冊'=>'ce','册'=>'ce','厕'=>'ce','厠'=>'ce','墄'=>'ce','廁'=>'ce','恻'=>'ce','惻'=>'ce','憡'=>'ce','拺'=>'ce','敇'=>'ce','测'=>'ce','測'=>'ce','畟'=>'ce','笧'=>'ce','策'=>'ce','筞'=>'ce','筴'=>'ce','箣'=>'ce','簎'=>'ce','粣'=>'ce','荝'=>'ce','萗'=>'ce','萴'=>'ce','蓛'=>'ce','㥽'=>'ce','㨲'=>'ce','㩍'=>'ce','䇲'=>'ce','䈟'=>'ce','䊂'=>'ce','䔴'=>'ce','䜺'=>'ce','侩'=>'kuai','儈'=>'kuai','凷'=>'kuai','哙'=>'kuai','噲'=>'kuai','圦'=>'kuai','块'=>'kuai','塊'=>'kuai','墤'=>'kuai','华科智软'=>'kuai','廥'=>'kuai','快'=>'kuai','擓'=>'kuai','旝'=>'kuai','狯'=>'kuai','獪'=>'kuai','筷'=>'kuai','糩'=>'kuai','脍'=>'kuai','膾'=>'kuai','蒯'=>'kuai','郐'=>'kuai','鄶'=>'kuai','鱠'=>'kuai','鲙'=>'kuai','㔞'=>'kuai','㙕'=>'kuai','㙗'=>'kuai','㟴'=>'kuai','㧟'=>'kuai','㬮'=>'kuai','㱮'=>'kuai','䈛'=>'kuai','䓒'=>'kuai','䭝'=>'kuai','䯤'=>'kuai','䶐'=>'kuai','侪'=>'chai','儕'=>'chai','勑'=>'chai','喍'=>'chai','囆'=>'chai','拆'=>'chai','柴'=>'chai','犲'=>'chai','瘥'=>'chai','祡'=>'chai','茝'=>'chai','虿'=>'chai','蠆'=>'chai','袃'=>'chai','豺'=>'chai','㑪'=>'chai','㳗'=>'chai','㾹'=>'chai','䓱'=>'chai','䘍'=>'chai','侬'=>'nong','儂'=>'nong','农'=>'nong','哝'=>'nong','噥'=>'nong','弄'=>'nong','憹'=>'nong','挊'=>'nong','挵'=>'nong','欁'=>'nong','浓'=>'nong','濃'=>'nong','癑'=>'nong','禯'=>'nong','秾'=>'nong','穠'=>'nong','繷'=>'nong','脓'=>'nong','膿'=>'nong','蕽'=>'nong','襛'=>'nong','農'=>'nong','辳'=>'nong','醲'=>'nong','齈'=>'nong','㶶'=>'nong','䁸'=>'nong','䢉'=>'nong','䵜'=>'nong','侯'=>'hou','候'=>'hou','厚'=>'hou','后'=>'hou','吼'=>'hou','吽'=>'hou','喉'=>'hou','垕'=>'hou','堠'=>'hou','帿'=>'hou','後'=>'hou','洉'=>'hou','犼'=>'hou','猴'=>'hou','瘊'=>'hou','睺'=>'hou','矦'=>'hou','篌'=>'hou','糇'=>'hou','翭'=>'hou','葔'=>'hou','豞'=>'hou','逅'=>'hou','郈'=>'hou','鄇'=>'hou','銗'=>'hou','鍭'=>'hou','餱'=>'hou','骺'=>'hou','鮜'=>'hou','鯸'=>'hou','鱟'=>'hou','鲎'=>'hou','鲘'=>'hou','齁'=>'hou','㕈'=>'hou','㖃'=>'hou','㗋'=>'hou','㤧'=>'hou','㫗'=>'hou','㬋'=>'hou','㮢'=>'hou','㸸'=>'hou','㺅'=>'hou','䂉'=>'hou','䗔'=>'hou','䙈'=>'hou','䞧'=>'hou','䪷'=>'hou','䫛'=>'hou','䳧'=>'hou','侰'=>'jiong','僒'=>'jiong','冂'=>'jiong','冋'=>'jiong','冏'=>'jiong','囧'=>'jiong','坰'=>'jiong','埛'=>'jiong','扃'=>'jiong','泂'=>'jiong','浻'=>'jiong','澃'=>'jiong','炯'=>'jiong','烱'=>'jiong','煚'=>'jiong','煛'=>'jiong','熲'=>'jiong','燑'=>'jiong','燛'=>'jiong','窘'=>'jiong','絅'=>'jiong','綗'=>'jiong','蘏'=>'jiong','蘔'=>'jiong','褧'=>'jiong','迥'=>'jiong','逈'=>'jiong','顈'=>'jiong','颎'=>'jiong','駉'=>'jiong','駫'=>'jiong','㑋'=>'jiong','㓏'=>'jiong','㖥'=>'jiong','㢠'=>'jiong','㤯'=>'jiong','㷗'=>'jiong','㷡'=>'jiong','䌹'=>'jiong','䐃'=>'jiong','䢛'=>'jiong','侽'=>'nan','南'=>'nan','喃'=>'nan','囡'=>'nan','娚'=>'nan','婻'=>'nan','戁'=>'nan','抩'=>'nan','揇'=>'nan','暔'=>'nan','枏'=>'nan','枬'=>'nan','柟'=>'nan','楠'=>'nan','湳'=>'nan','煵'=>'nan','男'=>'nan','畘'=>'nan','腩'=>'nan','莮'=>'nan','萳'=>'nan','蝻'=>'nan','諵'=>'nan','赧'=>'nan','遖'=>'nan','难'=>'nan','難'=>'nan','㓓'=>'nan','㫱'=>'nan','㽖'=>'nan','䁪'=>'nan','䈒'=>'nan','䔜'=>'nan','䔳'=>'nan','䕼'=>'nan','䛁'=>'nan','䶲'=>'nan','侾'=>'xiao','俲'=>'xiao','傚'=>'xiao','削'=>'xiao','効'=>'xiao','呺'=>'xiao','咲'=>'xiao','哓'=>'xiao','哮'=>'xiao','啋'=>'xiao','啸'=>'xiao','嘋'=>'xiao','嘐'=>'xiao','嘨'=>'xiao','嘯'=>'xiao','嘵'=>'xiao','嚣'=>'xiao','嚻'=>'xiao','囂'=>'xiao','婋'=>'xiao','孝'=>'xiao','宯'=>'xiao','宵'=>'xiao','小'=>'xiao','崤'=>'xiao','庨'=>'xiao','彇'=>'xiao','恔'=>'xiao','恷'=>'xiao','憢'=>'xiao','揱'=>'xiao','撨'=>'xiao','效'=>'xiao','敩'=>'xiao','斅'=>'xiao','斆'=>'xiao','晓'=>'xiao','暁'=>'xiao','曉'=>'xiao','枭'=>'xiao','枵'=>'xiao','校'=>'xiao','梟'=>'xiao','櫹'=>'xiao','歊'=>'xiao','歗'=>'xiao','毊'=>'xiao','洨'=>'xiao','消'=>'xiao','涍'=>'xiao','淆'=>'xiao','滧'=>'xiao','潇'=>'xiao','瀟'=>'xiao','灱'=>'xiao','灲'=>'xiao','焇'=>'xiao','熽'=>'xiao','猇'=>'xiao','獢'=>'xiao','痚'=>'xiao','痟'=>'xiao','皛'=>'xiao','皢'=>'xiao','硝'=>'xiao','硣'=>'xiao','穘'=>'xiao','窙'=>'xiao','笑'=>'xiao','筱'=>'xiao','筿'=>'xiao','箫'=>'xiao','篠'=>'xiao','簘'=>'xiao','簫'=>'xiao','綃'=>'xiao','绡'=>'xiao','翛'=>'xiao','肖'=>'xiao','膮'=>'xiao','萧'=>'xiao','萷'=>'xiao','蕭'=>'xiao','藃'=>'xiao','虈'=>'xiao','虓'=>'xiao','蟂'=>'xiao','蟏'=>'xiao','蟰'=>'xiao','蠨'=>'xiao','訤'=>'xiao','詨'=>'xiao','誟'=>'xiao','誵'=>'xiao','謏'=>'xiao','謞'=>'xiao','踃'=>'xiao','逍'=>'xiao','郩'=>'xiao','銷'=>'xiao','销'=>'xiao','霄'=>'xiao','驍'=>'xiao','骁'=>'xiao','髇'=>'xiao','髐'=>'xiao','魈'=>'xiao','鴞'=>'xiao','鴵'=>'xiao','鷍'=>'xiao','鸮'=>'xiao','㑾'=>'xiao','㔅'=>'xiao','㗛'=>'xiao','㚣'=>'xiao','㤊'=>'xiao','㬵'=>'xiao','㹲'=>'xiao','䊥'=>'xiao','䒕'=>'xiao','䒝'=>'xiao','䕧'=>'xiao','䥵'=>'xiao','便'=>'bian','匾'=>'bian','卞'=>'bian','变'=>'bian','変'=>'bian','峅'=>'bian','弁'=>'bian','徧'=>'bian','忭'=>'bian','惼'=>'bian','扁'=>'bian','抃'=>'bian','拚'=>'bian','揙'=>'bian','昪'=>'bian','汳'=>'bian','汴'=>'bian','炞'=>'bian','煸'=>'bian','牑'=>'bian','猵'=>'bian','獱'=>'bian','甂'=>'bian','砭'=>'bian','碥'=>'bian','稨'=>'bian','窆'=>'bian','笾'=>'bian','箯'=>'bian','籩'=>'bian','糄'=>'bian','編'=>'bian','緶'=>'bian','缏'=>'bian','编'=>'bian','艑'=>'bian','苄'=>'bian','萹'=>'bian','藊'=>'bian','蝙'=>'bian','褊'=>'bian','覍'=>'bian','變'=>'bian','貶'=>'bian','贬'=>'bian','辡'=>'bian','辧'=>'bian','辨'=>'bian','辩'=>'bian','辪'=>'bian','辫'=>'bian','辮'=>'bian','辯'=>'bian','边'=>'bian','遍'=>'bian','邉'=>'bian','邊'=>'bian','釆'=>'bian','鍽'=>'bian','閞'=>'bian','鞭'=>'bian','頨'=>'bian','鯾'=>'bian','鯿'=>'bian','鳊'=>'bian','鴘'=>'bian','㝸'=>'bian','㣐'=>'bian','㦚'=>'bian','㭓'=>'bian','㲢'=>'bian','㳎'=>'bian','㳒'=>'bian','㴜'=>'bian','㵷'=>'bian','㺹'=>'bian','㻞'=>'bian','䁵'=>'bian','䉸'=>'bian','䒪'=>'bian','䛒'=>'bian','䡢'=>'bian','䪻'=>'bian','俀'=>'tui','僓'=>'tui','娧'=>'tui','尵'=>'tui','推'=>'tui','煺'=>'tui','穨'=>'tui','脮'=>'tui','腿'=>'tui','蓷'=>'tui','藬'=>'tui','蘈'=>'tui','蛻'=>'tui','蜕'=>'tui','褪'=>'tui','蹆'=>'tui','蹪'=>'tui','退'=>'tui','隤'=>'tui','頹'=>'tui','頺'=>'tui','頽'=>'tui','颓'=>'tui','駾'=>'tui','骽'=>'tui','魋'=>'tui','㞂'=>'tui','㢈'=>'tui','㢑'=>'tui','㦌'=>'tui','㱣'=>'tui','㷟'=>'tui','㾯'=>'tui','㾼'=>'tui','㾽'=>'tui','㿉'=>'tui','㿗'=>'tui','䀃'=>'tui','䅪'=>'tui','䍾'=>'tui','䫋'=>'tui','促'=>'cu','噈'=>'cu','媨'=>'cu','徂'=>'cu','憱'=>'cu','殂'=>'cu','猝'=>'cu','瘄'=>'cu','瘯'=>'cu','簇'=>'cu','粗'=>'cu','縬'=>'cu','蔟'=>'cu','觕'=>'cu','誎'=>'cu','趗'=>'cu','踧'=>'cu','蹙'=>'cu','蹴'=>'cu','蹵'=>'cu','酢'=>'cu','醋'=>'cu','顣'=>'cu','麁'=>'cu','麄'=>'cu','麤'=>'cu','鼀'=>'cu','㗤'=>'cu','㰗'=>'cu','䃚'=>'cu','䎌'=>'cu','䓚'=>'cu','䙯'=>'cu','䛤'=>'cu','䟟'=>'cu','䠓'=>'cu','䠞'=>'cu','䢐'=>'cu','䥄'=>'cu','䥘'=>'cu','䬨'=>'cu','俄'=>'e','偔'=>'e','僫'=>'e','匎'=>'e','卾'=>'e','厄'=>'e','吪'=>'e','呃'=>'e','呝'=>'e','咢'=>'e','咹'=>'e','噁'=>'e','噩'=>'e','囮'=>'e','垩'=>'e','堊'=>'e','堮'=>'e','妸'=>'e','妿'=>'e','姶'=>'e','娥'=>'e','娿'=>'e','婀'=>'e','屙'=>'e','屵'=>'e','岋'=>'e','峉'=>'e','峨'=>'e','峩'=>'e','崿'=>'e','廅'=>'e','恶'=>'e','悪'=>'e','惡'=>'e','愕'=>'e','戹'=>'e','扼'=>'e','搤'=>'e','搹'=>'e','擜'=>'e','枙'=>'e','櫮'=>'e','歞'=>'e','歺'=>'e','涐'=>'e','湂'=>'e','珴'=>'e','琧'=>'e','皒'=>'e','睋'=>'e','砈'=>'e','砐'=>'e','砨'=>'e','硆'=>'e','磀'=>'e','腭'=>'e','苊'=>'e','莪'=>'e','萼'=>'e','蕚'=>'e','蚅'=>'e','蛾'=>'e','蝁'=>'e','覨'=>'e','訛'=>'e','詻'=>'e','誐'=>'e','諤'=>'e','譌'=>'e','讍'=>'e','讹'=>'e','谔'=>'e','豟'=>'e','軛'=>'e','軶'=>'e','轭'=>'e','迗'=>'e','遌'=>'e','遏'=>'e','遻'=>'e','鄂'=>'e','鈋'=>'e','鋨'=>'e','鍔'=>'e','鑩'=>'e','锇'=>'e','锷'=>'e','閼'=>'e','阏'=>'e','阨'=>'e','阸'=>'e','頞'=>'e','頟'=>'e','額'=>'e','顎'=>'e','颚'=>'e','额'=>'e','餓'=>'e','餩'=>'e','饿'=>'e','騀'=>'e','魤'=>'e','鰐'=>'e','鱷'=>'e','鳄'=>'e','鵈'=>'e','鵝'=>'e','鵞'=>'e','鶚'=>'e','鹅'=>'e','鹗'=>'e','齶'=>'e','㓵'=>'e','㔩'=>'e','㕎'=>'e','㖾'=>'e','㗁'=>'e','㟧'=>'e','㠋'=>'e','㡋'=>'e','㦍'=>'e','㧖'=>'e','㩵'=>'e','㮙'=>'e','㱦'=>'e','㷈'=>'e','㼂'=>'e','㼢'=>'e','㼰'=>'e','䄉'=>'e','䆓'=>'e','䑥'=>'e','䑪'=>'e','䓊'=>'e','䔾'=>'e','䕏'=>'e','䖸'=>'e','䙳'=>'e','䛖'=>'e','䝈'=>'e','䞩'=>'e','䣞'=>'e','䩹'=>'e','䫷'=>'e','䱮'=>'e','䳗'=>'e','䳘'=>'e','䳬'=>'e','俈'=>'ku','刳'=>'ku','哭'=>'ku','喾'=>'ku','嚳'=>'ku','圐'=>'ku','堀'=>'ku','崫'=>'ku','库'=>'ku','庫'=>'ku','扝'=>'ku','枯'=>'ku','桍'=>'ku','楛'=>'ku','焅'=>'ku','狜'=>'ku','瘔'=>'ku','矻'=>'ku','秙'=>'ku','窟'=>'ku','絝'=>'ku','绔'=>'ku','苦'=>'ku','袴'=>'ku','裤'=>'ku','褲'=>'ku','跍'=>'ku','郀'=>'ku','酷'=>'ku','骷'=>'ku','鮬'=>'ku','㒂'=>'ku','㠸'=>'ku','䇢'=>'ku','俊'=>'jun','儁'=>'jun','军'=>'jun','君'=>'jun','呁'=>'jun','均'=>'jun','埈'=>'jun','姰'=>'jun','寯'=>'jun','峻'=>'jun','懏'=>'jun','捃'=>'jun','攈'=>'jun','晙'=>'jun','桾'=>'jun','汮'=>'jun','浚'=>'jun','濬'=>'jun','焌'=>'jun','燇'=>'jun','珺'=>'jun','畯'=>'jun','皲'=>'jun','皸'=>'jun','皹'=>'jun','碅'=>'jun','竣'=>'jun','筠'=>'jun','箘'=>'jun','箟'=>'jun','莙'=>'jun','菌'=>'jun','蚐'=>'jun','蜠'=>'jun','袀'=>'jun','覠'=>'jun','軍'=>'jun','郡'=>'jun','鈞'=>'jun','銁'=>'jun','銞'=>'jun','鍕'=>'jun','钧'=>'jun','陖'=>'jun','餕'=>'jun','馂'=>'jun','駿'=>'jun','骏'=>'jun','鮶'=>'jun','鲪'=>'jun','鵔'=>'jun','鵕'=>'jun','鵘'=>'jun','麇'=>'jun','麏'=>'jun','麕'=>'jun','㑺'=>'jun','㒞'=>'jun','㓴'=>'jun','㕙'=>'jun','㝦'=>'jun','㴫'=>'jun','㻒'=>'jun','㽙'=>'jun','䇹'=>'jun','䕑'=>'jun','䜭'=>'jun','䝍'=>'jun','俎'=>'zu','傶'=>'zu','卆'=>'zu','卒'=>'zu','哫'=>'zu','崒'=>'zu','崪'=>'zu','族'=>'zu','爼'=>'zu','珇'=>'zu','祖'=>'zu','租'=>'zu','稡'=>'zu','箤'=>'zu','組'=>'zu','组'=>'zu','菹'=>'zu','葅'=>'zu','蒩'=>'zu','詛'=>'zu','謯'=>'zu','诅'=>'zu','足'=>'zu','踤'=>'zu','踿'=>'zu','鎺'=>'zu','鏃'=>'zu','镞'=>'zu','阻'=>'zu','靻'=>'zu','㞺'=>'zu','㰵'=>'zu','㲞'=>'zu','䅸'=>'zu','䔃'=>'zu','䖕'=>'zu','䚝'=>'zu','䯿'=>'zu','䱣'=>'zu','俒'=>'hun','倱'=>'hun','圂'=>'hun','婚'=>'hun','忶'=>'hun','惛'=>'hun','惽'=>'hun','慁'=>'hun','掍'=>'hun','昏'=>'hun','昬'=>'hun','棔'=>'hun','殙'=>'hun','浑'=>'hun','涽'=>'hun','混'=>'hun','渾'=>'hun','溷'=>'hun','焝'=>'hun','睧'=>'hun','睯'=>'hun','繉'=>'hun','荤'=>'hun','葷'=>'hun','觨'=>'hun','諢'=>'hun','诨'=>'hun','轋'=>'hun','閽'=>'hun','阍'=>'hun','餛'=>'hun','馄'=>'hun','魂'=>'hun','鼲'=>'hun','㑮'=>'hun','㥵'=>'hun','㨡'=>'hun','䅙'=>'hun','䅱'=>'hun','䚠'=>'hun','䛰'=>'hun','䧰'=>'hun','䫟'=>'hun','䰟'=>'hun','䴷'=>'hun','俗'=>'su','傃'=>'su','僳'=>'su','嗉'=>'su','嗽'=>'su','囌'=>'su','塐'=>'su','塑'=>'su','夙'=>'su','嫊'=>'su','宿'=>'su','愫'=>'su','愬'=>'su','憟'=>'su','梀'=>'su','榡'=>'su','樎'=>'su','樕'=>'su','橚'=>'su','櫯'=>'su','殐'=>'su','泝'=>'su','洬'=>'su','涑'=>'su','溯'=>'su','溸'=>'su','潚'=>'su','潥'=>'su','玊'=>'su','珟'=>'su','璛'=>'su','甦'=>'su','碿'=>'su','稣'=>'su','穌'=>'su','窣'=>'su','簌'=>'su','粛'=>'su','粟'=>'su','素'=>'su','縤'=>'su','肃'=>'su','肅'=>'su','膆'=>'su','苏'=>'su','蔌'=>'su','藗'=>'su','蘇'=>'su','蘓'=>'su','觫'=>'su','訴'=>'su','謖'=>'su','诉'=>'su','谡'=>'su','趚'=>'su','蹜'=>'su','速'=>'su','遡'=>'su','遬'=>'su','酥'=>'su','鋉'=>'su','餗'=>'su','驌'=>'su','骕'=>'su','鯂'=>'su','鱐'=>'su','鷫'=>'su','鹔'=>'su','㑉'=>'su','㑛'=>'su','㓘'=>'su','㔄'=>'su','㕖'=>'su','㜚'=>'su','㝛'=>'su','㨞'=>'su','㩋'=>'su','㪩'=>'su','㬘'=>'su','㯈'=>'su','㴋'=>'su','㴑'=>'su','㴼'=>'su','䃤'=>'su','䅇'=>'su','䌚'=>'su','䎘'=>'su','䏋'=>'su','䑿'=>'su','䔎'=>'su','䘻'=>'su','䛾'=>'su','䥔'=>'su','俩'=>'lia','倆'=>'lia','俳'=>'pai','哌'=>'pai','徘'=>'pai','拍'=>'pai','排'=>'pai','棑'=>'pai','派'=>'pai','湃'=>'pai','牌'=>'pai','犤'=>'pai','猅'=>'pai','磗'=>'pai','箄'=>'pai','簰'=>'pai','蒎'=>'pai','輫'=>'pai','鎃'=>'pai','㭛'=>'pai','㵺'=>'pai','䖰'=>'pai','俵'=>'biao','儦'=>'biao','墂'=>'biao','婊'=>'biao','幖'=>'biao','彪'=>'biao','摽'=>'biao','杓'=>'biao','标'=>'biao','標'=>'biao','檦'=>'biao','淲'=>'biao','滮'=>'biao','瀌'=>'biao','灬'=>'biao','熛'=>'biao','爂'=>'biao','猋'=>'biao','瘭'=>'biao','穮'=>'biao','脿'=>'biao','膘'=>'biao','臕'=>'biao','蔈'=>'biao','藨'=>'biao','表'=>'biao','裱'=>'biao','褾'=>'biao','諘'=>'biao','謤'=>'biao','贆'=>'biao','錶'=>'biao','鏢'=>'biao','鑣'=>'biao','镖'=>'biao','镳'=>'biao','颮'=>'biao','颷'=>'biao','飆'=>'biao','飇'=>'biao','飈'=>'biao','飊'=>'biao','飑'=>'biao','飙'=>'biao','飚'=>'biao','驃'=>'biao','驫'=>'biao','骉'=>'biao','骠'=>'biao','髟'=>'biao','鰾'=>'biao','鳔'=>'biao','麃'=>'biao','㟽'=>'biao','㠒'=>'biao','㧼'=>'biao','㯱'=>'biao','㯹'=>'biao','䔸'=>'biao','䞄'=>'biao','俷'=>'fei','剕'=>'fei','匪'=>'fei','厞'=>'fei','吠'=>'fei','啡'=>'fei','奜'=>'fei','妃'=>'fei','婓'=>'fei','婔'=>'fei','屝'=>'fei','废'=>'fei','廃'=>'fei','廢'=>'fei','悱'=>'fei','扉'=>'fei','斐'=>'fei','昲'=>'fei','暃'=>'fei','曊'=>'fei','朏'=>'fei','杮'=>'fei','棐'=>'fei','榧'=>'fei','櫠'=>'fei','沸'=>'fei','淝'=>'fei','渄'=>'fei','濷'=>'fei','狒'=>'fei','猆'=>'fei','疿'=>'fei','痱'=>'fei','癈'=>'fei','篚'=>'fei','緋'=>'fei','绯'=>'fei','翡'=>'fei','肥'=>'fei','肺'=>'fei','胐'=>'fei','腓'=>'fei','菲'=>'fei','萉'=>'fei','蕜'=>'fei','蕟'=>'fei','蜚'=>'fei','蜰'=>'fei','蟦'=>'fei','裶'=>'fei','誹'=>'fei','诽'=>'fei','費'=>'fei','费'=>'fei','鐨'=>'fei','镄'=>'fei','霏'=>'fei','靅'=>'fei','非'=>'fei','靟'=>'fei','飛'=>'fei','飝'=>'fei','飞'=>'fei','餥'=>'fei','馡'=>'fei','騑'=>'fei','騛'=>'fei','鯡'=>'fei','鲱'=>'fei','鼣'=>'fei','㔗'=>'fei','㥱'=>'fei','㩌'=>'fei','㭭'=>'fei','㵒'=>'fei','䆏'=>'fei','䈈'=>'fei','䉬'=>'fei','䑔'=>'fei','䕁'=>'fei','䕠'=>'fei','䚨'=>'fei','䛍'=>'fei','䠊'=>'fei','䤵'=>'fei','䨽'=>'fei','䨾'=>'fei','䰁'=>'fei','俻'=>'bei','倍'=>'bei','偝'=>'bei','偹'=>'bei','備'=>'bei','僃'=>'bei','北'=>'bei','卑'=>'bei','喺'=>'bei','备'=>'bei','悖'=>'bei','悲'=>'bei','惫'=>'bei','愂'=>'bei','憊'=>'bei','揹'=>'bei','昁'=>'bei','杯'=>'bei','桮'=>'bei','梖'=>'bei','焙'=>'bei','牬'=>'bei','犕'=>'bei','狈'=>'bei','狽'=>'bei','珼'=>'bei','琲'=>'bei','盃'=>'bei','碑'=>'bei','碚'=>'bei','禙'=>'bei','糒'=>'bei','背'=>'bei','苝'=>'bei','蓓'=>'bei','藣'=>'bei','蛽'=>'bei','被'=>'bei','褙'=>'bei','誖'=>'bei','貝'=>'bei','贝'=>'bei','軰'=>'bei','輩'=>'bei','辈'=>'bei','邶'=>'bei','鄁'=>'bei','鉳'=>'bei','鋇'=>'bei','鐾'=>'bei','钡'=>'bei','陂'=>'bei','鞴'=>'bei','骳'=>'bei','鵯'=>'bei','鹎'=>'bei','㔨'=>'bei','㛝'=>'bei','㣁'=>'bei','㤳'=>'bei','㰆'=>'bei','㶔'=>'bei','㷶'=>'bei','㸢'=>'bei','㸬'=>'bei','㸽'=>'bei','㻗'=>'bei','㼎'=>'bei','㾱'=>'bei','䁅'=>'bei','䋳'=>'bei','䔒'=>'bei','䠙'=>'bei','䡶'=>'bei','䩀'=>'bei','䰽'=>'bei','倊'=>'zong','倧'=>'zong','偬'=>'zong','傯'=>'zong','堫'=>'zong','宗'=>'zong','嵏'=>'zong','嵕'=>'zong','嵸'=>'zong','总'=>'zong','惣'=>'zong','惾'=>'zong','愡'=>'zong','捴'=>'zong','揔'=>'zong','搃'=>'zong','摠'=>'zong','昮'=>'zong','朡'=>'zong','棕'=>'zong','椶'=>'zong','熧'=>'zong','燪'=>'zong','猔'=>'zong','猣'=>'zong','疭'=>'zong','瘲'=>'zong','碂'=>'zong','磫'=>'zong','稯'=>'zong','粽'=>'zong','糉'=>'zong','綜'=>'zong','緃'=>'zong','総'=>'zong','緵'=>'zong','縂'=>'zong','縦'=>'zong','縱'=>'zong','總'=>'zong','纵'=>'zong','综'=>'zong','翪'=>'zong','腙'=>'zong','艐'=>'zong','葼'=>'zong','蓗'=>'zong','蝬'=>'zong','豵'=>'zong','踨'=>'zong','踪'=>'zong','蹤'=>'zong','錝'=>'zong','鍯'=>'zong','鏓'=>'zong','鑁'=>'zong','騌'=>'zong','騣'=>'zong','骔'=>'zong','鬃'=>'zong','鬉'=>'zong','鬷'=>'zong','鯮'=>'zong','鯼'=>'zong','㢔'=>'zong','㯶'=>'zong','㷓'=>'zong','㹅'=>'zong','䍟'=>'zong','䝋'=>'zong','䰌'=>'zong','倎'=>'tian','兲'=>'tian','唺'=>'tian','塡'=>'tian','填'=>'tian','天'=>'tian','婖'=>'tian','屇'=>'tian','忝'=>'tian','恬'=>'tian','悿'=>'tian','捵'=>'tian','掭'=>'tian','搷'=>'tian','晪'=>'tian','殄'=>'tian','沺'=>'tian','淟'=>'tian','添'=>'tian','湉'=>'tian','琠'=>'tian','瑱'=>'tian','璳'=>'tian','甛'=>'tian','甜'=>'tian','田'=>'tian','畋'=>'tian','畑'=>'tian','畠'=>'tian','痶'=>'tian','盷'=>'tian','睓'=>'tian','睼'=>'tian','碵'=>'tian','磌'=>'tian','窴'=>'tian','緂'=>'tian','胋'=>'tian','腆'=>'tian','舔'=>'tian','舚'=>'tian','菾'=>'tian','覥'=>'tian','觍'=>'tian','賟'=>'tian','酟'=>'tian','錪'=>'tian','闐'=>'tian','阗'=>'tian','靔'=>'tian','靝'=>'tian','靦'=>'tian','餂'=>'tian','鴫'=>'tian','鷆'=>'tian','鷏'=>'tian','黇'=>'tian','㐁'=>'tian','㖭'=>'tian','㙉'=>'tian','㥏'=>'tian','㧂'=>'tian','㮇'=>'tian','㶺'=>'tian','䄼'=>'tian','䄽'=>'tian','䐌'=>'tian','䑚'=>'tian','䟧'=>'tian','䠄'=>'tian','䡒'=>'tian','䡘'=>'tian','䣯'=>'tian','䥖'=>'tian','䩄'=>'tian','倒'=>'dao','刀'=>'dao','刂'=>'dao','到'=>'dao','叨'=>'dao','噵'=>'dao','壔'=>'dao','宲'=>'dao','导'=>'dao','導'=>'dao','屶'=>'dao','岛'=>'dao','島'=>'dao','嶋'=>'dao','嶌'=>'dao','嶹'=>'dao','忉'=>'dao','悼'=>'dao','捣'=>'dao','捯'=>'dao','搗'=>'dao','擣'=>'dao','朷'=>'dao','椡'=>'dao','槝'=>'dao','檤'=>'dao','氘'=>'dao','焘'=>'dao','燾'=>'dao','瓙'=>'dao','盗'=>'dao','盜'=>'dao','祷'=>'dao','禂'=>'dao','禱'=>'dao','稲'=>'dao','稻'=>'dao','纛'=>'dao','翢'=>'dao','翿'=>'dao','舠'=>'dao','菿'=>'dao','衜'=>'dao','衟'=>'dao','蹈'=>'dao','軇'=>'dao','道'=>'dao','釖'=>'dao','陦'=>'dao','隝'=>'dao','隯'=>'dao','魛'=>'dao','鱽'=>'dao','㠀'=>'dao','㿒'=>'dao','䆃'=>'dao','䌦'=>'dao','䧂'=>'dao','䲽'=>'dao','倓'=>'tan','傝'=>'tan','僋'=>'tan','叹'=>'tan','啴'=>'tan','嗿'=>'tan','嘆'=>'tan','嘽'=>'tan','坍'=>'tan','坛'=>'tan','坦'=>'tan','埮'=>'tan','墰'=>'tan','墵'=>'tan','壇'=>'tan','壜'=>'tan','婒'=>'tan','弾'=>'tan','忐'=>'tan','怹'=>'tan','惔'=>'tan','憛'=>'tan','憳'=>'tan','憻'=>'tan','探'=>'tan','摊'=>'tan','撢'=>'tan','擹'=>'tan','攤'=>'tan','昙'=>'tan','暺'=>'tan','曇'=>'tan','榃'=>'tan','橝'=>'tan','檀'=>'tan','歎'=>'tan','毯'=>'tan','湠'=>'tan','滩'=>'tan','潬'=>'tan','潭'=>'tan','灘'=>'tan','炭'=>'tan','璮'=>'tan','痑'=>'tan','痰'=>'tan','瘫'=>'tan','癱'=>'tan','碳'=>'tan','罈'=>'tan','罎'=>'tan','舑'=>'tan','舕'=>'tan','菼'=>'tan','藫'=>'tan','袒'=>'tan','襢'=>'tan','覃'=>'tan','談'=>'tan','譚'=>'tan','譠'=>'tan','谈'=>'tan','谭'=>'tan','貚'=>'tan','貪'=>'tan','賧'=>'tan','贪'=>'tan','赕'=>'tan','郯'=>'tan','醈'=>'tan','醓'=>'tan','醰'=>'tan','鉭'=>'tan','錟'=>'tan','钽'=>'tan','锬'=>'tan','顃'=>'tan','鷤'=>'tan','㲜'=>'tan','㲭'=>'tan','㷋'=>'tan','㽑'=>'tan','䃪'=>'tan','䆱'=>'tan','䉡'=>'tan','䊤'=>'tan','䏙'=>'tan','䐺'=>'tan','䕊'=>'tan','䜖'=>'tan','䞡'=>'tan','䦔'=>'tan','倕'=>'chui','吹'=>'chui','垂'=>'chui','埀'=>'chui','捶'=>'chui','搥'=>'chui','桘'=>'chui','棰'=>'chui','槌'=>'chui','炊'=>'chui','箠'=>'chui','腄'=>'chui','菙'=>'chui','錘'=>'chui','鎚'=>'chui','锤'=>'chui','陲'=>'chui','顀'=>'chui','龡'=>'chui','㓃'=>'chui','㝽'=>'chui','㥨'=>'chui','㩾'=>'chui','䄲'=>'chui','䍋'=>'chui','䞼'=>'chui','䳠'=>'chui','倘'=>'tang','偒'=>'tang','傏'=>'tang','傥'=>'tang','儻'=>'tang','劏'=>'tang','唐'=>'tang','啺'=>'tang','嘡'=>'tang','坣'=>'tang','堂'=>'tang','塘'=>'tang','嵣'=>'tang','帑'=>'tang','戃'=>'tang','搪'=>'tang','摥'=>'tang','曭'=>'tang','棠'=>'tang','榶'=>'tang','樘'=>'tang','橖'=>'tang','汤'=>'tang','淌'=>'tang','湯'=>'tang','溏'=>'tang','漟'=>'tang','烫'=>'tang','煻'=>'tang','燙'=>'tang','爣'=>'tang','瑭'=>'tang','矘'=>'tang','磄'=>'tang','禟'=>'tang','篖'=>'tang','糃'=>'tang','糖'=>'tang','糛'=>'tang','羰'=>'tang','耥'=>'tang','膅'=>'tang','膛'=>'tang','蓎'=>'tang','薚'=>'tang','蝪'=>'tang','螗'=>'tang','螳'=>'tang','赯'=>'tang','趟'=>'tang','踼'=>'tang','蹚'=>'tang','躺'=>'tang','鄌'=>'tang','醣'=>'tang','鎕'=>'tang','鎲'=>'tang','鏜'=>'tang','鐋'=>'tang','钂'=>'tang','铴'=>'tang','镋'=>'tang','镗'=>'tang','闛'=>'tang','隚'=>'tang','鞺'=>'tang','餳'=>'tang','餹'=>'tang','饄'=>'tang','饧'=>'tang','鶶'=>'tang','鼞'=>'tang','㑽'=>'tang','㒉'=>'tang','㙶'=>'tang','㜍'=>'tang','㭻'=>'tang','㲥'=>'tang','㼺'=>'tang','㿩'=>'tang','䅯'=>'tang','䉎'=>'tang','䌅'=>'tang','䟖'=>'tang','䣘'=>'tang','䧜'=>'tang','倥'=>'kong','埪'=>'kong','孔'=>'kong','崆'=>'kong','恐'=>'kong','悾'=>'kong','控'=>'kong','涳'=>'kong','硿'=>'kong','空'=>'kong','箜'=>'kong','躻'=>'kong','躼'=>'kong','錓'=>'kong','鞚'=>'kong','鵼'=>'kong','㤟'=>'kong','㸜'=>'kong','倦'=>'juan','劵'=>'juan','勌'=>'juan','勬'=>'juan','卷'=>'juan','呟'=>'juan','埍'=>'juan','奆'=>'juan','姢'=>'juan','娟'=>'juan','帣'=>'juan','弮'=>'juan','慻'=>'juan','捐'=>'juan','捲'=>'juan','桊'=>'juan','涓'=>'juan','淃'=>'juan','狷'=>'juan','獧'=>'juan','瓹'=>'juan','眷'=>'juan','睊'=>'juan','睠'=>'juan','絭'=>'juan','絹'=>'juan','绢'=>'juan','罥'=>'juan','羂'=>'juan','脧'=>'juan','臇'=>'juan','菤'=>'juan','蔨'=>'juan','蠲'=>'juan','裐'=>'juan','鄄'=>'juan','鋑'=>'juan','鋗'=>'juan','錈'=>'juan','鎸'=>'juan','鐫'=>'juan','锩'=>'juan','镌'=>'juan','隽'=>'juan','雋'=>'juan','飬'=>'juan','餋'=>'juan','鵑'=>'juan','鹃'=>'juan','㢧'=>'juan','㢾'=>'juan','㪻'=>'juan','㯞'=>'juan','㷷'=>'juan','䄅'=>'juan','䌸'=>'juan','䖭'=>'juan','䚈'=>'juan','䡓'=>'juan','䳪'=>'juan','倮'=>'luo','儸'=>'luo','剆'=>'luo','啰'=>'luo','囉'=>'luo','峈'=>'luo','捋'=>'luo','摞'=>'luo','攞'=>'luo','曪'=>'luo','椤'=>'luo','欏'=>'luo','泺'=>'luo','洛'=>'luo','洜'=>'luo','漯'=>'luo','濼'=>'luo','犖'=>'luo','猡'=>'luo','玀'=>'luo','珞'=>'luo','瘰'=>'luo','癳'=>'luo','砢'=>'luo','笿'=>'luo','箩'=>'luo','籮'=>'luo','絡'=>'luo','纙'=>'luo','络'=>'luo','罗'=>'luo','羅'=>'luo','脶'=>'luo','腡'=>'luo','臝'=>'luo','荦'=>'luo','萝'=>'luo','落'=>'luo','蓏'=>'luo','蘿'=>'luo','螺'=>'luo','蠃'=>'luo','裸'=>'luo','覶'=>'luo','覼'=>'luo','躶'=>'luo','逻'=>'luo','邏'=>'luo','鏍'=>'luo','鑼'=>'luo','锣'=>'luo','镙'=>'luo','雒'=>'luo','頱'=>'luo','饠'=>'luo','駱'=>'luo','騾'=>'luo','驘'=>'luo','骆'=>'luo','骡'=>'luo','鮥'=>'luo','鱳'=>'luo','鵅'=>'luo','鸁'=>'luo','㑩'=>'luo','㒩'=>'luo','㓢'=>'luo','㦬'=>'luo','㩡'=>'luo','㰁'=>'luo','㱻'=>'luo','㴖'=>'luo','㼈'=>'luo','㽋'=>'luo','㿚'=>'luo','䀩'=>'luo','䇔'=>'luo','䈷'=>'luo','䊨'=>'luo','䌱'=>'luo','䌴'=>'luo','䯁'=>'luo','倯'=>'song','傱'=>'song','凇'=>'song','娀'=>'song','宋'=>'song','崧'=>'song','嵩'=>'song','嵷'=>'song','庺'=>'song','忪'=>'song','怂'=>'song','悚'=>'song','愯'=>'song','慫'=>'song','憽'=>'song','捒'=>'song','松'=>'song','枀'=>'song','枩'=>'song','柗'=>'song','梥'=>'song','檧'=>'song','淞'=>'song','濍'=>'song','硹'=>'song','竦'=>'song','耸'=>'song','聳'=>'song','菘'=>'song','蜙'=>'song','訟'=>'song','誦'=>'song','讼'=>'song','诵'=>'song','送'=>'song','鎹'=>'song','頌'=>'song','颂'=>'song','餸'=>'song','駷'=>'song','鬆'=>'song','㕬'=>'song','㧐'=>'song','㨦'=>'song','㩳'=>'song','㮸'=>'song','䉥'=>'song','䛦'=>'song','䜬'=>'song','䢠'=>'song','倰'=>'leng','冷'=>'leng','堎'=>'leng','塄'=>'leng','愣'=>'leng','棱'=>'leng','楞'=>'leng','睖'=>'leng','碐'=>'leng','稜'=>'leng','薐'=>'leng','踜'=>'leng','䉄'=>'leng','䚏'=>'leng','䬋'=>'leng','䮚'=>'leng','倴'=>'ben','坌'=>'ben','奔'=>'ben','奙'=>'ben','捹'=>'ben','撪'=>'ben','本'=>'ben','桳'=>'ben','楍'=>'ben','泍'=>'ben','渀'=>'ben','犇'=>'ben','獖'=>'ben','畚'=>'ben','笨'=>'ben','苯'=>'ben','賁'=>'ben','贲'=>'ben','輽'=>'ben','逩'=>'ben','錛'=>'ben','锛'=>'ben','㡷'=>'ben','㤓'=>'ben','㨧'=>'ben','㮺'=>'ben','㱵'=>'ben','䬱'=>'ben','债'=>'zhai','債'=>'zhai','夈'=>'zhai','宅'=>'zhai','寨'=>'zhai','捚'=>'zhai','摘'=>'zhai','斋'=>'zhai','斎'=>'zhai','斏'=>'zhai','榸'=>'zhai','瘵'=>'zhai','砦'=>'zhai','窄'=>'zhai','粂'=>'zhai','鉙'=>'zhai','齋'=>'zhai','㡯'=>'zhai','㩟'=>'zhai','倾'=>'qing','傾'=>'qing','儬'=>'qing','凊'=>'qing','剠'=>'qing','勍'=>'qing','卿'=>'qing','圊'=>'qing','埥'=>'qing','夝'=>'qing','庆'=>'qing','庼'=>'qing','廎'=>'qing','情'=>'qing','慶'=>'qing','掅'=>'qing','擎'=>'qing','擏'=>'qing','晴'=>'qing','暒'=>'qing','棾'=>'qing','樈'=>'qing','檠'=>'qing','檾'=>'qing','櫦'=>'qing','殑'=>'qing','殸'=>'qing','氢'=>'qing','氫'=>'qing','氰'=>'qing','淸'=>'qing','清'=>'qing','漀'=>'qing','濪'=>'qing','甠'=>'qing','硘'=>'qing','碃'=>'qing','磬'=>'qing','箐'=>'qing','罄'=>'qing','苘'=>'qing','葝'=>'qing','蜻'=>'qing','請'=>'qing','謦'=>'qing','请'=>'qing','軽'=>'qing','輕'=>'qing','轻'=>'qing','郬'=>'qing','鑋'=>'qing','靑'=>'qing','青'=>'qing','靘'=>'qing','頃'=>'qing','顷'=>'qing','鯖'=>'qing','鲭'=>'qing','黥'=>'qing','㯳'=>'qing','㷫'=>'qing','䋜'=>'qing','䌠'=>'qing','䔛'=>'qing','䝼'=>'qing','䞍'=>'qing','䯧'=>'qing','䲔'=>'qing','偀'=>'ying','僌'=>'ying','啨'=>'ying','営'=>'ying','嘤'=>'ying','噟'=>'ying','嚶'=>'ying','塋'=>'ying','婴'=>'ying','媖'=>'ying','媵'=>'ying','嫈'=>'ying','嬰'=>'ying','嬴'=>'ying','孆'=>'ying','孾'=>'ying','巆'=>'ying','巊'=>'ying','应'=>'ying','廮'=>'ying','影'=>'ying','応'=>'ying','愥'=>'ying','應'=>'ying','摬'=>'ying','撄'=>'ying','攍'=>'ying','攖'=>'ying','攚'=>'ying','映'=>'ying','暎'=>'ying','朠'=>'ying','桜'=>'ying','梬'=>'ying','楹'=>'ying','樱'=>'ying','櫻'=>'ying','櫿'=>'ying','浧'=>'ying','渶'=>'ying','溁'=>'ying','溋'=>'ying','滎'=>'ying','滢'=>'ying','潁'=>'ying','潆'=>'ying','濙'=>'ying','濚'=>'ying','濴'=>'ying','瀅'=>'ying','瀛'=>'ying','瀠'=>'ying','瀯'=>'ying','瀴'=>'ying','灐'=>'ying','灜'=>'ying','煐'=>'ying','熒'=>'ying','營'=>'ying','珱'=>'ying','瑛'=>'ying','瑩'=>'ying','璎'=>'ying','瓔'=>'ying','甇'=>'ying','甖'=>'ying','瘿'=>'ying','癭'=>'ying','盁'=>'ying','盈'=>'ying','矨'=>'ying','硬'=>'ying','碤'=>'ying','礯'=>'ying','穎'=>'ying','籝'=>'ying','籯'=>'ying','緓'=>'ying','縈'=>'ying','纓'=>'ying','绬'=>'ying','缨'=>'ying','罂'=>'ying','罃'=>'ying','罌'=>'ying','膡'=>'ying','膺'=>'ying','英'=>'ying','茔'=>'ying','荥'=>'ying','荧'=>'ying','莹'=>'ying','莺'=>'ying','萤'=>'ying','营'=>'ying','萦'=>'ying','萾'=>'ying','蓥'=>'ying','藀'=>'ying','蘡'=>'ying','蛍'=>'ying','蝇'=>'ying','蝧'=>'ying','蝿'=>'ying','螢'=>'ying','蠅'=>'ying','蠳'=>'ying','褮'=>'ying','覮'=>'ying','謍'=>'ying','譍'=>'ying','譻'=>'ying','賏'=>'ying','贏'=>'ying','赢'=>'ying','軈'=>'ying','迎'=>'ying','郢'=>'ying','鎣'=>'ying','鐛'=>'ying','鑍'=>'ying','锳'=>'ying','霙'=>'ying','鞕'=>'ying','韺'=>'ying','頴'=>'ying','颍'=>'ying','颕'=>'ying','颖'=>'ying','鴬'=>'ying','鶧'=>'ying','鶯'=>'ying','鷪'=>'ying','鷹'=>'ying','鸎'=>'ying','鸚'=>'ying','鹦'=>'ying','鹰'=>'ying','㑞'=>'ying','㢍'=>'ying','㨕'=>'ying','㯋'=>'ying','㲟'=>'ying','㴄'=>'ying','㵬'=>'ying','㶈'=>'ying','㹙'=>'ying','㹚'=>'ying','㿘'=>'ying','䀴'=>'ying','䁐'=>'ying','䁝'=>'ying','䃷'=>'ying','䇾'=>'ying','䑉'=>'ying','䕦'=>'ying','䙬'=>'ying','䤝'=>'ying','䨍'=>'ying','䪯'=>'ying','䭊'=>'ying','䭗'=>'ying','偄'=>'ruan','堧'=>'ruan','壖'=>'ruan','媆'=>'ruan','嫰'=>'ruan','愞'=>'ruan','撋'=>'ruan','朊'=>'ruan','瑌'=>'ruan','瓀'=>'ruan','碝'=>'ruan','礝'=>'ruan','緛'=>'ruan','耎'=>'ruan','腝'=>'ruan','蝡'=>'ruan','軟'=>'ruan','輭'=>'ruan','软'=>'ruan','阮'=>'ruan','㼱'=>'ruan','㽭'=>'ruan','䓴'=>'ruan','䞂'=>'ruan','䪭'=>'ruan','偆'=>'chun','唇'=>'chun','堾'=>'chun','媋'=>'chun','惷'=>'chun','旾'=>'chun','春'=>'chun','暙'=>'chun','杶'=>'chun','椿'=>'chun','槆'=>'chun','橁'=>'chun','櫄'=>'chun','浱'=>'chun','淳'=>'chun','湻'=>'chun','滣'=>'chun','漘'=>'chun','犉'=>'chun','瑃'=>'chun','睶'=>'chun','箺'=>'chun','純'=>'chun','纯'=>'chun','脣'=>'chun','莼'=>'chun','萅'=>'chun','萶'=>'chun','蒓'=>'chun','蓴'=>'chun','蝽'=>'chun','蠢'=>'chun','賰'=>'chun','踳'=>'chun','輴'=>'chun','醇'=>'chun','醕'=>'chun','錞'=>'chun','陙'=>'chun','鯙'=>'chun','鰆'=>'chun','鶉'=>'chun','鶞'=>'chun','鹑'=>'chun','㖺'=>'chun','㝄'=>'chun','㝇'=>'chun','㵮'=>'chun','㸪'=>'chun','㿤'=>'chun','䄝'=>'chun','䏛'=>'chun','䏝'=>'chun','䐇'=>'chun','䐏'=>'chun','䓐'=>'chun','䔚'=>'chun','䞐'=>'chun','䣨'=>'chun','䣩'=>'chun','䥎'=>'chun','䦮'=>'chun','䫃'=>'chun','偌'=>'ruo','叒'=>'ruo','婼'=>'ruo','嵶'=>'ruo','弱'=>'ruo','挼'=>'ruo','捼'=>'ruo','楉'=>'ruo','渃'=>'ruo','焫'=>'ruo','爇'=>'ruo','箬'=>'ruo','篛'=>'ruo','若'=>'ruo','蒻'=>'ruo','鄀'=>'ruo','鰙'=>'ruo','鰯'=>'ruo','鶸'=>'ruo','䐞'=>'ruo','偏'=>'pian','囨'=>'pian','媥'=>'pian','楄'=>'pian','楩'=>'pian','片'=>'pian','犏'=>'pian','篇'=>'pian','翩'=>'pian','胼'=>'pian','腁'=>'pian','覑'=>'pian','諚'=>'pian','諞'=>'pian','谝'=>'pian','貵'=>'pian','賆'=>'pian','蹁'=>'pian','駢'=>'pian','騈'=>'pian','騗'=>'pian','騙'=>'pian','骈'=>'pian','骗'=>'pian','骿'=>'pian','魸'=>'pian','鶣'=>'pian','㓲'=>'pian','㛹'=>'pian','㸤'=>'pian','㼐'=>'pian','䏒'=>'pian','䮁'=>'pian','偗'=>'sheng','剩'=>'sheng','剰'=>'sheng','勝'=>'sheng','升'=>'sheng','呏'=>'sheng','圣'=>'sheng','墭'=>'sheng','声'=>'sheng','嵊'=>'sheng','憴'=>'sheng','斘'=>'sheng','昇'=>'sheng','晟'=>'sheng','晠'=>'sheng','曻'=>'sheng','枡'=>'sheng','榺'=>'sheng','橳'=>'sheng','殅'=>'sheng','泩'=>'sheng','渑'=>'sheng','渻'=>'sheng','湦'=>'sheng','澠'=>'sheng','焺'=>'sheng','牲'=>'sheng','珄'=>'sheng','琞'=>'sheng','生'=>'sheng','甥'=>'sheng','盛'=>'sheng','省'=>'sheng','眚'=>'sheng','竔'=>'sheng','笙'=>'sheng','縄'=>'sheng','繩'=>'sheng','绳'=>'sheng','聖'=>'sheng','聲'=>'sheng','胜'=>'sheng','苼'=>'sheng','蕂'=>'sheng','譝'=>'sheng','貹'=>'sheng','賸'=>'sheng','鉎'=>'sheng','鍟'=>'sheng','阩'=>'sheng','陞'=>'sheng','陹'=>'sheng','鱦'=>'sheng','鵿'=>'sheng','鼪'=>'sheng','㗂'=>'sheng','㼳'=>'sheng','㾪'=>'sheng','䁞'=>'sheng','䎴'=>'sheng','䚇'=>'sheng','䞉'=>'sheng','䪿'=>'sheng','䱆'=>'sheng','偟'=>'huang','兤'=>'huang','凰'=>'huang','喤'=>'huang','堭'=>'huang','塃'=>'huang','墴'=>'huang','奛'=>'huang','媓'=>'huang','宺'=>'huang','崲'=>'huang','巟'=>'huang','幌'=>'huang','徨'=>'huang','怳'=>'huang','恍'=>'huang','惶'=>'huang','愰'=>'huang','慌'=>'huang','揘'=>'huang','晃'=>'huang','晄'=>'huang','曂'=>'huang','朚'=>'huang','楻'=>'huang','榥'=>'huang','櫎'=>'huang','湟'=>'huang','滉'=>'huang','潢'=>'huang','炾'=>'huang','煌'=>'huang','熀'=>'huang','熿'=>'huang','獚'=>'huang','瑝'=>'huang','璜'=>'huang','癀'=>'huang','皇'=>'huang','皝'=>'huang','皩'=>'huang','磺'=>'huang','穔'=>'huang','篁'=>'huang','簧'=>'huang','縨'=>'huang','肓'=>'huang','艎'=>'huang','荒'=>'huang','葟'=>'huang','蝗'=>'huang','蟥'=>'huang','衁'=>'huang','詤'=>'huang','諻'=>'huang','謊'=>'huang','谎'=>'huang','趪'=>'huang','遑'=>'huang','鍠'=>'huang','鎤'=>'huang','鐄'=>'huang','锽'=>'huang','隍'=>'huang','韹'=>'huang','餭'=>'huang','騜'=>'huang','鰉'=>'huang','鱑'=>'huang','鳇'=>'huang','鷬'=>'huang','黃'=>'huang','黄'=>'huang','㞷'=>'huang','㤺'=>'huang','㨪'=>'huang','㬻'=>'huang','㾠'=>'huang','㾮'=>'huang','䁜'=>'huang','䅣'=>'huang','䊗'=>'huang','䊣'=>'huang','䌙'=>'huang','䍿'=>'huang','䐠'=>'huang','䐵'=>'huang','䑟'=>'huang','䞹'=>'huang','䪄'=>'huang','䮲'=>'huang','䳨'=>'huang','偳'=>'duan','塅'=>'duan','媏'=>'duan','断'=>'duan','斷'=>'duan','椴'=>'duan','段'=>'duan','毈'=>'duan','煅'=>'duan','瑖'=>'duan','短'=>'duan','碫'=>'duan','端'=>'duan','簖'=>'duan','籪'=>'duan','緞'=>'duan','缎'=>'duan','耑'=>'duan','腶'=>'duan','葮'=>'duan','褍'=>'duan','躖'=>'duan','鍛'=>'duan','鍴'=>'duan','锻'=>'duan','㫁'=>'duan','㱭'=>'duan','䠪'=>'duan','偺'=>'zan','儧'=>'zan','儹'=>'zan','兂'=>'zan','咱'=>'zan','喒'=>'zan','囋'=>'zan','寁'=>'zan','撍'=>'zan','攒'=>'zan','攢'=>'zan','昝'=>'zan','暂'=>'zan','暫'=>'zan','濽'=>'zan','灒'=>'zan','瓉'=>'zan','瓒'=>'zan','瓚'=>'zan','禶'=>'zan','簪'=>'zan','簮'=>'zan','糌'=>'zan','襸'=>'zan','讃'=>'zan','讚'=>'zan','賛'=>'zan','贊'=>'zan','赞'=>'zan','趱'=>'zan','趲'=>'zan','蹔'=>'zan','鄼'=>'zan','酂'=>'zan','酇'=>'zan','錾'=>'zan','鏨'=>'zan','鐕'=>'zan','饡'=>'zan','㜺'=>'zan','㟛'=>'zan','㣅'=>'zan','㤰'=>'zan','偻'=>'lou','僂'=>'lou','喽'=>'lou','嘍'=>'lou','塿'=>'lou','娄'=>'lou','婁'=>'lou','屚'=>'lou','嵝'=>'lou','嶁'=>'lou','廔'=>'lou','慺'=>'lou','搂'=>'lou','摟'=>'lou','楼'=>'lou','樓'=>'lou','溇'=>'lou','漊'=>'lou','漏'=>'lou','熡'=>'lou','甊'=>'lou','瘘'=>'lou','瘺'=>'lou','瘻'=>'lou','瞜'=>'lou','篓'=>'lou','簍'=>'lou','耧'=>'lou','耬'=>'lou','艛'=>'lou','蒌'=>'lou','蔞'=>'lou','蝼'=>'lou','螻'=>'lou','謱'=>'lou','軁'=>'lou','遱'=>'lou','鏤'=>'lou','镂'=>'lou','陋'=>'lou','鞻'=>'lou','髅'=>'lou','髏'=>'lou','㔷'=>'lou','㟺'=>'lou','㥪'=>'lou','㪹'=>'lou','㲎'=>'lou','㺏'=>'lou','䁖'=>'lou','䄛'=>'lou','䅹'=>'lou','䝏'=>'lou','䣚'=>'lou','䫫'=>'lou','䮫'=>'lou','䱾'=>'lou','傁'=>'sou','凁'=>'sou','叜'=>'sou','叟'=>'sou','嗖'=>'sou','嗾'=>'sou','廀'=>'sou','廋'=>'sou','捜'=>'sou','搜'=>'sou','摗'=>'sou','擞'=>'sou','擻'=>'sou','櫢'=>'sou','溲'=>'sou','獀'=>'sou','瘶'=>'sou','瞍'=>'sou','艘'=>'sou','蒐'=>'sou','蓃'=>'sou','薮'=>'sou','藪'=>'sou','螋'=>'sou','鄋'=>'sou','醙'=>'sou','鎪'=>'sou','锼'=>'sou','颼'=>'sou','飕'=>'sou','餿'=>'sou','馊'=>'sou','騪'=>'sou','㖩'=>'sou','㛐'=>'sou','㵻'=>'sou','䈹'=>'sou','䉤'=>'sou','䏂'=>'sou','䮟'=>'sou','傆'=>'yuan','元'=>'yuan','冤'=>'yuan','剈'=>'yuan','原'=>'yuan','厡'=>'yuan','厵'=>'yuan','员'=>'yuan','員'=>'yuan','噮'=>'yuan','囦'=>'yuan','园'=>'yuan','圆'=>'yuan','圎'=>'yuan','園'=>'yuan','圓'=>'yuan','圜'=>'yuan','垣'=>'yuan','垸'=>'yuan','塬'=>'yuan','夗'=>'yuan','妴'=>'yuan','媛'=>'yuan','媴'=>'yuan','嫄'=>'yuan','嬽'=>'yuan','寃'=>'yuan','弲'=>'yuan','怨'=>'yuan','悁'=>'yuan','惌'=>'yuan','愿'=>'yuan','掾'=>'yuan','援'=>'yuan','杬'=>'yuan','棩'=>'yuan','榞'=>'yuan','榬'=>'yuan','橼'=>'yuan','櫞'=>'yuan','沅'=>'yuan','淵'=>'yuan','渁'=>'yuan','渆'=>'yuan','渊'=>'yuan','渕'=>'yuan','湲'=>'yuan','源'=>'yuan','溒'=>'yuan','灁'=>'yuan','爰'=>'yuan','猨'=>'yuan','猿'=>'yuan','獂'=>'yuan','瑗'=>'yuan','盶'=>'yuan','眢'=>'yuan','禐'=>'yuan','笎'=>'yuan','箢'=>'yuan','緣'=>'yuan','縁'=>'yuan','缘'=>'yuan','羱'=>'yuan','肙'=>'yuan','苑'=>'yuan','葾'=>'yuan','蒝'=>'yuan','蒬'=>'yuan','薗'=>'yuan','蚖'=>'yuan','蜎'=>'yuan','蜵'=>'yuan','蝝'=>'yuan','蝯'=>'yuan','螈'=>'yuan','衏'=>'yuan','袁'=>'yuan','裫'=>'yuan','褑'=>'yuan','褤'=>'yuan','謜'=>'yuan','貟'=>'yuan','贠'=>'yuan','轅'=>'yuan','辕'=>'yuan','远'=>'yuan','逺'=>'yuan','遠'=>'yuan','邍'=>'yuan','邧'=>'yuan','酛'=>'yuan','鈨'=>'yuan','鋺'=>'yuan','鎱'=>'yuan','院'=>'yuan','願'=>'yuan','駌'=>'yuan','騵'=>'yuan','魭'=>'yuan','鳶'=>'yuan','鴛'=>'yuan','鵷'=>'yuan','鶢'=>'yuan','鶰'=>'yuan','鸢'=>'yuan','鸳'=>'yuan','鹓'=>'yuan','黿'=>'yuan','鼋'=>'yuan','鼘'=>'yuan','鼝'=>'yuan','㟶'=>'yuan','㤪'=>'yuan','㥐'=>'yuan','㥳'=>'yuan','㭇'=>'yuan','㹉'=>'yuan','䅈'=>'yuan','䏍'=>'yuan','䖠'=>'yuan','䛄'=>'yuan','䛇'=>'yuan','䩩'=>'yuan','䬇'=>'yuan','䬧'=>'yuan','䬼'=>'yuan','䲮'=>'yuan','䳒'=>'yuan','䳣'=>'yuan','傇'=>'rong','冗'=>'rong','媶'=>'rong','嫆'=>'rong','嬫'=>'rong','宂'=>'rong','容'=>'rong','峵'=>'rong','嵘'=>'rong','嵤'=>'rong','嶸'=>'rong','戎'=>'rong','搈'=>'rong','搑'=>'rong','摉'=>'rong','曧'=>'rong','栄'=>'rong','榕'=>'rong','榮'=>'rong','榵'=>'rong','毧'=>'rong','氄'=>'rong','溶'=>'rong','瀜'=>'rong','烿'=>'rong','熔'=>'rong','爃'=>'rong','狨'=>'rong','瑢'=>'rong','穁'=>'rong','穃'=>'rong','絨'=>'rong','縙'=>'rong','绒'=>'rong','羢'=>'rong','肜'=>'rong','茙'=>'rong','茸'=>'rong','荣'=>'rong','蓉'=>'rong','蝾'=>'rong','融'=>'rong','螎'=>'rong','蠑'=>'rong','褣'=>'rong','軵'=>'rong','鎔'=>'rong','镕'=>'rong','駥'=>'rong','髶'=>'rong','㘇'=>'rong','㝐'=>'rong','㣑'=>'rong','㭜'=>'rong','㲓'=>'rong','㲝'=>'rong','㲨'=>'rong','㺎'=>'rong','㼸'=>'rong','䇀'=>'rong','䇯'=>'rong','䈶'=>'rong','䘬'=>'rong','䠜'=>'rong','䡆'=>'rong','䡥'=>'rong','䢇'=>'rong','䤊'=>'rong','䩸'=>'rong','傋'=>'jiang','僵'=>'jiang','勥'=>'jiang','匞'=>'jiang','匠'=>'jiang','壃'=>'jiang','夅'=>'jiang','奖'=>'jiang','奨'=>'jiang','奬'=>'jiang','姜'=>'jiang','将'=>'jiang','將'=>'jiang','嵹'=>'jiang','弜'=>'jiang','弶'=>'jiang','彊'=>'jiang','摪'=>'jiang','摾'=>'jiang','杢'=>'jiang','桨'=>'jiang','槳'=>'jiang','橿'=>'jiang','櫤'=>'jiang','殭'=>'jiang','江'=>'jiang','洚'=>'jiang','浆'=>'jiang','滰'=>'jiang','漿'=>'jiang','犟'=>'jiang','獎'=>'jiang','畕'=>'jiang','畺'=>'jiang','疅'=>'jiang','疆'=>'jiang','礓'=>'jiang','糡'=>'jiang','糨'=>'jiang','絳'=>'jiang','繮'=>'jiang','绛'=>'jiang','缰'=>'jiang','翞'=>'jiang','耩'=>'jiang','膙'=>'jiang','茳'=>'jiang','葁'=>'jiang','蒋'=>'jiang','蔣'=>'jiang','薑'=>'jiang','螀'=>'jiang','螿'=>'jiang','袶'=>'jiang','講'=>'jiang','謽'=>'jiang','讲'=>'jiang','豇'=>'jiang','酱'=>'jiang','醤'=>'jiang','醬'=>'jiang','降'=>'jiang','韁'=>'jiang','顜'=>'jiang','鱂'=>'jiang','鳉'=>'jiang','㢡'=>'jiang','㯍'=>'jiang','䁰'=>'jiang','䉃'=>'jiang','䋌'=>'jiang','䒂'=>'jiang','䕭'=>'jiang','䕯'=>'jiang','䙹'=>'jiang','䞪'=>'jiang','傍'=>'bang','垹'=>'bang','塝'=>'bang','峀'=>'bang','帮'=>'bang','幇'=>'bang','幚'=>'bang','幫'=>'bang','徬'=>'bang','捠'=>'bang','梆'=>'bang','棒'=>'bang','棓'=>'bang','榜'=>'bang','浜'=>'bang','牓'=>'bang','玤'=>'bang','硥'=>'bang','磅'=>'bang','稖'=>'bang','綁'=>'bang','縍'=>'bang','绑'=>'bang','膀'=>'bang','艕'=>'bang','蒡'=>'bang','蚌'=>'bang','蜯'=>'bang','謗'=>'bang','谤'=>'bang','邦'=>'bang','邫'=>'bang','鎊'=>'bang','镑'=>'bang','鞤'=>'bang','㔙'=>'bang','㭋'=>'bang','㮄'=>'bang','㯁'=>'bang','㾦'=>'bang','䂜'=>'bang','䎧'=>'bang','䖫'=>'bang','䟺'=>'bang','䧛'=>'bang','䰷'=>'bang','傐'=>'hao','儫'=>'hao','兞'=>'hao','号'=>'hao','哠'=>'hao','嗥'=>'hao','嘷'=>'hao','噑'=>'hao','嚆'=>'hao','嚎'=>'hao','壕'=>'hao','好'=>'hao','恏'=>'hao','悎'=>'hao','昊'=>'hao','昦'=>'hao','晧'=>'hao','暤'=>'hao','暭'=>'hao','曍'=>'hao','椃'=>'hao','毫'=>'hao','浩'=>'hao','淏'=>'hao','滈'=>'hao','澔'=>'hao','濠'=>'hao','灏'=>'hao','灝'=>'hao','獆'=>'hao','獋'=>'hao','皓'=>'hao','皜'=>'hao','皞'=>'hao','皡'=>'hao','皥'=>'hao','秏'=>'hao','竓'=>'hao','籇'=>'hao','耗'=>'hao','聕'=>'hao','茠'=>'hao','蒿'=>'hao','薃'=>'hao','薅'=>'hao','薧'=>'hao','號'=>'hao','蚝'=>'hao','蠔'=>'hao','譹'=>'hao','豪'=>'hao','郝'=>'hao','顥'=>'hao','颢'=>'hao','鰝'=>'hao','㕺'=>'hao','㘪'=>'hao','㙱'=>'hao','㚪'=>'hao','㝀'=>'hao','㞻'=>'hao','㠙'=>'hao','㩝'=>'hao','㬔'=>'hao','㬶'=>'hao','㵆'=>'hao','䒵'=>'hao','䚽'=>'hao','䝞'=>'hao','䝥'=>'hao','䧫'=>'hao','䪽'=>'hao','䬉'=>'hao','䯫'=>'hao','傓'=>'shan','僐'=>'shan','删'=>'shan','刪'=>'shan','剡'=>'shan','剼'=>'shan','善'=>'shan','嘇'=>'shan','圸'=>'shan','埏'=>'shan','墠'=>'shan','墡'=>'shan','姍'=>'shan','姗'=>'shan','嬗'=>'shan','山'=>'shan','幓'=>'shan','彡'=>'shan','扇'=>'shan','挻'=>'shan','搧'=>'shan','擅'=>'shan','敾'=>'shan','晱'=>'shan','曑'=>'shan','杉'=>'shan','杣'=>'shan','椫'=>'shan','樿'=>'shan','檆'=>'shan','汕'=>'shan','潸'=>'shan','澘'=>'shan','灗'=>'shan','炶'=>'shan','烻'=>'shan','煔'=>'shan','煽'=>'shan','熌'=>'shan','狦'=>'shan','珊'=>'shan','疝'=>'shan','痁'=>'shan','睒'=>'shan','磰'=>'shan','笘'=>'shan','縿'=>'shan','繕'=>'shan','缮'=>'shan','羴'=>'shan','羶'=>'shan','脠'=>'shan','膳'=>'shan','膻'=>'shan','舢'=>'shan','芟'=>'shan','苫'=>'shan','蔪'=>'shan','蟮'=>'shan','蟺'=>'shan','衫'=>'shan','覢'=>'shan','訕'=>'shan','謆'=>'shan','譱'=>'shan','讪'=>'shan','贍'=>'shan','赡'=>'shan','赸'=>'shan','跚'=>'shan','軕'=>'shan','邖'=>'shan','鄯'=>'shan','釤'=>'shan','銏'=>'shan','鐥'=>'shan','钐'=>'shan','閃'=>'shan','閊'=>'shan','闪'=>'shan','陕'=>'shan','陝'=>'shan','饍'=>'shan','騸'=>'shan','骟'=>'shan','鯅'=>'shan','鱓'=>'shan','鱔'=>'shan','鳝'=>'shan','㚒'=>'shan','㣌'=>'shan','㣣'=>'shan','㨛'=>'shan','㪎'=>'shan','㪨'=>'shan','㶒'=>'shan','䄠'=>'shan','䆄'=>'shan','䚲'=>'shan','䠾'=>'shan','䥇'=>'shan','䦂'=>'shan','䦅'=>'shan','䱇'=>'shan','䱉'=>'shan','䴮'=>'shan','傞'=>'suo','唆'=>'suo','唢'=>'suo','嗦'=>'suo','嗩'=>'suo','娑'=>'suo','惢'=>'suo','所'=>'suo','挲'=>'suo','摍'=>'suo','暛'=>'suo','桫'=>'suo','梭'=>'suo','溑'=>'suo','溹'=>'suo','琐'=>'suo','琑'=>'suo','瑣'=>'suo','睃'=>'suo','簑'=>'suo','簔'=>'suo','索'=>'suo','縮'=>'suo','缩'=>'suo','羧'=>'suo','莏'=>'suo','蓑'=>'suo','蜶'=>'suo','趖'=>'suo','逤'=>'suo','鎍'=>'suo','鎖'=>'suo','鎻'=>'suo','鎼'=>'suo','鏁'=>'suo','锁'=>'suo','髿'=>'suo','鮻'=>'suo','㪽'=>'suo','䂹'=>'suo','䅴'=>'suo','䈗'=>'suo','䐝'=>'suo','䖛'=>'suo','䗢'=>'suo','䞆'=>'suo','䞽'=>'suo','䣔'=>'suo','䵀'=>'suo','傤'=>'zai','儎'=>'zai','再'=>'zai','哉'=>'zai','在'=>'zai','宰'=>'zai','崽'=>'zai','扗'=>'zai','栽'=>'zai','洅'=>'zai','渽'=>'zai','溨'=>'zai','災'=>'zai','灾'=>'zai','烖'=>'zai','甾'=>'zai','睵'=>'zai','縡'=>'zai','菑'=>'zai','賳'=>'zai','載'=>'zai','载'=>'zai','酨'=>'zai','㞨'=>'zai','㱰'=>'zai','㴓'=>'zai','䏁'=>'zai','䣬'=>'zai','䮨'=>'zai','䵧'=>'zai','傧'=>'bin','儐'=>'bin','宾'=>'bin','彬'=>'bin','摈'=>'bin','擯'=>'bin','斌'=>'bin','椕'=>'bin','槟'=>'bin','殡'=>'bin','殯'=>'bin','氞'=>'bin','汃'=>'bin','滨'=>'bin','濒'=>'bin','濱'=>'bin','濵'=>'bin','瀕'=>'bin','瑸'=>'bin','璸'=>'bin','砏'=>'bin','繽'=>'bin','缤'=>'bin','膑'=>'bin','臏'=>'bin','虨'=>'bin','蠙'=>'bin','豩'=>'bin','豳'=>'bin','賓'=>'bin','賔'=>'bin','邠'=>'bin','鑌'=>'bin','镔'=>'bin','霦'=>'bin','顮'=>'bin','髌'=>'bin','髕'=>'bin','髩'=>'bin','鬂'=>'bin','鬓'=>'bin','鬢'=>'bin','䐔'=>'bin','傩'=>'nuo','儺'=>'nuo','喏'=>'nuo','懦'=>'nuo','懧'=>'nuo','挪'=>'nuo','掿'=>'nuo','搦'=>'nuo','搻'=>'nuo','桛'=>'nuo','梛'=>'nuo','榒'=>'nuo','橠'=>'nuo','燶'=>'nuo','硸'=>'nuo','稬'=>'nuo','穤'=>'nuo','糑'=>'nuo','糥'=>'nuo','糯'=>'nuo','諾'=>'nuo','诺'=>'nuo','蹃'=>'nuo','逽'=>'nuo','郍'=>'nuo','鍩'=>'nuo','锘'=>'nuo','黁'=>'nuo','㐡'=>'nuo','㑚'=>'nuo','㔮'=>'nuo','㛂'=>'nuo','㡅'=>'nuo','㰙'=>'nuo','䚥'=>'nuo','傪'=>'can','儏'=>'can','参'=>'can','參'=>'can','叄'=>'can','叅'=>'can','喰'=>'can','噆'=>'can','嬠'=>'can','惨'=>'can','惭'=>'can','慘'=>'can','慙'=>'can','慚'=>'can','憯'=>'can','朁'=>'can','残'=>'can','殘'=>'can','湌'=>'can','澯'=>'can','灿'=>'can','燦'=>'can','爘'=>'can','璨'=>'can','穇'=>'can','粲'=>'can','薒'=>'can','蚕'=>'can','蝅'=>'can','蠶'=>'can','蠺'=>'can','謲'=>'can','飡'=>'can','餐'=>'can','驂'=>'can','骖'=>'can','黪'=>'can','黲'=>'can','㘔'=>'can','㛑'=>'can','㜗'=>'can','㣓'=>'can','㥇'=>'can','㦧'=>'can','㨻'=>'can','㱚'=>'can','㺑'=>'can','㻮'=>'can','㽩'=>'can','㿊'=>'can','䅟'=>'can','䍼'=>'can','䏼'=>'can','䑶'=>'can','䗝'=>'can','䗞'=>'can','䘉'=>'can','䙁'=>'can','䛹'=>'can','䝳'=>'can','䣟'=>'can','䫮'=>'can','䬫'=>'can','䳻'=>'can','傫'=>'lei','儡'=>'lei','儽'=>'lei','厽'=>'lei','嘞'=>'lei','垒'=>'lei','塁'=>'lei','壘'=>'lei','壨'=>'lei','嫘'=>'lei','擂'=>'lei','攂'=>'lei','樏'=>'lei','檑'=>'lei','櫐'=>'lei','櫑'=>'lei','欙'=>'lei','泪'=>'lei','洡'=>'lei','涙'=>'lei','淚'=>'lei','灅'=>'lei','瓃'=>'lei','畾'=>'lei','癗'=>'lei','矋'=>'lei','磊'=>'lei','磥'=>'lei','礌'=>'lei','礧'=>'lei','礨'=>'lei','禷'=>'lei','类'=>'lei','累'=>'lei','絫'=>'lei','縲'=>'lei','纇'=>'lei','纍'=>'lei','纝'=>'lei','缧'=>'lei','罍'=>'lei','羸'=>'lei','耒'=>'lei','肋'=>'lei','脷'=>'lei','蔂'=>'lei','蕌'=>'lei','蕾'=>'lei','藟'=>'lei','蘱'=>'lei','蘲'=>'lei','蘽'=>'lei','虆'=>'lei','蠝'=>'lei','誄'=>'lei','讄'=>'lei','诔'=>'lei','轠'=>'lei','酹'=>'lei','銇'=>'lei','錑'=>'lei','鐳'=>'lei','鑘'=>'lei','鑸'=>'lei','镭'=>'lei','雷'=>'lei','靁'=>'lei','頛'=>'lei','頪'=>'lei','類'=>'lei','颣'=>'lei','鱩'=>'lei','鸓'=>'lei','鼺'=>'lei','㑍'=>'lei','㒍'=>'lei','㒦'=>'lei','㔣'=>'lei','㙼'=>'lei','㡞'=>'lei','㭩'=>'lei','㲕'=>'lei','㴃'=>'lei','㵢'=>'lei','㶟'=>'lei','㹎'=>'lei','㼍'=>'lei','㿔'=>'lei','䉂'=>'lei','䉓'=>'lei','䉪'=>'lei','䍣'=>'lei','䍥'=>'lei','䐯'=>'lei','䒹'=>'lei','䛶'=>'lei','䢮'=>'lei','䣂'=>'lei','䣦'=>'lei','䨓'=>'lei','䮑'=>'lei','䴎'=>'lei','傮'=>'zao','凿'=>'zao','唕'=>'zao','唣'=>'zao','喿'=>'zao','噪'=>'zao','慥'=>'zao','早'=>'zao','枣'=>'zao','栆'=>'zao','梍'=>'zao','棗'=>'zao','澡'=>'zao','灶'=>'zao','煰'=>'zao','燥'=>'zao','璅'=>'zao','璪'=>'zao','皁'=>'zao','皂'=>'zao','竃'=>'zao','竈'=>'zao','簉'=>'zao','糟'=>'zao','艁'=>'zao','薻'=>'zao','藻'=>'zao','蚤'=>'zao','譟'=>'zao','趮'=>'zao','蹧'=>'zao','躁'=>'zao','造'=>'zao','遭'=>'zao','醩'=>'zao','鑿'=>'zao','㲧'=>'zao','㿷'=>'zao','䜊'=>'zao','䥣'=>'zao','䲃'=>'zao','傲'=>'ao','凹'=>'ao','厫'=>'ao','嗷'=>'ao','嗸'=>'ao','坳'=>'ao','垇'=>'ao','墺'=>'ao','奡'=>'ao','奥'=>'ao','奧'=>'ao','媪'=>'ao','媼'=>'ao','嫯'=>'ao','岙'=>'ao','岰'=>'ao','嶅'=>'ao','嶴'=>'ao','廒'=>'ao','慠'=>'ao','懊'=>'ao','扷'=>'ao','抝'=>'ao','拗'=>'ao','摮'=>'ao','擙'=>'ao','敖'=>'ao','柪'=>'ao','滶'=>'ao','澚'=>'ao','澳'=>'ao','熬'=>'ao','爊'=>'ao','獒'=>'ao','獓'=>'ao','璈'=>'ao','磝'=>'ao','翱'=>'ao','翶'=>'ao','翺'=>'ao','聱'=>'ao','芺'=>'ao','蔜'=>'ao','螯'=>'ao','袄'=>'ao','襖'=>'ao','謷'=>'ao','謸'=>'ao','軪'=>'ao','遨'=>'ao','鏊'=>'ao','鏖'=>'ao','镺'=>'ao','隞'=>'ao','驁'=>'ao','骜'=>'ao','鰲'=>'ao','鳌'=>'ao','鷔'=>'ao','鼇'=>'ao','㑃'=>'ao','㕭'=>'ao','㘬'=>'ao','㘭'=>'ao','㜜'=>'ao','㜩'=>'ao','㟼'=>'ao','㠂'=>'ao','㠗'=>'ao','㤇'=>'ao','㥿'=>'ao','㿰'=>'ao','䁱'=>'ao','䐿'=>'ao','䚫'=>'ao','䜒'=>'ao','䞝'=>'ao','䥝'=>'ao','䦋'=>'ao','䫨'=>'ao','䮯'=>'ao','䯠'=>'ao','䴈'=>'ao','䵅'=>'ao','傸'=>'chuang','刅'=>'chuang','创'=>'chuang','刱'=>'chuang','剏'=>'chuang','剙'=>'chuang','創'=>'chuang','噇'=>'chuang','幢'=>'chuang','床'=>'chuang','怆'=>'chuang','愴'=>'chuang','摐'=>'chuang','漺'=>'chuang','牀'=>'chuang','牎'=>'chuang','牕'=>'chuang','疮'=>'chuang','瘡'=>'chuang','磢'=>'chuang','窓'=>'chuang','窗'=>'chuang','窻'=>'chuang','闖'=>'chuang','闯'=>'chuang','㡖'=>'chuang','㵂'=>'chuang','䃥'=>'chuang','䆫'=>'chuang','䇬'=>'chuang','䎫'=>'chuang','䚒'=>'chuang','䡴'=>'chuang','䭚'=>'chuang','僄'=>'piao','剽'=>'piao','勡'=>'piao','嘌'=>'piao','嫖'=>'piao','彯'=>'piao','徱'=>'piao','慓'=>'piao','旚'=>'piao','殍'=>'piao','漂'=>'piao','犥'=>'piao','瓢'=>'piao','皫'=>'piao','瞟'=>'piao','磦'=>'piao','票'=>'piao','篻'=>'piao','縹'=>'piao','缥'=>'piao','翲'=>'piao','薸'=>'piao','螵'=>'piao','醥'=>'piao','闝'=>'piao','顠'=>'piao','飃'=>'piao','飄'=>'piao','飘'=>'piao','魒'=>'piao','㩠'=>'piao','㬓'=>'piao','㵱'=>'piao','㹾'=>'piao','㺓'=>'piao','㼼'=>'piao','䏇'=>'piao','䴩'=>'piao','僈'=>'man','墁'=>'man','姏'=>'man','嫚'=>'man','屘'=>'man','幔'=>'man','悗'=>'man','慢'=>'man','慲'=>'man','摱'=>'man','曼'=>'man','槾'=>'man','樠'=>'man','満'=>'man','满'=>'man','滿'=>'man','漫'=>'man','澫'=>'man','澷'=>'man','熳'=>'man','獌'=>'man','睌'=>'man','瞒'=>'man','瞞'=>'man','矕'=>'man','縵'=>'man','缦'=>'man','蔄'=>'man','蔓'=>'man','蘰'=>'man','蛮'=>'man','螨'=>'man','蟃'=>'man','蟎'=>'man','蠻'=>'man','襔'=>'man','謾'=>'man','谩'=>'man','鄤'=>'man','鏋'=>'man','鏝'=>'man','镘'=>'man','鞔'=>'man','顢'=>'man','颟'=>'man','饅'=>'man','馒'=>'man','鬗'=>'man','鬘'=>'man','鰻'=>'man','鳗'=>'man','㒼'=>'man','㗄'=>'man','㗈'=>'man','㙢'=>'man','㛧'=>'man','㡢'=>'man','㬅'=>'man','㵘'=>'man','䅼'=>'man','䊡'=>'man','䐽'=>'man','䑱'=>'man','䕕'=>'man','䛲'=>'man','䜱'=>'man','䝡'=>'man','䝢'=>'man','䟂'=>'man','䡬'=>'man','䯶'=>'man','䰋'=>'man','僔'=>'zun','噂'=>'zun','尊'=>'zun','嶟'=>'zun','捘'=>'zun','撙'=>'zun','樽'=>'zun','繜'=>'zun','罇'=>'zun','譐'=>'zun','遵'=>'zun','銌'=>'zun','鐏'=>'zun','鱒'=>'zun','鳟'=>'zun','鶎'=>'zun','鷷'=>'zun','僜'=>'deng','凳'=>'deng','噔'=>'deng','墱'=>'deng','嬁'=>'deng','嶝'=>'deng','戥'=>'deng','櫈'=>'deng','灯'=>'deng','燈'=>'deng','璒'=>'deng','登'=>'deng','瞪'=>'deng','磴'=>'deng','竳'=>'deng','等'=>'deng','簦'=>'deng','艠'=>'deng','覴'=>'deng','豋'=>'deng','蹬'=>'deng','邓'=>'deng','鄧'=>'deng','鐙'=>'deng','镫'=>'deng','隥'=>'deng','䃶'=>'deng','䒭'=>'deng','䠬'=>'deng','䮴'=>'deng','僣'=>'tie','呫'=>'tie','帖'=>'tie','怗'=>'tie','聑'=>'tie','萜'=>'tie','蛈'=>'tie','貼'=>'tie','贴'=>'tie','跕'=>'tie','鉄'=>'tie','銕'=>'tie','鐡'=>'tie','鐢'=>'tie','鐵'=>'tie','铁'=>'tie','飻'=>'tie','餮'=>'tie','驖'=>'tie','鴩'=>'tie','䥫'=>'tie','䴴'=>'tie','䵿'=>'tie','僧'=>'seng','僶'=>'min','冧'=>'min','冺'=>'min','刡'=>'min','勄'=>'min','垊'=>'min','姄'=>'min','岷'=>'min','崏'=>'min','忞'=>'min','怋'=>'min','悯'=>'min','愍'=>'min','慜'=>'min','憫'=>'min','抿'=>'min','捪'=>'min','敃'=>'min','敏'=>'min','敯'=>'min','旻'=>'min','旼'=>'min','暋'=>'min','民'=>'min','泯'=>'min','湣'=>'min','潣'=>'min','玟'=>'min','珉'=>'min','琘'=>'min','琝'=>'min','瑉'=>'min','痻'=>'min','皿'=>'min','盿'=>'min','碈'=>'min','笢'=>'min','笽'=>'min','簢'=>'min','緍'=>'min','緡'=>'min','缗'=>'min','罠'=>'min','苠'=>'min','蠠'=>'min','賯'=>'min','鈱'=>'min','錉'=>'min','鍲'=>'min','閔'=>'min','閩'=>'min','闵'=>'min','闽'=>'min','鰵'=>'min','鳘'=>'min','鴖'=>'min','黽'=>'min','㞶'=>'min','㟩'=>'min','㟭'=>'min','㢯'=>'min','㥸'=>'min','㨉'=>'min','䁕'=>'min','䂥'=>'min','䃉'=>'min','䋋'=>'min','䟨'=>'min','䡅'=>'min','䡑'=>'min','䡻'=>'min','䪸'=>'min','䲄'=>'min','僿'=>'sai','嗮'=>'sai','嘥'=>'sai','噻'=>'sai','塞'=>'sai','愢'=>'sai','揌'=>'sai','毢'=>'sai','毸'=>'sai','簺'=>'sai','腮'=>'sai','虄'=>'sai','賽'=>'sai','赛'=>'sai','顋'=>'sai','鰓'=>'sai','鳃'=>'sai','㗷'=>'sai','䈢'=>'sai','儅'=>'dang','党'=>'dang','凼'=>'dang','噹'=>'dang','圵'=>'dang','垱'=>'dang','壋'=>'dang','婸'=>'dang','宕'=>'dang','当'=>'dang','挡'=>'dang','擋'=>'dang','攩'=>'dang','档'=>'dang','檔'=>'dang','欓'=>'dang','氹'=>'dang','潒'=>'dang','澢'=>'dang','灙'=>'dang','珰'=>'dang','璗'=>'dang','璫'=>'dang','瓽'=>'dang','當'=>'dang','盪'=>'dang','瞊'=>'dang','砀'=>'dang','碭'=>'dang','礑'=>'dang','筜'=>'dang','簜'=>'dang','簹'=>'dang','艡'=>'dang','荡'=>'dang','菪'=>'dang','蕩'=>'dang','蘯'=>'dang','蟷'=>'dang','裆'=>'dang','襠'=>'dang','譡'=>'dang','讜'=>'dang','谠'=>'dang','趤'=>'dang','逿'=>'dang','闣'=>'dang','雼'=>'dang','黨'=>'dang','䑗'=>'dang','䣊'=>'dang','䣣'=>'dang','䦒'=>'dang','儇'=>'xuan','吅'=>'xuan','咺'=>'xuan','喧'=>'xuan','塇'=>'xuan','媗'=>'xuan','嫙'=>'xuan','嬛'=>'xuan','宣'=>'xuan','怰'=>'xuan','悬'=>'xuan','愃'=>'xuan','愋'=>'xuan','懸'=>'xuan','揎'=>'xuan','旋'=>'xuan','昍'=>'xuan','昡'=>'xuan','晅'=>'xuan','暄'=>'xuan','暅'=>'xuan','暶'=>'xuan','梋'=>'xuan','楥'=>'xuan','楦'=>'xuan','檈'=>'xuan','泫'=>'xuan','渲'=>'xuan','漩'=>'xuan','炫'=>'xuan','烜'=>'xuan','煊'=>'xuan','玄'=>'xuan','玹'=>'xuan','琁'=>'xuan','琄'=>'xuan','瑄'=>'xuan','璇'=>'xuan','璿'=>'xuan','痃'=>'xuan','癣'=>'xuan','癬'=>'xuan','眩'=>'xuan','眴'=>'xuan','睻'=>'xuan','矎'=>'xuan','碹'=>'xuan','禤'=>'xuan','箮'=>'xuan','絢'=>'xuan','縼'=>'xuan','繏'=>'xuan','绚'=>'xuan','翧'=>'xuan','翾'=>'xuan','萱'=>'xuan','萲'=>'xuan','蓒'=>'xuan','蔙'=>'xuan','蕿'=>'xuan','藼'=>'xuan','蘐'=>'xuan','蜁'=>'xuan','蝖'=>'xuan','蠉'=>'xuan','衒'=>'xuan','袨'=>'xuan','諠'=>'xuan','諼'=>'xuan','譞'=>'xuan','讂'=>'xuan','谖'=>'xuan','贙'=>'xuan','軒'=>'xuan','轩'=>'xuan','选'=>'xuan','選'=>'xuan','鉉'=>'xuan','鍹'=>'xuan','鏇'=>'xuan','铉'=>'xuan','镟'=>'xuan','鞙'=>'xuan','颴'=>'xuan','駽'=>'xuan','鰚'=>'xuan','㘣'=>'xuan','㧦'=>'xuan','㳙'=>'xuan','㳬'=>'xuan','㹡'=>'xuan','㾌'=>'xuan','䁢'=>'xuan','䍗'=>'xuan','䍻'=>'xuan','䗠'=>'xuan','䘩'=>'xuan','䝮'=>'xuan','䠣'=>'xuan','䧎'=>'xuan','䩙'=>'xuan','䩰'=>'xuan','䮄'=>'xuan','䲂'=>'xuan','䲻'=>'xuan','䴉'=>'xuan','䴋'=>'xuan','儓'=>'tai','冭'=>'tai','台'=>'tai','囼'=>'tai','坮'=>'tai','太'=>'tai','夳'=>'tai','嬯'=>'tai','孡'=>'tai','忲'=>'tai','态'=>'tai','態'=>'tai','抬'=>'tai','擡'=>'tai','旲'=>'tai','檯'=>'tai','汰'=>'tai','泰'=>'tai','溙'=>'tai','炱'=>'tai','炲'=>'tai','燤'=>'tai','珆'=>'tai','箈'=>'tai','籉'=>'tai','粏'=>'tai','肽'=>'tai','胎'=>'tai','臺'=>'tai','舦'=>'tai','苔'=>'tai','菭'=>'tai','薹'=>'tai','跆'=>'tai','邰'=>'tai','酞'=>'tai','鈦'=>'tai','钛'=>'tai','颱'=>'tai','駘'=>'tai','骀'=>'tai','鮐'=>'tai','鲐'=>'tai','㑷'=>'tai','㒗'=>'tai','㘆'=>'tai','㙵'=>'tai','㣍'=>'tai','㥭'=>'tai','㬃'=>'tai','㷘'=>'tai','㸀'=>'tai','䈚'=>'tai','䑓'=>'tai','䢰'=>'tai','䣭'=>'tai','儖'=>'lan','兰'=>'lan','厱'=>'lan','嚂'=>'lan','囒'=>'lan','壈'=>'lan','壏'=>'lan','婪'=>'lan','嬾'=>'lan','孄'=>'lan','孏'=>'lan','岚'=>'lan','嵐'=>'lan','幱'=>'lan','懒'=>'lan','懢'=>'lan','懶'=>'lan','拦'=>'lan','揽'=>'lan','擥'=>'lan','攔'=>'lan','攬'=>'lan','斓'=>'lan','斕'=>'lan','栏'=>'lan','榄'=>'lan','欄'=>'lan','欖'=>'lan','欗'=>'lan','浨'=>'lan','滥'=>'lan','漤'=>'lan','澜'=>'lan','濫'=>'lan','瀾'=>'lan','灆'=>'lan','灠'=>'lan','灡'=>'lan','烂'=>'lan','燗'=>'lan','燣'=>'lan','爁'=>'lan','爛'=>'lan','爤'=>'lan','爦'=>'lan','璼'=>'lan','瓓'=>'lan','礷'=>'lan','篮'=>'lan','籃'=>'lan','籣'=>'lan','糷'=>'lan','繿'=>'lan','纜'=>'lan','缆'=>'lan','罱'=>'lan','葻'=>'lan','蓝'=>'lan','蓞'=>'lan','藍'=>'lan','蘭'=>'lan','褴'=>'lan','襕'=>'lan','襤'=>'lan','襴'=>'lan','襽'=>'lan','覧'=>'lan','覽'=>'lan','览'=>'lan','譋'=>'lan','讕'=>'lan','谰'=>'lan','躝'=>'lan','醂'=>'lan','鑭'=>'lan','钄'=>'lan','镧'=>'lan','闌'=>'lan','阑'=>'lan','韊'=>'lan','㑣'=>'lan','㘓'=>'lan','㛦'=>'lan','㜮'=>'lan','㞩'=>'lan','㦨'=>'lan','㨫'=>'lan','㩜'=>'lan','㰖'=>'lan','㱫'=>'lan','㳕'=>'lan','䃹'=>'lan','䆾'=>'lan','䊖'=>'lan','䌫'=>'lan','䍀'=>'lan','䑌'=>'lan','䦨'=>'lan','䪍'=>'lan','䰐'=>'lan','䳿'=>'lan','儚'=>'meng','冡'=>'meng','勐'=>'meng','夢'=>'meng','夣'=>'meng','孟'=>'meng','幪'=>'meng','庬'=>'meng','懜'=>'meng','懞'=>'meng','懵'=>'meng','掹'=>'meng','擝'=>'meng','曚'=>'meng','朦'=>'meng','梦'=>'meng','橗'=>'meng','檬'=>'meng','氋'=>'meng','溕'=>'meng','濛'=>'meng','猛'=>'meng','獴'=>'meng','瓾'=>'meng','甍'=>'meng','甿'=>'meng','盟'=>'meng','瞢'=>'meng','矇'=>'meng','矒'=>'meng','礞'=>'meng','罞'=>'meng','艋'=>'meng','艨'=>'meng','莔'=>'meng','萌'=>'meng','萠'=>'meng','蒙'=>'meng','蕄'=>'meng','虻'=>'meng','蜢'=>'meng','蝱'=>'meng','蠓'=>'meng','鄳'=>'meng','鄸'=>'meng','錳'=>'meng','锰'=>'meng','雺'=>'meng','霥'=>'meng','霿'=>'meng','靀'=>'meng','顭'=>'meng','饛'=>'meng','鯍'=>'meng','鯭'=>'meng','鸏'=>'meng','鹲'=>'meng','鼆'=>'meng','㙹'=>'meng','㚞'=>'meng','㜴'=>'meng','㝱'=>'meng','㠓'=>'meng','㩚'=>'meng','䀄'=>'meng','䇇'=>'meng','䉚'=>'meng','䏵'=>'meng','䑃'=>'meng','䑅'=>'meng','䒐'=>'meng','䓝'=>'meng','䗈'=>'meng','䙦'=>'meng','䙩'=>'meng','䠢'=>'meng','䤓'=>'meng','䥂'=>'meng','䥰'=>'meng','䰒'=>'meng','䲛'=>'meng','䴌'=>'meng','䴿'=>'meng','䵆'=>'meng','儝'=>'qiong','卭'=>'qiong','宆'=>'qiong','惸'=>'qiong','憌'=>'qiong','桏'=>'qiong','橩'=>'qiong','焪'=>'qiong','焭'=>'qiong','煢'=>'qiong','熍'=>'qiong','琼'=>'qiong','璚'=>'qiong','瓊'=>'qiong','瓗'=>'qiong','睘'=>'qiong','瞏'=>'qiong','穷'=>'qiong','穹'=>'qiong','窮'=>'qiong','竆'=>'qiong','笻'=>'qiong','筇'=>'qiong','舼'=>'qiong','茕'=>'qiong','藑'=>'qiong','藭'=>'qiong','蛩'=>'qiong','蛬'=>'qiong','赹'=>'qiong','跫'=>'qiong','邛'=>'qiong','銎'=>'qiong','㒌'=>'qiong','㧭'=>'qiong','㮪'=>'qiong','㷀'=>'qiong','㼇'=>'qiong','䅃'=>'qiong','䆳'=>'qiong','䊄'=>'qiong','䓖'=>'qiong','䛪'=>'qiong','䠻'=>'qiong','儠'=>'lie','冽'=>'lie','列'=>'lie','劣'=>'lie','劽'=>'lie','咧'=>'lie','埒'=>'lie','埓'=>'lie','姴'=>'lie','峢'=>'lie','巤'=>'lie','挒'=>'lie','挘'=>'lie','捩'=>'lie','擸'=>'lie','毟'=>'lie','洌'=>'lie','浖'=>'lie','烈'=>'lie','烮'=>'lie','煭'=>'lie','犣'=>'lie','猎'=>'lie','猟'=>'lie','獵'=>'lie','睙'=>'lie','聗'=>'lie','脟'=>'lie','茢'=>'lie','蛚'=>'lie','裂'=>'lie','趔'=>'lie','躐'=>'lie','迾'=>'lie','颲'=>'lie','鬛'=>'lie','鬣'=>'lie','鮤'=>'lie','鱲'=>'lie','鴷'=>'lie','㤠'=>'lie','㧜'=>'lie','㬯'=>'lie','㭞'=>'lie','㯿'=>'lie','㲱'=>'lie','㸹'=>'lie','㼲'=>'lie','㽟'=>'lie','䁽'=>'lie','䅀'=>'lie','䉭'=>'lie','䓟'=>'lie','䜲'=>'lie','䟩'=>'lie','䟹'=>'lie','䢪'=>'lie','䴕'=>'lie','儣'=>'kuang','况'=>'kuang','劻'=>'kuang','匡'=>'kuang','匩'=>'kuang','哐'=>'kuang','圹'=>'kuang','壙'=>'kuang','夼'=>'kuang','岲'=>'kuang','恇'=>'kuang','懬'=>'kuang','懭'=>'kuang','抂'=>'kuang','旷'=>'kuang','昿'=>'kuang','曠'=>'kuang','框'=>'kuang','況'=>'kuang','洭'=>'kuang','爌'=>'kuang','狂'=>'kuang','狅'=>'kuang','眖'=>'kuang','眶'=>'kuang','矌'=>'kuang','矿'=>'kuang','砿'=>'kuang','礦'=>'kuang','穬'=>'kuang','筐'=>'kuang','筺'=>'kuang','絋'=>'kuang','絖'=>'kuang','纊'=>'kuang','纩'=>'kuang','誆'=>'kuang','誑'=>'kuang','诓'=>'kuang','诳'=>'kuang','貺'=>'kuang','贶'=>'kuang','軖'=>'kuang','軠'=>'kuang','軦'=>'kuang','軭'=>'kuang','邝'=>'kuang','邼'=>'kuang','鄺'=>'kuang','鉱'=>'kuang','鋛'=>'kuang','鑛'=>'kuang','鵟'=>'kuang','黋'=>'kuang','㤮'=>'kuang','䊯'=>'kuang','䵃'=>'kuang','儭'=>'chen','嗔'=>'chen','嚫'=>'chen','塵'=>'chen','墋'=>'chen','夦'=>'chen','宸'=>'chen','尘'=>'chen','忱'=>'chen','愖'=>'chen','抻'=>'chen','揨'=>'chen','敐'=>'chen','晨'=>'chen','曟'=>'chen','棽'=>'chen','榇'=>'chen','樄'=>'chen','櫬'=>'chen','沉'=>'chen','烥'=>'chen','煁'=>'chen','琛'=>'chen','疢'=>'chen','瘎'=>'chen','瞋'=>'chen','硶'=>'chen','碜'=>'chen','磣'=>'chen','稱'=>'chen','綝'=>'chen','臣'=>'chen','茞'=>'chen','莀'=>'chen','莐'=>'chen','蔯'=>'chen','薼'=>'chen','螴'=>'chen','衬'=>'chen','襯'=>'chen','訦'=>'chen','諃'=>'chen','諶'=>'chen','謓'=>'chen','讖'=>'chen','谌'=>'chen','谶'=>'chen','賝'=>'chen','贂'=>'chen','趁'=>'chen','趂'=>'chen','趻'=>'chen','踸'=>'chen','軙'=>'chen','辰'=>'chen','迧'=>'chen','郴'=>'chen','鈂'=>'chen','陈'=>'chen','陳'=>'chen','霃'=>'chen','鷐'=>'chen','麎'=>'chen','齓'=>'chen','齔'=>'chen','龀'=>'chen','㕴'=>'chen','㧱'=>'chen','㫳'=>'chen','㲀'=>'chen','㴴'=>'chen','㽸'=>'chen','䆣'=>'chen','䒞'=>'chen','䚘'=>'chen','䜟'=>'chen','䞋'=>'chen','䟢'=>'chen','䢅'=>'chen','䢈'=>'chen','䢻'=>'chen','䣅'=>'chen','䤟'=>'chen','䫖'=>'chen','儯'=>'teng','唞'=>'teng','幐'=>'teng','朰'=>'teng','滕'=>'teng','漛'=>'teng','疼'=>'teng','痋'=>'teng','籐'=>'teng','籘'=>'teng','縢'=>'teng','腾'=>'teng','膯'=>'teng','藤'=>'teng','虅'=>'teng','螣'=>'teng','誊'=>'teng','謄'=>'teng','邆'=>'teng','霯'=>'teng','駦'=>'teng','騰'=>'teng','驣'=>'teng','鰧'=>'teng','鼟'=>'teng','䒅'=>'teng','䕨'=>'teng','䠮'=>'teng','䲍'=>'teng','䲢'=>'teng','儱'=>'long','咙'=>'long','哢'=>'long','嚨'=>'long','垄'=>'long','垅'=>'long','壟'=>'long','壠'=>'long','屸'=>'long','嶐'=>'long','巃'=>'long','巄'=>'long','徿'=>'long','拢'=>'long','攏'=>'long','昽'=>'long','曨'=>'long','朧'=>'long','栊'=>'long','梇'=>'long','槞'=>'long','櫳'=>'long','泷'=>'long','湰'=>'long','漋'=>'long','瀧'=>'long','爖'=>'long','珑'=>'long','瓏'=>'long','癃'=>'long','眬'=>'long','矓'=>'long','砻'=>'long','硦'=>'long','礱'=>'long','礲'=>'long','窿'=>'long','竉'=>'long','竜'=>'long','笼'=>'long','篭'=>'long','籠'=>'long','聋'=>'long','聾'=>'long','胧'=>'long','茏'=>'long','蕯'=>'long','蘢'=>'long','蠪'=>'long','蠬'=>'long','衖'=>'long','襱'=>'long','豅'=>'long','贚'=>'long','躘'=>'long','鏧'=>'long','鑨'=>'long','陇'=>'long','隆'=>'long','隴'=>'long','霳'=>'long','靇'=>'long','驡'=>'long','鸗'=>'long','龍'=>'long','龒'=>'long','龓'=>'long','龙'=>'long','㑝'=>'long','㙙'=>'long','㚅'=>'long','㛞'=>'long','㝫'=>'long','㟖'=>'long','㡣'=>'long','㢅'=>'long','㦕'=>'long','㰍'=>'long','㴳'=>'long','䃧'=>'long','䏊'=>'long','䙪'=>'long','䡁'=>'long','䥢'=>'long','䪊'=>'long','儴'=>'rang','勷'=>'rang','嚷'=>'rang','壌'=>'rang','壤'=>'rang','懹'=>'rang','攘'=>'rang','瀼'=>'rang','爙'=>'rang','獽'=>'rang','瓤'=>'rang','禳'=>'rang','穣'=>'rang','穰'=>'rang','纕'=>'rang','蘘'=>'rang','譲'=>'rang','讓'=>'rang','让'=>'rang','躟'=>'rang','鬤'=>'rang','㚂'=>'rang','䉴'=>'rang','兄'=>'xiong','兇'=>'xiong','凶'=>'xiong','匈'=>'xiong','哅'=>'xiong','夐'=>'xiong','忷'=>'xiong','恟'=>'xiong','敻'=>'xiong','汹'=>'xiong','洶'=>'xiong','熊'=>'xiong','胷'=>'xiong','胸'=>'xiong','芎'=>'xiong','訩'=>'xiong','詗'=>'xiong','詾'=>'xiong','讻'=>'xiong','诇'=>'xiong','雄'=>'xiong','㐫'=>'xiong','䧺'=>'xiong','充'=>'chong','冲'=>'chong','嘃'=>'chong','埫'=>'chong','宠'=>'chong','寵'=>'chong','崇'=>'chong','崈'=>'chong','徸'=>'chong','忡'=>'chong','憃'=>'chong','憧'=>'chong','揰'=>'chong','摏'=>'chong','沖'=>'chong','浺'=>'chong','漴'=>'chong','爞'=>'chong','珫'=>'chong','緟'=>'chong','罿'=>'chong','翀'=>'chong','舂'=>'chong','艟'=>'chong','茺'=>'chong','虫'=>'chong','蝩'=>'chong','蟲'=>'chong','衝'=>'chong','褈'=>'chong','蹖'=>'chong','銃'=>'chong','铳'=>'chong','隀'=>'chong','㓽'=>'chong','㧤'=>'chong','㹐'=>'chong','䌬'=>'chong','䖝'=>'chong','䳯'=>'chong','兊'=>'dui','兌'=>'dui','兑'=>'dui','叾'=>'dui','垖'=>'dui','堆'=>'dui','塠'=>'dui','对'=>'dui','対'=>'dui','對'=>'dui','嵟'=>'dui','怼'=>'dui','憝'=>'dui','懟'=>'dui','濧'=>'dui','瀩'=>'dui','痽'=>'dui','碓'=>'dui','磓'=>'dui','祋'=>'dui','綐'=>'dui','薱'=>'dui','譈'=>'dui','譵'=>'dui','鐓'=>'dui','鐜'=>'dui','镦'=>'dui','队'=>'dui','陮'=>'dui','隊'=>'dui','頧'=>'dui','鴭'=>'dui','㙂'=>'dui','㟋'=>'dui','㠚'=>'dui','㬣'=>'dui','㳔'=>'dui','㵽'=>'dui','䇏'=>'dui','䇤'=>'dui','䔪'=>'dui','䨴'=>'dui','䨺'=>'dui','䬈'=>'dui','䬽'=>'dui','䯟'=>'dui','克'=>'ke','刻'=>'ke','剋'=>'ke','勀'=>'ke','勊'=>'ke','匼'=>'ke','可'=>'ke','咳'=>'ke','嗑'=>'ke','坷'=>'ke','堁'=>'ke','壳'=>'ke','娔'=>'ke','客'=>'ke','尅'=>'ke','岢'=>'ke','峇'=>'ke','嵑'=>'ke','嵙'=>'ke','嶱'=>'ke','恪'=>'ke','愙'=>'ke','揢'=>'ke','搕'=>'ke','敤'=>'ke','柯'=>'ke','棵'=>'ke','榼'=>'ke','樖'=>'ke','殻'=>'ke','氪'=>'ke','渇'=>'ke','渴'=>'ke','溘'=>'ke','炣'=>'ke','牁'=>'ke','犐'=>'ke','珂'=>'ke','疴'=>'ke','痾'=>'ke','瞌'=>'ke','碦'=>'ke','磕'=>'ke','礊'=>'ke','礚'=>'ke','科'=>'ke','稞'=>'ke','窠'=>'ke','緙'=>'ke','缂'=>'ke','翗'=>'ke','胢'=>'ke','苛'=>'ke','萪'=>'ke','薖'=>'ke','蝌'=>'ke','課'=>'ke','课'=>'ke','趷'=>'ke','軻'=>'ke','轲'=>'ke','醘'=>'ke','鈳'=>'ke','錁'=>'ke','钶'=>'ke','锞'=>'ke','頦'=>'ke','顆'=>'ke','颏'=>'ke','颗'=>'ke','騍'=>'ke','骒'=>'ke','髁'=>'ke','㕉'=>'ke','㞹'=>'ke','㤩'=>'ke','㪃'=>'ke','㪙'=>'ke','㪡'=>'ke','㪼'=>'ke','㰤'=>'ke','㵣'=>'ke','㾧'=>'ke','䙐'=>'ke','䶗'=>'ke','兎'=>'tu','兔'=>'tu','凃'=>'tu','凸'=>'tu','吐'=>'tu','唋'=>'tu','図'=>'tu','图'=>'tu','圖'=>'tu','圗'=>'tu','土'=>'tu','圡'=>'tu','堍'=>'tu','堗'=>'tu','塗'=>'tu','屠'=>'tu','峹'=>'tu','嵞'=>'tu','嶀'=>'tu','庩'=>'tu','廜'=>'tu','徒'=>'tu','怢'=>'tu','悇'=>'tu','捈'=>'tu','捸'=>'tu','揬'=>'tu','梌'=>'tu','汢'=>'tu','涂'=>'tu','涋'=>'tu','湥'=>'tu','潳'=>'tu','痜'=>'tu','瘏'=>'tu','禿'=>'tu','秃'=>'tu','稌'=>'tu','突'=>'tu','筡'=>'tu','腯'=>'tu','荼'=>'tu','莵'=>'tu','菟'=>'tu','葖'=>'tu','蒤'=>'tu','跿'=>'tu','迌'=>'tu','途'=>'tu','酴'=>'tu','釷'=>'tu','鈯'=>'tu','鋵'=>'tu','鍎'=>'tu','钍'=>'tu','馟'=>'tu','駼'=>'tu','鵌'=>'tu','鵚'=>'tu','鵵'=>'tu','鶟'=>'tu','鷋'=>'tu','鷵'=>'tu','鼵'=>'tu','㭸'=>'tu','㻌'=>'tu','㻠'=>'tu','㻬'=>'tu','㻯'=>'tu','䅷'=>'tu','䖘'=>'tu','䠈'=>'tu','䣄'=>'tu','䣝'=>'tu','䤅'=>'tu','䳜'=>'tu','兛'=>'qiang','呛'=>'qiang','唴'=>'qiang','嗆'=>'qiang','嗴'=>'qiang','墏'=>'qiang','墙'=>'qiang','墻'=>'qiang','嫱'=>'qiang','嬙'=>'qiang','嶈'=>'qiang','廧'=>'qiang','強'=>'qiang','强'=>'qiang','戕'=>'qiang','戗'=>'qiang','戧'=>'qiang','抢'=>'qiang','搶'=>'qiang','摤'=>'qiang','斨'=>'qiang','枪'=>'qiang','椌'=>'qiang','槍'=>'qiang','樯'=>'qiang','檣'=>'qiang','溬'=>'qiang','漒'=>'qiang','炝'=>'qiang','熗'=>'qiang','牄'=>'qiang','牆'=>'qiang','猐'=>'qiang','獇'=>'qiang','玱'=>'qiang','琷'=>'qiang','瑲'=>'qiang','瓩'=>'qiang','篬'=>'qiang','繈'=>'qiang','繦'=>'qiang','羌'=>'qiang','羗'=>'qiang','羟'=>'qiang','羥'=>'qiang','羫'=>'qiang','羻'=>'qiang','腔'=>'qiang','艢'=>'qiang','蔃'=>'qiang','蔷'=>'qiang','薔'=>'qiang','蘠'=>'qiang','蜣'=>'qiang','襁'=>'qiang','謒'=>'qiang','跄'=>'qiang','蹌'=>'qiang','蹡'=>'qiang','錆'=>'qiang','鎗'=>'qiang','鏘'=>'qiang','鏹'=>'qiang','锖'=>'qiang','锵'=>'qiang','镪'=>'qiang','㛨'=>'qiang','㩖'=>'qiang','䅚'=>'qiang','䵁'=>'qiang','內'=>'nei','内'=>'nei','娞'=>'nei','氝'=>'nei','焾'=>'nei','腇'=>'nei','餒'=>'nei','馁'=>'nei','鮾'=>'nei','鯘'=>'nei','㕯'=>'nei','㖏'=>'nei','㘨'=>'nei','㨅'=>'nei','㼏'=>'nei','䡾'=>'nei','䲎'=>'nei','䳖'=>'nei','六'=>'liu','刘'=>'liu','劉'=>'liu','嚠'=>'liu','囖'=>'liu','塯'=>'liu','媹'=>'liu','嬼'=>'liu','嵧'=>'liu','廇'=>'liu','懰'=>'liu','旈'=>'liu','旒'=>'liu','柳'=>'liu','栁'=>'liu','桞'=>'liu','桺'=>'liu','榴'=>'liu','橊'=>'liu','橮'=>'liu','沠'=>'liu','流'=>'liu','浏'=>'liu','溜'=>'liu','澑'=>'liu','瀏'=>'liu','熘'=>'liu','熮'=>'liu','珋'=>'liu','琉'=>'liu','瑠'=>'liu','瑬'=>'liu','璢'=>'liu','瓼'=>'liu','甅'=>'liu','畄'=>'liu','留'=>'liu','畱'=>'liu','疁'=>'liu','瘤'=>'liu','癅'=>'liu','硫'=>'liu','磂'=>'liu','磟'=>'liu','綹'=>'liu','绺'=>'liu','罶'=>'liu','羀'=>'liu','翏'=>'liu','蒥'=>'liu','蓅'=>'liu','藰'=>'liu','蟉'=>'liu','裗'=>'liu','蹓'=>'liu','遛'=>'liu','鋶'=>'liu','鎏'=>'liu','鎦'=>'liu','鏐'=>'liu','鐂'=>'liu','锍'=>'liu','镏'=>'liu','镠'=>'liu','雡'=>'liu','霤'=>'liu','飀'=>'liu','飂'=>'liu','飅'=>'liu','飗'=>'liu','餾'=>'liu','馏'=>'liu','駠'=>'liu','駵'=>'liu','騮'=>'liu','驑'=>'liu','骝'=>'liu','鬸'=>'liu','鰡'=>'liu','鶹'=>'liu','鷚'=>'liu','鹠'=>'liu','鹨'=>'liu','麍'=>'liu','㐬'=>'liu','㙀'=>'liu','㨨'=>'liu','㶯'=>'liu','㽌'=>'liu','㽞'=>'liu','䄂'=>'liu','䉧'=>'liu','䋷'=>'liu','䗜'=>'liu','䚧'=>'liu','䬟'=>'liu','䭷'=>'liu','䰘'=>'liu','䱖'=>'liu','䱞'=>'liu','䶉'=>'liu','兺'=>'pou','咅'=>'pou','哛'=>'pou','哣'=>'pou','堷'=>'pou','婄'=>'pou','抔'=>'pou','抙'=>'pou','捊'=>'pou','掊'=>'pou','犃'=>'pou','箁'=>'pou','裒'=>'pou','颒'=>'pou','㕻'=>'pou','㧵'=>'pou','兽'=>'shou','収'=>'shou','受'=>'shou','售'=>'shou','垨'=>'shou','壽'=>'shou','夀'=>'shou','守'=>'shou','寿'=>'shou','手'=>'shou','扌'=>'shou','授'=>'shou','收'=>'shou','涭'=>'shou','狩'=>'shou','獣'=>'shou','獸'=>'shou','痩'=>'shou','瘦'=>'shou','綬'=>'shou','绶'=>'shou','膄'=>'shou','艏'=>'shou','鏉'=>'shou','首'=>'shou','㖟'=>'shou','㝊'=>'shou','㥅'=>'shou','䛵'=>'shou','䭭'=>'shou','冃'=>'mao','冇'=>'mao','冐'=>'mao','冒'=>'mao','卯'=>'mao','唜'=>'mao','堥'=>'mao','夘'=>'mao','媢'=>'mao','峁'=>'mao','帽'=>'mao','愗'=>'mao','懋'=>'mao','戼'=>'mao','旄'=>'mao','昴'=>'mao','暓'=>'mao','枆'=>'mao','楙'=>'mao','毛'=>'mao','毜'=>'mao','毝'=>'mao','毷'=>'mao','泖'=>'mao','渵'=>'mao','牦'=>'mao','猫'=>'mao','瑁'=>'mao','皃'=>'mao','眊'=>'mao','瞀'=>'mao','矛'=>'mao','笷'=>'mao','緢'=>'mao','耄'=>'mao','芼'=>'mao','茂'=>'mao','茅'=>'mao','茆'=>'mao','蓩'=>'mao','蛑'=>'mao','蝐'=>'mao','蝥'=>'mao','蟊'=>'mao','袤'=>'mao','覒'=>'mao','貌'=>'mao','貓'=>'mao','貿'=>'mao','贸'=>'mao','軞'=>'mao','鄚'=>'mao','鄮'=>'mao','酕'=>'mao','鉚'=>'mao','錨'=>'mao','铆'=>'mao','锚'=>'mao','髦'=>'mao','髳'=>'mao','鶜'=>'mao','㒵'=>'mao','㒻'=>'mao','㚹'=>'mao','㝟'=>'mao','㡌'=>'mao','㧇'=>'mao','㧌'=>'mao','㪞'=>'mao','㫯'=>'mao','㮘'=>'mao','㲠'=>'mao','㴘'=>'mao','㺺'=>'mao','㿞'=>'mao','䀤'=>'mao','䅦'=>'mao','䋃'=>'mao','䓮'=>'mao','䡚'=>'mao','䫉'=>'mao','冄'=>'ran','冉'=>'ran','呥'=>'ran','嘫'=>'ran','姌'=>'ran','媣'=>'ran','染'=>'ran','橪'=>'ran','然'=>'ran','燃'=>'ran','珃'=>'ran','繎'=>'ran','肰'=>'ran','苒'=>'ran','蒅'=>'ran','蚦'=>'ran','蚺'=>'ran','衻'=>'ran','袇'=>'ran','袡'=>'ran','髥'=>'ran','髯'=>'ran','㚩'=>'ran','㜣'=>'ran','㯗'=>'ran','㲯'=>'ran','㸐'=>'ran','㾆'=>'ran','㿵'=>'ran','䎃'=>'ran','䑙'=>'ran','䒣'=>'ran','䖄'=>'ran','䡮'=>'ran','䣸'=>'ran','䤡'=>'ran','䫇'=>'ran','冈'=>'gang','冮'=>'gang','刚'=>'gang','剛'=>'gang','堈'=>'gang','堽'=>'gang','岗'=>'gang','岡'=>'gang','崗'=>'gang','戆'=>'gang','戇'=>'gang','掆'=>'gang','杠'=>'gang','棡'=>'gang','槓'=>'gang','港'=>'gang','焵'=>'gang','牨'=>'gang','犅'=>'gang','疘'=>'gang','矼'=>'gang','筻'=>'gang','綱'=>'gang','纲'=>'gang','缸'=>'gang','罁'=>'gang','罓'=>'gang','罡'=>'gang','肛'=>'gang','釭'=>'gang','鋼'=>'gang','鎠'=>'gang','钢'=>'gang','阬'=>'gang','㟠'=>'gang','㟵'=>'gang','㽘'=>'gang','䴚'=>'gang','冎'=>'gua','刮'=>'gua','剐'=>'gua','剮'=>'gua','劀'=>'gua','卦'=>'gua','叧'=>'gua','呱'=>'gua','啩'=>'gua','坬'=>'gua','寡'=>'gua','挂'=>'gua','掛'=>'gua','歄'=>'gua','焻'=>'gua','煱'=>'gua','瓜'=>'gua','絓'=>'gua','緺'=>'gua','罣'=>'gua','罫'=>'gua','胍'=>'gua','苽'=>'gua','褂'=>'gua','詿'=>'gua','诖'=>'gua','趏'=>'gua','銽'=>'gua','颪'=>'gua','颳'=>'gua','騧'=>'gua','鴰'=>'gua','鸹'=>'gua','㒷'=>'gua','䈑'=>'gua','冦'=>'kou','剾'=>'kou','劶'=>'kou','口'=>'kou','叩'=>'kou','宼'=>'kou','寇'=>'kou','廤'=>'kou','彄'=>'kou','怐'=>'kou','扣'=>'kou','抠'=>'kou','摳'=>'kou','敂'=>'kou','滱'=>'kou','眍'=>'kou','瞉'=>'kou','瞘'=>'kou','窛'=>'kou','筘'=>'kou','簆'=>'kou','芤'=>'kou','蔲'=>'kou','蔻'=>'kou','釦'=>'kou','鷇'=>'kou','㓂'=>'kou','㔚'=>'kou','㰯'=>'kou','㲄'=>'kou','㽛'=>'kou','䳟'=>'kou','䳹'=>'kou','冸'=>'pan','判'=>'pan','叛'=>'pan','坢'=>'pan','媻'=>'pan','幋'=>'pan','搫'=>'pan','攀'=>'pan','柈'=>'pan','槃'=>'pan','沜'=>'pan','泮'=>'pan','溿'=>'pan','潘'=>'pan','瀊'=>'pan','炍'=>'pan','爿'=>'pan','牉'=>'pan','畔'=>'pan','畨'=>'pan','盘'=>'pan','盤'=>'pan','盼'=>'pan','眅'=>'pan','磐'=>'pan','縏'=>'pan','蒰'=>'pan','蟠'=>'pan','袢'=>'pan','襻'=>'pan','詊'=>'pan','跘'=>'pan','蹒'=>'pan','蹣'=>'pan','鋬'=>'pan','鎜'=>'pan','鑻'=>'pan','鞶'=>'pan','頖'=>'pan','鵥'=>'pan','㐴'=>'pan','㳪'=>'pan','䃑'=>'pan','䃲'=>'pan','䈲'=>'pan','䰉'=>'pan','䰔'=>'pan','冾'=>'qia','圶'=>'qia','帢'=>'qia','恰'=>'qia','愘'=>'qia','拤'=>'qia','掐'=>'qia','殎'=>'qia','洽'=>'qia','硈'=>'qia','葜'=>'qia','跒'=>'qia','酠'=>'qia','鞐'=>'qia','髂'=>'qia','㓣'=>'qia','㡊'=>'qia','㤉'=>'qia','䜑'=>'qia','䠍'=>'qia','䨐'=>'qia','䯊'=>'qia','䶝'=>'qia','凂'=>'mei','呅'=>'mei','嚜'=>'mei','堳'=>'mei','塺'=>'mei','妹'=>'mei','媄'=>'mei','媒'=>'mei','媚'=>'mei','媺'=>'mei','嬍'=>'mei','寐'=>'mei','嵄'=>'mei','嵋'=>'mei','徾'=>'mei','抺'=>'mei','挴'=>'mei','攗'=>'mei','攟'=>'mei','昧'=>'mei','枚'=>'mei','栂'=>'mei','梅'=>'mei','楣'=>'mei','楳'=>'mei','槑'=>'mei','毎'=>'mei','每'=>'mei','沒'=>'mei','没'=>'mei','沬'=>'mei','浼'=>'mei','渼'=>'mei','湄'=>'mei','湈'=>'mei','煝'=>'mei','煤'=>'mei','燘'=>'mei','猸'=>'mei','玫'=>'mei','珻'=>'mei','瑂'=>'mei','痗'=>'mei','眉'=>'mei','眛'=>'mei','睂'=>'mei','睸'=>'mei','矀'=>'mei','祙'=>'mei','禖'=>'mei','篃'=>'mei','美'=>'mei','脄'=>'mei','脢'=>'mei','腜'=>'mei','苺'=>'mei','莓'=>'mei','葿'=>'mei','蘪'=>'mei','蝞'=>'mei','袂'=>'mei','跊'=>'mei','躾'=>'mei','郿'=>'mei','酶'=>'mei','鋂'=>'mei','鎂'=>'mei','鎇'=>'mei','镁'=>'mei','镅'=>'mei','霉'=>'mei','韎'=>'mei','鬽'=>'mei','魅'=>'mei','鶥'=>'mei','鹛'=>'mei','黣'=>'mei','黴'=>'mei','㭑'=>'mei','㶬'=>'mei','㺳'=>'mei','䀛'=>'mei','䆀'=>'mei','䉋'=>'mei','䊈'=>'mei','䊊'=>'mei','䍙'=>'mei','䒽'=>'mei','䓺'=>'mei','䜸'=>'mei','䤂'=>'mei','䰨'=>'mei','䰪'=>'mei','䵢'=>'mei','准'=>'zhun','凖'=>'zhun','埻'=>'zhun','宒'=>'zhun','準'=>'zhun','稕'=>'zhun','窀'=>'zhun','綧'=>'zhun','肫'=>'zhun','衠'=>'zhun','訰'=>'zhun','諄'=>'zhun','谆'=>'zhun','迍'=>'zhun','凑'=>'cou','楱'=>'cou','湊'=>'cou','腠'=>'cou','輳'=>'cou','辏'=>'cou','㫶'=>'cou','凟'=>'du','剢'=>'du','匵'=>'du','厾'=>'du','嘟'=>'du','堵'=>'du','妒'=>'du','妬'=>'du','嬻'=>'du','帾'=>'du','度'=>'du','杜'=>'du','椟'=>'du','櫝'=>'du','殬'=>'du','殰'=>'du','毒'=>'du','涜'=>'du','渎'=>'du','渡'=>'du','瀆'=>'du','牍'=>'du','牘'=>'du','犊'=>'du','犢'=>'du','独'=>'du','獨'=>'du','琽'=>'du','瓄'=>'du','皾'=>'du','督'=>'du','睹'=>'du','秺'=>'du','笃'=>'du','篤'=>'du','肚'=>'du','芏'=>'du','荰'=>'du','蝳'=>'du','螙'=>'du','蠧'=>'du','蠹'=>'du','裻'=>'du','覩'=>'du','読'=>'du','讀'=>'du','讟'=>'du','读'=>'du','豄'=>'du','賭'=>'du','贕'=>'du','赌'=>'du','都'=>'du','醏'=>'du','錖'=>'du','鍍'=>'du','鑟'=>'du','镀'=>'du','闍'=>'du','阇'=>'du','靯'=>'du','韇'=>'du','韣'=>'du','韥'=>'du','騳'=>'du','髑'=>'du','黩'=>'du','黷'=>'du','㱩'=>'du','㸿'=>'du','㾄'=>'du','䀾'=>'du','䄍'=>'du','䅊'=>'du','䈞'=>'du','䐗'=>'du','䓯'=>'du','䙱'=>'du','䟻'=>'du','䢱'=>'du','䪅'=>'du','䫳'=>'du','䮷'=>'du','䲧'=>'du','刌'=>'cun','吋'=>'cun','墫'=>'cun','存'=>'cun','寸'=>'cun','忖'=>'cun','拵'=>'cun','村'=>'cun','澊'=>'cun','皴'=>'cun','竴'=>'cun','籿'=>'cun','踆'=>'cun','邨'=>'cun','䍎'=>'cun','刎'=>'wen','吻'=>'wen','呚'=>'wen','呡'=>'wen','問'=>'wen','塭'=>'wen','妏'=>'wen','彣'=>'wen','忟'=>'wen','抆'=>'wen','揾'=>'wen','搵'=>'wen','文'=>'wen','桽'=>'wen','榅'=>'wen','榲'=>'wen','殟'=>'wen','汶'=>'wen','渂'=>'wen','温'=>'wen','溫'=>'wen','炆'=>'wen','珳'=>'wen','瑥'=>'wen','璺'=>'wen','瘒'=>'wen','瘟'=>'wen','砇'=>'wen','稳'=>'wen','穏'=>'wen','穩'=>'wen','紊'=>'wen','紋'=>'wen','絻'=>'wen','纹'=>'wen','聞'=>'wen','肳'=>'wen','脕'=>'wen','脗'=>'wen','芠'=>'wen','莬'=>'wen','蚉'=>'wen','蚊'=>'wen','螡'=>'wen','蟁'=>'wen','豱'=>'wen','輼'=>'wen','轀'=>'wen','辒'=>'wen','鈫'=>'wen','鎾'=>'wen','閺'=>'wen','閿'=>'wen','闅'=>'wen','闦'=>'wen','闧'=>'wen','问'=>'wen','闻'=>'wen','阌'=>'wen','雯'=>'wen','顐'=>'wen','饂'=>'wen','馼'=>'wen','魰'=>'wen','鰛'=>'wen','鰮'=>'wen','鳁'=>'wen','鳼'=>'wen','鴍'=>'wen','鼤'=>'wen','㒚'=>'wen','㖧'=>'wen','㗃'=>'wen','㝧'=>'wen','㳷'=>'wen','䎹'=>'wen','䎽'=>'wen','䘇'=>'wen','䰚'=>'wen','划'=>'hua','劃'=>'hua','化'=>'hua','华'=>'hua','哗'=>'hua','嘩'=>'hua','埖'=>'hua','姡'=>'hua','婲'=>'hua','婳'=>'hua','嫿'=>'hua','嬅'=>'hua','崋'=>'hua','摦'=>'hua','撶'=>'hua','杹'=>'hua','桦'=>'hua','椛'=>'hua','槬'=>'hua','樺'=>'hua','滑'=>'hua','澅'=>'hua','猾'=>'hua','璍'=>'hua','画'=>'hua','畫'=>'hua','畵'=>'hua','硴'=>'hua','磆'=>'hua','糀'=>'hua','繣'=>'hua','舙'=>'hua','花'=>'hua','芲'=>'hua','華'=>'hua','蕐'=>'hua','蘤'=>'hua','蘳'=>'hua','螖'=>'hua','觟'=>'hua','話'=>'hua','誮'=>'hua','諙'=>'hua','諣'=>'hua','譁'=>'hua','话'=>'hua','鋘'=>'hua','錵'=>'hua','鏵'=>'hua','铧'=>'hua','驊'=>'hua','骅'=>'hua','鷨'=>'hua','黊'=>'hua','㓰'=>'hua','㕦'=>'hua','㕲'=>'hua','㕷'=>'hua','㚌'=>'hua','㟆'=>'hua','㠏'=>'hua','㠢'=>'hua','㦊'=>'hua','㦎'=>'hua','㩇'=>'hua','㭉'=>'hua','㮯'=>'hua','䅿'=>'hua','䏦'=>'hua','䔢'=>'hua','䛡'=>'hua','䠉'=>'hua','䱻'=>'hua','䶤'=>'hua','刖'=>'yue','嬳'=>'yue','岄'=>'yue','岳'=>'yue','嶽'=>'yue','彟'=>'yue','彠'=>'yue','恱'=>'yue','悅'=>'yue','悦'=>'yue','戉'=>'yue','抈'=>'yue','捳'=>'yue','曰'=>'yue','曱'=>'yue','月'=>'yue','枂'=>'yue','樾'=>'yue','汋'=>'yue','瀹'=>'yue','爚'=>'yue','玥'=>'yue','矱'=>'yue','礿'=>'yue','禴'=>'yue','箹'=>'yue','篗'=>'yue','籆'=>'yue','籥'=>'yue','籰'=>'yue','粤'=>'yue','粵'=>'yue','約'=>'yue','约'=>'yue','蘥'=>'yue','蚎'=>'yue','蚏'=>'yue','越'=>'yue','跀'=>'yue','跃'=>'yue','躍'=>'yue','軏'=>'yue','鈅'=>'yue','鉞'=>'yue','钥'=>'yue','钺'=>'yue','閱'=>'yue','閲'=>'yue','阅'=>'yue','鸑'=>'yue','鸙'=>'yue','黦'=>'yue','龠'=>'yue','龥'=>'yue','㜧'=>'yue','㜰'=>'yue','㬦'=>'yue','㰛'=>'yue','㹊'=>'yue','䋐'=>'yue','䖃'=>'yue','䟠'=>'yue','䠯'=>'yue','䡇'=>'yue','䢁'=>'yue','䢲'=>'yue','䤦'=>'yue','䥃'=>'yue','䶳'=>'yue','別'=>'bie','别'=>'bie','咇'=>'bie','彆'=>'bie','徶'=>'bie','憋'=>'bie','瘪'=>'bie','癟'=>'bie','莂'=>'bie','虌'=>'bie','蛂'=>'bie','蟞'=>'bie','襒'=>'bie','蹩'=>'bie','鱉'=>'bie','鳖'=>'bie','鼈'=>'bie','龞'=>'bie','㢼'=>'bie','㿜'=>'bie','䉲'=>'bie','䋢'=>'bie','䏟'=>'bie','䠥'=>'bie','䭱'=>'bie','刨'=>'pao','匏'=>'pao','咆'=>'pao','垉'=>'pao','奅'=>'pao','庖'=>'pao','抛'=>'pao','拋'=>'pao','泡'=>'pao','炮'=>'pao','炰'=>'pao','爮'=>'pao','狍'=>'pao','疱'=>'pao','皰'=>'pao','砲'=>'pao','礟'=>'pao','礮'=>'pao','脬'=>'pao','萢'=>'pao','蚫'=>'pao','袍'=>'pao','褜'=>'pao','跑'=>'pao','軳'=>'pao','鞄'=>'pao','麅'=>'pao','麭'=>'pao','㘐'=>'pao','㚿'=>'pao','㯡'=>'pao','䛌'=>'pao','䩝'=>'pao','䶌'=>'pao','刷'=>'shua','唰'=>'shua','耍'=>'shua','誜'=>'shua','剉'=>'cuo','剒'=>'cuo','厝'=>'cuo','夎'=>'cuo','嵯'=>'cuo','嵳'=>'cuo','挫'=>'cuo','措'=>'cuo','搓'=>'cuo','撮'=>'cuo','棤'=>'cuo','瑳'=>'cuo','痤'=>'cuo','睉'=>'cuo','矬'=>'cuo','磋'=>'cuo','脞'=>'cuo','莝'=>'cuo','莡'=>'cuo','蒫'=>'cuo','蓌'=>'cuo','蔖'=>'cuo','虘'=>'cuo','蹉'=>'cuo','逪'=>'cuo','遳'=>'cuo','醝'=>'cuo','銼'=>'cuo','錯'=>'cuo','锉'=>'cuo','错'=>'cuo','髊'=>'cuo','鹺'=>'cuo','鹾'=>'cuo','齹'=>'cuo','㟇'=>'cuo','㽨'=>'cuo','䂳'=>'cuo','䐣'=>'cuo','䟶'=>'cuo','䠡'=>'cuo','䣜'=>'cuo','䱜'=>'cuo','䴾'=>'cuo','剌'=>'la','啦'=>'la','喇'=>'la','嚹'=>'la','垃'=>'la','拉'=>'la','揦'=>'la','揧'=>'la','搚'=>'la','攋'=>'la','旯'=>'la','柆'=>'la','楋'=>'la','櫴'=>'la','溂'=>'la','爉'=>'la','瓎'=>'la','瘌'=>'la','砬'=>'la','磖'=>'la','翋'=>'la','腊'=>'la','臈'=>'la','臘'=>'la','菈'=>'la','藞'=>'la','蜡'=>'la','蝋'=>'la','蝲'=>'la','蠟'=>'la','辢'=>'la','辣'=>'la','邋'=>'la','鑞'=>'la','镴'=>'la','鞡'=>'la','鬎'=>'la','鯻'=>'la','㕇'=>'la','㸊'=>'la','㻋'=>'la','㻝'=>'la','䂰'=>'la','䃳'=>'la','䏀'=>'la','䓥'=>'la','䗶'=>'la','䝓'=>'la','䟑'=>'la','䪉'=>'la','䱫'=>'la','䶛'=>'la','剖'=>'po','叵'=>'po','哱'=>'po','嘙'=>'po','坡'=>'po','奤'=>'po','娝'=>'po','婆'=>'po','尀'=>'po','岥'=>'po','岶'=>'po','廹'=>'po','敀'=>'po','昢'=>'po','櫇'=>'po','泼'=>'po','洦'=>'po','溌'=>'po','潑'=>'po','烞'=>'po','珀'=>'po','皤'=>'po','破'=>'po','砶'=>'po','笸'=>'po','粕'=>'po','蒪'=>'po','蔢'=>'po','謈'=>'po','迫'=>'po','鄱'=>'po','酦'=>'po','醱'=>'po','釙'=>'po','鉕'=>'po','鏺'=>'po','钋'=>'po','钷'=>'po','頗'=>'po','颇'=>'po','駊'=>'po','魄'=>'po','㛘'=>'po','㨇'=>'po','㰴'=>'po','䄸'=>'po','䎊'=>'po','䞟'=>'po','䣪'=>'po','䣮'=>'po','䨰'=>'po','䪖'=>'po','䯙'=>'po','剬'=>'tuan','剸'=>'tuan','团'=>'tuan','団'=>'tuan','圕'=>'tuan','團'=>'tuan','塼'=>'tuan','彖'=>'tuan','慱'=>'tuan','抟'=>'tuan','摶'=>'tuan','槫'=>'tuan','檲'=>'tuan','湍'=>'tuan','湪'=>'tuan','漙'=>'tuan','煓'=>'tuan','猯'=>'tuan','疃'=>'tuan','篿'=>'tuan','糰'=>'tuan','褖'=>'tuan','貒'=>'tuan','鏄'=>'tuan','鷒'=>'tuan','鷻'=>'tuan','㩛'=>'tuan','䊜'=>'tuan','䜝'=>'tuan','䵯'=>'tuan','劗'=>'zuan','揝'=>'zuan','攥'=>'zuan','籫'=>'zuan','繤'=>'zuan','纂'=>'zuan','纉'=>'zuan','纘'=>'zuan','缵'=>'zuan','躜'=>'zuan','躦'=>'zuan','鑚'=>'zuan','鑽'=>'zuan','钻'=>'zuan','䂎'=>'zuan','䌣'=>'zuan','䎱'=>'zuan','䤸'=>'zuan','劭'=>'shao','勺'=>'shao','卲'=>'shao','哨'=>'shao','娋'=>'shao','少'=>'shao','弰'=>'shao','捎'=>'shao','旓'=>'shao','柖'=>'shao','梢'=>'shao','潲'=>'shao','烧'=>'shao','焼'=>'shao','焽'=>'shao','燒'=>'shao','玿'=>'shao','稍'=>'shao','筲'=>'shao','紹'=>'shao','綤'=>'shao','绍'=>'shao','艄'=>'shao','芍'=>'shao','苕'=>'shao','莦'=>'shao','萔'=>'shao','蕱'=>'shao','蛸'=>'shao','袑'=>'shao','輎'=>'shao','邵'=>'shao','韶'=>'shao','颵'=>'shao','髾'=>'shao','鮹'=>'shao','㪢'=>'shao','㲈'=>'shao','㷹'=>'shao','㸛'=>'shao','䏴'=>'shao','䒚'=>'shao','䔠'=>'shao','䙼'=>'shao','䬰'=>'shao','勂'=>'gao','吿'=>'gao','告'=>'gao','夰'=>'gao','峼'=>'gao','搞'=>'gao','暠'=>'gao','杲'=>'gao','槀'=>'gao','槁'=>'gao','槔'=>'gao','槹'=>'gao','橰'=>'gao','檺'=>'gao','櫜'=>'gao','滜'=>'gao','獔'=>'gao','皋'=>'gao','皐'=>'gao','睪'=>'gao','睾'=>'gao','祮'=>'gao','祰'=>'gao','禞'=>'gao','稁'=>'gao','稾'=>'gao','稿'=>'gao','筶'=>'gao','篙'=>'gao','糕'=>'gao','縞'=>'gao','缟'=>'gao','羔'=>'gao','羙'=>'gao','膏'=>'gao','臯'=>'gao','菒'=>'gao','藁'=>'gao','藳'=>'gao','誥'=>'gao','诰'=>'gao','郜'=>'gao','鋯'=>'gao','鎬'=>'gao','锆'=>'gao','镐'=>'gao','韟'=>'gao','餻'=>'gao','高'=>'gao','髙'=>'gao','鷎'=>'gao','鷱'=>'gao','鼛'=>'gao','㚏'=>'gao','㚖'=>'gao','㾸'=>'gao','䗣'=>'gao','勆'=>'lang','唥'=>'lang','啷'=>'lang','埌'=>'lang','塱'=>'lang','嫏'=>'lang','崀'=>'lang','廊'=>'lang','悢'=>'lang','朖'=>'lang','朗'=>'lang','朤'=>'lang','桹'=>'lang','榔'=>'lang','樃'=>'lang','欴'=>'lang','浪'=>'lang','烺'=>'lang','狼'=>'lang','琅'=>'lang','瑯'=>'lang','硠'=>'lang','稂'=>'lang','筤'=>'lang','艆'=>'lang','莨'=>'lang','蒗'=>'lang','蓈'=>'lang','蓢'=>'lang','蜋'=>'lang','螂'=>'lang','誏'=>'lang','躴'=>'lang','郎'=>'lang','郒'=>'lang','郞'=>'lang','鋃'=>'lang','鎯'=>'lang','锒'=>'lang','閬'=>'lang','阆'=>'lang','駺'=>'lang','㓪'=>'lang','㙟'=>'lang','㝗'=>'lang','㟍'=>'lang','㢃'=>'lang','㫰'=>'lang','㮾'=>'lang','㱢'=>'lang','㾗'=>'lang','㾿'=>'lang','䀶'=>'lang','䁁'=>'lang','䆡'=>'lang','䍚'=>'lang','䕞'=>'lang','䡙'=>'lang','䯖'=>'lang','䱶'=>'lang','勜'=>'weng','嗡'=>'weng','塕'=>'weng','奣'=>'weng','嵡'=>'weng','暡'=>'weng','滃'=>'weng','瓮'=>'weng','甕'=>'weng','瞈'=>'weng','罋'=>'weng','翁'=>'weng','聬'=>'weng','蓊'=>'weng','蕹'=>'weng','螉'=>'weng','鎓'=>'weng','鶲'=>'weng','鹟'=>'weng','齆'=>'weng','㘢'=>'weng','㜲'=>'weng','䐥'=>'weng','䤰'=>'weng','匁'=>'mang','厖'=>'mang','吂'=>'mang','哤'=>'mang','壾'=>'mang','娏'=>'mang','尨'=>'mang','忙'=>'mang','恾'=>'mang','杗'=>'mang','杧'=>'mang','氓'=>'mang','汒'=>'mang','浝'=>'mang','漭'=>'mang','牤'=>'mang','牻'=>'mang','狵'=>'mang','痝'=>'mang','盲'=>'mang','硭'=>'mang','笀'=>'mang','芒'=>'mang','茫'=>'mang','茻'=>'mang','莽'=>'mang','莾'=>'mang','蘉'=>'mang','蛖'=>'mang','蟒'=>'mang','蠎'=>'mang','邙'=>'mang','釯'=>'mang','鋩'=>'mang','铓'=>'mang','駹'=>'mang','㙁'=>'mang','㝑'=>'mang','㟌'=>'mang','㟐'=>'mang','㟿'=>'mang','㡛'=>'mang','㬒'=>'mang','㻊'=>'mang','䀮'=>'mang','䁳'=>'mang','䅒'=>'mang','䈍'=>'mang','䒎'=>'mang','䖟'=>'mang','䟥'=>'mang','䵨'=>'mang','匘'=>'nao','呶'=>'nao','垴'=>'nao','堖'=>'nao','夒'=>'nao','婥'=>'nao','嫐'=>'nao','孬'=>'nao','峱'=>'nao','嶩'=>'nao','巎'=>'nao','怓'=>'nao','恼'=>'nao','悩'=>'nao','惱'=>'nao','挠'=>'nao','撓'=>'nao','檂'=>'nao','淖'=>'nao','猱'=>'nao','獶'=>'nao','獿'=>'nao','瑙'=>'nao','硇'=>'nao','碙'=>'nao','碯'=>'nao','脑'=>'nao','脳'=>'nao','腦'=>'nao','臑'=>'nao','蛲'=>'nao','蟯'=>'nao','詉'=>'nao','譊'=>'nao','鐃'=>'nao','铙'=>'nao','閙'=>'nao','闹'=>'nao','鬧'=>'nao','㑎'=>'nao','㛴'=>'nao','㞪'=>'nao','㺀'=>'nao','㺁'=>'nao','䃩'=>'nao','䄩'=>'nao','䑋'=>'nao','䛝'=>'nao','䜀'=>'nao','䜧'=>'nao','䫸'=>'nao','䴃'=>'nao','匝'=>'za','咂'=>'za','囐'=>'za','帀'=>'za','拶'=>'za','杂'=>'za','桚'=>'za','沞'=>'za','沯'=>'za','砸'=>'za','磼'=>'za','紥'=>'za','紮'=>'za','臜'=>'za','臢'=>'za','襍'=>'za','鉔'=>'za','雑'=>'za','雜'=>'za','雥'=>'za','韴'=>'za','魳'=>'za','䕹'=>'za','䞙'=>'za','䪞'=>'za','匴'=>'suan','狻'=>'suan','痠'=>'suan','祘'=>'suan','笇'=>'suan','筭'=>'suan','算'=>'suan','蒜'=>'suan','酸'=>'suan','㔯'=>'suan','卄'=>'nian','哖'=>'nian','埝'=>'nian','姩'=>'nian','年'=>'nian','廿'=>'nian','念'=>'nian','拈'=>'nian','捻'=>'nian','撚'=>'nian','撵'=>'nian','攆'=>'nian','涊'=>'nian','淰'=>'nian','碾'=>'nian','秊'=>'nian','秥'=>'nian','簐'=>'nian','艌'=>'nian','蔫'=>'nian','蹨'=>'nian','躎'=>'nian','輦'=>'nian','辇'=>'nian','鮎'=>'nian','鯰'=>'nian','鲇'=>'nian','鲶'=>'nian','鵇'=>'nian','黏'=>'nian','㘝'=>'nian','㞋'=>'nian','㲽'=>'nian','䄭'=>'nian','䄹'=>'nian','䚓'=>'nian','䩞'=>'nian','䬯'=>'nian','卛'=>'shuai','帅'=>'shuai','帥'=>'shuai','摔'=>'shuai','甩'=>'shuai','蟀'=>'shuai','衰'=>'shuai','䢦'=>'shuai','却'=>'que','卻'=>'que','埆'=>'que','塙'=>'que','墧'=>'que','崅'=>'que','悫'=>'que','愨'=>'que','慤'=>'que','搉'=>'que','榷'=>'que','毃'=>'que','炔'=>'que','燩'=>'que','瘸'=>'que','皵'=>'que','硞'=>'que','确'=>'que','碏'=>'que','確'=>'que','礐'=>'que','礭'=>'que','缺'=>'que','舃'=>'que','蒛'=>'que','趞'=>'que','闋'=>'que','闕'=>'que','阕'=>'que','阙'=>'que','雀'=>'que','鵲'=>'que','鹊'=>'que','㕁'=>'que','㩁'=>'que','㰌'=>'que','㱋'=>'que','㱿'=>'que','㴶'=>'que','㾡'=>'que','䇎'=>'que','䦬'=>'que','䧿'=>'que','厇'=>'zhe','哲'=>'zhe','啠'=>'zhe','喆'=>'zhe','嗻'=>'zhe','嚞'=>'zhe','埑'=>'zhe','嫬'=>'zhe','悊'=>'zhe','折'=>'zhe','摺'=>'zhe','晢'=>'zhe','晣'=>'zhe','柘'=>'zhe','棏'=>'zhe','樀'=>'zhe','樜'=>'zhe','歽'=>'zhe','浙'=>'zhe','淛'=>'zhe','矺'=>'zhe','砓'=>'zhe','磔'=>'zhe','籷'=>'zhe','粍'=>'zhe','者'=>'zhe','蔗'=>'zhe','虴'=>'zhe','蛰'=>'zhe','蜇'=>'zhe','蟄'=>'zhe','蟅'=>'zhe','袩'=>'zhe','褶'=>'zhe','襵'=>'zhe','詟'=>'zhe','謫'=>'zhe','謺'=>'zhe','讁'=>'zhe','讋'=>'zhe','谪'=>'zhe','赭'=>'zhe','輒'=>'zhe','輙'=>'zhe','轍'=>'zhe','辄'=>'zhe','辙'=>'zhe','这'=>'zhe','這'=>'zhe','遮'=>'zhe','銸'=>'zhe','鍺'=>'zhe','锗'=>'zhe','鮿'=>'zhe','鷓'=>'zhe','鹧'=>'zhe','㞏'=>'zhe','㪿'=>'zhe','㯰'=>'zhe','䂞'=>'zhe','䊞'=>'zhe','䎲'=>'zhe','䏳'=>'zhe','䐑'=>'zhe','䐲'=>'zhe','䓆'=>'zhe','䗪'=>'zhe','䝃'=>'zhe','䝕'=>'zhe','䠦'=>'zhe','䩾'=>'zhe','䵭'=>'zhe','厑'=>'a','吖'=>'a','啊'=>'a','嗄'=>'a','錒'=>'a','锕'=>'a','阿'=>'a','厜'=>'zui','嗺'=>'zui','嘴'=>'zui','噿'=>'zui','嶊'=>'zui','嶵'=>'zui','晬'=>'zui','最'=>'zui','朘'=>'zui','枠'=>'zui','栬'=>'zui','樶'=>'zui','檇'=>'zui','檌'=>'zui','欈'=>'zui','濢'=>'zui','璻'=>'zui','祽'=>'zui','穝'=>'zui','絊'=>'zui','纗'=>'zui','罪'=>'zui','蕞'=>'zui','蟕'=>'zui','辠'=>'zui','酔'=>'zui','酻'=>'zui','醉'=>'zui','鋷'=>'zui','錊'=>'zui','㝡'=>'zui','㠑'=>'zui','㰎'=>'zui','䘹'=>'zui','䮔'=>'zui','厹'=>'rou','媃'=>'rou','宍'=>'rou','揉'=>'rou','柔'=>'rou','楺'=>'rou','渘'=>'rou','煣'=>'rou','瑈'=>'rou','瓇'=>'rou','禸'=>'rou','粈'=>'rou','糅'=>'rou','肉'=>'rou','腬'=>'rou','葇'=>'rou','蝚'=>'rou','蹂'=>'rou','輮'=>'rou','鍒'=>'rou','鞣'=>'rou','韖'=>'rou','騥'=>'rou','鰇'=>'rou','鶔'=>'rou','㖻'=>'rou','㽥'=>'rou','䄾'=>'rou','䐓'=>'rou','䧷'=>'rou','䰆'=>'rou','双'=>'shuang','塽'=>'shuang','孀'=>'shuang','孇'=>'shuang','慡'=>'shuang','樉'=>'shuang','欆'=>'shuang','滝'=>'shuang','灀'=>'shuang','爽'=>'shuang','礵'=>'shuang','縔'=>'shuang','艭'=>'shuang','鏯'=>'shuang','雙'=>'shuang','霜'=>'shuang','騻'=>'shuang','驦'=>'shuang','骦'=>'shuang','鷞'=>'shuang','鸘'=>'shuang','鹴'=>'shuang','㦼'=>'shuang','㼽'=>'shuang','䗮'=>'shuang','䡯'=>'shuang','䫪'=>'shuang','叠'=>'die','哋'=>'die','啑'=>'die','喋'=>'die','嚸'=>'die','垤'=>'die','堞'=>'die','峌'=>'die','嵽'=>'die','幉'=>'die','恎'=>'die','惵'=>'die','戜'=>'die','挕'=>'die','揲'=>'die','昳'=>'die','曡'=>'die','曢'=>'die','殜'=>'die','氎'=>'die','爹'=>'die','牃'=>'die','牒'=>'die','瓞'=>'die','畳'=>'die','疂'=>'die','疉'=>'die','疊'=>'die','眣'=>'die','眰'=>'die','碟'=>'die','絰'=>'die','绖'=>'die','耊'=>'die','耋'=>'die','胅'=>'die','臷'=>'die','艓'=>'die','苵'=>'die','蜨'=>'die','蝶'=>'die','褋'=>'die','褺'=>'die','詄'=>'die','諜'=>'die','谍'=>'die','趃'=>'die','跌'=>'die','蹀'=>'die','迭'=>'die','镻'=>'die','鰈'=>'die','鲽'=>'die','㑙'=>'die','㥈'=>'die','㦶'=>'die','㩸'=>'die','㩹'=>'die','㫼'=>'die','㬪'=>'die','㭯'=>'die','㲲'=>'die','㲳'=>'die','㷸'=>'die','㻡'=>'die','䘭'=>'die','䞇'=>'die','䞕'=>'die','䠟'=>'die','䪥'=>'die','䮢'=>'die','䲀'=>'die','䳀'=>'die','䴑'=>'die','叡'=>'rui','壡'=>'rui','枘'=>'rui','桵'=>'rui','橤'=>'rui','汭'=>'rui','瑞'=>'rui','甤'=>'rui','睿'=>'rui','緌'=>'rui','繠'=>'rui','芮'=>'rui','蕊'=>'rui','蕋'=>'rui','蕤'=>'rui','蘂'=>'rui','蘃'=>'rui','蚋'=>'rui','蜹'=>'rui','銳'=>'rui','鋭'=>'rui','锐'=>'rui','㓹'=>'rui','㛱'=>'rui','㪫'=>'rui','㮃'=>'rui','㲊'=>'rui','䅑'=>'rui','䌼'=>'rui','䓲'=>'rui','吞'=>'tun','呑'=>'tun','啍'=>'tun','坉'=>'tun','屯'=>'tun','忳'=>'tun','旽'=>'tun','暾'=>'tun','朜'=>'tun','氽'=>'tun','涒'=>'tun','焞'=>'tun','畽'=>'tun','臀'=>'tun','臋'=>'tun','芚'=>'tun','豘'=>'tun','豚'=>'tun','軘'=>'tun','霕'=>'tun','飩'=>'tun','饨'=>'tun','魨'=>'tun','鲀'=>'tun','黗'=>'tun','㖔'=>'tun','㞘'=>'tun','㩔'=>'tun','㹠'=>'tun','㼊'=>'tun','否'=>'fou','垺'=>'fou','妚'=>'fou','紑'=>'fou','缶'=>'fou','缹'=>'fou','缻'=>'fou','雬'=>'fou','鴀'=>'fou','䳕'=>'fou','吮'=>'shun','瞬'=>'shun','舜'=>'shun','顺'=>'shun','㥧'=>'shun','䀢'=>'shun','䀵'=>'shun','䑞'=>'shun','呙'=>'guo','咼'=>'guo','啯'=>'guo','嘓'=>'guo','囯'=>'guo','囶'=>'guo','囻'=>'guo','国'=>'guo','圀'=>'guo','國'=>'guo','埚'=>'guo','堝'=>'guo','墎'=>'guo','崞'=>'guo','帼'=>'guo','幗'=>'guo','彉'=>'guo','彍'=>'guo','惈'=>'guo','慖'=>'guo','掴'=>'guo','摑'=>'guo','果'=>'guo','椁'=>'guo','楇'=>'guo','槨'=>'guo','淉'=>'guo','漍'=>'guo','濄'=>'guo','猓'=>'guo','瘑'=>'guo','粿'=>'guo','綶'=>'guo','聒'=>'guo','聝'=>'guo','腂'=>'guo','腘'=>'guo','膕'=>'guo','菓'=>'guo','蔮'=>'guo','虢'=>'guo','蜾'=>'guo','蝈'=>'guo','蟈'=>'guo','裹'=>'guo','褁'=>'guo','輠'=>'guo','过'=>'guo','過'=>'guo','郭'=>'guo','鈛'=>'guo','鍋'=>'guo','鐹'=>'guo','锅'=>'guo','餜'=>'guo','馃'=>'guo','馘'=>'guo','㕵'=>'guo','㖪'=>'guo','㚍'=>'guo','㞅'=>'guo','㳀'=>'guo','㶁'=>'guo','䂸'=>'guo','䆐'=>'guo','䐸'=>'guo','䙨'=>'guo','䤋'=>'guo','䬎'=>'guo','䴹'=>'guo','呠'=>'pen','喯'=>'pen','喷'=>'pen','噴'=>'pen','歕'=>'pen','湓'=>'pen','濆'=>'pen','瓫'=>'pen','盆'=>'pen','翉'=>'pen','翸'=>'pen','葐'=>'pen','呢'=>'ne','抐'=>'ne','疒'=>'ne','眲'=>'ne','訥'=>'ne','讷'=>'ne','䎪'=>'ne','䭆'=>'ne','呣'=>'m','嘸'=>'m','咶'=>'huai','坏'=>'huai','壊'=>'huai','壞'=>'huai','徊'=>'huai','怀'=>'huai','懐'=>'huai','懷'=>'huai','槐'=>'huai','櫰'=>'huai','淮'=>'huai','瀤'=>'huai','耲'=>'huai','蘹'=>'huai','蘾'=>'huai','褢'=>'huai','褱'=>'huai','踝'=>'huai','㜳'=>'huai','䈭'=>'huai','䴜'=>'huai','品'=>'pin','嚬'=>'pin','姘'=>'pin','娉'=>'pin','嫔'=>'pin','嬪'=>'pin','拼'=>'pin','朩'=>'pin','榀'=>'pin','汖'=>'pin','牝'=>'pin','玭'=>'pin','琕'=>'pin','矉'=>'pin','礗'=>'pin','穦'=>'pin','聘'=>'pin','薲'=>'pin','貧'=>'pin','贫'=>'pin','頻'=>'pin','顰'=>'pin','频'=>'pin','颦'=>'pin','馪'=>'pin','驞'=>'pin','㰋'=>'pin','䀻'=>'pin','哟'=>'yo','唷'=>'yo','喲'=>'yo','哦'=>'o','哾'=>'shui','帨'=>'shui','楯'=>'shui','橓'=>'shui','水'=>'shui','氵'=>'shui','氺'=>'shui','涗'=>'shui','涚'=>'shui','睡'=>'shui','瞚'=>'shui','瞤'=>'shui','祱'=>'shui','稅'=>'shui','税'=>'shui','脽'=>'shui','蕣'=>'shui','裞'=>'shui','說'=>'shui','説'=>'shui','誰'=>'shui','谁'=>'shui','閖'=>'shui','順'=>'shui','鬊'=>'shui','㽷'=>'shui','䭨'=>'shui','唤'=>'huan','喚'=>'huan','喛'=>'huan','嚾'=>'huan','堚'=>'huan','奂'=>'huan','奐'=>'huan','宦'=>'huan','寏'=>'huan','寰'=>'huan','峘'=>'huan','嵈'=>'huan','幻'=>'huan','患'=>'huan','愌'=>'huan','懁'=>'huan','懽'=>'huan','换'=>'huan','換'=>'huan','擐'=>'huan','攌'=>'huan','桓'=>'huan','梙'=>'huan','槵'=>'huan','欢'=>'huan','欥'=>'huan','歓'=>'huan','歡'=>'huan','洹'=>'huan','浣'=>'huan','涣'=>'huan','渙'=>'huan','漶'=>'huan','澣'=>'huan','澴'=>'huan','烉'=>'huan','焕'=>'huan','煥'=>'huan','狟'=>'huan','獾'=>'huan','环'=>'huan','瑍'=>'huan','環'=>'huan','瓛'=>'huan','痪'=>'huan','瘓'=>'huan','睆'=>'huan','瞣'=>'huan','糫'=>'huan','絙'=>'huan','綄'=>'huan','緩'=>'huan','繯'=>'huan','缓'=>'huan','缳'=>'huan','羦'=>'huan','肒'=>'huan','荁'=>'huan','萈'=>'huan','萑'=>'huan','藧'=>'huan','讙'=>'huan','豢'=>'huan','豲'=>'huan','貆'=>'huan','貛'=>'huan','輐'=>'huan','轘'=>'huan','还'=>'huan','逭'=>'huan','還'=>'huan','郇'=>'huan','酄'=>'huan','鍰'=>'huan','鐶'=>'huan','锾'=>'huan','镮'=>'huan','闤'=>'huan','阛'=>'huan','雈'=>'huan','驩'=>'huan','鬟'=>'huan','鯇'=>'huan','鯶'=>'huan','鰀'=>'huan','鲩'=>'huan','鴅'=>'huan','鵍'=>'huan','鹮'=>'huan','㓉'=>'huan','㕕'=>'huan','㡲'=>'huan','㣪'=>'huan','㦥'=>'huan','㪱'=>'huan','㬇'=>'huan','㬊'=>'huan','㵹'=>'huan','㶎'=>'huan','㹖'=>'huan','㼫'=>'huan','㿪'=>'huan','䀓'=>'huan','䀨'=>'huan','䆠'=>'huan','䈠'=>'huan','䍺'=>'huan','䝠'=>'huan','䥧'=>'huan','䦡'=>'huan','䭴'=>'huan','䮝'=>'huan','䯘'=>'huan','䴟'=>'huan','啂'=>'nou','槈'=>'nou','檽'=>'nou','獳'=>'nou','羺'=>'nou','耨'=>'nou','譨'=>'nou','譳'=>'nou','鎒'=>'nou','鐞'=>'nou','㝹'=>'nou','䅶'=>'nou','䘫'=>'nou','䨲'=>'nou','䰭'=>'nou','啃'=>'ken','垦'=>'ken','墾'=>'ken','恳'=>'ken','懇'=>'ken','掯'=>'ken','肎'=>'ken','肯'=>'ken','肻'=>'ken','裉'=>'ken','褃'=>'ken','豤'=>'ken','貇'=>'ken','錹'=>'ken','㸧'=>'ken','啜'=>'chuai','嘬'=>'chuai','揣'=>'chuai','膗'=>'chuai','踹'=>'chuai','㪓'=>'chuai','㪜'=>'chuai','䦟'=>'chuai','䦤'=>'chuai','䦷'=>'chuai','啪'=>'pa','妑'=>'pa','帊'=>'pa','帕'=>'pa','怕'=>'pa','掱'=>'pa','杷'=>'pa','潖'=>'pa','爬'=>'pa','琶'=>'pa','皅'=>'pa','筢'=>'pa','舥'=>'pa','葩'=>'pa','袙'=>'pa','趴'=>'pa','䯲'=>'pa','䶕'=>'pa','啬'=>'se','嗇'=>'se','懎'=>'se','擌'=>'se','栜'=>'se','槮'=>'se','歮'=>'se','歰'=>'se','洓'=>'se','涩'=>'se','渋'=>'se','澀'=>'se','澁'=>'se','濇'=>'se','濏'=>'se','瀒'=>'se','琗'=>'se','瑟'=>'se','璱'=>'se','瘷'=>'se','穑'=>'se','穡'=>'se','穯'=>'se','篸'=>'se','縇'=>'se','繬'=>'se','聓'=>'se','色'=>'se','裇'=>'se','襂'=>'se','譅'=>'se','轖'=>'se','銫'=>'se','鏼'=>'se','铯'=>'se','閪'=>'se','雭'=>'se','飋'=>'se','鬙'=>'se','㒊'=>'se','㥶'=>'se','㮦'=>'se','㱇'=>'se','㴔'=>'se','㻭'=>'se','䉢'=>'se','䔼'=>'se','䨛'=>'se','啮'=>'nie','喦'=>'nie','嗫'=>'nie','噛'=>'nie','嚙'=>'nie','囁'=>'nie','囓'=>'nie','圼'=>'nie','孼'=>'nie','孽'=>'nie','嵲'=>'nie','嶭'=>'nie','巕'=>'nie','帇'=>'nie','惗'=>'nie','捏'=>'nie','揑'=>'nie','摰'=>'nie','敜'=>'nie','枿'=>'nie','槷'=>'nie','櫱'=>'nie','涅'=>'nie','篞'=>'nie','籋'=>'nie','糱'=>'nie','糵'=>'nie','聂'=>'nie','聶'=>'nie','肀'=>'nie','臬'=>'nie','臲'=>'nie','苶'=>'nie','菍'=>'nie','蘖'=>'nie','蠥'=>'nie','讘'=>'nie','踂'=>'nie','踗'=>'nie','踙'=>'nie','蹑'=>'nie','躡'=>'nie','鉩'=>'nie','錜'=>'nie','鎳'=>'nie','鑷'=>'nie','钀'=>'nie','镊'=>'nie','镍'=>'nie','闑'=>'nie','陧'=>'nie','隉'=>'nie','顳'=>'nie','颞'=>'nie','齧'=>'nie','㖖'=>'nie','㘿'=>'nie','㙞'=>'nie','㚔'=>'nie','㜸'=>'nie','㡪'=>'nie','㩶'=>'nie','㮆'=>'nie','㴪'=>'nie','㸎'=>'nie','䂼'=>'nie','䄒'=>'nie','䌜'=>'nie','䜓'=>'nie','䯀'=>'nie','䯅'=>'nie','䯵'=>'nie','啱'=>'n','嗯'=>'n','莻'=>'n','鈪'=>'n','銰'=>'n','㐻'=>'n','喎'=>'wai','外'=>'wai','崴'=>'wai','歪'=>'wai','竵'=>'wai','顡'=>'wai','㖞'=>'wai','䠿'=>'wai','喵'=>'miao','妙'=>'miao','媌'=>'miao','嫹'=>'miao','庙'=>'miao','庿'=>'miao','廟'=>'miao','描'=>'miao','杪'=>'miao','淼'=>'miao','渺'=>'miao','玅'=>'miao','眇'=>'miao','瞄'=>'miao','秒'=>'miao','竗'=>'miao','篎'=>'miao','緲'=>'miao','缈'=>'miao','苗'=>'miao','藐'=>'miao','邈'=>'miao','鱙'=>'miao','鶓'=>'miao','鹋'=>'miao','㑤'=>'miao','㠺'=>'miao','㦝'=>'miao','䁧'=>'miao','䅺'=>'miao','䖢'=>'miao','嗍'=>'shuo','妁'=>'shuo','搠'=>'shuo','朔'=>'shuo','槊'=>'shuo','欶'=>'shuo','烁'=>'shuo','爍'=>'shuo','獡'=>'shuo','矟'=>'shuo','硕'=>'shuo','碩'=>'shuo','箾'=>'shuo','蒴'=>'shuo','说'=>'shuo','鎙'=>'shuo','鑠'=>'shuo','铄'=>'shuo','䀥'=>'shuo','䈾'=>'shuo','䌃'=>'shuo','嗲'=>'dia','嘈'=>'cao','嶆'=>'cao','愺'=>'cao','懆'=>'cao','撡'=>'cao','操'=>'cao','曹'=>'cao','曺'=>'cao','槽'=>'cao','漕'=>'cao','糙'=>'cao','肏'=>'cao','艚'=>'cao','艸'=>'cao','艹'=>'cao','草'=>'cao','蓸'=>'cao','螬'=>'cao','褿'=>'cao','襙'=>'cao','鄵'=>'cao','鏪'=>'cao','騲'=>'cao','鼜'=>'cao','㜖'=>'cao','㯥'=>'cao','䄚'=>'cao','䏆'=>'cao','䐬'=>'cao','䒃'=>'cao','䒑'=>'cao','嘚'=>'de','得'=>'de','徳'=>'de','德'=>'de','恴'=>'de','悳'=>'de','惪'=>'de','淂'=>'de','的'=>'de','鍀'=>'de','锝'=>'de','㝵'=>'de','㤫'=>'de','㥀'=>'de','㥁'=>'de','㯖'=>'de','䙷'=>'de','䙸'=>'de','嘿'=>'hei','嬒'=>'hei','潶'=>'hei','黑'=>'hei','黒'=>'hei','噋'=>'kuo','廓'=>'kuo','懖'=>'kuo','扩'=>'kuo','拡'=>'kuo','括'=>'kuo','挄'=>'kuo','擴'=>'kuo','栝'=>'kuo','桰'=>'kuo','濶'=>'kuo','穒'=>'kuo','筈'=>'kuo','萿'=>'kuo','葀'=>'kuo','蛞'=>'kuo','闊'=>'kuo','阔'=>'kuo','霩'=>'kuo','鞟'=>'kuo','鞹'=>'kuo','韕'=>'kuo','頢'=>'kuo','髺'=>'kuo','鬠'=>'kuo','㗥'=>'kuo','䟯'=>'kuo','䦢'=>'kuo','䯺'=>'kuo','嚓'=>'ca','囃'=>'ca','擦'=>'ca','攃'=>'ca','礤'=>'ca','礸'=>'ca','遪'=>'ca','䟃'=>'ca','䵽'=>'ca','嚽'=>'chuo','娕'=>'chuo','娖'=>'chuo','惙'=>'chuo','戳'=>'chuo','擉'=>'chuo','歠'=>'chuo','涰'=>'chuo','磭'=>'chuo','綽'=>'chuo','绰'=>'chuo','腏'=>'chuo','趠'=>'chuo','踔'=>'chuo','輟'=>'chuo','辍'=>'chuo','辵'=>'chuo','辶'=>'chuo','逴'=>'chuo','酫'=>'chuo','鑡'=>'chuo','齪'=>'chuo','齱'=>'chuo','龊'=>'chuo','㚟'=>'chuo','㲋'=>'chuo','䂐'=>'chuo','䃗'=>'chuo','䄪'=>'chuo','䆯'=>'chuo','䇍'=>'chuo','䋘'=>'chuo','䍳'=>'chuo','䓎'=>'chuo','䮕'=>'chuo','囎'=>'zen','怎'=>'zen','譖'=>'zen','譛'=>'zen','谮'=>'zen','䫈'=>'zen','囜'=>'nin','您'=>'nin','拰'=>'nin','脌'=>'nin','㤛'=>'nin','䋻'=>'nin','䚾'=>'nin','䛘'=>'nin','困'=>'kun','坤'=>'kun','堃'=>'kun','堒'=>'kun','壸'=>'kun','壼'=>'kun','婫'=>'kun','尡'=>'kun','崐'=>'kun','崑'=>'kun','悃'=>'kun','捆'=>'kun','昆'=>'kun','晜'=>'kun','梱'=>'kun','涃'=>'kun','潉'=>'kun','焜'=>'kun','熴'=>'kun','猑'=>'kun','琨'=>'kun','瑻'=>'kun','睏'=>'kun','硱'=>'kun','祵'=>'kun','稇'=>'kun','稛'=>'kun','綑'=>'kun','臗'=>'kun','菎'=>'kun','蜫'=>'kun','裈'=>'kun','裍'=>'kun','裩'=>'kun','褌'=>'kun','醌'=>'kun','錕'=>'kun','锟'=>'kun','閫'=>'kun','閸'=>'kun','阃'=>'kun','騉'=>'kun','髠'=>'kun','髡'=>'kun','髨'=>'kun','鯤'=>'kun','鲲'=>'kun','鵾'=>'kun','鶤'=>'kun','鹍'=>'kun','㩲'=>'kun','㫻'=>'kun','䠅'=>'kun','囷'=>'qun','夋'=>'qun','宭'=>'qun','峮'=>'qun','帬'=>'qun','羣'=>'qun','群'=>'qun','裙'=>'qun','裠'=>'qun','輑'=>'qun','逡'=>'qun','㪊'=>'qun','㿏'=>'qun','䭽'=>'qun','囸'=>'ri','日'=>'ri','釰'=>'ri','鈤'=>'ri','馹'=>'ri','驲'=>'ri','䒤'=>'ri','圙'=>'lve','擽'=>'lve','畧'=>'lve','稤'=>'lve','稥'=>'lve','鋝'=>'lve','鋢'=>'lve','锊'=>'lve','㑼'=>'lve','㔀'=>'lve','㨼'=>'lve','䂮'=>'lve','䌎'=>'lve','䛚'=>'lve','䤣'=>'lve','坠'=>'zhui','墜'=>'zhui','娷'=>'zhui','惴'=>'zhui','椎'=>'zhui','沝'=>'zhui','甀'=>'zhui','畷'=>'zhui','硾'=>'zhui','礈'=>'zhui','笍'=>'zhui','綴'=>'zhui','縋'=>'zhui','缀'=>'zhui','缒'=>'zhui','膇'=>'zhui','諈'=>'zhui','贅'=>'zhui','赘'=>'zhui','轛'=>'zhui','追'=>'zhui','醊'=>'zhui','錐'=>'zhui','錣'=>'zhui','鑆'=>'zhui','锥'=>'zhui','隹'=>'zhui','餟'=>'zhui','騅'=>'zhui','骓'=>'zhui','鵻'=>'zhui','䄌'=>'zhui','垳'=>'hang','夯'=>'hang','妔'=>'hang','斻'=>'hang','杭'=>'hang','沆'=>'hang','笐'=>'hang','筕'=>'hang','絎'=>'hang','绗'=>'hang','航'=>'hang','苀'=>'hang','蚢'=>'hang','貥'=>'hang','迒'=>'hang','頏'=>'hang','颃'=>'hang','魧'=>'hang','㤚'=>'hang','䀪'=>'hang','䘕'=>'hang','䟘'=>'hang','䣈'=>'hang','䦳'=>'hang','䲳'=>'hang','䴂'=>'hang','埽'=>'sao','嫂'=>'sao','慅'=>'sao','扫'=>'sao','掃'=>'sao','掻'=>'sao','搔'=>'sao','氉'=>'sao','溞'=>'sao','瘙'=>'sao','矂'=>'sao','繅'=>'sao','缫'=>'sao','臊'=>'sao','颾'=>'sao','騒'=>'sao','騷'=>'sao','骚'=>'sao','髞'=>'sao','鰠'=>'sao','鱢'=>'sao','鳋'=>'sao','㛮'=>'sao','㿋'=>'sao','䐹'=>'sao','䕅'=>'sao','䖣'=>'sao','塟'=>'zang','奘'=>'zang','弉'=>'zang','牂'=>'zang','羘'=>'zang','脏'=>'zang','臓'=>'zang','臟'=>'zang','臧'=>'zang','葬'=>'zang','賍'=>'zang','賘'=>'zang','贓'=>'zang','贜'=>'zang','赃'=>'zang','銺'=>'zang','駔'=>'zang','驵'=>'zang','髒'=>'zang','㘸'=>'zang','増'=>'zeng','增'=>'zeng','憎'=>'zeng','曽'=>'zeng','曾'=>'zeng','橧'=>'zeng','熷'=>'zeng','璔'=>'zeng','甑'=>'zeng','矰'=>'zeng','磳'=>'zeng','繒'=>'zeng','缯'=>'zeng','罾'=>'zeng','譄'=>'zeng','贈'=>'zeng','赠'=>'zeng','鄫'=>'zeng','鋥'=>'zeng','锃'=>'zeng','鱛'=>'zeng','㽪'=>'zeng','䙢'=>'zeng','䰝'=>'zeng','奀'=>'en','峎'=>'en','恩'=>'en','摁'=>'en','煾'=>'en','蒽'=>'en','䅰'=>'en','䊐'=>'en','䬶'=>'en','䭓'=>'en','䭡'=>'en','奏'=>'zou','媰'=>'zou','掫'=>'zou','揍'=>'zou','棷'=>'zou','棸'=>'zou','箃'=>'zou','緅'=>'zou','菆'=>'zou','諏'=>'zou','诹'=>'zou','走'=>'zou','赱'=>'zou','邹'=>'zou','郰'=>'zou','鄒'=>'zou','鄹'=>'zou','陬'=>'zou','騶'=>'zou','驺'=>'zou','鯐'=>'zou','鯫'=>'zou','鲰'=>'zou','黀'=>'zou','齺'=>'zou','㔿'=>'zou','㵵'=>'zou','䠫'=>'zou','女'=>'nv','恧'=>'nv','朒'=>'nv','籹'=>'nv','衂'=>'nv','衄'=>'nv','釹'=>'nv','钕'=>'nv','㵖'=>'nv','䖡'=>'nv','䘐'=>'nv','䚼'=>'nv','䶊'=>'nv','奻'=>'nuan','暖'=>'nuan','渜'=>'nuan','煖'=>'nuan','煗'=>'nuan','餪'=>'nuan','㬉'=>'nuan','䎡'=>'nuan','䙇'=>'nuan','妞'=>'niu','忸'=>'niu','扭'=>'niu','杻'=>'niu','汼'=>'niu','沑'=>'niu','炄'=>'niu','牛'=>'niu','牜'=>'niu','狃'=>'niu','紐'=>'niu','纽'=>'niu','莥'=>'niu','鈕'=>'niu','钮'=>'niu','靵'=>'niu','㺲'=>'niu','䀔'=>'niu','䋴'=>'niu','䏔'=>'niu','䒜'=>'niu','娆'=>'rao','嬈'=>'rao','扰'=>'rao','擾'=>'rao','桡'=>'rao','橈'=>'rao','犪'=>'rao','繞'=>'rao','绕'=>'rao','荛'=>'rao','蕘'=>'rao','襓'=>'rao','遶'=>'rao','隢'=>'rao','饒'=>'rao','饶'=>'rao','㑱'=>'rao','㹛'=>'rao','䫞'=>'rao','娘'=>'niang','嬢'=>'niang','孃'=>'niang','酿'=>'niang','醸'=>'niang','釀'=>'niang','䖆'=>'niang','嫋'=>'niao','嬝'=>'niao','嬲'=>'niao','尿'=>'niao','脲'=>'niao','茑'=>'niao','茒'=>'niao','蔦'=>'niao','袅'=>'niao','裊'=>'niao','褭'=>'niao','鳥'=>'niao','鸟'=>'niao','㒟'=>'niao','㜵'=>'niao','㞙'=>'niao','㠡'=>'niao','㭤'=>'niao','㳮'=>'niao','䃵'=>'niao','䐁'=>'niao','䙚'=>'niao','䦊'=>'niao','䮍'=>'niao','嫩'=>'nen','㜛'=>'nen','㯎'=>'nen','㶧'=>'nen','孙'=>'sun','孫'=>'sun','巺'=>'sun','损'=>'sun','損'=>'sun','搎'=>'sun','榫'=>'sun','槂'=>'sun','潠'=>'sun','狲'=>'sun','猻'=>'sun','畃'=>'sun','笋'=>'sun','筍'=>'sun','箰'=>'sun','簨'=>'sun','荪'=>'sun','蓀'=>'sun','蕵'=>'sun','薞'=>'sun','鎨'=>'sun','隼'=>'sun','飧'=>'sun','飱'=>'sun','鶽'=>'sun','㔼'=>'sun','㡄'=>'sun','㦏'=>'sun','䁚'=>'sun','宽'=>'kuan','寛'=>'kuan','寬'=>'kuan','梡'=>'kuan','欵'=>'kuan','款'=>'kuan','歀'=>'kuan','窽'=>'kuan','窾'=>'kuan','鑧'=>'kuan','髋'=>'kuan','髖'=>'kuan','㯘'=>'kuan','䕀'=>'kuan','䤭'=>'kuan','䥗'=>'kuan','䲌'=>'kuan','岃'=>'yen','膶'=>'yen','岇'=>'ang','昂'=>'ang','昻'=>'ang','枊'=>'ang','盎'=>'ang','肮'=>'ang','醠'=>'ang','骯'=>'ang','㦹'=>'ang','㭿'=>'ang','㼜'=>'ang','䀚'=>'ang','䍩'=>'ang','䒢'=>'ang','䩕'=>'ang','䭹'=>'ang','䭺'=>'ang','岑'=>'cen','嵾'=>'cen','梣'=>'cen','涔'=>'cen','笒'=>'cen','膥'=>'cen','㞥'=>'cen','㻸'=>'cen','䃡'=>'cen','䅾'=>'cen','䤁'=>'cen','䨙'=>'cen','䯔'=>'cen','䲋'=>'cen','巑'=>'cuan','撺'=>'cuan','攅'=>'cuan','攛'=>'cuan','櫕'=>'cuan','欑'=>'cuan','殩'=>'cuan','汆'=>'cuan','熶'=>'cuan','爨'=>'cuan','穳'=>'cuan','窜'=>'cuan','竄'=>'cuan','篡'=>'cuan','篹'=>'cuan','簒'=>'cuan','蹿'=>'cuan','躥'=>'cuan','鑹'=>'cuan','㠝'=>'cuan','㭫'=>'cuan','㵀'=>'cuan','㸑'=>'cuan','䆘'=>'cuan','䰖'=>'cuan','忑'=>'te','忒'=>'te','慝'=>'te','特'=>'te','犆'=>'te','脦'=>'te','蟘'=>'te','貣'=>'te','鋱'=>'te','铽'=>'te','㥂'=>'te','㧹'=>'te','惹'=>'re','热'=>'re','熱'=>'re','扥'=>'den','扽'=>'den','揼'=>'den','抓'=>'zhua','檛'=>'zhua','爪'=>'zhua','簻'=>'zhua','膼'=>'zhua','髽'=>'zhua','拴'=>'shuan','栓'=>'shuan','涮'=>'shuan','腨'=>'shuan','閂'=>'shuan','闩'=>'shuan','䧠'=>'shuan','拽'=>'zhuai','跩'=>'zhuai','掠'=>'lue','略'=>'lue','晒'=>'shai','曬'=>'shai','筛'=>'shai','篩'=>'shai','簁'=>'shai','簛'=>'shai','㩄'=>'shai','㬠'=>'shai','森'=>'sen','橍'=>'run','润'=>'run','潤'=>'run','閏'=>'run','閠'=>'run','闰'=>'run','㠈'=>'run','䦞'=>'run','疟'=>'nue','虐'=>'nue','瘧'=>'nve','䖈'=>'nve','䖋'=>'nve','䨋'=>'nve','給'=>'gei','给'=>'gei','繆'=>'miu','缪'=>'miu','謬'=>'miu','谬'=>'miu','能'=>'neng','㲌'=>'neng','㴰'=>'neng','䏻'=>'neng','蠈'=>'zei','賊'=>'zei','贼'=>'zei','鰂'=>'zei','鱡'=>'zei','鲗'=>'zei','覅'=>'fiao','鞥'=>'eng','㕶'=>'ng','䫄'=>'chua');
+
+ /**
+ * 将中文编码成拼音
+ * @param string $str utf8字符串
+ * @param string $ret_format 返回格式 [all:全拼音|head:首字母|one:仅第一字符首字母]
+ * @param string $placeholder 无法识别的字符占位符
+ * @param string $allow_chars 允许的非中文字符
+ * @return string 拼音字符串
+ */
+ public static function encode($str, $ret_format = 'head', $placeholder = '*', $allow_chars = '/[a-zA-Z\d]/'){
+ $str = trim($str);
+ $len = mb_strlen($str, 'UTF-8');
+ $rs = '';
+ for ($i = 0; $i < $len; $i++) {
+ $chr = mb_substr($str, $i, 1, 'UTF-8');
+ $asc = ord($chr);
+ if ($asc < 0x80) { // 0-127
+ if (preg_match($allow_chars, $chr)) { // 用参数控制正则
+ $rs .= $chr; // 0-9 a-z A-Z 空格
+ } else { // 其他字符用填充符代替
+ $rs .= $placeholder;
+ }
+ } else { // 128-255
+ if (isset(self::$_aMaps[$chr])) {
+ $rs .= 'head' === $ret_format ? self::$_aMaps[$chr][0] : (self::$_aMaps[$chr].'');
+ } else {
+ $rs .= $placeholder;
+ }
+ }
+ if ('one' === $ret_format && '' !== $rs) {
+ return $rs[0];
+ }
+ }
+ return $rs;
+ }
+}
+?>
\ No newline at end of file
diff --git a/serve/extend/org/ttfs/1.ttf b/serve/extend/org/ttfs/1.ttf
new file mode 100644
index 0000000..9eae6f2
Binary files /dev/null and b/serve/extend/org/ttfs/1.ttf differ
diff --git a/serve/extend/org/ttfs/2.ttf b/serve/extend/org/ttfs/2.ttf
new file mode 100644
index 0000000..6386c6b
Binary files /dev/null and b/serve/extend/org/ttfs/2.ttf differ
diff --git a/serve/extend/org/ttfs/3.ttf b/serve/extend/org/ttfs/3.ttf
new file mode 100644
index 0000000..678a491
Binary files /dev/null and b/serve/extend/org/ttfs/3.ttf differ
diff --git a/serve/extend/org/ttfs/4.ttf b/serve/extend/org/ttfs/4.ttf
new file mode 100644
index 0000000..db43334
Binary files /dev/null and b/serve/extend/org/ttfs/4.ttf differ
diff --git a/serve/extend/org/ttfs/5.ttf b/serve/extend/org/ttfs/5.ttf
new file mode 100644
index 0000000..8c082c8
Binary files /dev/null and b/serve/extend/org/ttfs/5.ttf differ
diff --git a/serve/extend/org/ttfs/6.ttf b/serve/extend/org/ttfs/6.ttf
new file mode 100644
index 0000000..45a038b
Binary files /dev/null and b/serve/extend/org/ttfs/6.ttf differ
diff --git a/serve/extend/wechat/WxPay.Api.php b/serve/extend/wechat/WxPay.Api.php
new file mode 100644
index 0000000..bd94623
--- /dev/null
+++ b/serve/extend/wechat/WxPay.Api.php
@@ -0,0 +1,616 @@
+IsOut_trade_noSet()) {
+ throw new WxPayException("缺少统一支付接口必填参数out_trade_no!");
+ }else if(!$inputObj->IsBodySet()){
+ throw new WxPayException("缺少统一支付接口必填参数body!");
+ }else if(!$inputObj->IsTotal_feeSet()) {
+ throw new WxPayException("缺少统一支付接口必填参数total_fee!");
+ }else if(!$inputObj->IsTrade_typeSet()) {
+ throw new WxPayException("缺少统一支付接口必填参数trade_type!");
+ }
+
+ //关联参数
+ if($inputObj->GetTrade_type() == "JSAPI" && !$inputObj->IsOpenidSet()){
+ throw new WxPayException("统一支付接口中,缺少必填参数openid!trade_type为JSAPI时,openid为必填参数!");
+ }
+ if($inputObj->GetTrade_type() == "NATIVE" && !$inputObj->IsProduct_idSet()){
+ throw new WxPayException("统一支付接口中,缺少必填参数product_id!trade_type为JSAPI时,product_id为必填参数!");
+ }
+
+ //异步通知url未设置,则使用配置文件中的url
+ if(!$inputObj->IsNotify_urlSet() && $config->GetNotifyUrl() != ""){
+ $inputObj->SetNotify_url($config->GetNotifyUrl());//异步通知url
+ }
+
+ $inputObj->SetAppid($config->GetAppId());//公众账号ID
+ $inputObj->SetMch_id($config->GetMerchantId());//商户号
+ $inputObj->SetSpbill_create_ip($_SERVER['REMOTE_ADDR']);//终端ip
+ $inputObj->SetNonce_str(self::getNonceStr());//随机字符串
+
+ //签名
+ $inputObj->SetSign($config);
+ $xml = $inputObj->ToXml();
+
+ $startTimeStamp = self::getMillisecond();//请求开始时间
+ $response = self::postXmlCurl($config, $xml, $url, false, $timeOut);
+ $result = WxPayResults::Init($config, $response);
+ self::reportCostTime($config, $url, $startTimeStamp, $result);//上报请求花费时间
+
+ return $result;
+ }
+
+ /**
+ *
+ * 查询订单,WxPayOrderQuery中out_trade_no、transaction_id至少填一个
+ * appid、mchid、spbill_create_ip、nonce_str不需要填入
+ * @param WxPayConfigInterface $config 配置对象
+ * @param WxPayOrderQuery $inputObj
+ * @param int $timeOut
+ * @throws WxPayException
+ * @return 成功时返回,其他抛异常
+ */
+ public static function orderQuery($config, $inputObj, $timeOut = 6)
+ {
+ $url = "https://api.mch.weixin.qq.com/pay/orderquery";
+ //检测必填参数
+ if(!$inputObj->IsOut_trade_noSet() && !$inputObj->IsTransaction_idSet()) {
+ throw new WxPayException("订单查询接口中,out_trade_no、transaction_id至少填一个!");
+ }
+ $inputObj->SetAppid($config->GetAppId());//公众账号ID
+ $inputObj->SetMch_id($config->GetMerchantId());//商户号
+ $inputObj->SetNonce_str(self::getNonceStr());//随机字符串
+
+ $inputObj->SetSign($config);//签名
+ $xml = $inputObj->ToXml();
+
+ $startTimeStamp = self::getMillisecond();//请求开始时间
+ $response = self::postXmlCurl($config, $xml, $url, false, $timeOut);
+ $result = WxPayResults::Init($config, $response);
+ self::reportCostTime($config, $url, $startTimeStamp, $result);//上报请求花费时间
+
+ return $result;
+ }
+
+ /**
+ *
+ * 关闭订单,WxPayCloseOrder中out_trade_no必填
+ * appid、mchid、spbill_create_ip、nonce_str不需要填入
+ * @param WxPayConfigInterface $config 配置对象
+ * @param WxPayCloseOrder $inputObj
+ * @param int $timeOut
+ * @throws WxPayException
+ * @return 成功时返回,其他抛异常
+ */
+ public static function closeOrder($config, $inputObj, $timeOut = 6)
+ {
+ $url = "https://api.mch.weixin.qq.com/pay/closeorder";
+ //检测必填参数
+ if(!$inputObj->IsOut_trade_noSet()) {
+ throw new WxPayException("订单查询接口中,out_trade_no必填!");
+ }
+ $inputObj->SetAppid($config->GetAppId());//公众账号ID
+ $inputObj->SetMch_id($config->GetMerchantId());//商户号
+ $inputObj->SetNonce_str(self::getNonceStr());//随机字符串
+
+ $inputObj->SetSign($config);//签名
+ $xml = $inputObj->ToXml();
+
+ $startTimeStamp = self::getMillisecond();//请求开始时间
+ $response = self::postXmlCurl($config, $xml, $url, false, $timeOut);
+ $result = WxPayResults::Init($config, $response);
+ self::reportCostTime($config, $url, $startTimeStamp, $result);//上报请求花费时间
+
+ return $result;
+ }
+
+ /**
+ *
+ * 申请退款,WxPayRefund中out_trade_no、transaction_id至少填一个且
+ * out_refund_no、total_fee、refund_fee、op_user_id为必填参数
+ * appid、mchid、spbill_create_ip、nonce_str不需要填入
+ * @param WxPayConfigInterface $config 配置对象
+ * @param WxPayRefund $inputObj
+ * @param int $timeOut
+ * @throws WxPayException
+ * @return 成功时返回,其他抛异常
+ */
+ public static function refund($config, $inputObj, $timeOut = 6)
+ {
+ $url = "https://api.mch.weixin.qq.com/secapi/pay/refund";
+ //检测必填参数
+ if(!$inputObj->IsOut_trade_noSet() && !$inputObj->IsTransaction_idSet()) {
+ throw new WxPayException("退款申请接口中,out_trade_no、transaction_id至少填一个!");
+ }else if(!$inputObj->IsOut_refund_noSet()){
+ throw new WxPayException("退款申请接口中,缺少必填参数out_refund_no!");
+ }else if(!$inputObj->IsTotal_feeSet()){
+ throw new WxPayException("退款申请接口中,缺少必填参数total_fee!");
+ }else if(!$inputObj->IsRefund_feeSet()){
+ throw new WxPayException("退款申请接口中,缺少必填参数refund_fee!");
+ }else if(!$inputObj->IsOp_user_idSet()){
+ throw new WxPayException("退款申请接口中,缺少必填参数op_user_id!");
+ }
+ $inputObj->SetAppid($config->GetAppId());//公众账号ID
+ $inputObj->SetMch_id($config->GetMerchantId());//商户号
+ $inputObj->SetNonce_str(self::getNonceStr());//随机字符串
+
+ $inputObj->SetSign($config);//签名
+ $xml = $inputObj->ToXml();
+ $startTimeStamp = self::getMillisecond();//请求开始时间
+ $response = self::postXmlCurl($config, $xml, $url, true, $timeOut);
+ $result = WxPayResults::Init($config, $response);
+ self::reportCostTime($config, $url, $startTimeStamp, $result);//上报请求花费时间
+
+ return $result;
+ }
+
+ /**
+ *
+ * 查询退款
+ * 提交退款申请后,通过调用该接口查询退款状态。退款有一定延时,
+ * 用零钱支付的退款20分钟内到账,银行卡支付的退款3个工作日后重新查询退款状态。
+ * WxPayRefundQuery中out_refund_no、out_trade_no、transaction_id、refund_id四个参数必填一个
+ * appid、mchid、spbill_create_ip、nonce_str不需要填入
+ * @param WxPayConfigInterface $config 配置对象
+ * @param WxPayRefundQuery $inputObj
+ * @param int $timeOut
+ * @throws WxPayException
+ * @return 成功时返回,其他抛异常
+ */
+ public static function refundQuery($config, $inputObj, $timeOut = 6)
+ {
+ $url = "https://api.mch.weixin.qq.com/pay/refundquery";
+ //检测必填参数
+ if(!$inputObj->IsOut_refund_noSet() &&
+ !$inputObj->IsOut_trade_noSet() &&
+ !$inputObj->IsTransaction_idSet() &&
+ !$inputObj->IsRefund_idSet()) {
+ throw new WxPayException("退款查询接口中,out_refund_no、out_trade_no、transaction_id、refund_id四个参数必填一个!");
+ }
+ $inputObj->SetAppid($config->GetAppId());//公众账号ID
+ $inputObj->SetMch_id($config->GetMerchantId());//商户号
+ $inputObj->SetNonce_str(self::getNonceStr());//随机字符串
+
+ $inputObj->SetSign($config);//签名
+ $xml = $inputObj->ToXml();
+
+ $startTimeStamp = self::getMillisecond();//请求开始时间
+ $response = self::postXmlCurl($config, $xml, $url, false, $timeOut);
+ $result = WxPayResults::Init($config, $response);
+ self::reportCostTime($config, $url, $startTimeStamp, $result);//上报请求花费时间
+
+ return $result;
+ }
+
+ /**
+ * 下载对账单,WxPayDownloadBill中bill_date为必填参数
+ * appid、mchid、spbill_create_ip、nonce_str不需要填入
+ * @param WxPayConfigInterface $config 配置对象
+ * @param WxPayDownloadBill $inputObj
+ * @param int $timeOut
+ * @throws WxPayException
+ * @return 成功时返回,其他抛异常
+ */
+ public static function downloadBill($config, $inputObj, $timeOut = 6)
+ {
+ $url = "https://api.mch.weixin.qq.com/pay/downloadbill";
+ //检测必填参数
+ if(!$inputObj->IsBill_dateSet()) {
+ throw new WxPayException("对账单接口中,缺少必填参数bill_date!");
+ }
+ $inputObj->SetAppid($config->GetAppId());//公众账号ID
+ $inputObj->SetMch_id($config->GetMerchantId());//商户号
+ $inputObj->SetNonce_str(self::getNonceStr());//随机字符串
+
+ $inputObj->SetSign($config);//签名
+ $xml = $inputObj->ToXml();
+
+ $response = self::postXmlCurl($config, $xml, $url, false, $timeOut);
+ if(substr($response, 0 , 5) == ""){
+ return "";
+ }
+ return $response;
+ }
+
+ /**
+ * 提交被扫支付API
+ * 收银员使用扫码设备读取微信用户刷卡授权码以后,二维码或条码信息传送至商户收银台,
+ * 由商户收银台或者商户后台调用该接口发起支付。
+ * WxPayWxPayMicroPay中body、out_trade_no、total_fee、auth_code参数必填
+ * appid、mchid、spbill_create_ip、nonce_str不需要填入
+ * @param WxPayConfigInterface $config 配置对象
+ * @param WxPayWxPayMicroPay $inputObj
+ * @param int $timeOut
+ */
+ public static function micropay($config, $inputObj, $timeOut = 10)
+ {
+ $url = "https://api.mch.weixin.qq.com/pay/micropay";
+ //检测必填参数
+ if(!$inputObj->IsBodySet()) {
+ throw new WxPayException("提交被扫支付API接口中,缺少必填参数body!");
+ } else if(!$inputObj->IsOut_trade_noSet()) {
+ throw new WxPayException("提交被扫支付API接口中,缺少必填参数out_trade_no!");
+ } else if(!$inputObj->IsTotal_feeSet()) {
+ throw new WxPayException("提交被扫支付API接口中,缺少必填参数total_fee!");
+ } else if(!$inputObj->IsAuth_codeSet()) {
+ throw new WxPayException("提交被扫支付API接口中,缺少必填参数auth_code!");
+ }
+
+ $inputObj->SetSpbill_create_ip($_SERVER['REMOTE_ADDR']);//终端ip
+ $inputObj->SetAppid($config->GetAppId());//公众账号ID
+ $inputObj->SetMch_id($config->GetMerchantId());//商户号
+ $inputObj->SetNonce_str(self::getNonceStr());//随机字符串
+
+ $inputObj->SetSign($config);//签名
+ $xml = $inputObj->ToXml();
+
+ $startTimeStamp = self::getMillisecond();//请求开始时间
+ $response = self::postXmlCurl($config, $xml, $url, false, $timeOut);
+ $result = WxPayResults::Init($config, $response);
+ self::reportCostTime($config, $url, $startTimeStamp, $result);//上报请求花费时间
+
+ return $result;
+ }
+
+ /**
+ *
+ * 撤销订单API接口,WxPayReverse中参数out_trade_no和transaction_id必须填写一个
+ * appid、mchid、spbill_create_ip、nonce_str不需要填入
+ * @param WxPayConfigInterface $config 配置对象
+ * @param WxPayReverse $inputObj
+ * @param int $timeOut
+ * @throws WxPayException
+ */
+ public static function reverse($config, $inputObj, $timeOut = 6)
+ {
+ $url = "https://api.mch.weixin.qq.com/secapi/pay/reverse";
+ //检测必填参数
+ if(!$inputObj->IsOut_trade_noSet() && !$inputObj->IsTransaction_idSet()) {
+ throw new WxPayException("撤销订单API接口中,参数out_trade_no和transaction_id必须填写一个!");
+ }
+
+ $inputObj->SetAppid($config->GetAppId());//公众账号ID
+ $inputObj->SetMch_id($config->GetMerchantId());//商户号
+ $inputObj->SetNonce_str(self::getNonceStr());//随机字符串
+
+ $inputObj->SetSign($config);//签名
+ $xml = $inputObj->ToXml();
+
+ $startTimeStamp = self::getMillisecond();//请求开始时间
+ $response = self::postXmlCurl($config, $xml, $url, true, $timeOut);
+ $result = WxPayResults::Init($config, $response);
+ self::reportCostTime($config, $url, $startTimeStamp, $result);//上报请求花费时间
+
+ return $result;
+ }
+
+ /**
+ *
+ * 测速上报,该方法内部封装在report中,使用时请注意异常流程
+ * WxPayReport中interface_url、return_code、result_code、user_ip、execute_time_必填
+ * appid、mchid、spbill_create_ip、nonce_str不需要填入
+ * @param WxPayConfigInterface $config 配置对象
+ * @param WxPayReport $inputObj
+ * @param int $timeOut
+ * @throws WxPayException
+ * @return 成功时返回,其他抛异常
+ */
+ public static function report($config, $inputObj, $timeOut = 1)
+ {
+ $url = "https://api.mch.weixin.qq.com/payitil/report";
+ //检测必填参数
+ if(!$inputObj->IsInterface_urlSet()) {
+ throw new WxPayException("接口URL,缺少必填参数interface_url!");
+ } if(!$inputObj->IsReturn_codeSet()) {
+ throw new WxPayException("返回状态码,缺少必填参数return_code!");
+ } if(!$inputObj->IsResult_codeSet()) {
+ throw new WxPayException("业务结果,缺少必填参数result_code!");
+ } if(!$inputObj->IsUser_ipSet()) {
+ throw new WxPayException("访问接口IP,缺少必填参数user_ip!");
+ } if(!$inputObj->IsExecute_time_Set()) {
+ throw new WxPayException("接口耗时,缺少必填参数execute_time_!");
+ }
+ $inputObj->SetAppid($config->GetAppId());//公众账号ID
+ $inputObj->SetMch_id($config->GetMerchantId());//商户号
+ $inputObj->SetUser_ip($_SERVER['REMOTE_ADDR']);//终端ip
+ $inputObj->SetTime(date("YmdHis"));//商户上报时间
+ $inputObj->SetNonce_str(self::getNonceStr());//随机字符串
+
+ $inputObj->SetSign($config);//签名
+ $xml = $inputObj->ToXml();
+
+ $startTimeStamp = self::getMillisecond();//请求开始时间
+ $response = self::postXmlCurl($config, $xml, $url, false, $timeOut);
+ return $response;
+ }
+
+ /**
+ *
+ * 生成二维码规则,模式一生成支付二维码
+ * appid、mchid、spbill_create_ip、nonce_str不需要填入
+ * @param WxPayConfigInterface $config 配置对象
+ * @param WxPayBizPayUrl $inputObj
+ * @param int $timeOut
+ * @throws WxPayException
+ * @return 成功时返回,其他抛异常
+ */
+ public static function bizpayurl($config, $inputObj, $timeOut = 6)
+ {
+ if(!$inputObj->IsProduct_idSet()){
+ throw new WxPayException("生成二维码,缺少必填参数product_id!");
+ }
+
+ $inputObj->SetAppid($config->GetAppId());//公众账号ID
+ $inputObj->SetMch_id($config->GetMerchantId());//商户号
+ $inputObj->SetTime_stamp(time());//时间戳
+ $inputObj->SetNonce_str(self::getNonceStr());//随机字符串
+
+ $inputObj->SetSign($config);//签名
+
+ return $inputObj->GetValues();
+ }
+
+ /**
+ *
+ * 转换短链接
+ * 该接口主要用于扫码原生支付模式一中的二维码链接转成短链接(weixin://wxpay/s/XXXXXX),
+ * 减小二维码数据量,提升扫描速度和精确度。
+ * appid、mchid、spbill_create_ip、nonce_str不需要填入
+ * @param WxPayConfigInterface $config 配置对象
+ * @param WxPayShortUrl $inputObj
+ * @param int $timeOut
+ * @throws WxPayException
+ * @return 成功时返回,其他抛异常
+ */
+ public static function shorturl($config, $inputObj, $timeOut = 6)
+ {
+ $url = "https://api.mch.weixin.qq.com/tools/shorturl";
+ //检测必填参数
+ if(!$inputObj->IsLong_urlSet()) {
+ throw new WxPayException("需要转换的URL,签名用原串,传输需URL encode!");
+ }
+ $inputObj->SetAppid($config->GetAppId());//公众账号ID
+ $inputObj->SetMch_id($config->GetMerchantId());//商户号
+ $inputObj->SetNonce_str(self::getNonceStr());//随机字符串
+
+ $inputObj->SetSign($config);//签名
+ $xml = $inputObj->ToXml();
+
+ $startTimeStamp = self::getMillisecond();//请求开始时间
+ $response = self::postXmlCurl($config, $xml, $url, false, $timeOut);
+ $result = WxPayResults::Init($config, $response);
+ self::reportCostTime($config, $url, $startTimeStamp, $result);//上报请求花费时间
+
+ return $result;
+ }
+
+ /**
+ *
+ * 支付结果通用通知
+ * @param function $callback
+ * 直接回调函数使用方法: notify(you_function);
+ * 回调类成员函数方法:notify(array($this, you_function));
+ * $callback 原型为:function function_name($data){}
+ */
+ public static function notify($config, $callback, &$msg)
+ {
+ //获取通知的数据
+ $xml = isset($GLOBALS['HTTP_RAW_POST_DATA']) ? $GLOBALS['HTTP_RAW_POST_DATA'] : file_get_contents("php://input");
+ if (empty($xml)) {
+ # 如果没有数据,直接返回失败
+ return false;
+ }
+
+ //如果返回成功则验证签名
+ try {
+ $result = WxPayNotifyResults::Init($config, $xml);
+ } catch (WxPayException $e){
+ $msg = $e->errorMessage();
+ return false;
+ }
+
+ return call_user_func($callback, $result);
+ }
+
+ /**
+ *
+ * 产生随机字符串,不长于32位
+ * @param int $length
+ * @return 产生的随机字符串
+ */
+ public static function getNonceStr($length = 32)
+ {
+ $chars = "abcdefghijklmnopqrstuvwxyz0123456789";
+ $str ="";
+ for ( $i = 0; $i < $length; $i++ ) {
+ $str .= substr($chars, mt_rand(0, strlen($chars)-1), 1);
+ }
+ return $str;
+ }
+
+ /**
+ * 直接输出xml
+ * @param string $xml
+ */
+ public static function replyNotify($xml)
+ {
+ echo $xml;
+ }
+
+ /**
+ *
+ * 上报数据, 上报的时候将屏蔽所有异常流程
+ * @param WxPayConfigInterface $config 配置对象
+ * @param string $usrl
+ * @param int $startTimeStamp
+ * @param array $data
+ */
+ private static function reportCostTime($config, $url, $startTimeStamp, $data)
+ {
+ //如果不需要上报数据
+ $reportLevenl = $config->GetReportLevenl();
+ if($reportLevenl == 0){
+ return;
+ }
+ //如果仅失败上报
+ if($reportLevenl == 1 &&
+ array_key_exists("return_code", $data) &&
+ $data["return_code"] == "SUCCESS" &&
+ array_key_exists("result_code", $data) &&
+ $data["result_code"] == "SUCCESS")
+ {
+ return;
+ }
+
+ //上报逻辑
+ $endTimeStamp = self::getMillisecond();
+ $objInput = new WxPayReport();
+ $objInput->SetInterface_url($url);
+ $objInput->SetExecute_time_($endTimeStamp - $startTimeStamp);
+ //返回状态码
+ if(array_key_exists("return_code", $data)){
+ $objInput->SetReturn_code($data["return_code"]);
+ }
+ //返回信息
+ if(array_key_exists("return_msg", $data)){
+ $objInput->SetReturn_msg($data["return_msg"]);
+ }
+ //业务结果
+ if(array_key_exists("result_code", $data)){
+ $objInput->SetResult_code($data["result_code"]);
+ }
+ //错误代码
+ if(array_key_exists("err_code", $data)){
+ $objInput->SetErr_code($data["err_code"]);
+ }
+ //错误代码描述
+ if(array_key_exists("err_code_des", $data)){
+ $objInput->SetErr_code_des($data["err_code_des"]);
+ }
+ //商户订单号
+ if(array_key_exists("out_trade_no", $data)){
+ $objInput->SetOut_trade_no($data["out_trade_no"]);
+ }
+ //设备号
+ if(array_key_exists("device_info", $data)){
+ $objInput->SetDevice_info($data["device_info"]);
+ }
+
+ try{
+ self::report($config, $objInput);
+ } catch (WxPayException $e){
+ //不做任何处理
+ }
+ }
+
+ /**
+ * 以post方式提交xml到对应的接口url
+ *
+ * @param WxPayConfigInterface $config 配置对象
+ * @param string $xml 需要post的xml数据
+ * @param string $url url
+ * @param bool $useCert 是否需要证书,默认不需要
+ * @param int $second url执行超时时间,默认30s
+ * @throws WxPayException
+ */
+ private static function postXmlCurl($config, $xml, $url, $useCert = false, $second = 30)
+ {
+ $ch = curl_init();
+ $curlVersion = curl_version();
+ $ua = "WXPaySDK/".self::$VERSION." (".PHP_OS.") PHP/".PHP_VERSION." CURL/".$curlVersion['version']." "
+ .$config->GetMerchantId();
+
+ //设置超时
+ curl_setopt($ch, CURLOPT_TIMEOUT, $second);
+
+ $proxyHost = "0.0.0.0";
+ $proxyPort = 0;
+ $config->GetProxy($proxyHost, $proxyPort);
+ //如果有配置代理这里就设置代理
+ if($proxyHost != "0.0.0.0" && $proxyPort != 0){
+ curl_setopt($ch,CURLOPT_PROXY, $proxyHost);
+ curl_setopt($ch,CURLOPT_PROXYPORT, $proxyPort);
+ }
+ curl_setopt($ch,CURLOPT_URL, $url);
+ curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,TRUE);
+ curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,2);//严格校验
+ curl_setopt($ch,CURLOPT_USERAGENT, $ua);
+ //设置header
+ curl_setopt($ch, CURLOPT_HEADER, FALSE);
+ //要求结果为字符串且输出到屏幕上
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
+
+ if($useCert == true){
+ //设置证书
+ //使用证书:cert 与 key 分别属于两个.pem文件
+ //证书文件请放入服务器的非web目录下
+ $sslCertPath = "";
+ $sslKeyPath = "";
+ $config->GetSSLCertPath($sslCertPath, $sslKeyPath);
+ curl_setopt($ch,CURLOPT_SSLCERTTYPE,'PEM');
+ curl_setopt($ch,CURLOPT_SSLCERT, $sslCertPath);
+ curl_setopt($ch,CURLOPT_SSLKEYTYPE,'PEM');
+ curl_setopt($ch,CURLOPT_SSLKEY, $sslKeyPath);
+ }
+ //post提交方式
+ curl_setopt($ch, CURLOPT_POST, TRUE);
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
+ //运行curl
+ $data = curl_exec($ch);
+ //返回结果
+ if($data){
+ curl_close($ch);
+ return $data;
+ } else {
+ $error = curl_errno($ch);
+ curl_close($ch);
+ throw new WxPayException("curl出错,错误码:$error");
+ }
+ }
+
+ /**
+ * 获取毫秒级别的时间戳
+ */
+ private static function getMillisecond()
+ {
+ //获取毫秒的时间戳
+ $time = explode ( " ", microtime () );
+ $time = $time[1] . ($time[0] * 1000);
+ $time2 = explode( ".", $time );
+ $time = $time2[0];
+ return $time;
+ }
+}
+
diff --git a/serve/extend/wechat/WxPay.Config.Interface.php b/serve/extend/wechat/WxPay.Config.Interface.php
new file mode 100644
index 0000000..5f02e5b
--- /dev/null
+++ b/serve/extend/wechat/WxPay.Config.Interface.php
@@ -0,0 +1,76 @@
+appId;
+ }
+
+ //商户号
+ public function GetMerchantId(){
+ return $this->merchantId;
+ }
+
+ //异步通知地址
+ public function GetNotifyUrl(){
+ return $this->notifyUrl;
+ }
+
+ //签名方式
+ public function GetSignType(){
+ return $this->signType;
+ }
+
+ //代理信息
+ public function GetProxy(&$proxyHost, &$proxyPort){
+ $proxyHost = $this->proxyHost;
+ $proxyPort = $this->proxyPort;
+ }
+
+ //错误上报等级
+ public function GetReportLevenl(){
+ return $this->reportLevenl;
+ }
+
+ //支付密钥
+ public function GetKey(){
+ return $this->key;
+ }
+
+ //公众帐号secert
+ public function GetAppSecret(){
+ return $this->appSecret;
+ }
+
+ //证书路径
+ public function GetSSLCertPath(&$sslCertPath, &$sslKeyPath){
+ $sslCertPath = $this->sslCertPath;
+ $sslKeyPath = $this->sslKeyPath;
+ }
+}
diff --git a/serve/extend/wechat/WxPay.Data.php b/serve/extend/wechat/WxPay.Data.php
new file mode 100644
index 0000000..fcb4390
--- /dev/null
+++ b/serve/extend/wechat/WxPay.Data.php
@@ -0,0 +1,3094 @@
+values['sign_type'] = $sign_type;
+ return $sign_type;
+ }
+
+ /**
+ * 设置签名,详见签名生成算法
+ * @param string $value
+ **/
+ public function SetSign($config)
+ {
+ $sign = $this->MakeSign($config);
+ $this->values['sign'] = $sign;
+ return $sign;
+ }
+
+ /**
+ * 获取签名,详见签名生成算法的值
+ * @return 值
+ **/
+ public function GetSign()
+ {
+ return $this->values['sign'];
+ }
+
+ /**
+ * 判断签名,详见签名生成算法是否存在
+ * @return true 或 false
+ **/
+ public function IsSignSet()
+ {
+ return array_key_exists('sign', $this->values);
+ }
+
+ /**
+ * 输出xml字符
+ * @throws WxPayException
+ **/
+ public function ToXml()
+ {
+ if(!is_array($this->values) || count($this->values) <= 0)
+ {
+ throw new WxPayException("数组数据异常!");
+ }
+
+ $xml = "";
+ foreach ($this->values as $key=>$val)
+ {
+ if (is_numeric($val)){
+ $xml.="<".$key.">".$val."".$key.">";
+ }else{
+ $xml.="<".$key.">".$key.">";
+ }
+ }
+ $xml.="";
+ return $xml;
+ }
+
+ /**
+ * 将xml转为array
+ * @param string $xml
+ * @throws WxPayException
+ */
+ public function FromXml($xml)
+ {
+ if(!$xml){
+ throw new WxPayException("xml数据异常!");
+ }
+ //将XML转为array
+ //禁止引用外部xml实体
+ libxml_disable_entity_loader(true);
+ $this->values = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
+ return $this->values;
+ }
+
+ /**
+ * 格式化参数格式化成url参数
+ */
+ public function ToUrlParams()
+ {
+ $buff = "";
+ foreach ($this->values as $k => $v)
+ {
+ if($k != "sign" && $v != "" && !is_array($v)){
+ $buff .= $k . "=" . $v . "&";
+ }
+ }
+
+ $buff = trim($buff, "&");
+ return $buff;
+ }
+
+ /**
+ * 生成签名
+ * @param WxPayConfigInterface $config 配置对象
+ * @param bool $needSignType 是否需要补signtype
+ * @return 签名,本函数不覆盖sign成员变量,如要设置签名需要调用SetSign方法赋值
+ */
+ public function MakeSign($config, $needSignType = true)
+ {
+ if($needSignType) {
+ $this->SetSignType($config->GetSignType());
+ }
+ //签名步骤一:按字典序排序参数
+ ksort($this->values);
+ $string = $this->ToUrlParams();
+ //签名步骤二:在string后加入KEY
+ $string = $string . "&key=".$config->GetKey();
+ //签名步骤三:MD5加密或者HMAC-SHA256
+ if($config->GetSignType() == "MD5"){
+ $string = md5($string);
+ } else if($config->GetSignType() == "HMAC-SHA256") {
+ $string = hash_hmac("sha256",$string ,$config->GetKey());
+ } else {
+ throw new WxPayException("签名类型不支持!");
+ }
+
+ //签名步骤四:所有字符转为大写
+ $result = strtoupper($string);
+ return $result;
+ }
+
+ /**
+ * 获取设置的值
+ */
+ public function GetValues()
+ {
+ return $this->values;
+ }
+}
+
+/**
+ *
+ * 只使用md5算法进行签名, 不管配置的是什么签名方式,都只支持md5签名方式
+ *
+**/
+class WxPayDataBaseSignMd5 extends WxPayDataBase
+{
+ /**
+ * 生成签名 - 重写该方法
+ * @param WxPayConfigInterface $config 配置对象
+ * @param bool $needSignType 是否需要补signtype
+ * @return 签名,本函数不覆盖sign成员变量,如要设置签名需要调用SetSign方法赋值
+ */
+ public function MakeSign($config, $needSignType = false)
+ {
+ if($needSignType) {
+ $this->SetSignType($config->GetSignType());
+ }
+ //签名步骤一:按字典序排序参数
+ ksort($this->values);
+ $string = $this->ToUrlParams();
+ //签名步骤二:在string后加入KEY
+ $string = $string . "&key=".$config->GetKey();
+ //签名步骤三:MD5加密
+ $string = md5($string);
+ //签名步骤四:所有字符转为大写
+ $result = strtoupper($string);
+ return $result;
+ }
+}
+
+/**
+ *
+ * 接口调用结果类
+ * @author widyhu
+ *
+ */
+class WxPayResults extends WxPayDataBase
+{
+ /**
+ * 生成签名 - 重写该方法
+ * @param WxPayConfigInterface $config 配置对象
+ * @param bool $needSignType 是否需要补signtype
+ * @return 签名,本函数不覆盖sign成员变量,如要设置签名需要调用SetSign方法赋值
+ */
+ public function MakeSign($config, $needSignType = false)
+ {
+ //签名步骤一:按字典序排序参数
+ ksort($this->values);
+ $string = $this->ToUrlParams();
+ //签名步骤二:在string后加入KEY
+ $string = $string . "&key=".$config->GetKey();
+ //签名步骤三:MD5加密或者HMAC-SHA256
+ if(strlen($this->GetSign()) <= 32){
+ //如果签名小于等于32个,则使用md5验证
+ $string = md5($string);
+ } else {
+ //是用sha256校验
+ $string = hash_hmac("sha256",$string ,$config->GetKey());
+ }
+ //签名步骤四:所有字符转为大写
+ $result = strtoupper($string);
+ return $result;
+ }
+
+ /**
+ * @param WxPayConfigInterface $config 配置对象
+ * 检测签名
+ */
+ public function CheckSign($config)
+ {
+ if(!$this->IsSignSet()){
+ throw new WxPayException("签名错误!");
+ }
+
+ $sign = $this->MakeSign($config, false);
+ if($this->GetSign() == $sign){
+ //签名正确
+ return true;
+ }
+ throw new WxPayException("签名错误!");
+ }
+
+ /**
+ *
+ * 使用数组初始化
+ * @param array $array
+ */
+ public function FromArray($array)
+ {
+ $this->values = $array;
+ }
+
+ /**
+ *
+ * 使用数组初始化对象
+ * @param array $array
+ * @param 是否检测签名 $noCheckSign
+ */
+ public static function InitFromArray($config, $array, $noCheckSign = false)
+ {
+ $obj = new self();
+ $obj->FromArray($array);
+ if($noCheckSign == false){
+ $obj->CheckSign($config);
+ }
+ return $obj;
+ }
+
+ /**
+ *
+ * 设置参数
+ * @param string $key
+ * @param string $value
+ */
+ public function SetData($key, $value)
+ {
+ $this->values[$key] = $value;
+ }
+
+ /**
+ * 将xml转为array
+ * @param WxPayConfigInterface $config 配置对象
+ * @param string $xml
+ * @throws WxPayException
+ */
+ public static function Init($config, $xml)
+ {
+ $obj = new self();
+ $obj->FromXml($xml);
+ //失败则直接返回失败
+ if($obj->values['return_code'] != 'SUCCESS') {
+ foreach ($obj->values as $key => $value) {
+ #除了return_code和return_msg之外其他的参数存在,则报错
+ if($key != "return_code" && $key != "return_msg"){
+ throw new WxPayException("输入数据存在异常!");
+ return false;
+ }
+ }
+ return $obj->GetValues();
+ }
+ $obj->CheckSign($config);
+ return $obj->GetValues();
+ }
+}
+
+/**
+ *
+ * 回调回包数据基类
+ *
+ **/
+class WxPayNotifyResults extends WxPayResults
+{
+ /**
+ * 将xml转为array
+ * @param WxPayConfigInterface $config
+ * @param string $xml
+ * @return WxPayNotifyResults
+ * @throws WxPayException
+ */
+ public static function Init($config, $xml)
+ {
+ $obj = new self();
+ $obj->FromXml($xml);
+ //失败则直接返回失败
+ $obj->CheckSign($config);
+ return $obj;
+ }
+}
+
+/**
+ *
+ * 回调基础类
+ * @author widyhu
+ *
+ */
+class WxPayNotifyReply extends WxPayDataBaseSignMd5
+{
+ /**
+ *
+ * 设置错误码 FAIL 或者 SUCCESS
+ * @param string
+ */
+ public function SetReturn_code($return_code)
+ {
+ $this->values['return_code'] = $return_code;
+ }
+
+ /**
+ *
+ * 获取错误码 FAIL 或者 SUCCESS
+ * @return string $return_code
+ */
+ public function GetReturn_code()
+ {
+ return $this->values['return_code'];
+ }
+
+ /**
+ *
+ * 设置错误信息
+ * @param string $return_code
+ */
+ public function SetReturn_msg($return_msg)
+ {
+ $this->values['return_msg'] = $return_msg;
+ }
+
+ /**
+ *
+ * 获取错误信息
+ * @return string
+ */
+ public function GetReturn_msg()
+ {
+ return $this->values['return_msg'];
+ }
+
+ /**
+ *
+ * 设置返回参数
+ * @param string $key
+ * @param string $value
+ */
+ public function SetData($key, $value)
+ {
+ $this->values[$key] = $value;
+ }
+}
+
+/**
+ *
+ * 统一下单输入对象
+ * @author widyhu
+ *
+ */
+class WxPayUnifiedOrder extends WxPayDataBase
+{
+ /**
+ * 设置微信分配的公众账号ID
+ * @param string $value
+ **/
+ public function SetAppid($value)
+ {
+ $this->values['appid'] = $value;
+ }
+ /**
+ * 获取微信分配的公众账号ID的值
+ * @return 值
+ **/
+ public function GetAppid()
+ {
+ return $this->values['appid'];
+ }
+ /**
+ * 判断微信分配的公众账号ID是否存在
+ * @return true 或 false
+ **/
+ public function IsAppidSet()
+ {
+ return array_key_exists('appid', $this->values);
+ }
+
+
+ /**
+ * 设置微信支付分配的商户号
+ * @param string $value
+ **/
+ public function SetMch_id($value)
+ {
+ $this->values['mch_id'] = $value;
+ }
+ /**
+ * 获取微信支付分配的商户号的值
+ * @return 值
+ **/
+ public function GetMch_id()
+ {
+ return $this->values['mch_id'];
+ }
+ /**
+ * 判断微信支付分配的商户号是否存在
+ * @return true 或 false
+ **/
+ public function IsMch_idSet()
+ {
+ return array_key_exists('mch_id', $this->values);
+ }
+
+
+ /**
+ * 设置微信支付分配的终端设备号,商户自定义
+ * @param string $value
+ **/
+ public function SetDevice_info($value)
+ {
+ $this->values['device_info'] = $value;
+ }
+ /**
+ * 获取微信支付分配的终端设备号,商户自定义的值
+ * @return 值
+ **/
+ public function GetDevice_info()
+ {
+ return $this->values['device_info'];
+ }
+ /**
+ * 判断微信支付分配的终端设备号,商户自定义是否存在
+ * @return true 或 false
+ **/
+ public function IsDevice_infoSet()
+ {
+ return array_key_exists('device_info', $this->values);
+ }
+
+
+ /**
+ * 设置随机字符串,不长于32位。推荐随机数生成算法
+ * @param string $value
+ **/
+ public function SetNonce_str($value)
+ {
+ $this->values['nonce_str'] = $value;
+ }
+ /**
+ * 获取随机字符串,不长于32位。推荐随机数生成算法的值
+ * @return 值
+ **/
+ public function GetNonce_str()
+ {
+ return $this->values['nonce_str'];
+ }
+ /**
+ * 判断随机字符串,不长于32位。推荐随机数生成算法是否存在
+ * @return true 或 false
+ **/
+ public function IsNonce_strSet()
+ {
+ return array_key_exists('nonce_str', $this->values);
+ }
+
+ /**
+ * 设置商品或支付单简要描述
+ * @param string $value
+ **/
+ public function SetBody($value)
+ {
+ $this->values['body'] = $value;
+ }
+ /**
+ * 获取商品或支付单简要描述的值
+ * @return 值
+ **/
+ public function GetBody()
+ {
+ return $this->values['body'];
+ }
+ /**
+ * 判断商品或支付单简要描述是否存在
+ * @return true 或 false
+ **/
+ public function IsBodySet()
+ {
+ return array_key_exists('body', $this->values);
+ }
+
+
+ /**
+ * 设置商品名称明细列表
+ * @param string $value
+ **/
+ public function SetDetail($value)
+ {
+ $this->values['detail'] = $value;
+ }
+ /**
+ * 获取商品名称明细列表的值
+ * @return 值
+ **/
+ public function GetDetail()
+ {
+ return $this->values['detail'];
+ }
+ /**
+ * 判断商品名称明细列表是否存在
+ * @return true 或 false
+ **/
+ public function IsDetailSet()
+ {
+ return array_key_exists('detail', $this->values);
+ }
+
+
+ /**
+ * 设置附加数据,在查询API和支付通知中原样返回,该字段主要用于商户携带订单的自定义数据
+ * @param string $value
+ **/
+ public function SetAttach($value)
+ {
+ $this->values['attach'] = $value;
+ }
+ /**
+ * 获取附加数据,在查询API和支付通知中原样返回,该字段主要用于商户携带订单的自定义数据的值
+ * @return 值
+ **/
+ public function GetAttach()
+ {
+ return $this->values['attach'];
+ }
+ /**
+ * 判断附加数据,在查询API和支付通知中原样返回,该字段主要用于商户携带订单的自定义数据是否存在
+ * @return true 或 false
+ **/
+ public function IsAttachSet()
+ {
+ return array_key_exists('attach', $this->values);
+ }
+
+
+ /**
+ * 设置商户系统内部的订单号,32个字符内、可包含字母, 其他说明见商户订单号
+ * @param string $value
+ **/
+ public function SetOut_trade_no($value)
+ {
+ $this->values['out_trade_no'] = $value;
+ }
+ /**
+ * 获取商户系统内部的订单号,32个字符内、可包含字母, 其他说明见商户订单号的值
+ * @return 值
+ **/
+ public function GetOut_trade_no()
+ {
+ return $this->values['out_trade_no'];
+ }
+ /**
+ * 判断商户系统内部的订单号,32个字符内、可包含字母, 其他说明见商户订单号是否存在
+ * @return true 或 false
+ **/
+ public function IsOut_trade_noSet()
+ {
+ return array_key_exists('out_trade_no', $this->values);
+ }
+
+
+ /**
+ * 设置符合ISO 4217标准的三位字母代码,默认人民币:CNY,其他值列表详见货币类型
+ * @param string $value
+ **/
+ public function SetFee_type($value)
+ {
+ $this->values['fee_type'] = $value;
+ }
+ /**
+ * 获取符合ISO 4217标准的三位字母代码,默认人民币:CNY,其他值列表详见货币类型的值
+ * @return 值
+ **/
+ public function GetFee_type()
+ {
+ return $this->values['fee_type'];
+ }
+ /**
+ * 判断符合ISO 4217标准的三位字母代码,默认人民币:CNY,其他值列表详见货币类型是否存在
+ * @return true 或 false
+ **/
+ public function IsFee_typeSet()
+ {
+ return array_key_exists('fee_type', $this->values);
+ }
+
+
+ /**
+ * 设置订单总金额,只能为整数,详见支付金额
+ * @param string $value
+ **/
+ public function SetTotal_fee($value)
+ {
+ $this->values['total_fee'] = $value;
+ }
+ /**
+ * 获取订单总金额,只能为整数,详见支付金额的值
+ * @return 值
+ **/
+ public function GetTotal_fee()
+ {
+ return $this->values['total_fee'];
+ }
+ /**
+ * 判断订单总金额,只能为整数,详见支付金额是否存在
+ * @return true 或 false
+ **/
+ public function IsTotal_feeSet()
+ {
+ return array_key_exists('total_fee', $this->values);
+ }
+
+
+ /**
+ * 设置APP和网页支付提交用户端ip,Native支付填调用微信支付API的机器IP。
+ * @param string $value
+ **/
+ public function SetSpbill_create_ip($value)
+ {
+ $this->values['spbill_create_ip'] = $value;
+ }
+ /**
+ * 获取APP和网页支付提交用户端ip,Native支付填调用微信支付API的机器IP。的值
+ * @return 值
+ **/
+ public function GetSpbill_create_ip()
+ {
+ return $this->values['spbill_create_ip'];
+ }
+ /**
+ * 判断APP和网页支付提交用户端ip,Native支付填调用微信支付API的机器IP。是否存在
+ * @return true 或 false
+ **/
+ public function IsSpbill_create_ipSet()
+ {
+ return array_key_exists('spbill_create_ip', $this->values);
+ }
+
+
+ /**
+ * 设置订单生成时间,格式为yyyyMMddHHmmss,如2009年12月25日9点10分10秒表示为20091225091010。其他详见时间规则
+ * @param string $value
+ **/
+ public function SetTime_start($value)
+ {
+ $this->values['time_start'] = $value;
+ }
+ /**
+ * 获取订单生成时间,格式为yyyyMMddHHmmss,如2009年12月25日9点10分10秒表示为20091225091010。其他详见时间规则的值
+ * @return 值
+ **/
+ public function GetTime_start()
+ {
+ return $this->values['time_start'];
+ }
+ /**
+ * 判断订单生成时间,格式为yyyyMMddHHmmss,如2009年12月25日9点10分10秒表示为20091225091010。其他详见时间规则是否存在
+ * @return true 或 false
+ **/
+ public function IsTime_startSet()
+ {
+ return array_key_exists('time_start', $this->values);
+ }
+
+
+ /**
+ * 设置订单失效时间,格式为yyyyMMddHHmmss,如2009年12月27日9点10分10秒表示为20091227091010。其他详见时间规则
+ * @param string $value
+ **/
+ public function SetTime_expire($value)
+ {
+ $this->values['time_expire'] = $value;
+ }
+ /**
+ * 获取订单失效时间,格式为yyyyMMddHHmmss,如2009年12月27日9点10分10秒表示为20091227091010。其他详见时间规则的值
+ * @return 值
+ **/
+ public function GetTime_expire()
+ {
+ return $this->values['time_expire'];
+ }
+ /**
+ * 判断订单失效时间,格式为yyyyMMddHHmmss,如2009年12月27日9点10分10秒表示为20091227091010。其他详见时间规则是否存在
+ * @return true 或 false
+ **/
+ public function IsTime_expireSet()
+ {
+ return array_key_exists('time_expire', $this->values);
+ }
+
+
+ /**
+ * 设置商品标记,代金券或立减优惠功能的参数,说明详见代金券或立减优惠
+ * @param string $value
+ **/
+ public function SetGoods_tag($value)
+ {
+ $this->values['goods_tag'] = $value;
+ }
+ /**
+ * 获取商品标记,代金券或立减优惠功能的参数,说明详见代金券或立减优惠的值
+ * @return 值
+ **/
+ public function GetGoods_tag()
+ {
+ return $this->values['goods_tag'];
+ }
+ /**
+ * 判断商品标记,代金券或立减优惠功能的参数,说明详见代金券或立减优惠是否存在
+ * @return true 或 false
+ **/
+ public function IsGoods_tagSet()
+ {
+ return array_key_exists('goods_tag', $this->values);
+ }
+
+
+ /**
+ * 设置接收微信支付异步通知回调地址
+ * @param string $value
+ **/
+ public function SetNotify_url($value)
+ {
+ $this->values['notify_url'] = $value;
+ }
+ /**
+ * 获取接收微信支付异步通知回调地址的值
+ * @return 值
+ **/
+ public function GetNotify_url()
+ {
+ return $this->values['notify_url'];
+ }
+ /**
+ * 判断接收微信支付异步通知回调地址是否存在
+ * @return true 或 false
+ **/
+ public function IsNotify_urlSet()
+ {
+ return array_key_exists('notify_url', $this->values);
+ }
+
+
+ /**
+ * 设置取值如下:JSAPI,NATIVE,APP,详细说明见参数规定
+ * @param string $value
+ **/
+ public function SetTrade_type($value)
+ {
+ $this->values['trade_type'] = $value;
+ }
+ /**
+ * 获取取值如下:JSAPI,NATIVE,APP,详细说明见参数规定的值
+ * @return 值
+ **/
+ public function GetTrade_type()
+ {
+ return $this->values['trade_type'];
+ }
+ /**
+ * 判断取值如下:JSAPI,NATIVE,APP,详细说明见参数规定是否存在
+ * @return true 或 false
+ **/
+ public function IsTrade_typeSet()
+ {
+ return array_key_exists('trade_type', $this->values);
+ }
+
+
+ /**
+ * 设置trade_type=NATIVE,此参数必传。此id为二维码中包含的商品ID,商户自行定义。
+ * @param string $value
+ **/
+ public function SetProduct_id($value)
+ {
+ $this->values['product_id'] = $value;
+ }
+ /**
+ * 获取trade_type=NATIVE,此参数必传。此id为二维码中包含的商品ID,商户自行定义。的值
+ * @return 值
+ **/
+ public function GetProduct_id()
+ {
+ return $this->values['product_id'];
+ }
+ /**
+ * 判断trade_type=NATIVE,此参数必传。此id为二维码中包含的商品ID,商户自行定义。是否存在
+ * @return true 或 false
+ **/
+ public function IsProduct_idSet()
+ {
+ return array_key_exists('product_id', $this->values);
+ }
+
+
+ /**
+ * 设置trade_type=JSAPI,此参数必传,用户在商户appid下的唯一标识。下单前需要调用【网页授权获取用户信息】接口获取到用户的Openid。
+ * @param string $value
+ **/
+ public function SetOpenid($value)
+ {
+ $this->values['openid'] = $value;
+ }
+ /**
+ * 获取trade_type=JSAPI,此参数必传,用户在商户appid下的唯一标识。下单前需要调用【网页授权获取用户信息】接口获取到用户的Openid。 的值
+ * @return 值
+ **/
+ public function GetOpenid()
+ {
+ return $this->values['openid'];
+ }
+ /**
+ * 判断trade_type=JSAPI,此参数必传,用户在商户appid下的唯一标识。下单前需要调用【网页授权获取用户信息】接口获取到用户的Openid。 是否存在
+ * @return true 或 false
+ **/
+ public function IsOpenidSet()
+ {
+ return array_key_exists('openid', $this->values);
+ }
+}
+
+/**
+ *
+ * 订单查询输入对象
+ * @author widyhu
+ *
+ */
+class WxPayOrderQuery extends WxPayDataBase
+{
+ /**
+ * 设置微信分配的公众账号ID
+ * @param string $value
+ **/
+ public function SetAppid($value)
+ {
+ $this->values['appid'] = $value;
+ }
+ /**
+ * 获取微信分配的公众账号ID的值
+ * @return 值
+ **/
+ public function GetAppid()
+ {
+ return $this->values['appid'];
+ }
+ /**
+ * 判断微信分配的公众账号ID是否存在
+ * @return true 或 false
+ **/
+ public function IsAppidSet()
+ {
+ return array_key_exists('appid', $this->values);
+ }
+
+
+ /**
+ * 设置微信支付分配的商户号
+ * @param string $value
+ **/
+ public function SetMch_id($value)
+ {
+ $this->values['mch_id'] = $value;
+ }
+ /**
+ * 获取微信支付分配的商户号的值
+ * @return 值
+ **/
+ public function GetMch_id()
+ {
+ return $this->values['mch_id'];
+ }
+ /**
+ * 判断微信支付分配的商户号是否存在
+ * @return true 或 false
+ **/
+ public function IsMch_idSet()
+ {
+ return array_key_exists('mch_id', $this->values);
+ }
+
+
+ /**
+ * 设置微信的订单号,优先使用
+ * @param string $value
+ **/
+ public function SetTransaction_id($value)
+ {
+ $this->values['transaction_id'] = $value;
+ }
+ /**
+ * 获取微信的订单号,优先使用的值
+ * @return 值
+ **/
+ public function GetTransaction_id()
+ {
+ return $this->values['transaction_id'];
+ }
+ /**
+ * 判断微信的订单号,优先使用是否存在
+ * @return true 或 false
+ **/
+ public function IsTransaction_idSet()
+ {
+ return array_key_exists('transaction_id', $this->values);
+ }
+
+
+ /**
+ * 设置商户系统内部的订单号,当没提供transaction_id时需要传这个。
+ * @param string $value
+ **/
+ public function SetOut_trade_no($value)
+ {
+ $this->values['out_trade_no'] = $value;
+ }
+ /**
+ * 获取商户系统内部的订单号,当没提供transaction_id时需要传这个。的值
+ * @return 值
+ **/
+ public function GetOut_trade_no()
+ {
+ return $this->values['out_trade_no'];
+ }
+ /**
+ * 判断商户系统内部的订单号,当没提供transaction_id时需要传这个。是否存在
+ * @return true 或 false
+ **/
+ public function IsOut_trade_noSet()
+ {
+ return array_key_exists('out_trade_no', $this->values);
+ }
+
+
+ /**
+ * 设置随机字符串,不长于32位。推荐随机数生成算法
+ * @param string $value
+ **/
+ public function SetNonce_str($value)
+ {
+ $this->values['nonce_str'] = $value;
+ }
+ /**
+ * 获取随机字符串,不长于32位。推荐随机数生成算法的值
+ * @return 值
+ **/
+ public function GetNonce_str()
+ {
+ return $this->values['nonce_str'];
+ }
+ /**
+ * 判断随机字符串,不长于32位。推荐随机数生成算法是否存在
+ * @return true 或 false
+ **/
+ public function IsNonce_strSet()
+ {
+ return array_key_exists('nonce_str', $this->values);
+ }
+}
+
+/**
+ *
+ * 关闭订单输入对象
+ * @author widyhu
+ *
+ */
+class WxPayCloseOrder extends WxPayDataBase
+{
+ /**
+ * 设置微信分配的公众账号ID
+ * @param string $value
+ **/
+ public function SetAppid($value)
+ {
+ $this->values['appid'] = $value;
+ }
+ /**
+ * 获取微信分配的公众账号ID的值
+ * @return 值
+ **/
+ public function GetAppid()
+ {
+ return $this->values['appid'];
+ }
+ /**
+ * 判断微信分配的公众账号ID是否存在
+ * @return true 或 false
+ **/
+ public function IsAppidSet()
+ {
+ return array_key_exists('appid', $this->values);
+ }
+
+
+ /**
+ * 设置微信支付分配的商户号
+ * @param string $value
+ **/
+ public function SetMch_id($value)
+ {
+ $this->values['mch_id'] = $value;
+ }
+ /**
+ * 获取微信支付分配的商户号的值
+ * @return 值
+ **/
+ public function GetMch_id()
+ {
+ return $this->values['mch_id'];
+ }
+ /**
+ * 判断微信支付分配的商户号是否存在
+ * @return true 或 false
+ **/
+ public function IsMch_idSet()
+ {
+ return array_key_exists('mch_id', $this->values);
+ }
+
+
+ /**
+ * 设置商户系统内部的订单号
+ * @param string $value
+ **/
+ public function SetOut_trade_no($value)
+ {
+ $this->values['out_trade_no'] = $value;
+ }
+ /**
+ * 获取商户系统内部的订单号的值
+ * @return 值
+ **/
+ public function GetOut_trade_no()
+ {
+ return $this->values['out_trade_no'];
+ }
+ /**
+ * 判断商户系统内部的订单号是否存在
+ * @return true 或 false
+ **/
+ public function IsOut_trade_noSet()
+ {
+ return array_key_exists('out_trade_no', $this->values);
+ }
+
+
+ /**
+ * 设置商户系统内部的订单号,32个字符内、可包含字母, 其他说明见商户订单号
+ * @param string $value
+ **/
+ public function SetNonce_str($value)
+ {
+ $this->values['nonce_str'] = $value;
+ }
+ /**
+ * 获取商户系统内部的订单号,32个字符内、可包含字母, 其他说明见商户订单号的值
+ * @return 值
+ **/
+ public function GetNonce_str()
+ {
+ return $this->values['nonce_str'];
+ }
+ /**
+ * 判断商户系统内部的订单号,32个字符内、可包含字母, 其他说明见商户订单号是否存在
+ * @return true 或 false
+ **/
+ public function IsNonce_strSet()
+ {
+ return array_key_exists('nonce_str', $this->values);
+ }
+}
+
+/**
+ *
+ * 提交退款输入对象
+ * @author widyhu
+ *
+ */
+class WxPayRefund extends WxPayDataBase
+{
+ /**
+ * 设置微信分配的公众账号ID
+ * @param string $value
+ **/
+ public function SetAppid($value)
+ {
+ $this->values['appid'] = $value;
+ }
+ /**
+ * 获取微信分配的公众账号ID的值
+ * @return 值
+ **/
+ public function GetAppid()
+ {
+ return $this->values['appid'];
+ }
+ /**
+ * 判断微信分配的公众账号ID是否存在
+ * @return true 或 false
+ **/
+ public function IsAppidSet()
+ {
+ return array_key_exists('appid', $this->values);
+ }
+
+
+ /**
+ * 设置微信支付分配的商户号
+ * @param string $value
+ **/
+ public function SetMch_id($value)
+ {
+ $this->values['mch_id'] = $value;
+ }
+ /**
+ * 获取微信支付分配的商户号的值
+ * @return 值
+ **/
+ public function GetMch_id()
+ {
+ return $this->values['mch_id'];
+ }
+ /**
+ * 判断微信支付分配的商户号是否存在
+ * @return true 或 false
+ **/
+ public function IsMch_idSet()
+ {
+ return array_key_exists('mch_id', $this->values);
+ }
+
+
+ /**
+ * 设置微信支付分配的终端设备号,与下单一致
+ * @param string $value
+ **/
+ public function SetDevice_info($value)
+ {
+ $this->values['device_info'] = $value;
+ }
+ /**
+ * 获取微信支付分配的终端设备号,与下单一致的值
+ * @return 值
+ **/
+ public function GetDevice_info()
+ {
+ return $this->values['device_info'];
+ }
+ /**
+ * 判断微信支付分配的终端设备号,与下单一致是否存在
+ * @return true 或 false
+ **/
+ public function IsDevice_infoSet()
+ {
+ return array_key_exists('device_info', $this->values);
+ }
+
+
+ /**
+ * 设置随机字符串,不长于32位。推荐随机数生成算法
+ * @param string $value
+ **/
+ public function SetNonce_str($value)
+ {
+ $this->values['nonce_str'] = $value;
+ }
+ /**
+ * 获取随机字符串,不长于32位。推荐随机数生成算法的值
+ * @return 值
+ **/
+ public function GetNonce_str()
+ {
+ return $this->values['nonce_str'];
+ }
+ /**
+ * 判断随机字符串,不长于32位。推荐随机数生成算法是否存在
+ * @return true 或 false
+ **/
+ public function IsNonce_strSet()
+ {
+ return array_key_exists('nonce_str', $this->values);
+ }
+
+ /**
+ * 设置微信订单号
+ * @param string $value
+ **/
+ public function SetTransaction_id($value)
+ {
+ $this->values['transaction_id'] = $value;
+ }
+ /**
+ * 获取微信订单号的值
+ * @return 值
+ **/
+ public function GetTransaction_id()
+ {
+ return $this->values['transaction_id'];
+ }
+ /**
+ * 判断微信订单号是否存在
+ * @return true 或 false
+ **/
+ public function IsTransaction_idSet()
+ {
+ return array_key_exists('transaction_id', $this->values);
+ }
+
+
+ /**
+ * 设置商户系统内部的订单号,transaction_id、out_trade_no二选一,如果同时存在优先级:transaction_id> out_trade_no
+ * @param string $value
+ **/
+ public function SetOut_trade_no($value)
+ {
+ $this->values['out_trade_no'] = $value;
+ }
+ /**
+ * 获取商户系统内部的订单号,transaction_id、out_trade_no二选一,如果同时存在优先级:transaction_id> out_trade_no的值
+ * @return 值
+ **/
+ public function GetOut_trade_no()
+ {
+ return $this->values['out_trade_no'];
+ }
+ /**
+ * 判断商户系统内部的订单号,transaction_id、out_trade_no二选一,如果同时存在优先级:transaction_id> out_trade_no是否存在
+ * @return true 或 false
+ **/
+ public function IsOut_trade_noSet()
+ {
+ return array_key_exists('out_trade_no', $this->values);
+ }
+
+
+ /**
+ * 设置商户系统内部的退款单号,商户系统内部唯一,同一退款单号多次请求只退一笔
+ * @param string $value
+ **/
+ public function SetOut_refund_no($value)
+ {
+ $this->values['out_refund_no'] = $value;
+ }
+ /**
+ * 获取商户系统内部的退款单号,商户系统内部唯一,同一退款单号多次请求只退一笔的值
+ * @return 值
+ **/
+ public function GetOut_refund_no()
+ {
+ return $this->values['out_refund_no'];
+ }
+ /**
+ * 判断商户系统内部的退款单号,商户系统内部唯一,同一退款单号多次请求只退一笔是否存在
+ * @return true 或 false
+ **/
+ public function IsOut_refund_noSet()
+ {
+ return array_key_exists('out_refund_no', $this->values);
+ }
+
+
+ /**
+ * 设置订单总金额,单位为分,只能为整数,详见支付金额
+ * @param string $value
+ **/
+ public function SetTotal_fee($value)
+ {
+ $this->values['total_fee'] = $value;
+ }
+ /**
+ * 获取订单总金额,单位为分,只能为整数,详见支付金额的值
+ * @return 值
+ **/
+ public function GetTotal_fee()
+ {
+ return $this->values['total_fee'];
+ }
+ /**
+ * 判断订单总金额,单位为分,只能为整数,详见支付金额是否存在
+ * @return true 或 false
+ **/
+ public function IsTotal_feeSet()
+ {
+ return array_key_exists('total_fee', $this->values);
+ }
+
+
+ /**
+ * 设置退款总金额,订单总金额,单位为分,只能为整数,详见支付金额
+ * @param string $value
+ **/
+ public function SetRefund_fee($value)
+ {
+ $this->values['refund_fee'] = $value;
+ }
+ /**
+ * 获取退款总金额,订单总金额,单位为分,只能为整数,详见支付金额的值
+ * @return 值
+ **/
+ public function GetRefund_fee()
+ {
+ return $this->values['refund_fee'];
+ }
+ /**
+ * 判断退款总金额,订单总金额,单位为分,只能为整数,详见支付金额是否存在
+ * @return true 或 false
+ **/
+ public function IsRefund_feeSet()
+ {
+ return array_key_exists('refund_fee', $this->values);
+ }
+
+
+ /**
+ * 设置货币类型,符合ISO 4217标准的三位字母代码,默认人民币:CNY,其他值列表详见货币类型
+ * @param string $value
+ **/
+ public function SetRefund_fee_type($value)
+ {
+ $this->values['refund_fee_type'] = $value;
+ }
+ /**
+ * 获取货币类型,符合ISO 4217标准的三位字母代码,默认人民币:CNY,其他值列表详见货币类型的值
+ * @return 值
+ **/
+ public function GetRefund_fee_type()
+ {
+ return $this->values['refund_fee_type'];
+ }
+ /**
+ * 判断货币类型,符合ISO 4217标准的三位字母代码,默认人民币:CNY,其他值列表详见货币类型是否存在
+ * @return true 或 false
+ **/
+ public function IsRefund_fee_typeSet()
+ {
+ return array_key_exists('refund_fee_type', $this->values);
+ }
+
+
+ /**
+ * 设置操作员帐号, 默认为商户号
+ * @param string $value
+ **/
+ public function SetOp_user_id($value)
+ {
+ $this->values['op_user_id'] = $value;
+ }
+ /**
+ * 获取操作员帐号, 默认为商户号的值
+ * @return 值
+ **/
+ public function GetOp_user_id()
+ {
+ return $this->values['op_user_id'];
+ }
+ /**
+ * 判断操作员帐号, 默认为商户号是否存在
+ * @return true 或 false
+ **/
+ public function IsOp_user_idSet()
+ {
+ return array_key_exists('op_user_id', $this->values);
+ }
+}
+
+/**
+ *
+ * 退款查询输入对象
+ * @author widyhu
+ *
+ */
+class WxPayRefundQuery extends WxPayDataBase
+{
+ /**
+ * 设置微信分配的公众账号ID
+ * @param string $value
+ **/
+ public function SetAppid($value)
+ {
+ $this->values['appid'] = $value;
+ }
+ /**
+ * 获取微信分配的公众账号ID的值
+ * @return 值
+ **/
+ public function GetAppid()
+ {
+ return $this->values['appid'];
+ }
+ /**
+ * 判断微信分配的公众账号ID是否存在
+ * @return true 或 false
+ **/
+ public function IsAppidSet()
+ {
+ return array_key_exists('appid', $this->values);
+ }
+
+
+ /**
+ * 设置微信支付分配的商户号
+ * @param string $value
+ **/
+ public function SetMch_id($value)
+ {
+ $this->values['mch_id'] = $value;
+ }
+ /**
+ * 获取微信支付分配的商户号的值
+ * @return 值
+ **/
+ public function GetMch_id()
+ {
+ return $this->values['mch_id'];
+ }
+ /**
+ * 判断微信支付分配的商户号是否存在
+ * @return true 或 false
+ **/
+ public function IsMch_idSet()
+ {
+ return array_key_exists('mch_id', $this->values);
+ }
+
+
+ /**
+ * 设置微信支付分配的终端设备号
+ * @param string $value
+ **/
+ public function SetDevice_info($value)
+ {
+ $this->values['device_info'] = $value;
+ }
+ /**
+ * 获取微信支付分配的终端设备号的值
+ * @return 值
+ **/
+ public function GetDevice_info()
+ {
+ return $this->values['device_info'];
+ }
+ /**
+ * 判断微信支付分配的终端设备号是否存在
+ * @return true 或 false
+ **/
+ public function IsDevice_infoSet()
+ {
+ return array_key_exists('device_info', $this->values);
+ }
+
+
+ /**
+ * 设置随机字符串,不长于32位。推荐随机数生成算法
+ * @param string $value
+ **/
+ public function SetNonce_str($value)
+ {
+ $this->values['nonce_str'] = $value;
+ }
+ /**
+ * 获取随机字符串,不长于32位。推荐随机数生成算法的值
+ * @return 值
+ **/
+ public function GetNonce_str()
+ {
+ return $this->values['nonce_str'];
+ }
+ /**
+ * 判断随机字符串,不长于32位。推荐随机数生成算法是否存在
+ * @return true 或 false
+ **/
+ public function IsNonce_strSet()
+ {
+ return array_key_exists('nonce_str', $this->values);
+ }
+
+ /**
+ * 设置微信订单号
+ * @param string $value
+ **/
+ public function SetTransaction_id($value)
+ {
+ $this->values['transaction_id'] = $value;
+ }
+ /**
+ * 获取微信订单号的值
+ * @return 值
+ **/
+ public function GetTransaction_id()
+ {
+ return $this->values['transaction_id'];
+ }
+ /**
+ * 判断微信订单号是否存在
+ * @return true 或 false
+ **/
+ public function IsTransaction_idSet()
+ {
+ return array_key_exists('transaction_id', $this->values);
+ }
+
+
+ /**
+ * 设置商户系统内部的订单号
+ * @param string $value
+ **/
+ public function SetOut_trade_no($value)
+ {
+ $this->values['out_trade_no'] = $value;
+ }
+ /**
+ * 获取商户系统内部的订单号的值
+ * @return 值
+ **/
+ public function GetOut_trade_no()
+ {
+ return $this->values['out_trade_no'];
+ }
+ /**
+ * 判断商户系统内部的订单号是否存在
+ * @return true 或 false
+ **/
+ public function IsOut_trade_noSet()
+ {
+ return array_key_exists('out_trade_no', $this->values);
+ }
+
+
+ /**
+ * 设置商户退款单号
+ * @param string $value
+ **/
+ public function SetOut_refund_no($value)
+ {
+ $this->values['out_refund_no'] = $value;
+ }
+ /**
+ * 获取商户退款单号的值
+ * @return 值
+ **/
+ public function GetOut_refund_no()
+ {
+ return $this->values['out_refund_no'];
+ }
+ /**
+ * 判断商户退款单号是否存在
+ * @return true 或 false
+ **/
+ public function IsOut_refund_noSet()
+ {
+ return array_key_exists('out_refund_no', $this->values);
+ }
+
+
+ /**
+ * 设置微信退款单号refund_id、out_refund_no、out_trade_no、transaction_id四个参数必填一个,如果同时存在优先级为:refund_id>out_refund_no>transaction_id>out_trade_no
+ * @param string $value
+ **/
+ public function SetRefund_id($value)
+ {
+ $this->values['refund_id'] = $value;
+ }
+ /**
+ * 获取微信退款单号refund_id、out_refund_no、out_trade_no、transaction_id四个参数必填一个,如果同时存在优先级为:refund_id>out_refund_no>transaction_id>out_trade_no的值
+ * @return 值
+ **/
+ public function GetRefund_id()
+ {
+ return $this->values['refund_id'];
+ }
+ /**
+ * 判断微信退款单号refund_id、out_refund_no、out_trade_no、transaction_id四个参数必填一个,如果同时存在优先级为:refund_id>out_refund_no>transaction_id>out_trade_no是否存在
+ * @return true 或 false
+ **/
+ public function IsRefund_idSet()
+ {
+ return array_key_exists('refund_id', $this->values);
+ }
+}
+
+/**
+ *
+ * 下载对账单输入对象
+ * @author widyhu
+ *
+ */
+class WxPayDownloadBill extends WxPayDataBase
+{
+ /**
+ * 设置微信分配的公众账号ID
+ * @param string $value
+ **/
+ public function SetAppid($value)
+ {
+ $this->values['appid'] = $value;
+ }
+ /**
+ * 获取微信分配的公众账号ID的值
+ * @return 值
+ **/
+ public function GetAppid()
+ {
+ return $this->values['appid'];
+ }
+ /**
+ * 判断微信分配的公众账号ID是否存在
+ * @return true 或 false
+ **/
+ public function IsAppidSet()
+ {
+ return array_key_exists('appid', $this->values);
+ }
+
+
+ /**
+ * 设置微信支付分配的商户号
+ * @param string $value
+ **/
+ public function SetMch_id($value)
+ {
+ $this->values['mch_id'] = $value;
+ }
+ /**
+ * 获取微信支付分配的商户号的值
+ * @return 值
+ **/
+ public function GetMch_id()
+ {
+ return $this->values['mch_id'];
+ }
+ /**
+ * 判断微信支付分配的商户号是否存在
+ * @return true 或 false
+ **/
+ public function IsMch_idSet()
+ {
+ return array_key_exists('mch_id', $this->values);
+ }
+
+
+ /**
+ * 设置微信支付分配的终端设备号,填写此字段,只下载该设备号的对账单
+ * @param string $value
+ **/
+ public function SetDevice_info($value)
+ {
+ $this->values['device_info'] = $value;
+ }
+ /**
+ * 获取微信支付分配的终端设备号,填写此字段,只下载该设备号的对账单的值
+ * @return 值
+ **/
+ public function GetDevice_info()
+ {
+ return $this->values['device_info'];
+ }
+ /**
+ * 判断微信支付分配的终端设备号,填写此字段,只下载该设备号的对账单是否存在
+ * @return true 或 false
+ **/
+ public function IsDevice_infoSet()
+ {
+ return array_key_exists('device_info', $this->values);
+ }
+
+
+ /**
+ * 设置随机字符串,不长于32位。推荐随机数生成算法
+ * @param string $value
+ **/
+ public function SetNonce_str($value)
+ {
+ $this->values['nonce_str'] = $value;
+ }
+ /**
+ * 获取随机字符串,不长于32位。推荐随机数生成算法的值
+ * @return 值
+ **/
+ public function GetNonce_str()
+ {
+ return $this->values['nonce_str'];
+ }
+ /**
+ * 判断随机字符串,不长于32位。推荐随机数生成算法是否存在
+ * @return true 或 false
+ **/
+ public function IsNonce_strSet()
+ {
+ return array_key_exists('nonce_str', $this->values);
+ }
+
+ /**
+ * 设置下载对账单的日期,格式:20140603
+ * @param string $value
+ **/
+ public function SetBill_date($value)
+ {
+ $this->values['bill_date'] = $value;
+ }
+ /**
+ * 获取下载对账单的日期,格式:20140603的值
+ * @return 值
+ **/
+ public function GetBill_date()
+ {
+ return $this->values['bill_date'];
+ }
+ /**
+ * 判断下载对账单的日期,格式:20140603是否存在
+ * @return true 或 false
+ **/
+ public function IsBill_dateSet()
+ {
+ return array_key_exists('bill_date', $this->values);
+ }
+
+
+ /**
+ * 设置ALL,返回当日所有订单信息,默认值SUCCESS,返回当日成功支付的订单REFUND,返回当日退款订单REVOKED,已撤销的订单
+ * @param string $value
+ **/
+ public function SetBill_type($value)
+ {
+ $this->values['bill_type'] = $value;
+ }
+ /**
+ * 获取ALL,返回当日所有订单信息,默认值SUCCESS,返回当日成功支付的订单REFUND,返回当日退款订单REVOKED,已撤销的订单的值
+ * @return 值
+ **/
+ public function GetBill_type()
+ {
+ return $this->values['bill_type'];
+ }
+ /**
+ * 判断ALL,返回当日所有订单信息,默认值SUCCESS,返回当日成功支付的订单REFUND,返回当日退款订单REVOKED,已撤销的订单是否存在
+ * @return true 或 false
+ **/
+ public function IsBill_typeSet()
+ {
+ return array_key_exists('bill_type', $this->values);
+ }
+}
+
+/**
+ *
+ * 测速上报输入对象
+ * @author widyhu
+ *
+ */
+class WxPayReport extends WxPayDataBase
+{
+ /**
+ * 设置微信分配的公众账号ID
+ * @param string $value
+ **/
+ public function SetAppid($value)
+ {
+ $this->values['appid'] = $value;
+ }
+ /**
+ * 获取微信分配的公众账号ID的值
+ * @return 值
+ **/
+ public function GetAppid()
+ {
+ return $this->values['appid'];
+ }
+ /**
+ * 判断微信分配的公众账号ID是否存在
+ * @return true 或 false
+ **/
+ public function IsAppidSet()
+ {
+ return array_key_exists('appid', $this->values);
+ }
+
+
+ /**
+ * 设置微信支付分配的商户号
+ * @param string $value
+ **/
+ public function SetMch_id($value)
+ {
+ $this->values['mch_id'] = $value;
+ }
+ /**
+ * 获取微信支付分配的商户号的值
+ * @return 值
+ **/
+ public function GetMch_id()
+ {
+ return $this->values['mch_id'];
+ }
+ /**
+ * 判断微信支付分配的商户号是否存在
+ * @return true 或 false
+ **/
+ public function IsMch_idSet()
+ {
+ return array_key_exists('mch_id', $this->values);
+ }
+
+
+ /**
+ * 设置微信支付分配的终端设备号,商户自定义
+ * @param string $value
+ **/
+ public function SetDevice_info($value)
+ {
+ $this->values['device_info'] = $value;
+ }
+ /**
+ * 获取微信支付分配的终端设备号,商户自定义的值
+ * @return 值
+ **/
+ public function GetDevice_info()
+ {
+ return $this->values['device_info'];
+ }
+ /**
+ * 判断微信支付分配的终端设备号,商户自定义是否存在
+ * @return true 或 false
+ **/
+ public function IsDevice_infoSet()
+ {
+ return array_key_exists('device_info', $this->values);
+ }
+
+
+ /**
+ * 设置随机字符串,不长于32位。推荐随机数生成算法
+ * @param string $value
+ **/
+ public function SetNonce_str($value)
+ {
+ $this->values['nonce_str'] = $value;
+ }
+ /**
+ * 获取随机字符串,不长于32位。推荐随机数生成算法的值
+ * @return 值
+ **/
+ public function GetNonce_str()
+ {
+ return $this->values['nonce_str'];
+ }
+ /**
+ * 判断随机字符串,不长于32位。推荐随机数生成算法是否存在
+ * @return true 或 false
+ **/
+ public function IsNonce_strSet()
+ {
+ return array_key_exists('nonce_str', $this->values);
+ }
+
+
+ /**
+ * 设置上报对应的接口的完整URL,类似:https://api.mch.weixin.qq.com/pay/unifiedorder对于被扫支付,为更好的和商户共同分析一次业务行为的整体耗时情况,对于两种接入模式,请都在门店侧对一次被扫行为进行一次单独的整体上报,上报URL指定为:https://api.mch.weixin.qq.com/pay/micropay/total关于两种接入模式具体可参考本文档章节:被扫支付商户接入模式其它接口调用仍然按照调用一次,上报一次来进行。
+ * @param string $value
+ **/
+ public function SetInterface_url($value)
+ {
+ $this->values['interface_url'] = $value;
+ }
+ /**
+ * 获取上报对应的接口的完整URL,类似:https://api.mch.weixin.qq.com/pay/unifiedorder对于被扫支付,为更好的和商户共同分析一次业务行为的整体耗时情况,对于两种接入模式,请都在门店侧对一次被扫行为进行一次单独的整体上报,上报URL指定为:https://api.mch.weixin.qq.com/pay/micropay/total关于两种接入模式具体可参考本文档章节:被扫支付商户接入模式其它接口调用仍然按照调用一次,上报一次来进行。的值
+ * @return 值
+ **/
+ public function GetInterface_url()
+ {
+ return $this->values['interface_url'];
+ }
+ /**
+ * 判断上报对应的接口的完整URL,类似:https://api.mch.weixin.qq.com/pay/unifiedorder对于被扫支付,为更好的和商户共同分析一次业务行为的整体耗时情况,对于两种接入模式,请都在门店侧对一次被扫行为进行一次单独的整体上报,上报URL指定为:https://api.mch.weixin.qq.com/pay/micropay/total关于两种接入模式具体可参考本文档章节:被扫支付商户接入模式其它接口调用仍然按照调用一次,上报一次来进行。是否存在
+ * @return true 或 false
+ **/
+ public function IsInterface_urlSet()
+ {
+ return array_key_exists('interface_url', $this->values);
+ }
+
+
+ /**
+ * 设置接口耗时情况,单位为毫秒
+ * @param string $value
+ **/
+ public function SetExecute_time_($value)
+ {
+ $this->values['execute_time_'] = $value;
+ }
+ /**
+ * 获取接口耗时情况,单位为毫秒的值
+ * @return 值
+ **/
+ public function GetExecute_time_()
+ {
+ return $this->values['execute_time_'];
+ }
+ /**
+ * 判断接口耗时情况,单位为毫秒是否存在
+ * @return true 或 false
+ **/
+ public function IsExecute_time_Set()
+ {
+ return array_key_exists('execute_time_', $this->values);
+ }
+
+
+ /**
+ * 设置SUCCESS/FAIL此字段是通信标识,非交易标识,交易是否成功需要查看trade_state来判断
+ * @param string $value
+ **/
+ public function SetReturn_code($value)
+ {
+ $this->values['return_code'] = $value;
+ }
+ /**
+ * 获取SUCCESS/FAIL此字段是通信标识,非交易标识,交易是否成功需要查看trade_state来判断的值
+ * @return 值
+ **/
+ public function GetReturn_code()
+ {
+ return $this->values['return_code'];
+ }
+ /**
+ * 判断SUCCESS/FAIL此字段是通信标识,非交易标识,交易是否成功需要查看trade_state来判断是否存在
+ * @return true 或 false
+ **/
+ public function IsReturn_codeSet()
+ {
+ return array_key_exists('return_code', $this->values);
+ }
+
+
+ /**
+ * 设置返回信息,如非空,为错误原因签名失败参数格式校验错误
+ * @param string $value
+ **/
+ public function SetReturn_msg($value)
+ {
+ $this->values['return_msg'] = $value;
+ }
+ /**
+ * 获取返回信息,如非空,为错误原因签名失败参数格式校验错误的值
+ * @return 值
+ **/
+ public function GetReturn_msg()
+ {
+ return $this->values['return_msg'];
+ }
+ /**
+ * 判断返回信息,如非空,为错误原因签名失败参数格式校验错误是否存在
+ * @return true 或 false
+ **/
+ public function IsReturn_msgSet()
+ {
+ return array_key_exists('return_msg', $this->values);
+ }
+
+
+ /**
+ * 设置SUCCESS/FAIL
+ * @param string $value
+ **/
+ public function SetResult_code($value)
+ {
+ $this->values['result_code'] = $value;
+ }
+ /**
+ * 获取SUCCESS/FAIL的值
+ * @return 值
+ **/
+ public function GetResult_code()
+ {
+ return $this->values['result_code'];
+ }
+ /**
+ * 判断SUCCESS/FAIL是否存在
+ * @return true 或 false
+ **/
+ public function IsResult_codeSet()
+ {
+ return array_key_exists('result_code', $this->values);
+ }
+
+
+ /**
+ * 设置ORDERNOTEXIST—订单不存在SYSTEMERROR—系统错误
+ * @param string $value
+ **/
+ public function SetErr_code($value)
+ {
+ $this->values['err_code'] = $value;
+ }
+ /**
+ * 获取ORDERNOTEXIST—订单不存在SYSTEMERROR—系统错误的值
+ * @return 值
+ **/
+ public function GetErr_code()
+ {
+ return $this->values['err_code'];
+ }
+ /**
+ * 判断ORDERNOTEXIST—订单不存在SYSTEMERROR—系统错误是否存在
+ * @return true 或 false
+ **/
+ public function IsErr_codeSet()
+ {
+ return array_key_exists('err_code', $this->values);
+ }
+
+
+ /**
+ * 设置结果信息描述
+ * @param string $value
+ **/
+ public function SetErr_code_des($value)
+ {
+ $this->values['err_code_des'] = $value;
+ }
+ /**
+ * 获取结果信息描述的值
+ * @return 值
+ **/
+ public function GetErr_code_des()
+ {
+ return $this->values['err_code_des'];
+ }
+ /**
+ * 判断结果信息描述是否存在
+ * @return true 或 false
+ **/
+ public function IsErr_code_desSet()
+ {
+ return array_key_exists('err_code_des', $this->values);
+ }
+
+
+ /**
+ * 设置商户系统内部的订单号,商户可以在上报时提供相关商户订单号方便微信支付更好的提高服务质量。
+ * @param string $value
+ **/
+ public function SetOut_trade_no($value)
+ {
+ $this->values['out_trade_no'] = $value;
+ }
+ /**
+ * 获取商户系统内部的订单号,商户可以在上报时提供相关商户订单号方便微信支付更好的提高服务质量。 的值
+ * @return 值
+ **/
+ public function GetOut_trade_no()
+ {
+ return $this->values['out_trade_no'];
+ }
+ /**
+ * 判断商户系统内部的订单号,商户可以在上报时提供相关商户订单号方便微信支付更好的提高服务质量。 是否存在
+ * @return true 或 false
+ **/
+ public function IsOut_trade_noSet()
+ {
+ return array_key_exists('out_trade_no', $this->values);
+ }
+
+
+ /**
+ * 设置发起接口调用时的机器IP
+ * @param string $value
+ **/
+ public function SetUser_ip($value)
+ {
+ $this->values['user_ip'] = $value;
+ }
+ /**
+ * 获取发起接口调用时的机器IP 的值
+ * @return 值
+ **/
+ public function GetUser_ip()
+ {
+ return $this->values['user_ip'];
+ }
+ /**
+ * 判断发起接口调用时的机器IP 是否存在
+ * @return true 或 false
+ **/
+ public function IsUser_ipSet()
+ {
+ return array_key_exists('user_ip', $this->values);
+ }
+
+
+ /**
+ * 设置系统时间,格式为yyyyMMddHHmmss,如2009年12月27日9点10分10秒表示为20091227091010。其他详见时间规则
+ * @param string $value
+ **/
+ public function SetTime($value)
+ {
+ $this->values['time'] = $value;
+ }
+ /**
+ * 获取系统时间,格式为yyyyMMddHHmmss,如2009年12月27日9点10分10秒表示为20091227091010。其他详见时间规则的值
+ * @return 值
+ **/
+ public function GetTime()
+ {
+ return $this->values['time'];
+ }
+ /**
+ * 判断系统时间,格式为yyyyMMddHHmmss,如2009年12月27日9点10分10秒表示为20091227091010。其他详见时间规则是否存在
+ * @return true 或 false
+ **/
+ public function IsTimeSet()
+ {
+ return array_key_exists('time', $this->values);
+ }
+}
+
+/**
+ *
+ * 短链转换输入对象
+ * @author widyhu
+ *
+ */
+class WxPayShortUrl extends WxPayDataBase
+{
+ /**
+ * 设置微信分配的公众账号ID
+ * @param string $value
+ **/
+ public function SetAppid($value)
+ {
+ $this->values['appid'] = $value;
+ }
+ /**
+ * 获取微信分配的公众账号ID的值
+ * @return 值
+ **/
+ public function GetAppid()
+ {
+ return $this->values['appid'];
+ }
+ /**
+ * 判断微信分配的公众账号ID是否存在
+ * @return true 或 false
+ **/
+ public function IsAppidSet()
+ {
+ return array_key_exists('appid', $this->values);
+ }
+
+
+ /**
+ * 设置微信支付分配的商户号
+ * @param string $value
+ **/
+ public function SetMch_id($value)
+ {
+ $this->values['mch_id'] = $value;
+ }
+ /**
+ * 获取微信支付分配的商户号的值
+ * @return 值
+ **/
+ public function GetMch_id()
+ {
+ return $this->values['mch_id'];
+ }
+ /**
+ * 判断微信支付分配的商户号是否存在
+ * @return true 或 false
+ **/
+ public function IsMch_idSet()
+ {
+ return array_key_exists('mch_id', $this->values);
+ }
+
+
+ /**
+ * 设置需要转换的URL,签名用原串,传输需URL encode
+ * @param string $value
+ **/
+ public function SetLong_url($value)
+ {
+ $this->values['long_url'] = $value;
+ }
+ /**
+ * 获取需要转换的URL,签名用原串,传输需URL encode的值
+ * @return 值
+ **/
+ public function GetLong_url()
+ {
+ return $this->values['long_url'];
+ }
+ /**
+ * 判断需要转换的URL,签名用原串,传输需URL encode是否存在
+ * @return true 或 false
+ **/
+ public function IsLong_urlSet()
+ {
+ return array_key_exists('long_url', $this->values);
+ }
+
+
+ /**
+ * 设置随机字符串,不长于32位。推荐随机数生成算法
+ * @param string $value
+ **/
+ public function SetNonce_str($value)
+ {
+ $this->values['nonce_str'] = $value;
+ }
+ /**
+ * 获取随机字符串,不长于32位。推荐随机数生成算法的值
+ * @return 值
+ **/
+ public function GetNonce_str()
+ {
+ return $this->values['nonce_str'];
+ }
+ /**
+ * 判断随机字符串,不长于32位。推荐随机数生成算法是否存在
+ * @return true 或 false
+ **/
+ public function IsNonce_strSet()
+ {
+ return array_key_exists('nonce_str', $this->values);
+ }
+}
+
+/**
+ *
+ * 提交被扫输入对象
+ * @author widyhu
+ *
+ */
+class WxPayMicroPay extends WxPayDataBase
+{
+ /**
+ * 设置微信分配的公众账号ID
+ * @param string $value
+ **/
+ public function SetAppid($value)
+ {
+ $this->values['appid'] = $value;
+ }
+ /**
+ * 获取微信分配的公众账号ID的值
+ * @return 值
+ **/
+ public function GetAppid()
+ {
+ return $this->values['appid'];
+ }
+ /**
+ * 判断微信分配的公众账号ID是否存在
+ * @return true 或 false
+ **/
+ public function IsAppidSet()
+ {
+ return array_key_exists('appid', $this->values);
+ }
+
+
+ /**
+ * 设置微信支付分配的商户号
+ * @param string $value
+ **/
+ public function SetMch_id($value)
+ {
+ $this->values['mch_id'] = $value;
+ }
+ /**
+ * 获取微信支付分配的商户号的值
+ * @return 值
+ **/
+ public function GetMch_id()
+ {
+ return $this->values['mch_id'];
+ }
+ /**
+ * 判断微信支付分配的商户号是否存在
+ * @return true 或 false
+ **/
+ public function IsMch_idSet()
+ {
+ return array_key_exists('mch_id', $this->values);
+ }
+
+
+ /**
+ * 设置终端设备号(商户自定义,如门店编号)
+ * @param string $value
+ **/
+ public function SetDevice_info($value)
+ {
+ $this->values['device_info'] = $value;
+ }
+ /**
+ * 获取终端设备号(商户自定义,如门店编号)的值
+ * @return 值
+ **/
+ public function GetDevice_info()
+ {
+ return $this->values['device_info'];
+ }
+ /**
+ * 判断终端设备号(商户自定义,如门店编号)是否存在
+ * @return true 或 false
+ **/
+ public function IsDevice_infoSet()
+ {
+ return array_key_exists('device_info', $this->values);
+ }
+
+
+ /**
+ * 设置随机字符串,不长于32位。推荐随机数生成算法
+ * @param string $value
+ **/
+ public function SetNonce_str($value)
+ {
+ $this->values['nonce_str'] = $value;
+ }
+ /**
+ * 获取随机字符串,不长于32位。推荐随机数生成算法的值
+ * @return 值
+ **/
+ public function GetNonce_str()
+ {
+ return $this->values['nonce_str'];
+ }
+ /**
+ * 判断随机字符串,不长于32位。推荐随机数生成算法是否存在
+ * @return true 或 false
+ **/
+ public function IsNonce_strSet()
+ {
+ return array_key_exists('nonce_str', $this->values);
+ }
+
+ /**
+ * 设置商品或支付单简要描述
+ * @param string $value
+ **/
+ public function SetBody($value)
+ {
+ $this->values['body'] = $value;
+ }
+ /**
+ * 获取商品或支付单简要描述的值
+ * @return 值
+ **/
+ public function GetBody()
+ {
+ return $this->values['body'];
+ }
+ /**
+ * 判断商品或支付单简要描述是否存在
+ * @return true 或 false
+ **/
+ public function IsBodySet()
+ {
+ return array_key_exists('body', $this->values);
+ }
+
+
+ /**
+ * 设置商品名称明细列表
+ * @param string $value
+ **/
+ public function SetDetail($value)
+ {
+ $this->values['detail'] = $value;
+ }
+ /**
+ * 获取商品名称明细列表的值
+ * @return 值
+ **/
+ public function GetDetail()
+ {
+ return $this->values['detail'];
+ }
+ /**
+ * 判断商品名称明细列表是否存在
+ * @return true 或 false
+ **/
+ public function IsDetailSet()
+ {
+ return array_key_exists('detail', $this->values);
+ }
+
+
+ /**
+ * 设置附加数据,在查询API和支付通知中原样返回,该字段主要用于商户携带订单的自定义数据
+ * @param string $value
+ **/
+ public function SetAttach($value)
+ {
+ $this->values['attach'] = $value;
+ }
+ /**
+ * 获取附加数据,在查询API和支付通知中原样返回,该字段主要用于商户携带订单的自定义数据的值
+ * @return 值
+ **/
+ public function GetAttach()
+ {
+ return $this->values['attach'];
+ }
+ /**
+ * 判断附加数据,在查询API和支付通知中原样返回,该字段主要用于商户携带订单的自定义数据是否存在
+ * @return true 或 false
+ **/
+ public function IsAttachSet()
+ {
+ return array_key_exists('attach', $this->values);
+ }
+
+
+ /**
+ * 设置商户系统内部的订单号,32个字符内、可包含字母, 其他说明见商户订单号
+ * @param string $value
+ **/
+ public function SetOut_trade_no($value)
+ {
+ $this->values['out_trade_no'] = $value;
+ }
+ /**
+ * 获取商户系统内部的订单号,32个字符内、可包含字母, 其他说明见商户订单号的值
+ * @return 值
+ **/
+ public function GetOut_trade_no()
+ {
+ return $this->values['out_trade_no'];
+ }
+ /**
+ * 判断商户系统内部的订单号,32个字符内、可包含字母, 其他说明见商户订单号是否存在
+ * @return true 或 false
+ **/
+ public function IsOut_trade_noSet()
+ {
+ return array_key_exists('out_trade_no', $this->values);
+ }
+
+
+ /**
+ * 设置订单总金额,单位为分,只能为整数,详见支付金额
+ * @param string $value
+ **/
+ public function SetTotal_fee($value)
+ {
+ $this->values['total_fee'] = $value;
+ }
+ /**
+ * 获取订单总金额,单位为分,只能为整数,详见支付金额的值
+ * @return 值
+ **/
+ public function GetTotal_fee()
+ {
+ return $this->values['total_fee'];
+ }
+ /**
+ * 判断订单总金额,单位为分,只能为整数,详见支付金额是否存在
+ * @return true 或 false
+ **/
+ public function IsTotal_feeSet()
+ {
+ return array_key_exists('total_fee', $this->values);
+ }
+
+
+ /**
+ * 设置符合ISO 4217标准的三位字母代码,默认人民币:CNY,其他值列表详见货币类型
+ * @param string $value
+ **/
+ public function SetFee_type($value)
+ {
+ $this->values['fee_type'] = $value;
+ }
+ /**
+ * 获取符合ISO 4217标准的三位字母代码,默认人民币:CNY,其他值列表详见货币类型的值
+ * @return 值
+ **/
+ public function GetFee_type()
+ {
+ return $this->values['fee_type'];
+ }
+ /**
+ * 判断符合ISO 4217标准的三位字母代码,默认人民币:CNY,其他值列表详见货币类型是否存在
+ * @return true 或 false
+ **/
+ public function IsFee_typeSet()
+ {
+ return array_key_exists('fee_type', $this->values);
+ }
+
+
+ /**
+ * 设置调用微信支付API的机器IP
+ * @param string $value
+ **/
+ public function SetSpbill_create_ip($value)
+ {
+ $this->values['spbill_create_ip'] = $value;
+ }
+ /**
+ * 获取调用微信支付API的机器IP 的值
+ * @return 值
+ **/
+ public function GetSpbill_create_ip()
+ {
+ return $this->values['spbill_create_ip'];
+ }
+ /**
+ * 判断调用微信支付API的机器IP 是否存在
+ * @return true 或 false
+ **/
+ public function IsSpbill_create_ipSet()
+ {
+ return array_key_exists('spbill_create_ip', $this->values);
+ }
+
+ /**
+ * 设置订单生成时间,格式为yyyyMMddHHmmss,如2009年12月25日9点10分10秒表示为20091225091010。详见时间规则
+ * @param string $value
+ **/
+ public function SetTime_start($value)
+ {
+ $this->values['time_start'] = $value;
+ }
+ /**
+ * 获取订单生成时间,格式为yyyyMMddHHmmss,如2009年12月25日9点10分10秒表示为20091225091010。详见时间规则的值
+ * @return 值
+ **/
+ public function GetTime_start()
+ {
+ return $this->values['time_start'];
+ }
+ /**
+ * 判断订单生成时间,格式为yyyyMMddHHmmss,如2009年12月25日9点10分10秒表示为20091225091010。详见时间规则是否存在
+ * @return true 或 false
+ **/
+ public function IsTime_startSet()
+ {
+ return array_key_exists('time_start', $this->values);
+ }
+
+
+ /**
+ * 设置订单失效时间,格式为yyyyMMddHHmmss,如2009年12月27日9点10分10秒表示为20091227091010。详见时间规则
+ * @param string $value
+ **/
+ public function SetTime_expire($value)
+ {
+ $this->values['time_expire'] = $value;
+ }
+ /**
+ * 获取订单失效时间,格式为yyyyMMddHHmmss,如2009年12月27日9点10分10秒表示为20091227091010。详见时间规则的值
+ * @return 值
+ **/
+ public function GetTime_expire()
+ {
+ return $this->values['time_expire'];
+ }
+ /**
+ * 判断订单失效时间,格式为yyyyMMddHHmmss,如2009年12月27日9点10分10秒表示为20091227091010。详见时间规则是否存在
+ * @return true 或 false
+ **/
+ public function IsTime_expireSet()
+ {
+ return array_key_exists('time_expire', $this->values);
+ }
+
+
+ /**
+ * 设置商品标记,代金券或立减优惠功能的参数,说明详见代金券或立减优惠
+ * @param string $value
+ **/
+ public function SetGoods_tag($value)
+ {
+ $this->values['goods_tag'] = $value;
+ }
+ /**
+ * 获取商品标记,代金券或立减优惠功能的参数,说明详见代金券或立减优惠的值
+ * @return 值
+ **/
+ public function GetGoods_tag()
+ {
+ return $this->values['goods_tag'];
+ }
+ /**
+ * 判断商品标记,代金券或立减优惠功能的参数,说明详见代金券或立减优惠是否存在
+ * @return true 或 false
+ **/
+ public function IsGoods_tagSet()
+ {
+ return array_key_exists('goods_tag', $this->values);
+ }
+
+
+ /**
+ * 设置扫码支付授权码,设备读取用户微信中的条码或者二维码信息
+ * @param string $value
+ **/
+ public function SetAuth_code($value)
+ {
+ $this->values['auth_code'] = $value;
+ }
+ /**
+ * 获取扫码支付授权码,设备读取用户微信中的条码或者二维码信息的值
+ * @return 值
+ **/
+ public function GetAuth_code()
+ {
+ return $this->values['auth_code'];
+ }
+ /**
+ * 判断扫码支付授权码,设备读取用户微信中的条码或者二维码信息是否存在
+ * @return true 或 false
+ **/
+ public function IsAuth_codeSet()
+ {
+ return array_key_exists('auth_code', $this->values);
+ }
+}
+
+/**
+ *
+ * 撤销输入对象
+ * @author widyhu
+ *
+ */
+class WxPayReverse extends WxPayDataBase
+{
+ /**
+ * 设置微信分配的公众账号ID
+ * @param string $value
+ **/
+ public function SetAppid($value)
+ {
+ $this->values['appid'] = $value;
+ }
+ /**
+ * 获取微信分配的公众账号ID的值
+ * @return 值
+ **/
+ public function GetAppid()
+ {
+ return $this->values['appid'];
+ }
+ /**
+ * 判断微信分配的公众账号ID是否存在
+ * @return true 或 false
+ **/
+ public function IsAppidSet()
+ {
+ return array_key_exists('appid', $this->values);
+ }
+
+
+ /**
+ * 设置微信支付分配的商户号
+ * @param string $value
+ **/
+ public function SetMch_id($value)
+ {
+ $this->values['mch_id'] = $value;
+ }
+ /**
+ * 获取微信支付分配的商户号的值
+ * @return 值
+ **/
+ public function GetMch_id()
+ {
+ return $this->values['mch_id'];
+ }
+ /**
+ * 判断微信支付分配的商户号是否存在
+ * @return true 或 false
+ **/
+ public function IsMch_idSet()
+ {
+ return array_key_exists('mch_id', $this->values);
+ }
+
+
+ /**
+ * 设置微信的订单号,优先使用
+ * @param string $value
+ **/
+ public function SetTransaction_id($value)
+ {
+ $this->values['transaction_id'] = $value;
+ }
+ /**
+ * 获取微信的订单号,优先使用的值
+ * @return 值
+ **/
+ public function GetTransaction_id()
+ {
+ return $this->values['transaction_id'];
+ }
+ /**
+ * 判断微信的订单号,优先使用是否存在
+ * @return true 或 false
+ **/
+ public function IsTransaction_idSet()
+ {
+ return array_key_exists('transaction_id', $this->values);
+ }
+
+
+ /**
+ * 设置商户系统内部的订单号,transaction_id、out_trade_no二选一,如果同时存在优先级:transaction_id> out_trade_no
+ * @param string $value
+ **/
+ public function SetOut_trade_no($value)
+ {
+ $this->values['out_trade_no'] = $value;
+ }
+ /**
+ * 获取商户系统内部的订单号,transaction_id、out_trade_no二选一,如果同时存在优先级:transaction_id> out_trade_no的值
+ * @return 值
+ **/
+ public function GetOut_trade_no()
+ {
+ return $this->values['out_trade_no'];
+ }
+ /**
+ * 判断商户系统内部的订单号,transaction_id、out_trade_no二选一,如果同时存在优先级:transaction_id> out_trade_no是否存在
+ * @return true 或 false
+ **/
+ public function IsOut_trade_noSet()
+ {
+ return array_key_exists('out_trade_no', $this->values);
+ }
+
+
+ /**
+ * 设置随机字符串,不长于32位。推荐随机数生成算法
+ * @param string $value
+ **/
+ public function SetNonce_str($value)
+ {
+ $this->values['nonce_str'] = $value;
+ }
+ /**
+ * 获取随机字符串,不长于32位。推荐随机数生成算法的值
+ * @return 值
+ **/
+ public function GetNonce_str()
+ {
+ return $this->values['nonce_str'];
+ }
+ /**
+ * 判断随机字符串,不长于32位。推荐随机数生成算法是否存在
+ * @return true 或 false
+ **/
+ public function IsNonce_strSet()
+ {
+ return array_key_exists('nonce_str', $this->values);
+ }
+}
+
+/**
+ *
+ * 提交JSAPI输入对象
+ * @author widyhu
+ *
+ */
+class WxPayJsApiPay extends WxPayDataBase
+{
+ /**
+ * 设置微信分配的公众账号ID
+ * @param string $value
+ **/
+ public function SetAppid($value)
+ {
+ $this->values['appId'] = $value;
+ }
+ /**
+ * 获取微信分配的公众账号ID的值
+ * @return 值
+ **/
+ public function GetAppid()
+ {
+ return $this->values['appId'];
+ }
+ /**
+ * 判断微信分配的公众账号ID是否存在
+ * @return true 或 false
+ **/
+ public function IsAppidSet()
+ {
+ return array_key_exists('appId', $this->values);
+ }
+
+
+ /**
+ * 设置支付时间戳
+ * @param string $value
+ **/
+ public function SetTimeStamp($value)
+ {
+ $this->values['timeStamp'] = $value;
+ }
+ /**
+ * 获取支付时间戳的值
+ * @return 值
+ **/
+ public function GetTimeStamp()
+ {
+ return $this->values['timeStamp'];
+ }
+ /**
+ * 判断支付时间戳是否存在
+ * @return true 或 false
+ **/
+ public function IsTimeStampSet()
+ {
+ return array_key_exists('timeStamp', $this->values);
+ }
+
+ /**
+ * 随机字符串
+ * @param string $value
+ **/
+ public function SetNonceStr($value)
+ {
+ $this->values['nonceStr'] = $value;
+ }
+ /**
+ * 获取notify随机字符串值
+ * @return 值
+ **/
+ public function GetReturn_code()
+ {
+ return $this->values['nonceStr'];
+ }
+ /**
+ * 判断随机字符串是否存在
+ * @return true 或 false
+ **/
+ public function IsReturn_codeSet()
+ {
+ return array_key_exists('nonceStr', $this->values);
+ }
+
+
+ /**
+ * 设置订单详情扩展字符串
+ * @param string $value
+ **/
+ public function SetPackage($value)
+ {
+ $this->values['package'] = $value;
+ }
+ /**
+ * 获取订单详情扩展字符串的值
+ * @return 值
+ **/
+ public function GetPackage()
+ {
+ return $this->values['package'];
+ }
+ /**
+ * 判断订单详情扩展字符串是否存在
+ * @return true 或 false
+ **/
+ public function IsPackageSet()
+ {
+ return array_key_exists('package', $this->values);
+ }
+
+ /**
+ * 设置签名方式
+ * @param string $value
+ **/
+ public function SetSignType($value)
+ {
+ $this->values['signType'] = $value;
+ }
+ /**
+ * 获取签名方式
+ * @return 值
+ **/
+ public function GetSignType()
+ {
+ return $this->values['signType'];
+ }
+ /**
+ * 判断签名方式是否存在
+ * @return true 或 false
+ **/
+ public function IsSignTypeSet()
+ {
+ return array_key_exists('signType', $this->values);
+ }
+
+ /**
+ * 设置签名方式
+ * @param string $value
+ **/
+ public function SetPaySign($value)
+ {
+ $this->values['paySign'] = $value;
+ }
+ /**
+ * 获取签名方式
+ * @return 值
+ **/
+ public function GetPaySign()
+ {
+ return $this->values['paySign'];
+ }
+ /**
+ * 判断签名方式是否存在
+ * @return true 或 false
+ **/
+ public function IsPaySignSet()
+ {
+ return array_key_exists('paySign', $this->values);
+ }
+}
+
+/**
+ *
+ * 扫码支付模式一生成二维码参数
+ * @author widyhu
+ *
+ */
+class WxPayBizPayUrl extends WxPayDataBaseSignMd5
+{
+ /**
+ * 设置微信分配的公众账号ID
+ * @param string $value
+ **/
+ public function SetAppid($value)
+ {
+ $this->values['appid'] = $value;
+ }
+ /**
+ * 获取微信分配的公众账号ID的值
+ * @return 值
+ **/
+ public function GetAppid()
+ {
+ return $this->values['appid'];
+ }
+ /**
+ * 判断微信分配的公众账号ID是否存在
+ * @return true 或 false
+ **/
+ public function IsAppidSet()
+ {
+ return array_key_exists('appid', $this->values);
+ }
+
+
+ /**
+ * 设置微信支付分配的商户号
+ * @param string $value
+ **/
+ public function SetMch_id($value)
+ {
+ $this->values['mch_id'] = $value;
+ }
+ /**
+ * 获取微信支付分配的商户号的值
+ * @return 值
+ **/
+ public function GetMch_id()
+ {
+ return $this->values['mch_id'];
+ }
+ /**
+ * 判断微信支付分配的商户号是否存在
+ * @return true 或 false
+ **/
+ public function IsMch_idSet()
+ {
+ return array_key_exists('mch_id', $this->values);
+ }
+
+ /**
+ * 设置支付时间戳
+ * @param string $value
+ **/
+ public function SetTime_stamp($value)
+ {
+ $this->values['time_stamp'] = $value;
+ }
+ /**
+ * 获取支付时间戳的值
+ * @return 值
+ **/
+ public function GetTime_stamp()
+ {
+ return $this->values['time_stamp'];
+ }
+ /**
+ * 判断支付时间戳是否存在
+ * @return true 或 false
+ **/
+ public function IsTime_stampSet()
+ {
+ return array_key_exists('time_stamp', $this->values);
+ }
+
+ /**
+ * 设置随机字符串
+ * @param string $value
+ **/
+ public function SetNonce_str($value)
+ {
+ $this->values['nonce_str'] = $value;
+ }
+ /**
+ * 获取随机字符串的值
+ * @return 值
+ **/
+ public function GetNonce_str()
+ {
+ return $this->values['nonce_str'];
+ }
+ /**
+ * 判断随机字符串是否存在
+ * @return true 或 false
+ **/
+ public function IsNonce_strSet()
+ {
+ return array_key_exists('nonce_str', $this->values);
+ }
+
+ /**
+ * 设置商品ID
+ * @param string $value
+ **/
+ public function SetProduct_id($value)
+ {
+ $this->values['product_id'] = $value;
+ }
+ /**
+ * 获取商品ID的值
+ * @return 值
+ **/
+ public function GetProduct_id()
+ {
+ return $this->values['product_id'];
+ }
+ /**
+ * 判断商品ID是否存在
+ * @return true 或 false
+ **/
+ public function IsProduct_idSet()
+ {
+ return array_key_exists('product_id', $this->values);
+ }
+}
+
diff --git a/serve/extend/wechat/WxPay.Exception.php b/serve/extend/wechat/WxPay.Exception.php
new file mode 100644
index 0000000..dbe0853
--- /dev/null
+++ b/serve/extend/wechat/WxPay.Exception.php
@@ -0,0 +1,13 @@
+getMessage();
+ }
+}
diff --git a/serve/extend/wechat/WxPay.Notify.php b/serve/extend/wechat/WxPay.Notify.php
new file mode 100644
index 0000000..b3ca623
--- /dev/null
+++ b/serve/extend/wechat/WxPay.Notify.php
@@ -0,0 +1,105 @@
+config = $config;
+ $msg = "OK";
+ //当返回false的时候,表示notify中调用NotifyCallBack回调失败获取签名校验失败,此时直接回复失败
+ $result = WxpayApi::notify($config, array($this, 'NotifyCallBack'), $msg);
+ if($result == false){
+ $this->SetReturn_code("FAIL");
+ $this->SetReturn_msg($msg);
+ $this->ReplyNotify(false);
+ return;
+ } else {
+ //该分支在成功回调到NotifyCallBack方法,处理完成之后流程
+ $this->SetReturn_code("SUCCESS");
+ $this->SetReturn_msg("OK");
+ }
+ $this->ReplyNotify($needSign);
+ }
+
+ /**
+ *
+ * 回调方法入口,子类可重写该方法
+ //TODO 1、进行参数校验
+ //TODO 2、进行签名验证
+ //TODO 3、处理业务逻辑
+ * 注意:
+ * 1、微信回调超时时间为2s,建议用户使用异步处理流程,确认成功之后立刻回复微信服务器
+ * 2、微信服务器在调用失败或者接到回包为非确认包的时候,会发起重试,需确保你的回调是可以重入
+ * @param WxPayNotifyResults $objData 回调解释出的参数
+ * @param WxPayConfigInterface $config
+ * @param string $msg 如果回调处理失败,可以将错误信息输出到该方法
+ * @return true回调出来完成不需要继续回调,false回调处理未完成需要继续回调
+ */
+ public function NotifyProcess($objData, $config, &$msg)
+ {
+ //TODO 用户基础该类之后需要重写该方法,成功的时候返回true,失败返回false
+ return false;
+ }
+
+ /**
+ *
+ * 业务可以继承该方法,打印XML方便定位.
+ * @param string $xmlData 返回的xml参数
+ *
+ **/
+ public function LogAfterProcess($xmlData)
+ {
+ return;
+ }
+
+ /**
+ *
+ * notify回调方法,该方法中需要赋值需要输出的参数,不可重写
+ * @param array $data
+ * @return true回调出来完成不需要继续回调,false回调处理未完成需要继续回调
+ */
+ final public function NotifyCallBack($data)
+ {
+ $msg = "OK";
+ $result = $this->NotifyProcess($data, $this->config, $msg);
+
+ if($result == true){
+ $this->SetReturn_code("SUCCESS");
+ $this->SetReturn_msg("OK");
+ } else {
+ $this->SetReturn_code("FAIL");
+ $this->SetReturn_msg($msg);
+ }
+ return $result;
+ }
+
+ /**
+ *
+ * 回复通知
+ * @param bool $needSign 是否需要签名输出
+ */
+ final private function ReplyNotify($needSign = true)
+ {
+ //如果需要签名
+ if($needSign == true &&
+ $this->GetReturn_code() == "SUCCESS")
+ {
+ $this->SetSign($this->config);
+ }
+
+ $xml = $this->ToXml();
+ $this->LogAfterProcess($xml);
+ WxpayApi::replyNotify($xml);
+ }
+}
\ No newline at end of file
diff --git a/serve/favicon.ico b/serve/favicon.ico
new file mode 100644
index 0000000..b4bdb9d
Binary files /dev/null and b/serve/favicon.ico differ
diff --git a/serve/index.php b/serve/index.php
new file mode 100644
index 0000000..3ef963a
--- /dev/null
+++ b/serve/index.php
@@ -0,0 +1,30 @@
+
+// +----------------------------------------------------------------------
+
+// [ 应用入口文件 ]
+namespace think;
+//安装向导
+if(is_dir('install')){
+ if (!file_exists('install/install.lock')) {
+ header("Location:/install");
+ exit;
+ }
+}
+require __DIR__ . '/vendor/autoload.php';
+
+// 执行HTTP应用并响应
+$http = (new App())->http;
+
+$response = $http->run();
+
+$response->send();
+
+$http->end($response);
diff --git a/serve/install/css/lib.css b/serve/install/css/lib.css
new file mode 100644
index 0000000..aad140a
--- /dev/null
+++ b/serve/install/css/lib.css
@@ -0,0 +1,117 @@
+*{
+ margin: 0;
+ padding: 0;
+}
+body {
+ font: 14px "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "微软雅黑", Arial, sans-serif;
+ background: #f9f9f9;
+}
+header{
+ height:80px;
+ background: #0F86EA;
+}
+.container{
+ width: 820px;
+ margin: 0 auto;
+}
+.title{
+ color: #fff;
+ position: relative;
+}
+.title .name{
+ font-size: 18px;
+ line-height: 80px;
+}
+.title .product{
+ position: absolute;
+ right: 0;
+ bottom: 6px;
+}
+.box{
+ margin-top: 32px;
+ padding: 9px 12px;
+ border-radius: 2px;
+ background: #fcfcfc;
+ border: 1px solid #ccc;
+}
+.box > div{
+ display: none;
+}
+.box button{
+ padding: 2px 6px;
+}
+fieldset {
+ padding: 9px 12px;
+ border: 1px solid #eee;
+ background: #fafafa;
+}
+legend {
+ color: #4275a5;
+ font-weight: bold;
+}
+.success{
+ color: #009933;
+}
+.success i{
+ background: url(../img/success.png) 0 no-repeat;
+}
+.warning{
+ color: #f00;
+}
+.warning i{
+ background: url(../img/warning.png) 0 no-repeat;
+}
+#content1 > *{
+ color: #333;
+ line-height: 24px;
+}
+#content2 > *{
+ margin-bottom: 12px;
+}
+#content2 ul{
+ width: 90%;
+ margin: 0 auto;
+ list-style-type:none;
+}
+#content2 li{
+ width: 30%;
+ float: left;
+ line-height: 36px;
+}
+#content2 li i{
+ float: right;
+ margin-right: 20%;
+}
+#content2 li span{
+ width: 200px;
+}
+#content2 .group{
+ text-align: center;
+}
+#content2 .group button{
+ display: inline;
+}
+#content3{
+ color: #333;
+}
+#content3 > *{
+ margin-bottom: 12px;
+}
+#content3 .form{
+ margin-left: 16%;
+}
+#content3 .form .row{
+ line-height: 36px;
+}
+#content3 .form tip{
+ color: #999;
+}
+#content4 > *{
+ text-align: center;
+ margin-bottom: 12px;
+}
+footer p{
+ margin: 15px 0;
+ font-size: 12px;
+ text-align: center;
+}
\ No newline at end of file
diff --git a/serve/install/img/success.png b/serve/install/img/success.png
new file mode 100644
index 0000000..fc5029a
Binary files /dev/null and b/serve/install/img/success.png differ
diff --git a/serve/install/img/warning.png b/serve/install/img/warning.png
new file mode 100644
index 0000000..348e447
Binary files /dev/null and b/serve/install/img/warning.png differ
diff --git a/serve/install/index.php b/serve/install/index.php
new file mode 100644
index 0000000..6a1edd3
--- /dev/null
+++ b/serve/install/index.php
@@ -0,0 +1,144 @@
+
+
+
+
+
+ 点可云软件安装向导
+
+
+
+
+
+
+ [ 点可云软件中心 ]
+ 进销存软件
+
+
+
+
+
+
+
+
最终用户授权许可协议
+
感谢您选择点可云系列软件(以下简称本软件),我们致力于让办公简单、轻松、自动化,为云端办公而不懈努力!
+
本《最终用户授权许可协议》(以下简称本协议)是您(自然人、法人或其他组织)有关安装、复制、修改、使用本软件的法律协议,同时本协议亦适用于任何有关本软件的后期更新和升级。一旦以任何方式使用本软件,即表明您同意接受本协议各项条款的约束。
+
如果您不同意本协议中的条款,必须删除本软件及相关资料。
+
协议许可范围声明:
+
1. 本软件适用于学习与交流用途,不可用于商业用途,商业用途包括但不限于销售,转售,二次开发,OEM等,如需商业用途必须取得专属授权。
+
2.本软件允许免费使用,禁止对软件修改后二次发布,构成恶意传播的将一律视为侵权。
+
3.为了更好服务,本软件可能会收集您的域名等信息,并承诺不会收集除此之外的任何数据信息。
+
有限担保和免责声明:
+
1.本软件和附带的资料是作为不提供任何明确的或隐含的赔偿或担保的形式提供的。
+
2.用户出于自愿而使用本软件,您必须了解使用本软件系统的风险,在尚未获得合法授权前,我们不承诺提供任何形式的使用担保、技术支持,同时也不承担任何因使用本软件而产生的问题或损失的相关责任。
+
3.我方不对使用本软件构建的任何站点的任何信息内容导致的任何版权纠纷和法律争议及后果承担责任。
+
4.本协议的电子文档形式同双方书面签署协议一样,具有完全的和等同的法律效力。您一旦开始确认本协议并安装本软件,即被视为完全理解并接受本协议的各项条款,在享有上述条款授予的权力的同时受到相关的约束和限制。
+
5.本协议许可范围以外的行为,将直接违反本协议并构成侵权,我们有权随时终止授权、责令停止损害,并保留追究相关责任的权力。
+
6.本软件著作权所有者享有最终解释权。
+
点可云软件中心
+
+
+
+
+
请检查您的服务器是否支持安装本软件,请在继续安装前消除警告信息。
+
+
+
+
+
+
+
+
+
您需要在下方输入数据库相关配置信息。
+
+
+
+
+
:) 恭喜您,安装成功。
+
从今天开始,点可云软件将为您服务,感谢您的信任与支持。
+
默认登陆账号:admin 密码:admin888 登陆系统后您可以自行更改密码。
+
建议您删除 install 目录,以防止再次安装而覆盖数据。
+
点此登陆系统
+
+
+
+
+
+
+
+
+
diff --git a/serve/install/js/jquery.js b/serve/install/js/jquery.js
new file mode 100644
index 0000000..a1c07fd
--- /dev/null
+++ b/serve/install/js/jquery.js
@@ -0,0 +1,2 @@
+/*! jQuery v3.4.1 | (c) JS Foundation and other contributors | jquery.org/license */
+!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(C,e){"use strict";var t=[],E=C.document,r=Object.getPrototypeOf,s=t.slice,g=t.concat,u=t.push,i=t.indexOf,n={},o=n.toString,v=n.hasOwnProperty,a=v.toString,l=a.call(Object),y={},m=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType},x=function(e){return null!=e&&e===e.window},c={type:!0,src:!0,nonce:!0,noModule:!0};function b(e,t,n){var r,i,o=(n=n||E).createElement("script");if(o.text=e,t)for(r in c)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.4.1",k=function(e,t){return new k.fn.init(e,t)},p=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;function d(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!m(e)&&!x(e)&&("array"===n||0===t||"number"==typeof t&&0+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp($),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+$),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\([\\da-f]{1,6}"+M+"?|("+M+")|.)","ig"),ne=function(e,t,n){var r="0x"+t-65536;return r!=r||n?t:r<0?String.fromCharCode(r+65536):String.fromCharCode(r>>10|55296,1023&r|56320)},re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=function(){T()},ae=be(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{H.apply(t=O.call(m.childNodes),m.childNodes),t[m.childNodes.length].nodeType}catch(e){H={apply:t.length?function(e,t){L.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function se(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&((e?e.ownerDocument||e:m)!==C&&T(e),e=e||C,E)){if(11!==p&&(u=Z.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(f&&(a=f.getElementById(i))&&y(e,a)&&a.id===i)return n.push(a),n}else{if(u[2])return H.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&d.getElementsByClassName&&e.getElementsByClassName)return H.apply(n,e.getElementsByClassName(i)),n}if(d.qsa&&!A[t+" "]&&(!v||!v.test(t))&&(1!==p||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&U.test(t)){(s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=k),o=(l=h(t)).length;while(o--)l[o]="#"+s+" "+xe(l[o]);c=l.join(","),f=ee.test(t)&&ye(e.parentNode)||e}try{return H.apply(n,f.querySelectorAll(c)),n}catch(e){A(t,!0)}finally{s===k&&e.removeAttribute("id")}}}return g(t.replace(B,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[k]=!0,e}function ce(e){var t=C.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){var n=e.split("|"),r=n.length;while(r--)b.attrHandle[n[r]]=t}function pe(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function de(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function he(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function ge(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ae(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ve(a){return le(function(o){return o=+o,le(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function ye(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}for(e in d=se.support={},i=se.isXML=function(e){var t=e.namespaceURI,n=(e.ownerDocument||e).documentElement;return!Y.test(t||n&&n.nodeName||"HTML")},T=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:m;return r!==C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,E=!i(C),m!==C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),d.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=k,!C.getElementsByName||!C.getElementsByName(k).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(te,ne);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):d.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},b.find.CLASS=d.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],v=[],(d.qsa=K.test(C.querySelectorAll))&&(ce(function(e){a.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+k+"-]").length||v.push("~="),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+k+"+*").length||v.push(".#.+[+~]")}),ce(function(e){e.innerHTML="";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&v.push(":enabled",":disabled"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&v.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),v.push(",.*:")})),(d.matchesSelector=K.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",$)}),v=v.length&&new RegExp(v.join("|")),s=s.length&&new RegExp(s.join("|")),t=K.test(a.compareDocumentPosition),y=t||K.test(a.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},D=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)===(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e===C||e.ownerDocument===m&&y(m,e)?-1:t===C||t.ownerDocument===m&&y(m,t)?1:u?P(u,e)-P(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e===C?-1:t===C?1:i?-1:o?1:u?P(u,e)-P(u,t):0;if(i===o)return pe(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?pe(a[r],s[r]):a[r]===m?-1:s[r]===m?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if((e.ownerDocument||e)!==C&&T(e),d.matchesSelector&&E&&!A[t+" "]&&(!s||!s.test(t))&&(!v||!v.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){A(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||"").replace(te,ne),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=h(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,ne).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=p[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&p(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=se.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function j(e,n,r){return m(n)?k.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?k.grep(e,function(e){return e===n!==r}):"string"!=typeof n?k.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(k.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||q,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:L.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof k?t[0]:t,k.merge(this,k.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),D.test(r[1])&&k.isPlainObject(t))for(r in t)m(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):m(e)?void 0!==n.ready?n.ready(e):e(k):k.makeArray(e,this)}).prototype=k.fn,q=k(E);var H=/^(?:parents|prev(?:Until|All))/,O={children:!0,contents:!0,next:!0,prev:!0};function P(e,t){while((e=e[t])&&1!==e.nodeType);return e}k.fn.extend({has:function(e){var t=k(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,he=/^$|^module$|\/(?:java|ecma)script/i,ge={option:[1,""],thead:[1,""],col:[2,""],tr:[2,""],td:[3,""],_default:[0,"",""]};function ve(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?k.merge([e],n):n}function ye(e,t){for(var n=0,r=e.length;nx",y.noCloneChecked=!!me.cloneNode(!0).lastChild.defaultValue;var Te=/^key/,Ce=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,Ee=/^([^.]*)(?:\.(.+)|)/;function ke(){return!0}function Se(){return!1}function Ne(e,t){return e===function(){try{return E.activeElement}catch(e){}}()==("focus"===t)}function Ae(e,t,n,r,i,o){var a,s;if("object"==typeof t){for(s in"string"!=typeof n&&(r=r||n,n=void 0),t)Ae(e,s,n,r,t[s],o);return e}if(null==r&&null==i?(i=n,r=n=void 0):null==i&&("string"==typeof n?(i=r,r=void 0):(i=r,r=n,n=void 0)),!1===i)i=Se;else if(!i)return e;return 1===o&&(a=i,(i=function(e){return k().off(e),a.apply(this,arguments)}).guid=a.guid||(a.guid=k.guid++)),e.each(function(){k.event.add(this,t,i,r,n)})}function De(e,i,o){o?(Q.set(e,i,!1),k.event.add(e,i,{namespace:!1,handler:function(e){var t,n,r=Q.get(this,i);if(1&e.isTrigger&&this[i]){if(r.length)(k.event.special[i]||{}).delegateType&&e.stopPropagation();else if(r=s.call(arguments),Q.set(this,i,r),t=o(this,i),this[i](),r!==(n=Q.get(this,i))||t?Q.set(this,i,!1):n={},r!==n)return e.stopImmediatePropagation(),e.preventDefault(),n.value}else r.length&&(Q.set(this,i,{value:k.event.trigger(k.extend(r[0],k.Event.prototype),r.slice(1),this)}),e.stopImmediatePropagation())}})):void 0===Q.get(e,i)&&k.event.add(e,i,ke)}k.event={global:{},add:function(t,e,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,v=Q.get(t);if(v){n.handler&&(n=(o=n).handler,i=o.selector),i&&k.find.matchesSelector(ie,i),n.guid||(n.guid=k.guid++),(u=v.events)||(u=v.events={}),(a=v.handle)||(a=v.handle=function(e){return"undefined"!=typeof k&&k.event.triggered!==e.type?k.event.dispatch.apply(t,arguments):void 0}),l=(e=(e||"").match(R)||[""]).length;while(l--)d=g=(s=Ee.exec(e[l])||[])[1],h=(s[2]||"").split(".").sort(),d&&(f=k.event.special[d]||{},d=(i?f.delegateType:f.bindType)||d,f=k.event.special[d]||{},c=k.extend({type:d,origType:g,data:r,handler:n,guid:n.guid,selector:i,needsContext:i&&k.expr.match.needsContext.test(i),namespace:h.join(".")},o),(p=u[d])||((p=u[d]=[]).delegateCount=0,f.setup&&!1!==f.setup.call(t,r,h,a)||t.addEventListener&&t.addEventListener(d,a)),f.add&&(f.add.call(t,c),c.handler.guid||(c.handler.guid=n.guid)),i?p.splice(p.delegateCount++,0,c):p.push(c),k.event.global[d]=!0)}},remove:function(e,t,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,v=Q.hasData(e)&&Q.get(e);if(v&&(u=v.events)){l=(t=(t||"").match(R)||[""]).length;while(l--)if(d=g=(s=Ee.exec(t[l])||[])[1],h=(s[2]||"").split(".").sort(),d){f=k.event.special[d]||{},p=u[d=(r?f.delegateType:f.bindType)||d]||[],s=s[2]&&new RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"),a=o=p.length;while(o--)c=p[o],!i&&g!==c.origType||n&&n.guid!==c.guid||s&&!s.test(c.namespace)||r&&r!==c.selector&&("**"!==r||!c.selector)||(p.splice(o,1),c.selector&&p.delegateCount--,f.remove&&f.remove.call(e,c));a&&!p.length&&(f.teardown&&!1!==f.teardown.call(e,h,v.handle)||k.removeEvent(e,d,v.handle),delete u[d])}else for(d in u)k.event.remove(e,d+t[l],n,r,!0);k.isEmptyObject(u)&&Q.remove(e,"handle events")}},dispatch:function(e){var t,n,r,i,o,a,s=k.event.fix(e),u=new Array(arguments.length),l=(Q.get(this,"events")||{})[s.type]||[],c=k.event.special[s.type]||{};for(u[0]=s,t=1;t\x20\t\r\n\f]*)[^>]*)\/>/gi,qe=/"));
+ }
+
+ [Test]
+ public void TestPayWithOptionalNotify()
+ {
+ AlipayTradePagePayResponse response = Factory.Payment.Page().AsyncNotify("https://www.test2.com/newCallback")
+ .Pay("iPhone6 16G", "e5b5bd79-8310-447d-b63b-0fe3a393324d", "0.10", "https://www.taobao.com");
+
+ Assert.IsTrue(ResponseChecker.Success(response));
+ Assert.IsTrue(response.Body.Contains("