liuhairui před 2 týdny
rodič
revize
c700c512af

+ 5 - 5
application/api/controller/ProcessLib.php

@@ -109,11 +109,11 @@ class ProcessLib extends Api
         $list =  Db::name('产品_工艺库')
             ->field('
                 id,
-                gy_code as 工艺编码,
-                gy_name as 工艺名称,
-                big_process as 生产工序,
-                standard_hour as 标准工时,
-                standard_score as 标准工分,
+                gy_code,
+                gy_name,
+                big_process,
+                standard_hour,
+                standard_score,
                 sys_id,
                 createtime as 创建时间,
                 updatetime as 修改时间

+ 505 - 80
application/api/controller/Product.php

@@ -24,54 +24,13 @@ class Product extends Api
         $this->success('产品_基本资料');
     }
 
-    /**
-     * 产品资料
-     */
-    /**
-     * 新增产品资料
-     */
-    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('新增失败');
-        }
-    }
-
     /**
      * 获取左侧菜单产品分类列表
      * 按 product_type 分组 → 分类下显示对应产品
      */
     public function ProductTypeMenu()
     {
-        if (Request::instance()->isGet() == false){
+        if (Request::instance()->isGet() == false) {
             $this->error('非法请求');
         }
         $params = Request::instance()->param();
@@ -102,7 +61,7 @@ class Product extends Api
     }
 
     /**
-     * 获取产品资料列表(产品→部件→工艺 三层编号关联
+     * 获取产品资料列表(产品→部件→工艺)
      */
     public function ProductList()
     {
@@ -114,7 +73,7 @@ class Product extends Api
 
         $where = [];
         if (!empty($params['search'])) {
-            $where['product_code|product_name|product_type'] = array('like', '%'.$params['search'].'%');
+            $where['product_code|product_name|product_type'] = ['like', '%' . $params['search'] . '%'];
         }
 
         $limit = empty($params['limit']) ? 30 : $params['limit'];
@@ -135,20 +94,27 @@ class Product extends Api
         // 提取产品编号
         $productCodes = array_column($productList, 'product_code');
 
-        // 2. 查询部件(通过 product_code
+        // 2. 查询部件(按 product_code 关联,并按 part_sort 排序
         $parts = db('产品_部件资料')
             ->whereNull('mod_rq')
             ->whereIn('product_code', $productCodes)
+            ->order('part_sort asc') // 按部件排序号升序
             ->select();
 
-        // 提取部件编码 part_code
-        $partCodes = array_column($parts, 'part_code');
-        // 3. 查询工艺(通过 part_code)
+        // 提取 (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($partCodes)) {
+        if (!empty($productCodes)) {
             $process = db('产品_工艺资料')
                 ->whereNull('mod_rq')
-                ->whereIn('part_code', $partCodes)
+                ->whereIn('product_code', $productCodes)
+                ->order('part_sort asc, gy_sort asc') // 按部件排序+工序排序
                 ->select();
         }
 
@@ -158,17 +124,20 @@ class Product extends Api
             $partGroup[$val['product_code']][] = $val;
         }
 
-        // 工艺按 part_code 分组
+        // 工艺按 (product_code + part_sort) 分组
         $processGroup = [];
         foreach ($process as $val) {
-            $processGroup[$val['part_code']][] = $val;
+            $key = $val['product_code'] . '_' . $val['part_sort'];
+            $processGroup[$key][] = $val;
         }
 
-        // 组装数据
+        // 组装数据:产品 → 部件 → 工艺
         foreach ($productList as &$product) {
             $currentParts = $partGroup[$product['product_code']] ?? [];
             foreach ($currentParts as &$item) {
-                $item['processes'] = $processGroup[$item['part_code']] ?? [];
+                // 用 product_code + part_sort 关联工艺
+                $key = $product['product_code'] . '_' . $item['part_sort'];
+                $item['processes'] = $processGroup[$key] ?? [];
             }
             $product['parts'] = $currentParts;
         }
@@ -185,6 +154,44 @@ class Product extends Api
         ]);
     }
 
+    /**
+     * 新增产品资料
+     */
+    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('新增失败');
+        }
+    }
+
     /**
      * 修改产品资料
      */
@@ -206,11 +213,8 @@ class Product extends Api
         $data['product_name'] = $params['product_name'];
         $data['product_type'] = $params['product_type'];
         $data['unit'] = $params['unit'];
-        $data['Sys_id'] = $params['sys_id'];
+        $data['sys_id'] = $params['sys_id'];
         $data['updatetime'] = date('Y-m-d H:i:s');
-        echo "<pre>";
-        print_r($data);
-        echo "<pre>";die;
 
         $result = \db('产品_基本资料')
             ->where('id', $params['id'])
@@ -224,7 +228,7 @@ class Product extends Api
     }
 
     /**
-     * 删除产品资料(软删除)
+     * 删除产品资料
      */
     public function ProductDelete()
     {
@@ -250,30 +254,31 @@ class Product extends Api
         }
     }
 
+
     /**
      * 获取产品部件列表
      */
     public function ProductPartList()
     {
-        if (Request::instance()->isGet() == false){
+        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['search'])) {
+            $where['part_name'] = array('like', '%' . $params['search'] . '%');
         }
-        if (!empty($params['product_code'])){
-            $where['product_code'] = array('like','%'.$params['product_code'].'%');
+        if (!empty($params['product_code'])) {
+            $where['product_code'] = array('like', '%' . $params['product_code'] . '%');
         }
         $limit = $params['limit'];
-        if (empty($limit)){
+        if (empty($limit)) {
             $limit = 30;
         }
         $pages = $params['page'];
-        if (empty($pages)){
+        if (empty($pages)) {
             $pages = 1;
         }
         $list = \db('产品_部件资料')->whereNull('mod_rq')->where($where)->page($pages)->limit($limit)->order('id desc')->select();
@@ -282,40 +287,460 @@ class Product extends Api
         $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() == false){
+        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['search'])){
-            $where['gy_name'] = array('like','%'.$params['search'].'%');
+        if (!empty($params['product_code'])) {
+            $where['a.product_code'] = $params['product_code'];
         }
-        if (!empty($params['product_code'])){
-            $where['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.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('非法请求');
         }
-        $limit = $params['limit'];
-        if (empty($limit)){
-            $limit = 30;
+
+        $params = Request::instance()->param();
+
+        // 接收参数
+        $sys_id = $params['sys_id'] ?? '超级管理员';
+        $process_list = $params['process_list'] ?? [];
+
+        if (empty($process_list)) {
+            $this->error('工艺数据不能为空');
         }
-        $pages = $params['page'];
-        if (empty($pages)){
-            $pages = 1;
+
+        $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')
+            ];
         }
-        $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]);
+        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 "<pre>";
+//print_r($params);
+//echo "<pre>";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('删除失败');
+        }
+    }
+
+    /**
+     * Excel 导入 部件 + 工艺
+     */
+    public function ProcessExcel()
+    {
+        if (!Request::instance()->isPost()) {
+            $this->error('非法请求');
+        }
+
+        // 获取上传文件
+        $file = request()->file('file');
+        echo "<pre>";
+        print_r($file);
+        echo "<pre>";die;
+        if (empty($file)) {
+            $this->error('请上传Excel文件');
+        }
+
+        // 接收产品编号
+        $product_code = input('product_code');
+        if (empty($product_code)) {
+            $this->error('请传入产品编号 product_code');
+        }
 
+        // 获取文件路径
+        $file_path = $file->getRealPath();
+        $ext = strtolower($file->getExtension());
+
+        // 读取数据(兼容 xls + xlsx)
+        $data = [];
+        if ($ext == 'xlsx') {
+            $data = $this->readXlsx($file_path);
+        } elseif ($ext == 'xls') {
+            $data = $this->readXls($file_path);
+        } else {
+            $this->error('只支持 xls / xlsx 格式');
+        }
+
+        // 去掉表头,过滤空行
+        $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 无有效数据');
+        }
+
+        // ===================== 1. 处理部件(去重 + 排序) =====================
+        $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' => '超级管理员',
+                'createtime' => date('Y-m-d H:i:s'),
+                'mod_rq' => null,
+            ];
+        }
+
+        // 清空旧数据(可选)
+        db('产品_部件资料')->where('product_code', $product_code)->delete();
+        db('产品_部件资料')->insertAll($part_all);
+
+        // ===================== 2. 处理工艺 =====================
+        $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' => '超级管理员',
+                'createtime' => date('Y-m-d H:i:s'),
+                'mod_rq' => null,
+            ];
+        }
+
+        db('产品_工艺资料')->where('product_code', $product_code)->delete();
+        db('产品_工艺资料')->insertAll($process_all);
+
+        $this->success('导入成功', [
+            '部件数量' => count($part_all),
+            '工艺数量' => count($process_all)
+        ]);
     }
 
+// ------------------------------ 以下是内置读取函数,不用装任何插件 ------------------------------
+    /**
+     * 读取 xlsx
+     */
+    private function readXlsx($file)
+    {
+        $zip = new ZipArchive();
+        if ($zip->open($file) !== true) return [];
+
+        $content = $zip->getFromName('xl/worksheets/sheet1.xml');
+        $strings = $zip->getFromName('xl/sharedStrings.xml');
+        $zip->close();
+
+        $rows = [];
+        $str_map = [];
 
+        if ($strings) {
+            preg_match_all('/<si><t>([^<]+)<\/t><\/si>/', $strings, $m);
+            $str_map = $m[1] ?? [];
+        }
 
+        preg_match_all('/<row[^>]*>(.*?)<\/row>/s', $content, $row_matches);
+        foreach ($row_matches[1] as $row) {
+            $cols = [];
+            preg_match_all('/<c[^>]*><v>([^<]+)<\/v><\/c>/', $row, $m);
+            foreach ($m[1] ?? [] as $v) {
+                $cols[] = is_numeric($v) && isset($str_map[$v]) ? $str_map[$v] : $v;
+            }
+            $rows[] = $cols;
+        }
+        return $rows;
+    }
 
+    /**
+     * 读取 xls
+     */
+    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;
+    }
 }