success('成功');} /**第一屏*/ //年度承接产量 public function thisyear(){ $date = date("Y"); // 返回 JSON 格式数据 return json([ "status" => 0, "msg" => "", "data" => $date.'年度承接产量', ]); } public function lastyear(){ $date = date("Y") - 1; // 返回 JSON 格式数据 return json([ "status" => 0, "msg" => "", "data" => $date.'年度承接产量', ]); } //获取近三年年份 public function ymd_api(){ $data = [ ["name" => " ", "value" => strval(date('Y'))], // 将年份转换为字符串 ["name" => " ", "value" => strval(date('Y') - 1)], // 将年份转换为字符串 ["name" => " ", "value" => strval(date('Y') - 2)], // 将年份转换为字符串 ]; // 返回 JSON 格式数据 return json([ "status" => 0, "msg" => "", "data" => $data, ]); } /** *去年的年度承接产量【接口】 *统计去年订单个数,订单数量,包装完工数量,完成率。 */ public function Lastcontractedoutput_api(){ // 获取今年的年份 $last_year = date("Y") -1; // 查询条件:Mod_rq为null且年份为今年的记录数量 $count = \db('工单_基本资料') ->where('Sys_rq', 'between', ["$last_year-01-01 00:00:00", "$last_year-12-31 23:59:59"]) ->whereNull('Mod_rq') // 修正:使用 whereNull 方法 ->count(); // 查询条件:Mod_rq为null且年份为今年的订单数量字段的总和 $sum = \db('工单_基本资料') ->field("sum(`订单数量`) as total_sum") // 使用反引号包裹中文字段名,并设置别名 ->where('Sys_rq', 'between', ["$last_year-01-01 00:00:00", "$last_year-12-31 23:59:59"]) ->whereNull('Mod_rq') ->select(); $total_sum = 0; $s_num_total = 0; $ratio = 0; if (!empty($sum)) { foreach ($sum as $value) { $total_sum = $value['total_sum']; // 使用别名获取结果 if ($total_sum) { // 查询设备_产量计酬表中工序编号为7且mod_rq为null且年份为今年的s_num总和 $s_num_result = \db('设备_产量计酬') ->field("sum(`s_num`) as s_num_total") // 计算 s_num 的总和 ->where('工序编号', 7) ->whereNull('mod_rq') ->where('sys_rq', 'between', ["$last_year-01-01 00:00:00", "$last_year-12-31 23:59:59"]) ->select(); if (!empty($s_num_result)) { $s_num_total = $s_num_result[0]['s_num_total']; // 获取 s_num 的总和 // 计算比例并四舍五入保留两位小数 if ($total_sum != 0) { // 避免除数为0 $ratio = round(($s_num_total / $total_sum) * 100) . '%'; } } } } } // 构建返回数据 // $data = [ // ["name" => "总订单数", "value" => $count], // ["name" => "承接大货数", "value" => $total_sum], // ["name" => "完工数量", "value" => $s_num_total], // ["name" => "完成率", "value" => $ratio], // ]; $data = [ ["name" => " ", "value" => $count], ["name" => " ", "value" => $total_sum], ["name" => " ", "value" => $s_num_total], // ["name" => " ", "value" => $ratio], ]; // 返回 JSON 格式数据 return json([ "status" => 0, "msg" => "", "data" => $data, ]); } /** *当年的年度承接产量【接口】 *统计当年订单个数,订单数量,包装完工数量,完成率。 */ public function Annualcontractedoutput_api(){ // 获取今年的年份 $year = date("Y"); // 查询条件:Mod_rq为null且年份为今年的记录数量 $count = \db('工单_基本资料') ->where('Sys_rq', 'between', ["$year-01-01 00:00:00", "$year-12-31 23:59:59"]) ->whereNull('Mod_rq') // 修正:使用 whereNull 方法 ->count(); // 查询条件:Mod_rq为null且年份为今年的订单数量字段的总和 $sum = \db('工单_基本资料') ->field("sum(`订单数量`) as total_sum") // 使用反引号包裹中文字段名,并设置别名 ->where('Sys_rq', 'between', ["$year-01-01 00:00:00", "$year-12-31 23:59:59"]) ->whereNull('Mod_rq') ->select(); $total_sum = 0; $s_num_total = 0; $ratio = 0; if (!empty($sum)) { foreach ($sum as $value) { $total_sum = $value['total_sum']; // 使用别名获取结果 if ($total_sum) { // 查询设备_产量计酬表中工序编号为7且mod_rq为null且年份为今年的s_num总和 $s_num_result = \db('设备_产量计酬') ->field("sum(`s_num`) as s_num_total") // 计算 s_num 的总和 ->where('工序编号', 7) ->whereNull('mod_rq') ->where('sys_rq', 'between', ["$year-01-01 00:00:00", "$year-12-31 23:59:59"]) ->select(); if (!empty($s_num_result)) { $s_num_total = $s_num_result[0]['s_num_total']; // 获取 s_num 的总和 // 计算比例并四舍五入保留两位小数 if ($total_sum != 0) { // 避免除数为0 $ratio = round(($s_num_total / $total_sum) * 100) . '%'; } } } } } // 构建返回数据 $data = [ ["name" => " ", "value" => $count], ["name" => " ", "value" => $total_sum], ["name" => " ", "value" => $s_num_total], // ["name" => " ", "value" => $ratio], ]; // 返回 JSON 格式数据 return json([ "status" => 0, "msg" => "", "data" => $data, ]); } public function dcompletion_api(){ // 获取今年的年份 $year = date("Y"); // 查询条件:Mod_rq为null且年份为今年的记录数量 $count = \db('工单_基本资料') ->where('Sys_rq', 'between', ["$year-01-01 00:00:00", "$year-12-31 23:59:59"]) ->whereNull('Mod_rq') // 修正:使用 whereNull 方法 ->count(); // 查询条件:Mod_rq为null且年份为今年的订单数量字段的总和 $sum = \db('工单_基本资料') ->field("sum(`订单数量`) as total_sum") // 使用反引号包裹中文字段名,并设置别名 ->where('Sys_rq', 'between', ["$year-01-01 00:00:00", "$year-12-31 23:59:59"]) ->whereNull('Mod_rq') ->select(); $total_sum = 0; $s_num_total = 0; $ratio = 0; if (!empty($sum)) { foreach ($sum as $value) { $total_sum = $value['total_sum']; // 使用别名获取结果 if ($total_sum) { // 查询设备_产量计酬表中工序编号为7且mod_rq为null且年份为今年的s_num总和 $s_num_result = \db('设备_产量计酬') ->field("sum(`s_num`) as s_num_total") // 计算 s_num 的总和 ->where('工序编号', 7) ->whereNull('mod_rq') ->where('sys_rq', 'between', ["$year-01-01 00:00:00", "$year-12-31 23:59:59"]) ->select(); if (!empty($s_num_result)) { $s_num_total = $s_num_result[0]['s_num_total']; // 获取 s_num 的总和 // 计算比例并四舍五入取整数 if ($total_sum != 0) { // 避免除数为0 $ratio = ($s_num_total / $total_sum) * 100; // 四舍五入并取整数 } } } } } // 返回 JSON 格式数据 return json([ "status" => 0, "hitSugarSelf" => true, "msg" => "", "data" => round($ratio), // 返回计算后的整数完成率 ]); } public function qcompletion_api(){ // 获取今年的年份 $last_year = date("Y") - 1; // 查询条件:Mod_rq为null且年份为去年的记录数量 $count = \db('工单_基本资料') ->where('Sys_rq', 'between', ["$last_year-01-01 00:00:00", "$last_year-12-31 23:59:59"]) ->whereNull('Mod_rq') // 修正:使用 whereNull 方法 ->count(); // 查询条件:Mod_rq为null且年份为去年的订单数量字段的总和 $sum = \db('工单_基本资料') ->field("sum(`订单数量`) as total_sum") // 使用反引号包裹中文字段名,并设置别名 ->where('Sys_rq', 'between', ["$last_year-01-01 00:00:00", "$last_year-12-31 23:59:59"]) ->whereNull('Mod_rq') ->select(); $total_sum = 0; $s_num_total = 0; $ratio = 0; if (!empty($sum)) { foreach ($sum as $value) { $total_sum = $value['total_sum']; // 使用别名获取结果 if ($total_sum) { // 查询设备_产量计酬表中工序编号为7且mod_rq为null且年份为去年的s_num总和 $s_num_result = \db('设备_产量计酬') ->field("sum(`s_num`) as s_num_total") // 计算 s_num 的总和 ->where('工序编号', 7) ->whereNull('mod_rq') ->where('sys_rq', 'between', ["$last_year-01-01 00:00:00", "$last_year-12-31 23:59:59"]) ->select(); if (!empty($s_num_result)) { $s_num_total = $s_num_result[0]['s_num_total']; // 获取 s_num 的总和 // 计算比例并四舍五入保留两位小数 if ($total_sum != 0) { // 避免除数为0 $ratio = round(($s_num_total / $total_sum) * 100, 2); // 计算并保留两位小数 } } } } } // 返回 JSON 格式数据 return json([ "status" => 0, "hitSugarSelf" => true, "msg" => "", "data" => $ratio, ]); } /** * 年度订单个数【接口】 * 统计近三年的订单条数 */ public function orderlist_api(){ // 获取当前日期的年份 $currentYear = date('Y'); // 获取三年前的年份 $threeYearsAgo = $currentYear - 2; // 构建查询的年份范围 $years = [$threeYearsAgo, $threeYearsAgo + 1, $currentYear]; // 查询订单的年份和数量 $orderData = db('工单_基本资料') ->field('YEAR(Sys_rq) AS year, COUNT(*) AS order_count') ->whereNull('Mod_rq') ->where('YEAR(Sys_rq)', 'between', [$threeYearsAgo, $currentYear]) ->group('YEAR(Sys_rq)') ->select(); // 将查询结果按年份分组存储 $orderCountByYear = []; foreach ($orderData as $data) { $orderCountByYear[$data['year']] = $data['order_count']; } // 对于没有订单的年份,默认值为0 foreach ($years as $year) { if (!isset($orderCountByYear[$year])) { $orderCountByYear[$year] = 0; // 如果该年没有数据,则设置为0 } } // 准备 API 格式的响应数据 $response = [ 'status' => 0, 'msg' => '', 'data' => [ 'categories' => $years, // 输出年份数组 'series' => [ [ 'name' => '年度订单个数', 'data' => array_map(function($year) use ($orderCountByYear) { return $orderCountByYear[$year]; }, $years), // 根据年份返回对应的订单数量 ] ] ] ]; return json($response); } /** * 年度计划数量【接口】 * 统计近三年的订单总数量合计 */ public function ordersumlist_api(){ // 获取当前日期的年份 $currentYear = date('Y'); // 获取三年前的年份 $threeYearsAgo = $currentYear - 2; // 构建查询的年份范围 $years = [$threeYearsAgo, $threeYearsAgo + 1, $currentYear]; // 查询订单的年份和数量的合计 $orderData = db('工单_基本资料') ->field('YEAR(Sys_rq) AS year, SUM(订单数量) AS total_quantity') // 这里改为求“数量”的合计 ->whereNull('Mod_rq') ->where('YEAR(Sys_rq)', 'between', [$threeYearsAgo, $currentYear]) ->group('YEAR(Sys_rq)') ->select(); // 将查询结果按年份分组存储 $orderSumByYear = []; foreach ($orderData as $data) { $orderSumByYear[$data['year']] = $data['total_quantity']; } // 对于没有订单的年份,默认值为0 foreach ($years as $year) { if (!isset($orderSumByYear[$year])) { $orderSumByYear[$year] = 0; // 如果该年没有数据,则设置为0 } } // 准备 API 格式的响应数据 $response = [ 'status' => 0, 'msg' => '', 'data' => [ 'categories' => $years, // 输出年份数组 'series' => [ [ 'name' => '年度计划数量', 'data' => array_map(function($year) use ($orderSumByYear) { return $orderSumByYear[$year]; }, $years), // 根据年份返回对应的订单数量合计 ] ] ] ]; return json($response); } /** * 年度完工数量【接口】 * 统计每个月完成包装的数量 */ public function Annualcompletionrate_api() { // 获取当前年份和上一年份 $currentYear = date('Y'); $lastYear = $currentYear - 1; // 获取当前年份和去年的数据 $orderData = db('设备_产量计酬') ->field("DATE_FORMAT(sys_rq, '%Y-%m') AS sys_rq, SUM(s_num) AS 数量") ->where('工序名称', '包装') ->where('mod_rq',null) ->group('DATE_FORMAT(sys_rq, "%Y-%m")') // 按年月分组 ->select(); // 手动过滤数据,只保留当前年和去年的数据 $filteredData = array_filter($orderData, function ($data) use ($currentYear, $lastYear) { $year = explode('-', $data['sys_rq'])[0]; // 提取年份 return $year == $currentYear || $year == $lastYear; }); // 初始化月份和年份数组 $months = ["01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12"]; $responseData = [ 'categories' => $months, // 月份数组 'series' => [ ['name' => $lastYear . '年', 'data' => array_fill(0, 12, 0)], // 初始化为0 ['name' => $currentYear . '年', 'data' => array_fill(0, 12, 0)] // 初始化为0 ] ]; // 将查询结果按年份和月份存储 foreach ($filteredData as $data) { // 提取年和月 $yearMonth = explode('-', $data['sys_rq']); $year = $yearMonth[0]; $month = (int) $yearMonth[1] - 1; // 因为数组从0开始,所以要减去1 // 根据年份更新对应的月份数据 if ($year == $lastYear) { $responseData['series'][0]['data'][$month] = $data['数量']; } elseif ($year == $currentYear) { $responseData['series'][1]['data'][$month] = $data['数量']; } } // 构造最终的响应数据 $response = [ 'status' => 0, 'msg' => '', 'data' => $responseData ]; return json($response); } /** * 年度完成率【接口】 */ public function Annualcompletionraterate_api() { // 获取当前年份和上一年 $currentYear = date('Y'); $lastYear = $currentYear - 1; // 初始化月份数组 $months = ["01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12"]; // 初始化返回数据 $responseData = [ 'categories' => $months, // 月份 'series' => [ ['name' => $lastYear . '年完成率', 'data' => array_fill(0, 12, 0)], // 上一年完成率数据 ['name' => $currentYear . '年完成率', 'data' => array_fill(0, 12, 0)], // 当前年完成率数据 ] ]; // 1. 获取工单基本资料表每月的订单数量(近两年) $orderData = db('工单_基本资料') ->field("DATE_FORMAT(出库日期, '%Y-%m') AS 订单日期, SUM(订单数量) AS 订单数量") ->where('Mod_rq', null) // 筛选 Mod_rq 为 null ->group('DATE_FORMAT(出库日期, "%Y-%m")') // 按年月分组 ->select(); // 2. 获取设备产量计酬表每月的包装数量(s_num)(近两年) $productionData = db('设备_产量计酬') ->field("DATE_FORMAT(sys_rq, '%Y-%m') AS 报工日期, SUM(s_num) AS 完工数量") ->where('工序名称', '包装') // 筛选工序名称为包装 ->where('mod_rq', null) // 筛选 mod_rq 为 null ->group('DATE_FORMAT(sys_rq, "%Y-%m")') // 按年月分组 ->select(); // 将查询结果转换为数组,方便后续计算 $orderDataMap = []; foreach ($orderData as $data) { $orderDataMap[$data['订单日期']] = $data['订单数量']; } $productionDataMap = []; foreach ($productionData as $data) { $productionDataMap[$data['报工日期']] = $data['完工数量']; } // 3. 计算每月的完成率并四舍五入 foreach ($months as $month) { // 拼接当前月和上一年的年月 $currentMonth = $currentYear . '-' . $month; $lastMonth = $lastYear . '-' . $month; // 获取当前月和上一年的订单数量和完工数量 $totalOrdersCurrentYear = isset($orderDataMap[$currentMonth]) ? $orderDataMap[$currentMonth] : 0; $totalSNumCurrentYear = isset($productionDataMap[$currentMonth]) ? $productionDataMap[$currentMonth] : 0; $totalOrdersLastYear = isset($orderDataMap[$lastMonth]) ? $orderDataMap[$lastMonth] : 0; $totalSNumLastYear = isset($productionDataMap[$lastMonth]) ? $productionDataMap[$lastMonth] : 0; // 计算完成率,避免除以零,并四舍五入 // $completionRateCurrentYear = $totalOrdersCurrentYear > 0 ? round(($totalSNumCurrentYear / $totalOrdersCurrentYear) * 100) : 0; // $completionRateLastYear = $totalOrdersLastYear > 0 ? round(($totalSNumLastYear / $totalOrdersLastYear) * 100) : 0; // 计算完成率,避免除以零,并限制最大值为 100% $completionRateCurrentYear = $totalOrdersCurrentYear > 0 ? min(round(($totalSNumCurrentYear / $totalOrdersCurrentYear) * 100), 100) : 0; $completionRateLastYear = $totalOrdersLastYear > 0 ? min(round(($totalSNumLastYear / $totalOrdersLastYear) * 100), 100) : 0; // 存储每个月的完成率 $responseData['series'][0]['data'][$month - 1] = $completionRateLastYear; $responseData['series'][1]['data'][$month - 1] = $completionRateCurrentYear; } // 返回响应数据 $response = [ 'status' => 0, 'msg' => '', 'data' => $responseData ]; return json($response); } /** * 年度客户订单数量汇总【接口】 */ public function getOrderSummaryKhStyle() { // 获取当前年份 $last_year = date("Y"); // 查询工单_基本资料表,按客户编号分组并计算订单数量的总和 $result = \db('工单_基本资料') ->field('客户编号, SUM(订单数量) as 总订单数量') // 按客户编号分组并计算订单数量的总和 ->where('Sys_rq', '>=', "$last_year-01-01 00:00:00") // 用 >= 和 <= 来代替 between,提高查询效率 ->where('Sys_rq', '<=', "$last_year-12-31 23:59:59") ->whereNull('Mod_rq') // 确保 'Mod_rq' 为 null ->group('客户编号') // 按客户编号分组 ->order('总订单数量 desc') // 按总订单数量降序排序 ->cache(true, 60) // 添加缓存来减少数据库查询,60秒缓存一次 ->select(); // 如果没有数据,返回空结果 if (empty($result)) { return json([ 'status' => 0, 'msg' => '没有数据', 'data' => [ 'columns' => [], 'rows' => [] ] ]); } // 定义列格式 $columns = [ ['name' => '客户编号', 'id' => 'khbh', 'width' => '30', 'autoWrap' => "true", 'textAlign' => 'left'], ['name' => '总订单数量', 'id' => '总订单数量', 'width' => '30', 'autoWrap' => "true", 'textAlign' => 'left'] ]; // 格式化结果 $rows = array_map(function ($item) { return [ 'khbh' => $item['客户编号'], '总订单数量' => $item['总订单数量'] ]; }, $result); // 返回 JSON 格式的结果 return json([ 'status' => 0, 'msg' => '', 'data' => [ 'columns' => $columns, 'rows' => $rows ] ]); } /** * 年度款式上下装数量汇总【接口】 */ public function jacket() { // 获取当前年份 $last_year = date("Y"); // 查询数据库,统计款式订单数量 $row = \db('工单_基本资料') ->field('款式, COALESCE(SUM(订单数量), 0) as 总订单数量') // 避免 NULL 值 ->where('Sys_rq', 'between', ["$last_year-01-01 00:00:00", "$last_year-12-31 23:59:59"]) ->whereNull('Mod_rq') ->group('款式') // 按款式分组 ->order('总订单数量 desc') // 订单数量降序排列 ->limit(20) // 取前 20 个热销款式 ->select(); // 定义表格列 $result['columns'] = [ ['name' => '分类', 'id' => 'fl', 'width' => '20', 'textAlign' => 'left'], ['name' => '款式', 'id' => 'ks', 'width' => '35', 'textAlign' => 'left'], ['name' => '总订单数量', 'id' => 'zds', 'width' => '25', 'textAlign' => 'left'], ]; // 如果查询结果为空,返回空数据 if (empty($row)) { return json([ 'status' => 0, 'msg' => '没有数据', 'data' => $result ]); } // 分类关键词 $upperKeywords = ['衣', '装', '夹', '衫', '甲', '外套']; // 上装 $lowerKeywords = ['裤', '裙']; // 下装 // 处理查询结果,添加分类信息 foreach ($row as $k => $v) { $style = $v['款式']; $isUpper = $isLower = false; // 是否属于上装/下装 // 判断款式分类 if (preg_match('/(' . implode('|', $upperKeywords) . ')/u', $style)) { $isUpper = true; } if (preg_match('/(' . implode('|', $lowerKeywords) . ')/u', $style)) { $isLower = true; } // 归类 if (strpos($style, '+') !== false) { $category = '套装'; } elseif ($isUpper && $isLower) { $category = '全身'; } elseif ($isUpper) { $category = '上装'; } elseif ($isLower) { $category = '下装'; } else { $category = '其他'; } // 组装 `rows` 数据 $result['rows'][$k]['ks'] = $style; $result['rows'][$k]['zds'] = $v['总订单数量']; $result['rows'][$k]['fl'] = $category; } $res['status'] = 0; $res['msg'] = ''; $res['data'] = $result; return json($res); } /**第二屏*/ /** * 每月各个小组生产报工走势【接口】 * 统计每个工序小组的报工数据 */ public function Monthlyoutput_api() { $req = $this->request->param(); if (isset($req['jtbh']) && !empty($req['jtbh'])){ $jtbh = $req['jtbh']; } else { $this->error('参数错误'); } $currentYear = date('Y'); // 当前年份 $lastYear = $currentYear - 1; // 去年年份 $months = ["01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12"]; $wheres['sczl_jtbh'] = ['like', '%' . $jtbh . '%']; // 查询上个月的数据 // 查询数据库,按年份、月份和 jtbh 分组,获取近两年的数据 $queryResult = \db('设备_产量计酬') ->field(' YEAR(sys_rq) as year, DATE_FORMAT(sys_rq, "%m") as month, SUM( CASE WHEN 工序名称 IN ("裁剪", "车缝") THEN 数量 ELSE s_num END ) as 报工数量, 工序名称, sczl_jtbh as jtbh ') ->where($wheres) ->whereNull('mod_rq') ->where('sys_rq', 'between', ["$lastYear-01-01 00:00:00", "$currentYear-12-31 23:59:59"]) ->group('YEAR(sys_rq), DATE_FORMAT(sys_rq, "%m"), sczl_jtbh') ->select(); // 初始化结果数组,分开存储2024年和2025年的数据 $result = [ "categories" => $months, // 月份 "series" => [ ["name" => "{$lastYear}年", "data" => array_fill(0, 12, 0)], // 2024年数据,初始化为0 ["name" => "{$currentYear}年", "data" => array_fill(0, 12, 0)] // 2025年数据,初始化为0 ] ]; // 按年份分组数据 $dataByYear = [ $lastYear => array_fill(0, 12, 0), // 2024年的每月数据,初始化为0 $currentYear => array_fill(0, 12, 0) // 2025年的每月数据,初始化为0 ]; // 将查询结果填充到对应的年份和月份 foreach ($queryResult as $row) { $year = $row['year']; $month = (int)$row['month'] - 1; // 月份从0开始 $sNumTotal = $row['报工数量']; // 合并相同年份和月份的数据 if (isset($dataByYear[$year])) { $dataByYear[$year][$month] += $sNumTotal; // 这里是累加相同年月的数据 } } // 将数据填充到结果中的 series 中 foreach ($dataByYear as $year => $monthData) { foreach ($result['series'] as &$series) { if ($series['name'] == "{$year}年") { $series['data'] = $monthData; break; } } } // 返回结果 return json([ "status" => 0, "msg" => "", "data" => $result, ]); } /**第三屏*/ /** * 计划中 * */ public function plan_api(){ // 获取今年的年份 $last_year = date("Y"); // 查询条件:Mod_rq为null且年份为今年的订单状态字段的数量 $data = \db('工单_基本资料') ->field('gd_statu as 订单状态, COUNT(*) as 订单数量') // 统计每个订单状态的数量 ->where('Sys_rq', 'between', ["$last_year-01-01 00:00:00", "$last_year-12-31 23:59:59"]) ->whereNull('Mod_rq') ->group('gd_statu') // 按订单状态分组 ->select(); // 如果查询结果为空,设置一个默认值 if (empty($data)) { $formattedData[] = [ 'name' => ' ', 'value' => 0 ]; } else { // 否则根据查询结果格式化数据 $formattedData[] = [ 'name' => ' ', 'value' => isset($data[0]['订单数量']) ? $data[0]['订单数量'] : 0 ]; } // 返回 JSON 格式数据 return json([ "status" => 0, "msg" => "", "data" => $formattedData, ]); } /** * 生产中 * */ public function Production_api(){ // 获取今年的年份 $last_year = date("Y"); // 查询条件:Mod_rq为null且年份为今年的订单状态字段的数量 $data = \db('工单_基本资料') ->field('gd_statu as 订单状态, COUNT(*) as 订单数量') // 统计每个订单状态的数量 ->where('Sys_rq', 'between', ["$last_year-01-01 00:00:00", "$last_year-12-31 23:59:59"]) ->whereNull('Mod_rq') ->group('gd_statu') // 按订单状态分组 ->select(); // 如果查询结果为空,设置一个默认值 if (empty($data)) { $formattedData[] = [ 'name' => ' ', 'value' => 0 ]; } else { // 否则根据查询结果格式化数据 $formattedData[] = [ 'name' => ' ', 'value' => isset($data[1]['订单数量']) ? $data[1]['订单数量'] : 0 ]; } // 返回 JSON 格式数据 return json([ "status" => 0, "msg" => "", "data" => $formattedData, ]); } /** * 已完工 * */ public function Completed_api(){ // 获取今年的年份 $last_year = date("Y"); // 查询条件:Mod_rq为null且年份为今年的订单状态字段的数量 $data = \db('工单_基本资料') ->field('gd_statu as 订单状态, COUNT(*) as 订单数量') // 统计每个订单状态的数量 ->where('Sys_rq', 'between', ["$last_year-01-01 00:00:00", "$last_year-12-31 23:59:59"]) ->whereNull('Mod_rq') ->group('gd_statu') // 按订单状态分组 ->select(); // 如果查询结果为空,设置一个默认值 if (empty($data)) { $formattedData[] = [ 'name' => ' ', 'value' => 0 ]; } else { // 否则根据查询结果格式化数据 $formattedData[] = [ 'name' => ' ', 'value' => isset($data[2]['订单数量']) ? $data[2]['订单数量'] : 0 ]; } // 返回 JSON 格式数据 return json([ "status" => 0, "msg" => "", "data" => $formattedData, ]); } /** * 统计当前小组正在生产某个工单 * */ public function group_api() { $last_year = date("Y"); // 自定义小组排序规则 $group_order = [ '裁剪01组', '裁剪02组', '裁剪03组', '裁剪04组', '车缝01组', '车缝02组', '车缝03组', '车缝04组', '车缝05组', '车缝06组', '车缝07组', '车缝08组', '车缝09组', '车缝10组', '车缝11组', '车缝12组', '大办组', '美英组', '小芬组', '手工01组', '手工02组', '总检01组', '总检02组', '大烫01组', '包装01组', '包装02组' ]; // 查询条件:按小组和订单编号分组,取最新一条记录 $data = \db('设备_产量计酬')->alias('c') ->join('工单_基本资料 j', 'j.订单编号 = c.订单编号', 'LEFT') ->field([ 'c.订单编号', 'j.客户编号', 'c.款号', 'c.尺码', Db::raw('CASE WHEN c.工序名称 IN ("裁剪", "车缝") THEN c.数量 ELSE c.s_num END AS 数量'), 'c.工序名称', 'c.sczl_bh', // 小组名称 'c.sys_rq' // 时间字段 ]) ->group('c.订单编号, c.sczl_bh') // 按订单编号和小组分组,确保每个订单编号只出现一次 ->order('c.sys_rq DESC') // 按时间倒序排序,确保取到最新的一条 ->where('c.sys_rq', 'between', ["$last_year-01-01 00:00:00", "$last_year-12-31 23:59:59"]) // 时间过滤 ->select(); // 格式化数据,按小组取最新的一条工单 $groupedData = []; foreach ($data as $item) { // 确保每个小组只有一条最新记录 $groupedData[$item['sczl_bh']][] = [ '订单编号' => $item['订单编号'], '客户编号' => $item['客户编号'], '款号' => $item['款号'], '尺码' => $item['尺码'], '数量' => $item['数量'], '工序名称' => $item['工序名称'], '小组' => $item['sczl_bh'], '时间' => $item['sys_rq'], // 记录时间 ]; } // 筛选每个小组的最新一条数据 $latestData = []; foreach ($groupedData as $group => $groupItems) { // 只取最新一条记录 $latestData[$group] = $groupItems[0]; // 因为数据是按时间降序排列的,所以取第一个就是最新的 } // 对小组进行自定义排序 uasort($latestData, function($a, $b) use ($group_order) { // 获取小组排序位置 $a_index = array_search($a['小组'], $group_order); $b_index = array_search($b['小组'], $group_order); // 根据位置排序 return $a_index - $b_index; }); // 根据自定义列格式生成数据 $result['columns'] = [ // ['name' => '工序名称', 'id' => 'gxxm', 'width' => '10%', 'textAlign' => 'left'], ['name' => '小组', 'id' => 'xz', 'width' => '10', 'autoWrap' => "true",'textAlign' => 'left'], ['name' => '订单编号', 'id' => 'ddbh', 'width' => '14','autoWrap' => "true", 'textAlign' => 'left'], ['name' => '客户编号', 'id' => 'khbh', 'width' => '10','autoWrap' => "true", 'textAlign' => 'left'], ['name' => '款号', 'id' => 'kh', 'width' => '30', 'textAlign' => 'left'], ['name' => '尺码', 'id' => 'cm', 'width' => '7','autoWrap' => "true", 'textAlign' => 'left'], ['name' => '数量', 'id' => 'sl', 'width' => '7', 'autoWrap' => "true",'textAlign' => 'left'], ['name' => '时间', 'id' => 'sj', 'width' => '20','autoWrap' => "true", 'textAlign' => 'left'], ]; // 将最新的数据填充到表格行中 $rows = []; foreach ($latestData as $v) { $rows[] = [ 'ddbh' => $v['订单编号'], 'khbh' => $v['客户编号'], 'kh' => $v['款号'], 'gxxm' => $v['工序名称'], 'xz' => $v['小组'], 'cm' => $v['尺码'], 'sl' => $v['数量'], 'sj' => $v['时间'], ]; } // 如果没有数据,返回空行 if (empty($rows)) { $rows[] = [ 'ddbh' => '', 'khbh' => '', 'kh' => '', 'cm' => '', 'gxxm' => '', 'xz' => '', 'sl' => '', 'sj' => '' ]; } // 返回最终结果 $res['status'] = 0; $res['msg'] = '查询成功'; $res['data'] = [ 'columns' => $result['columns'], 'rows' => $rows ]; return json($res); } /** * 在产订单工序详情【缓存】 */ public function getJhzByRedis(){ //存缓存Redis $redis = redis(); $redis_key = md5('getJhzByRedis'); // 定义固定工序名称 $processNames = ['裁剪', '车缝', '手工', '大烫', '总检', '包装']; // $startTime = date('Y-m-d', strtotime('-180 days')); $startTime = date('Y-m-01'); $endTime = date('Y-m-d'); $where['c.Sys_rq'] = ['between', [$startTime, $endTime]]; $where['j.出库日期'] = ['<>', 'NULL']; $where['c.mod_rq'] = null; // 第一个查询:获取完工数量 $list = \db('工单_基本资料')->alias('j') ->join('设备_产量计酬 c', 'j.订单编号 = c.订单编号', 'LEFT') ->field('c.订单编号, j.工单入仓数量, j.客户编号, j.生产款号, j.款式, c.工序名称, CASE WHEN 工序名称 IN ("裁剪", "车缝") THEN SUM(数量) ELSE SUM(s_num) END as 完工数量, j.gd_statu as 订单状态') ->where($where) ->group('c.订单编号, c.工序名称') ->order('c.订单编号 desc') ->having('完工数量 > 0') ->select(); // 第二个查询:获取制单数 $yjwhere['y.Mod_rq'] = null; $yjlist = \db('工单_基本资料')->alias('j') ->join('工单_印件资料 y', 'j.订单编号 = y.订单编号', 'LEFT') ->field('y.订单编号, SUM(y.zdtotal) as 制单数') ->where($yjwhere) ->group('y.订单编号') ->order('y.订单编号 desc') ->select(); // 将制单数结果转换为以订单编号为键的数组,方便后续合并 $yjlistIndexed = []; foreach ($yjlist as $yj) { $yjlistIndexed[$yj['订单编号']] = $yj['制单数']; } // 合并数据 $mergedData = []; foreach ($list as $order) { $orderId = $order['订单编号']; // 初始化订单数据,如果还未存在 if (!isset($mergedData[$orderId])) { // 获取制单数和已完工数量 $zdTotal = $yjlistIndexed[$orderId] ?? 0; // 制单数 $completedTotal = $order['工单入仓数量']; // 已完工数量 // 计算完成百分比 $completionPercentage = $zdTotal > 0 ? round(($completedTotal / $zdTotal) * 100, 2) . '%' : '0%'; // 初始化订单数据 $mergedData[$orderId] = [ '订单编号' => $orderId, '客户编号' => $order['客户编号'], '生产款号' => $order['生产款号'], '款式' => $order['款式'], '订单状态' => $order['订单状态'], '已完工数量' => $completedTotal, '制单数' => $zdTotal, '完成百分比' => $completionPercentage, // 新增字段:完成百分比 ]; // 初始化所有工序的完工数量为空 foreach ($processNames as $process) { $mergedData[$orderId][$process] = ''; } } // 更新对应的工序名称和完工数量 if (in_array($order['工序名称'], $processNames)) { $mergedData[$orderId][$order['工序名称']] = $order['完工数量']; } } foreach ($mergedData as $key => $order) { // 判断裁剪是否为空 if (empty($order['裁剪'])) { unset($mergedData[$key]); // 如果裁剪为空,删除该订单 } } // 转换合并后的数组格式 $result = array_values($mergedData); $redis->set($redis_key, json_encode($result)); echo date("Y-m-d H:i:s").'----存进去了'; // return $result; } /** * 在产订单工序详情【接口】 */ public function getJhzBy(){ $redis = redis(); $row = json_decode($redis->get(md5('getJhzByRedis')), true); // 列定义 $result['columns'] = [ ['name' => '订单编号', 'id' => 'ddbh', 'width' => '7', 'textAlign' => 'left'], ['name' => '客户编号', 'id' => 'khbh', 'width' => '6','autoWrap' => "true", 'textAlign' => 'left'], ['name' => '生产款号', 'id' => 'sckh', 'width' => '12', 'textAlign' => 'left'], ['name' => '款式', 'id' => 'ks', 'width' => '10', 'textAlign' => 'left'], ['name' => '订单状态', 'id' => 'ddzt', 'width' => '6', 'textAlign' => 'left'], ['name' => '制单总数', 'id' => 'zds', 'width' => '6', 'textAlign' => 'left'], ['name' => '裁剪已完成', 'id' => 'cj', 'width' => '6','autoWrap'=>"true", 'textAlign' => 'left'], ['name' => '车缝已完成', 'id' => 'cf', 'width' => '6','autoWrap'=>"true", 'textAlign' => 'left'], ['name' => '手工已完成', 'id' => 'sg', 'width' => '6','autoWrap'=>"true", 'textAlign' => 'left'], ['name' => '大烫已完成', 'id' => 'dt', 'width' => '6','autoWrap'=>"true", 'textAlign' => 'left'], ['name' => '总检已完成', 'id' => 'zj', 'width' => '6','autoWrap'=>"true", 'textAlign' => 'left'], ['name' => '包装已完成', 'id' => 'bz', 'width' => '6','autoWrap'=>"true", 'textAlign' => 'left'], ['name' => '已完成数量', 'id' => 'ywgsl', 'width' => '6','autoWrap'=>"true", 'textAlign' => 'left'], ['name' => '完成百分比', 'id' => 'bfb', 'width' => '6','autoWrap'=>"true", 'textAlign' => 'left'], ]; if ($row) { foreach ($row as $k => $v) { $result['rows'][$k]['ddbh'] = $v['订单编号']; $result['rows'][$k]['khbh'] = $v['客户编号']; $result['rows'][$k]['sckh'] = $v['生产款号']; $result['rows'][$k]['ks'] = $v['款式']; $result['rows'][$k]['ddzt'] = $v['订单状态']; // 工序数量字段,根据之前的定义调整字段名 $result['rows'][$k]['cj'] = $v['裁剪'] ?? ''; $result['rows'][$k]['cf'] = $v['车缝'] ?? ''; $result['rows'][$k]['sg'] = $v['手工'] ?? ''; $result['rows'][$k]['dt'] = $v['大烫'] ?? ''; $result['rows'][$k]['zj'] = $v['总检'] ?? ''; $result['rows'][$k]['bz'] = $v['包装'] ?? ''; // 其他数量字段 $result['rows'][$k]['ywgsl'] = $v['已完工数量'] ?? ''; // 示例字段,需确保与数据一致 $result['rows'][$k]['zds'] = $v['制单数'] ?? ''; // 对应制单数 $result['rows'][$k]['bfb'] = $v['完成百分比'] ?? ''; // 对应制单数 } } else { // 如果没有数据,初始化空行 $result['rows'][0] = [ 'ddbh' => '', 'khbh' => '', 'sckh' => '', 'ks' => '', 'ddzt' => '', 'cj' => '', 'cf' => '', 'sg' => '', 'dt' => '', 'zj' => '', 'bz' => '', 'ywgsl' => '', 'zds' => '' ]; } // echo "
";print_r($result);echo "
";die;
        $res['status'] = 0;
        $res['msg'] = '';
        $res['data'] = $result;
        return json($res);
    }



    /**
     *当日班组报工产量【缓存】
     * 建议缓存时间,5--10分钟自动更新一次
     * 统计当天的各个小组报工完成数量
     */
    public function GroupProductionRedis() {
        // 存缓存到 Redis
        $redis = redis();
        $redis_key = md5('GroupProductionRedis');

        $today = date('Y-m-d'); // 获取今天的日期
        $sevenDaysAgo = date('Y-m-d', strtotime('-6 days')); // 计算6天前的日期(包含今天共7天)

        // 自定义需要显示的生产工序顺序
        $customGroups = ['裁剪', '车缝', '手工', '大烫', '总检', '包装'];

        // 获取所有设备资料,并按自定义工序顺序过滤
        $Machine = db('设备_基本资料')
            ->field('生产工序, 设备编组')
            ->whereIn('生产工序', $customGroups)
            ->select();

        // 查询当天设备产量数据
        $res = db('设备_产量计酬')->alias('c')
            ->field([
                'c.sczl_bh',
                // 使用 CASE 语句动态选择字段:裁剪和车缝使用数量,其他工序使用 s_num
                Db::raw('CASE 
            WHEN c.工序名称 IN ("裁剪", "车缝") THEN c.数量 
            ELSE s_num
            END AS 数量'),
                'c.工序名称',
                'c.sczl_jtbh',
                'c.sys_rq'
            ])
            ->where(function($query) {
                // 过滤 mod_rq 为 NULL 或 空字符串的记录
                $query->where('c.mod_rq', null)->whereOr('c.mod_rq', '');
            })
            ->where('c.sys_rq', '>=', $sevenDaysAgo . ' 00:00:00') // 从今天00:00开始
            ->where('c.sys_rq', '<=', $today . ' 23:59:59') // 到今天23:59结束
            ->select();

        // 将合并后的数据存储到 Redis 中
        $redis->set($redis_key, json_encode($res));
        echo date("Y-m-d H:i:s") . ' 存进去了';
    }

    //当日报工数量
    public function GroupMachineCFyi()
    {
        $redis = redis(); // 连接 Redis
        $row = json_decode($redis->get(md5('GroupProductionRedis')), true); // 从 Redis 获取数据

        // 获取请求参数中的组别代码
        $req = $this->request->param();
        if (isset($req['jtbh']) && !empty($req['jtbh'])) {
            $arr = $req['jtbh'];
        } else {
            $this->error('参数错误'); // 如果没有传递有效的组别代码,返回错误
        }

        // 获取当前日期
        $today = date('Y-m-d');
        $toYear = date('Y'); // 当前年份
        // 获取七天前的日期
        $sevenDaysAgo = date('Y-m-d', strtotime('-6 days'));

        // 初始化分类和数据系列
        $categories = []; // 存储七天的日期
        $dataSeries = []; // 存储不同工序的数量汇总

        // 获取近七天的日期数组(只取日期部分)
        for ($i = 6; $i >= 0; $i--) {
            $categories[] = date('d', strtotime("-{$i} days")); // 只取日期部分
        }

        // 遍历 Redis 获取的数据,筛选出符合条件的数据
        foreach ($row as $data) {
            // 检查组别代码是否匹配
            if ($data['sczl_jtbh'] === $arr) {
                $date = date('Y-m-d', strtotime($data['sys_rq'])); // 获取数据的日期
                if ($date >= $sevenDaysAgo && $date <= $today) {
                    // 计算该日期在七天日期数组中的索引
                    $dateIndex = array_search(date('d', strtotime($date)), $categories);
                    if ($dateIndex !== false) {
                        // 根据工序名称汇总
                        $processName = $data['工序名称'];

                        // 如果工序名称还没在 $dataSeries 中创建,先初始化
                        if (!isset($dataSeries[$processName])) {
                            $dataSeries[$processName] = array_fill(0, 7, 0); // 初始化该工序的数据
                        }

                        // 累加数量
                        $dataSeries[$processName][$dateIndex] += $data['数量']; // 使用工序名称作为键名
                    }
                }
            }
        }

        // 如果没有任何数据,确保工序数据为默认值
        if (empty($dataSeries)) {
            // 如果没有数据,初始化默认工序并设置数据为0
            $dataSeries = [
                '默认工序' => array_fill(0, 7, 0)
            ];
        }

        // 构建返回的数据格式
        $seriesData = [];
        foreach ($dataSeries as $processName => $values) {
            $seriesData[] = [
                'name' => $processName, // 工序名称作为名称
                'data' => $values // 当前工序的数量数据
            ];
        }

        $list = [
            'categories' => $categories, // 七天的日期
            'series' => $seriesData // 不同工序的数据
        ];

        // 返回 JSON 格式的结果
        $res = [
            'status' => 0,
            'msg' => '',
            'data' => $list
        ];

        return json($res); // 返回最终的 JSON 数据
    }



    //下面接口已写好-----暂时未用到

    //板房车缝当日报工数量
    public function GroupMachinebfCFyi()
    {
        $redis = redis();
        $row = json_decode($redis->get(md5('GroupProductionRedis')), true);

        // 初始化小组名称和数量
        $categories = [];
        $dataSeries = [];

// 遍历数据,找到所有工序名称为“车缝”的小组,且只包含“大办组”、“小芬组”、“美英组”
        foreach ($row as $data) {
            if ($data['工序名称'] === '车缝' && in_array($data['组别'], ['大办组', '小芬组', '美英组'])) {
                $categories[] = $data['组别']; // 添加组别到分类中
                $dataSeries[$data['组别']] = $data['数量']; // 更新小组数量
            }
        }

// 构建输出数据格式
        $list = [
            'categories' => $categories,
            'series' => [
                [
                    'name' => '完成',
                    'data' => array_values($dataSeries) // 获取数量数组
                ]
            ]
        ];

        $res = [
            'status' => 0,
            'msg' => '',
            'data' => $list
        ];
        // 返回 JSON 格式的结果
        return json($res);
    }
    //裁剪当日报工数量
    public function GroupMachineCJyi()
    {
        $redis = redis();
        $row = json_decode($redis->get(md5('GroupProductionRedis')), true);

        // 初始化小组名称和数量
        $categories = [];
        $dataSeries = [];

        // 遍历数据,找到所有工序名称为“车缝”的小组
        foreach ($row as $data) {
            if ($data['工序名称'] !== '车缝') {
                $categories[] = $data['组别']; // 添加组别到分类中
                $dataSeries[$data['组别']] = $data['数量']; // 更新小组数量
            }
        }

        // 构建输出数据格式
        $list = [
            'categories' => $categories,
            'series' => [
                [
                    'name' => '完成',
                    'data' => array_values($dataSeries) // 获取数量数组
                ]
            ]
        ];

        $res = [
            'status' => 0,
            'msg' => '',
            'data' => $list
        ];

        // 返回 JSON 格式的结果
        return json($res);
    }
    //手工当日报工数量
    public function GroupMachineSGyi()
    {
        $redis = redis();
        $row = json_decode($redis->get(md5('GroupProductionRedis')), true);

        // 初始化小组名称和数量
        $categories = [];
        $dataSeries = [];

        // 遍历数据,找到所有工序名称为“车缝”的小组
        foreach ($row as $data) {
            if ($data['工序名称'] === '手工') {
                $categories[] = $data['组别']; // 添加组别到分类中
                $dataSeries[$data['组别']] = $data['数量']; // 更新小组数量
            }
        }

        // 构建输出数据格式
        $list = [
            'categories' => $categories,
            'series' => [
                [
                    'name' => '完成',
                    'data' => array_values($dataSeries) // 获取数量数组
                ]
            ]
        ];

        $res = [
            'status' => 0,
            'msg' => '',
            'data' => $list
        ];

        // 返回 JSON 格式的结果
        return json($res);
    }
    //大烫当日报工数量
    public function GroupMachineDTyi()
    {
        $redis = redis();
        $row = json_decode($redis->get(md5('GroupProductionRedis')), true);

        // 初始化小组名称和数量
        $categories = [];
        $dataSeries = [];

        // 遍历数据,找到所有工序名称为“车缝”的小组
        foreach ($row as $data) {
            if ($data['工序名称'] === '大烫') {
                $categories[] = $data['组别']; // 添加组别到分类中
                $dataSeries[$data['组别']] = $data['数量']; // 更新小组数量
            }
        }

        // 构建输出数据格式
        $list = [
            'categories' => $categories,
            'series' => [
                [
                    'name' => '完成',
                    'data' => array_values($dataSeries) // 获取数量数组
                ]
            ]
        ];

        $res = [
            'status' => 0,
            'msg' => '',
            'data' => $list
        ];

        // 返回 JSON 格式的结果
        return json($res);
    }
    //总检当日报工数量
    public function GroupMachineZJyi()
    {
        $redis = redis();
        $row = json_decode($redis->get(md5('GroupProductionRedis')), true);

        // 初始化小组名称和数量
        $categories = [];
        $dataSeries = [];

        // 遍历数据,找到所有工序名称为“车缝”的小组
        foreach ($row as $data) {
            if ($data['工序名称'] === '总检') {
                $categories[] = $data['组别']; // 添加组别到分类中
                $dataSeries[$data['组别']] = $data['数量']; // 更新小组数量
            }
        }

        // 构建输出数据格式
        $list = [
            'categories' => $categories,
            'series' => [
                [
                    'name' => '完成',
                    'data' => array_values($dataSeries) // 获取数量数组
                ]
            ]
        ];

        $res = [
            'status' => 0,
            'msg' => '',
            'data' => $list
        ];

        // 返回 JSON 格式的结果
        return json($res);
    }
    //包装当日报工数量
    public function GroupMachineBZyi()
    {
        $redis = redis();
        $row = json_decode($redis->get(md5('GroupProductionRedis')), true);

        // 初始化小组名称和数量
        $categories = [];
        $dataSeries = [];

        // 遍历数据,找到所有工序名称为“车缝”的小组
        foreach ($row as $data) {
            if ($data['工序名称'] === '包装') {
                $categories[] = $data['组别']; // 添加组别到分类中
                $dataSeries[$data['组别']] = $data['数量']; // 更新小组数量
            }
        }

        // 构建输出数据格式
        $list = [
            'categories' => $categories,
            'series' => [
                [
                    'name' => '完成',
                    'data' => array_values($dataSeries) // 获取数量数组
                ]
            ]
        ];

        $res = [
            'status' => 0,
            'msg' => '',
            'data' => $list
        ];

        // 返回 JSON 格式的结果
        return json($res);
    }


    //自动生成面料以及调用---》GPT
    public function GtpAiOrder()
    {
        if (!$this->request->isGet()) {
            $this->error('请求错误');
        }
        $order = $this->request->param('订单编号');
        // 判断是否有指定的订单号
        if (!empty($order)) {
            // 查询单个订单的最大编号
            $maxOrder = \db('工单_基本资料')
                ->where('订单编号', 'like', "{$order}%")
                ->order('订单编号', 'desc')
                ->limit(1)
                ->value('订单编号');

            // 查询该订单的基本资料
            $list = \db('工单_基本资料')
                ->where('订单编号', 'like', "{$order}%")
                ->order('订单编号', 'desc')
                ->limit(1)
                ->find();

            // 如果面料数据为空,提示错误
            if (empty($list['面料'])) {
                $this->error('面料数据为空无法定义BOM');
            }

            // 处理订单编号
            $numericPart = substr($maxOrder, 2);
            $newNumericPart = str_pad((int)$numericPart + 1, strlen($numericPart), '0', STR_PAD_LEFT);
            $param['订单编号'] = $order . $newNumericPart;

            // 假设massage是从数据库获取的数据
            $massage = empty($list['粘衬']) || $list['粘衬'] == '无' ? $list['面料'] : $list['面料'] . ',粘衬:' . $list['粘衬'];

            $materialCategories = [];
            $pattern = '/(\S+?):([^,]+)/'; // 匹配 类别:物料 格式

            preg_match_all($pattern, $massage, $matches, PREG_SET_ORDER);

            foreach ($matches as $match) {
                $category = $match[1]; // 分类名称
                $materials = explode('+', $match[2]); // 如果物料名称中有‘+’,则分开处理多个物料

                // 将分类和对应的物料添加到数组中
                foreach ($materials as $material) {
                    $materialCategories[$category][] = trim($material); // 去除物料两边的空格
                }
            }

            $mianliao = $this->Gpt($massage);

            $data = [];
            foreach ($mianliao as $value) {
                if (!empty($value) && $value !== '粘衬') { // 排除空值和粘衬
                    $category = '';

                    // 查找物料对应的分类
                    foreach ($materialCategories as $cat => $materials) {
                        if (in_array($value, $materials)) {
                            $category = $cat;
                            break;
                        }
                    }

                    // 如果找到分类,将数据存入BOM
                    $data[] = [
                        'BOM_工单编号' => $list['订单编号'],
                        'BOM_物料名称' => $value,
                        'BOM_desc' => '',
                        '物料分类' => $category ? $category : '',
                        'Sys_rq' => date('Y-m-d H:i:s'),
                        'Sys_ID' => '超级管理员'
                    ];
                }
            }
            foreach ($data as &$item) {
                if (empty($item['物料分类'])) {
                    $item['物料分类'] = '';
                }
                // 去除所有非汉字字符
                $item['物料分类'] = preg_replace('/[^\p{Han}]/u', '', $item['物料分类']);
            }


//// 批量更新 BOM_desc,如果对应的 BOM_desc 没有填充就更新
//            foreach ($data as $item) {
//                if (!empty($item['物料分类'])) {
//                    \db('工单_bom资料')->insertAll($data);
//
////                    \db('工单_面料资料')
////                        ->where('BOM_工单编号', $item['BOM_工单编号'])
////                        ->where('BOM_物料名称', $item['BOM_物料名称'])
////                        ->update(['BOM_desc' => preg_replace('/[^\w\s]/u', '', $item['BOM_desc'])]);
//
//                }
//            }
//            $this->success('成功',$order);
        } else {
            // 如果没有指定订单号,批量查询订单号并处理
            $has_bom = \db('工单_bom资料')->alias('a')->field('a.BOM_工单编号')->group('a.BOM_工单编号')->select();
            $all_orders = \db('工单_基本资料')->alias('a')->field('a.订单编号')->where('a.面料', '<>', '')->group('a.订单编号')->select();

            // 提取有BOM资料的订单号
            $has_bom_orders = array_column($has_bom, 'BOM_工单编号');

            // 筛选出没有对应BOM资料的订单号
            $no_bom_orders = array_filter($all_orders, function ($order) use ($has_bom_orders) {
                return !in_array($order['订单编号'], $has_bom_orders);
            });

            // 遍历没有BOM资料的订单
            foreach ($no_bom_orders as $orderData) {
                // 获取该订单号的最大订单编号
                $maxOrder = \db('工单_基本资料')
                    ->where('订单编号', 'like', "{$orderData['订单编号']}%")
                    ->order('订单编号', 'desc')
                    ->limit(1)
                    ->value('订单编号');

                // 获取该订单号的具体数据
                $list = \db('工单_基本资料')
                    ->where('订单编号', 'like', "{$orderData['订单编号']}%")
                    ->order('订单编号', 'desc')
                    ->limit(1)
                    ->find();

                if (empty($list['面料'])) {
                    $this->error("订单 {$orderData['订单编号']} 面料数据为空,无法定义BOM");
                }

                // 处理订单编号
                $numericPart = substr($maxOrder, 2);
                $newNumericPart = str_pad((int)$numericPart + 1, strlen($numericPart), '0', STR_PAD_LEFT);
                $param['订单编号'] = $order . $newNumericPart;

                // 处理物料信息
                $massage = empty($list['粘衬']) || $list['粘衬'] == '无' ? $list['面料'] : $list['面料'] . ',粘衬:' . $list['粘衬'];
                $mianliao = $this->Gpt($massage);
                // 插入物料数据
                $data = [];
                foreach ($mianliao as $key => $value) {
                    if (!empty($value) && $value !== '粘衬') { // 排除空值和粘衬
                        $data[] = [
                            'BOM_工单编号' => $list['订单编号'],
                            'BOM_物料名称' => $value,
                            'BOM_desc' => '',
                            '物料分类' => '',
                            'Sys_rq' => date('Y-m-d H:i:s'),
                            'Sys_ID' => '超级管理员'
                        ];
                    }
                }

                // 批量插入BOM资料
                if (!empty($data)) {
                    \db('工单_bom资料')->insertAll($data);
                }
            }
            $this->success('成功');
        }
    }
    //GPT
    public function Gpt($massage)
    {
        // 设置 API 密钥
        $apiKey = 'sk-e0JuPjMntkbgi1BoMjrqyyzMKzAxILkQzyGMSy3xiMupuoWY'; // 替换为您的 API 密钥

        // 要发送给 GPT 的消息
        $messages = [
            [
                'role' => 'user',
                'content' => '你好,帮我按照:面料1、面料2、面料3……来整理归纳下面的面料信息,我只需要面料信息,不需要其他:'.$massage
            ]
        ];
        // 创建请求数据
        $data = [
            'model' => 'gpt-3.5-turbo', // 使用的模型
            'messages' => $messages,
            'max_tokens' => 100, // 设置最大 token 数
        ];

        // 初始化 cURL
        $ch = curl_init('https://niubi.zeabur.app/v1/chat/completions');

        // 设置 cURL 选项
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_HTTPHEADER, [
            'Content-Type: application/json',
            'Authorization: Bearer ' . $apiKey,
        ]);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
        curl_setopt($ch, CURLOPT_CAINFO, ROOT_PATH . '/public/uploads/cacert.pem');

        // 执行请求
        $response = curl_exec($ch);

        // 检查错误
        if (curl_errno($ch)) {
            echo 'Error:' . curl_error($ch);
        }

        // 关闭 cURL
        curl_close($ch);

        // 解析和输出响应
        $responseData = json_decode($response, true);

        // 获取 GPT 的回复
        if (isset($responseData['choices'][0]['message']['content'])) {
            //获取返回内容
            $gptReply = $responseData['choices'][0]['message']['content'];
//            halt($gptReply);
            //返回面料信息
            $gptArray = explode('面料',$gptReply);
            array_shift($gptArray);
            foreach ($gptArray as $key=>$value){
                $gptArray[$key] = preg_replace('/\s+/', '', substr($value,4));
            }
            return $gptArray;
        } else {
            echo "未能获取 GPT 的回复。";
        }
    }





}