| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286 | <?phpnamespace app\common\service;use think\facade\Db;use app\common\model\Good;use think\facade\Validate;use app\common\model\Stock;use app\common\util\Result;use think\facade\Filesystem;use app\common\model\GoodClass;use app\common\service\Service;use app\common\util\WhereBuilder;use app\common\util\PhpSpreadsheetImport;use app\common\util\PhpSpreadsheetExportV2;class GoodService extends Service{    /**     * 分页查询商品列表     *     * @param array $params 参数数组     * @return \think\Paginator 分页对象,包含商品列表     */    public function page($params = [])    {        // 自动处理参数        $this->autoParams($params);        // 获取关键字和商品分类ID        $keyword = $this->pg('keyword');        $valid = $this->pgd([], 'valid');        $good_class_id = $this->pg('good_class_id');        // 构建查询条件        $where = WhereBuilder::builder()            ->like('no|name|desc|unit|spec', $keyword)            ->eq('good_class_id', $good_class_id)            ->in('valid', $valid)            ->build();        // 执行分页查询        $page = (new Good)            ->where($where)            ->paginate($this->tp6Page());        // 关联加载商品分类信息        $page->getCollection()->append(['goodClass']);        // 返回分页对象        return $page;    }    /**     * 创建商品(事务处理)     *     * @param array $params 参数数组     * @return Good 创建的商品对象     */    public function createTrans($params = [])    {        // 使用事务处理创建商品        return Db::transaction(fn() => $this->create($params));    }    /**     * 创建商品     *     * @param array $params 参数数组     * @return Good 创建的商品对象     * @throws \Exception 如果商品编号已存在,则抛出异常     */    public function create($params = [])    {        // 自动处理参数        $params = $this->autoParams($params);        // 获取商品编号        $no = $this->pg('no');        // 获取商品分类对象        $goodClass = $this->one(GoodClass::class, 'good_class_id');        // 根据编号查找商品        $good = Good::getByNo($no);        if ($good) {            throw $this->exception("编号 $no 已存在");        }        // 创建商品        return Good::create($params);    }    /**     * 更新商品信息     *     * @param array $params 参数数组     * @return array 更新成功的商品对象数组     * @throws \Exception 如果未选中任何商品进行更新,则抛出异常     */    public function update($params = [])    {        // 自动处理参数        $params = $this->autoParams($params);        if (!$params) {            throw $this->exception('未选中任何商品进行更新');        }        // 更新商品信息并返回更新成功的商品对象数组        return (new Good)->allowField(['name', 'unit', 'img', 'valid', 'spec', 'good_class_id'])->saveAll($params);    }    /**     * 删除商品     *     * @param array $params 参数数组     * @return int 删除的商品数量     * @throws \Exception 如果非强制删除商品时,存在库存未处理,则抛出异常     */    public function delete($params = [])    {        // 自动处理参数        $this->autoParams($params);        // 获取商品ID和是否强制删除标志        $id = $this->req('id');        $force = $this->pgd(false, 'force');        if (is_int($id)) {            $id = [$id];        }        // 非强制删除时,检查仓库库存        if (!$force) {            foreach ($id as $i) {                $num = (new Stock)->where('good_id', '=', $i)->sum('num');                if ($num > 0) {                    $good = (new Good)->find($id);                    throw $this->exception("商品{$good->name}仍有库存未处理,请使用调拨/出库清理库存", 1);                }            }        }        // 删除商品并返回删除的商品数量        return Good::destroy($id);    }    /**     * 导入商品数据     *     * @return \think\Response 导入结果的响应对象     * @throws \think\Exception\ValidateException 如果上传文件格式或大小不符合要求,则抛出验证异常     * @throws \think\Exception 如果上传图片失败,则抛出异常     */    public function import()    {        // 获取表单上传文件        $files = request()->file();        // 验证上传文件格式和大小        $this->validate($files, Validate::rule(['file' => 'fileSize:20480000|fileExt:csv,xlsx']));        $file = request()->file('file');        try {            $path = Filesystem::putFile('execl', $file);        } catch (\Exception $e) {            throw $this->warpException($e, '上传图片失败:\n');        }        // 读取导入的数据        $data = PhpSpreadsheetImport::readData(runtime_path('../storage') . $path);        static $MAP = [        'A' => 'no',        'B' => 'name',        'C' => 'desc',        'D' => 'unit',        'E' => 'img',        'F' => 'spec',        'G' => 'good_class_id'        ];        /**         * @var GoodClassService $service          */        static $service;        if (!$service) {            $service = (new GoodClassService($this->app))->exceptionClass($this->exceptionClass);        }        $goods = [];        // 处理导入的每一行数据        foreach ($data as $row) {            $good = [];            foreach ($row as $key => $value) {                $newKey = $MAP[$key];                // 如果是分类字段,则替换为对应的ID,如果分类不存在则创建                if ($newKey == 'good_class_id') {                    $class = (new GoodClass)->cache()->where('name', '=', $value)->find();                    if (!$class) {                        $class = $service->create(['name' => $value]);                    }                    $value = $class->id;                }                $good[$newKey] = $value;            }            $goods[] = $good;        }        // 批量保存商品数据        $goods = (new Good)->saveAll($goods);        return Result::rest(true, 0, "成功{$goods->count()}个");    }    /**     * 导出商品数据     *     * @param array $params 导出参数     * @return mixed 导出结果     */    public function export($params = [])    {        $this->autoParams($params);        $keyword = $this->pg('name');        $repo_id = $this->pg('repo_id');        // 构建查询条件        $where = WhereBuilder::builder()            ->like('name', $keyword)            ->in('repo_id', $repo_id)            ->build();        $header = [            [                'id',                '序号',                '名称',                '介绍',                '单位',                '图片地址',                '创建时间',                '更新时间',                '删除时间',                '状态',                '规格',                '类别id',                '类别名称'            ]        ];        // 查询商品数据,并关联查询商品类别信息        $goods = (new Good)            ->field('g.*, c.name as class_name')            ->alias('g')            ->join('good_class c', 'c.id = g.good_class_id', 'LEFT')            ->where($where)            ->select()            ->map(fn(Good $good) => $good->getData())            ->each(function (array $good) {                // 格式化商品状态字段                $good['valid'] = $good['valid'] ? '启用' : '禁用';                return $good;            });        // 导出商品数据        $res = PhpSpreadsheetExportV2::outputFile(            $goods,            $header,            'good' . date('Ymdis'),            []        );        return $res;    }}
 |