123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286 |
- <?php
- namespace 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;
- }
- }
|