success('产品_基本资料'); } /** * 获取左侧菜单产品分类列表 * 按 product_type 分组 → 分类下显示对应产品 */ public function ProductTypeMenu() { if (Request::instance()->isGet() == false) { $this->error('非法请求'); } $params = Request::instance()->param(); // 获取所有产品 $productList = \db('产品_基本资料')->whereNull('mod_rq') ->column('id,product_code,product_name,product_type'); $data = []; if ($productList) { foreach ($productList as $item) { $type = $item['product_type'] ?: '未分类'; // 分类 $data[$type]['name'] = $type; // 分类下的产品 $data[$type]['list'][] = [ 'id' => $item['id'], 'product_code' => $item['product_code'], 'product_name' => $item['product_name'] ]; } } // 转成索引数组返回 $result = array_values($data); $this->success('获取成功', $result); } /** * 获取产品资料列表(产品→部件→工艺) */ public function ProductList() { if (!Request::instance()->isGet()) { $this->error('非法请求'); } $params = Request::instance()->param(); $where = []; if (!empty($params['search'])) { $where['product_code|product_name|product_type'] = ['like', '%' . $params['search'] . '%']; } $limit = empty($params['limit']) ? 30 : $params['limit']; $pages = empty($params['page']) ? 1 : $params['page']; // 1. 查询产品主表 $productList = db('产品_基本资料') ->whereNull('mod_rq') ->where($where) ->page($pages, $limit) ->order('id desc') ->select(); if (empty($productList)) { $this->success('获取成功', ['list' => [], 'count' => 0]); } // 提取产品编号 $productCodes = array_column($productList, 'product_code'); // 2. 查询部件(按 product_code 关联,并按 part_sort 排序) $parts = db('产品_部件资料') ->whereNull('mod_rq') ->whereIn('product_code', $productCodes) ->order('part_sort asc') // 按部件排序号升序 ->select(); // 提取 (product_code + part_sort) 作为关联键 $partKeys = []; foreach ($parts as $p) { $key = $p['product_code'] . '_' . $p['part_sort']; $partKeys[] = $key; } // 3. 查询工艺(按 product_code + part_sort 关联,并按 gy_sort 排序) $process = []; if (!empty($productCodes)) { $process = db('产品_工艺资料') ->whereNull('mod_rq') ->whereIn('product_code', $productCodes) ->order('part_sort asc, gy_sort asc') // 按部件排序+工序排序 ->select(); } // 部件按 product_code 分组 $partGroup = []; foreach ($parts as $val) { $partGroup[$val['product_code']][] = $val; } // 工艺按 (product_code + part_sort) 分组 $processGroup = []; foreach ($process as $val) { $key = $val['product_code'] . '_' . $val['part_sort']; $processGroup[$key][] = $val; } // 组装数据:产品 → 部件 → 工艺 foreach ($productList as &$product) { $currentParts = $partGroup[$product['product_code']] ?? []; foreach ($currentParts as &$item) { // 用 product_code + part_sort 关联工艺 $key = $product['product_code'] . '_' . $item['part_sort']; $item['processes'] = $processGroup[$key] ?? []; } $product['parts'] = $currentParts; } // 统计总数 $count = db('产品_基本资料') ->whereNull('mod_rq') ->where($where) ->count(); $this->success('获取成功', [ 'list' => $productList, 'count' => $count ]); } /** * 新增产品资料 */ public function ProductAdd() { if (!Request::instance()->isPost()) { $this->error('非法请求'); } $params = Request::instance()->param(); // 自动生成产品编号:CP000001 $lastCode = \db('产品_基本资料')->order('id desc')->value('product_code'); if ($lastCode) { $num = intval(str_replace('CP', '', $lastCode)) + 1; } else { $num = 1; } $params['product_code'] = 'CP' . str_pad($num, 6, '0', STR_PAD_LEFT); $data = []; $data['product_code'] = $params['product_code']; $data['product_name'] = $params['product_name']; $data['product_type'] = $params['product_type']; $data['unit'] = $params['unit']; $data['sys_id'] = $params['sys_id']; $data['status'] = 1; $data['sys_rq'] = date('Y-m-d H:i:s'); $result = \db('产品_基本资料')->insert($data); if ($result) { $this->success('新增成功'); } else { $this->error('新增失败'); } } /** * 修改产品资料 */ public function ProductEdit() { if (!Request::instance()->isPost()) { $this->error('非法请求'); } $params = Request::instance()->param(); if (empty($params['id'])) { $this->error('请选择数据'); } // 禁止修改编号 unset($params['product_code']); $data = []; $data['product_name'] = $params['product_name']; $data['product_type'] = $params['product_type']; $data['unit'] = $params['unit']; $data['sys_id'] = $params['sys_id']; $data['updatetime'] = date('Y-m-d H:i:s'); $result = \db('产品_基本资料') ->where('id', $params['id']) ->update($data); if ($result !== false) { $this->success('修改成功'); } else { $this->error('修改失败'); } } /** * 删除产品资料 */ public function ProductDelete() { if (!Request::instance()->isPost()) { $this->error('非法请求'); } $id = input('id'); if (empty($id)) { $this->error('请选择需要删除的数据'); } $ids = explode(',', $id); $result = \db('产品_基本资料') ->where('id', 'in', $ids) ->update(['mod_rq' => date('Y-m-d H:i:s')]); if ($result !== false) { $this->success('删除成功'); } else { $this->error('删除失败'); } } /** * 获取产品部件列表 */ public function ProductPartList() { if (Request::instance()->isGet() == false) { $this->error('非法请求'); } $params = Request::instance()->param(); $where = []; if (!empty($params['search'])) { $where['part_name'] = array('like', '%' . $params['search'] . '%'); } if (!empty($params['product_code'])) { $where['product_code'] = array('like', '%' . $params['product_code'] . '%'); } $limit = $params['limit']; if (empty($limit)) { $limit = 30; } $pages = $params['page']; if (empty($pages)) { $pages = 1; } $list = \db('产品_部件资料')->whereNull('mod_rq')->where($where)->page($pages)->limit($limit)->order('id desc')->select(); $count = \db('产品_部件资料')->whereNull('mod_rq')->where($where)->page($pages)->limit($limit)->count(); $this->success('获取成功', ['list' => $list, 'count' => $count]); } /** * 新增部件资料(支持批量) */ public function PartAdd() { if (!Request::instance()->isPost()) { $this->error('非法请求'); } $params = Request::instance()->param(); // 必传校验 if (empty($params['product_code']) || empty($params['part_list'])) { $this->error('产品编号/部件列表不能为空'); } $productCode = $params['product_code']; $sysId = $params['sys_id']; $partList = $params['part_list']; // 组装批量数据 $insertData = []; foreach ($partList as $item) { if (empty($item['part_name']) || empty($item['part_sort'])) { continue; // 跳过无效数据 } $insertData[] = [ 'product_code' => $productCode, 'part_sort' => $item['part_sort'], 'part_name' => $item['part_name'], 'sys_id' => $sysId, 'sys_rq' => date('Y-m-d H:i:s'), 'mod_rq' => null ]; } if (empty($insertData)) { $this->error('无有效部件数据'); } $res = db('产品_部件资料')->insertAll($insertData); return $res ? $this->success('新增成功') : $this->error('新增失败'); } /** * 修改部件资料 */ public function PartEdit() { if (!Request::instance()->isPost()) { $this->error('非法请求'); } $params = Request::instance()->param(); // 必传校验 if (empty($params['id']) || empty($params['part_name'])) { $this->error('ID/部件名称不能为空'); } $data = [ 'part_name' => $params['part_name'], 'sys_id' => $params['sys_id'], 'updatetime' => date('Y-m-d H:i:s') ]; $res = db('产品_部件资料') ->where('id', $params['id']) ->whereNull('mod_rq') ->update($data); return $res !== false ? $this->success('修改成功') : $this->error('修改失败'); } /** * 删除部件资料 */ public function PartDelete() { if (!Request::instance()->isPost()) { $this->error('非法请求'); } $id = input('id'); if (empty($id)) { $this->error('请选择需要删除的数据'); } $ids = explode(',', $id); $result = \db('产品_部件资料') ->where('id', 'in', $ids) ->update(['mod_rq' => date('Y-m-d H:i:s')]); if ($result !== false) { $this->success('删除成功'); } else { $this->error('删除失败'); } } /** * 获取产品工艺列表 */ public function ProductGyList() { if (!Request::instance()->isGet()) { $this->error('非法请求'); } $params = Request::instance()->param(); $where = []; if (!empty($params['search'])) { $where['a.gy_name'] = ['like', '%' . $params['search'] . '%']; } if (!empty($params['product_code'])) { $where['a.product_code'] = $params['product_code']; } $limit = empty($params['limit']) ? 30 : $params['limit']; $pages = empty($params['page']) ? 1 : $params['page']; //获取产品_工艺数据 $list = \db('产品_工艺资料')->alias('a') ->join('产品_部件资料 b', 'a.product_code = b.product_code AND a.part_sort = b.part_sort', 'LEFT') ->field(' a.id, a.product_code, a.part_sort, a.gy_sort, a.gy_name, a.big_process, a.standard_hour, a.standard_score, a.difficulty_coef, a.sys_id, a.sys_rq, a.updatetime, b.part_name ') ->whereNull('a.mod_rq') ->whereNull('b.mod_rq') ->where($where) ->page($pages, $limit) ->order('a.part_sort asc, a.id asc') ->select(); //统计总数量 $count = \db('产品_工艺资料')->alias('a') ->join('产品_部件资料 b', 'a.product_code = b.product_code AND a.part_sort = b.part_sort', 'LEFT') ->whereNull('a.mod_rq') ->whereNull('b.mod_rq') ->where($where) ->count(); $this->success('获取成功', [ 'list' => $list, 'count' => $count ]); } /** * 新增工艺资料(批量) */ public function ProcessAdd() { if (!Request::instance()->isPost()) { $this->error('非法请求'); } $params = Request::instance()->param(); $sys_id = $params['sys_id']; $process_list = $params['process_list'] ?? []; if (empty($process_list)) { $this->error('工艺数据不能为空'); } $insertData = []; foreach ($process_list as $item) { // 必传校验 if (empty($item['gy_name']) || empty($item['big_process'])) { continue; } $insertData[] = [ 'product_code' => $item['product_code'], 'part_sort' => $item['part_sort'], 'part_name' => $item['part_name'], 'gy_sort' => $item['gy_sort'], 'gy_name' => $item['gy_name'], 'big_process' => $item['big_process'], 'standard_hour' => $item['standard_hour'] ?? 0, 'standard_score' => $item['standard_score'] ?? 0, 'difficulty_coef' => $item['difficulty_coef'] ?? 1, 'sys_id' => $sys_id, 'sys_rq' => date('Y-m-d H:i:s') ]; } if (empty($insertData)) { $this->error('无有效工艺数据'); } $result = db('产品_工艺资料')->insertAll($insertData); return $result ? $this->success('新增成功') : $this->error('新增失败'); } /** * 修改工艺资料 */ public function ProcessEdit() { if (!Request::instance()->isPost()) { $this->error('非法请求'); } $params = Request::instance()->param(); //echo "
";
//print_r($params);
//echo "";die;
if (empty($params['id']) || empty($params['gy_name'])) {
$this->error('ID/工序名称不能为空');
}
$data = [
'gy_name' => $params['gy_name'],
'big_process' => $params['big_process'],
// 'part_sort' => $params['part_sort'],
'gy_sort' => $params['gy_sort'],
'standard_hour' => $params['standard_hour'] ?? 0,
'standard_score' => $params['standard_score'] ?? 0,
'difficulty_coef' => $params['difficulty_coef'] ?? 1,
'sys_id' => $params['sys_id'],
'updatetime' => date('Y-m-d H:i:s')
];
$res = db('产品_工艺资料')
->where('id', $params['id'])
->whereNull('mod_rq')
->update($data);
return $res !== false ? $this->success('修改成功') : $this->error('修改失败');
}
/**
* 删除工艺资料
*/
public function ProcessDelete()
{
if (!Request::instance()->isPost()) {
$this->error('非法请求');
}
$id = input('id');
if (empty($id)) {
$this->error('请选择需要删除的数据');
}
$ids = explode(',', $id);
$result = \db('产品_工艺资料')
->where('id', 'in', $ids)
->update(['mod_rq' => date('Y-m-d H:i:s')]);
if ($result !== false) {
$this->success('删除成功');
} else {
$this->error('删除失败');
}
}
/**
* 调整部件与工艺序号牌组
*/
public function UpdataSort(){
if (!Request::instance()->isPost()) {
$this->error('非法请求');
}
$params = Request::instance()->param();
$product_code = $params['product_code'];
$sys_id = $params['sys_id'];
if (empty($product_code)) {
$this->error('产品编号不能为空');
}
// ======================
// 更新 产品_部件资料
// ======================
if (!empty($params['part_list']) && is_array($params['part_list'])) {
foreach ($params['part_list'] as $item) {
$id = $item['id'] ?? 0;
if ($id <= 0) continue;
// 🔥 把要更新的内容放变量里
$updateData = [
'part_sort' => $item['part_sort'],
'part_name' => $item['part_name'],
'sys_id' => $sys_id
];
Db::name('产品_部件资料')
->where('id', $id)
->update($updateData);
}
}
// ======================
// 更新 产品_工艺资料
// ======================
if (!empty($params['process_list']) && is_array($params['process_list'])) {
foreach ($params['process_list'] as $item) {
$id = $item['id'] ?? 0;
if ($id <= 0) continue;
// 🔥 把要更新的内容放变量里
$updateData = [
'gy_sort' => $item['gy_sort'],
'gy_name' => $item['gy_name'] ,
'big_process' => $item['big_process'],
'standard_hour' => $item['standard_hour'],
'standard_score' => $item['standard_score'],
'part_sort' => $item['part_sort'],
'part_name' => $item['part_name'],
'sys_id' => $sys_id
];
Db::name('产品_工艺资料')
->where('id', $id)
->update($updateData);
}
}
$this->success('排序更新成功');
}
/**
* Excel 导入 部件 + 工艺
*/
public function ProcessExcel(){
if (!Request::instance()->isPost()) {
$this->error('非法请求');
}
$params = Request::instance()->param();
$file = request()->file('file');
// 1. 先判断文件是否存在
if (empty($file)) {
$this->error('请上传Excel文件');
}
// 2. 必传参数校验
$product_code = $params['product_code'];
$sys_id = $params['sys_id'];
if (empty($product_code)) {
$this->error('请选择产品后,再进行提交');
}
// 3. 正确获取文件扩展名(解决 getExtension 为空的问题)
$fileInfo = $file->getInfo();
$fileName = $fileInfo['name'];
$ext = strtolower(pathinfo($fileName, PATHINFO_EXTENSION));
if (!in_array($ext, ['xlsx', 'xls'])) {
$this->error('只支持 xls / xlsx 格式');
}
$file_path = $file->getRealPath();
$data = [];
if ($ext == 'xlsx') {
$data = $this->readXlsx($file_path);
} elseif ($ext == 'xls') {
$data = $this->readXls($file_path);
}
// 4. 解析数据
$rows = array_slice($data, 1);
$insert_data = [];
foreach ($rows as $row) {
$part_name = trim($row[0] ?? '');
$gy_name = trim($row[1] ?? '');
if (empty($part_name) || empty($gy_name)) continue;
$insert_data[] = [
'part_name' => $part_name,
'gy_name' => $gy_name,
'big_process' => trim($row[2] ?? ''),
'standard_hour' => floatval($row[3] ?? 0),
'standard_score' => floatval($row[4] ?? 0),
'difficulty_coef' => floatval($row[5] ?? 1),
];
}
if (empty($insert_data)) {
$this->error('Excel 无有效数据');
}
// 5. 处理部件
$part_map = [];
$part_sort = 1;
foreach ($insert_data as $item) {
$name = $item['part_name'];
if (!isset($part_map[$name])) {
$part_map[$name] = $part_sort++;
}
}
$part_all = [];
foreach ($part_map as $name => $sort) {
$part_all[] = [
'product_code' => $product_code,
'part_sort' => $sort,
'part_name' => $name,
'sys_id' => $sys_id,
'sys_rq' => date('Y-m-d H:i:s'),
'mod_rq' => null
];
}
// 6. 处理工艺
$gy_sort_map = [];
$process_all = [];
foreach ($insert_data as $item) {
$part_sort = $part_map[$item['part_name']];
$gy_sort_map[$part_sort] = isset($gy_sort_map[$part_sort]) ? $gy_sort_map[$part_sort] + 1 : 1;
$process_all[] = [
'product_code' => $product_code,
'part_sort' => $part_sort,
'part_name' => $item['part_name'],
'gy_sort' => $gy_sort_map[$part_sort],
'gy_name' => $item['gy_name'],
'big_process' => $item['big_process'],
'standard_hour' => $item['standard_hour'],
'standard_score' => $item['standard_score'],
'difficulty_coef' => $item['difficulty_coef'],
'sys_id' => $sys_id,
'sys_rq' => date('Y-m-d H:i:s'),
'mod_rq' => null
];
}
echo "";
print_r($part_all);
echo "";die;
// 7. 写入数据库(你可以按需注释)
db('产品_部件资料')->where('product_code', $product_code)->update(['mod_rq' => date('Y-m-d H:i:s')]);
db('产品_部件资料')->insertAll($part_all);
db('产品_工艺资料')->where('product_code', $product_code)->update(['mod_rq' => date('Y-m-d H:i:s')]);
db('产品_工艺资料')->insertAll($process_all);
$this->success('导入成功', [
'部件数量' => count($part_all),
'工艺数量' => count($process_all)
]);
}
private function readXlsx($file)
{
if (!class_exists('ZipArchive')) {
return [];
}
$zip = new \ZipArchive();
if ($zip->open($file) !== true) {
return [];
}
// 读取工作表内容和共享字符串
$content = $zip->getFromName('xl/worksheets/sheet1.xml');
$strings = $zip->getFromName('xl/sharedStrings.xml');
$zip->close();
// 解析共享字符串
$str_map = [];
if ($strings) {
preg_match_all('/]*>([^<]+)<\/t><\/si>/s', $strings, $matches);
$str_map = $matches[1] ?? [];
}
$rows = [];
// 解析每一行
preg_match_all('/]*>(.*?)<\/row>/s', $content, $row_matches);
foreach ($row_matches[1] as $row_xml) {
$cols = array_fill(0, 6, ''); // 固定6列,防止错位
$cellIndex = 0;
// 解析单元格
preg_match_all('/]*>(.*?)<\/c>/s', $row_xml, $cell_matches);
foreach ($cell_matches[0] as $i => $cell_xml) {
if ($cellIndex >= 6) break; // 只取前6列
$cell_type = $cell_matches[1][$i] ?? '';
$cell_inner = $cell_matches[2][$i] ?? '';
$value = '';
// 读取单元格值
if (preg_match('/([^<]+)<\/v>/', $cell_inner, $v_match)) {
$value = $v_match[1];
} elseif (preg_match('/([^<]+)<\/t>/', $cell_inner, $t_match)) {
$value = $t_match[1];
}
// 处理共享字符串
if ($cell_type === 's' && isset($str_map[$value])) {
$value = $str_map[$value];
}
$cols[$cellIndex] = $value;
$cellIndex++;
}
$rows[] = $cols;
}
return $rows;
}
private function readXls($file)
{
$data = file_get_contents($file);
$rows = [];
$len = strlen($data);
$p = 0;
while ($p < $len) {
$id = ord($data[$p]);
$size = unpack('v', substr($data, $p + 1, 2))[1];
if ($id == 0x20) {
$row = [];
$sp = $p + 4;
while ($sp < $p + $size) {
$type = ord($data[$sp]);
if ($type == 0x02) {
$val = substr($data, $sp + 3, 1);
$row[] = trim($val);
$sp += 8;
} else {
$sp++;
}
}
if (!empty($row)) $rows[] = $row;
}
$p += $size;
}
return $rows;
}
}