From e7955eeef370b79f369bf72b97914f20f16ef883 Mon Sep 17 00:00:00 2001 From: xjh <2423579486@qq.com> Date: Tue, 18 Apr 2023 11:29:46 +0800 Subject: [PATCH] =?UTF-8?q?feat:=E4=BA=A7=E5=93=81=E7=AE=A1=E7=90=86-?= =?UTF-8?q?=E4=BA=A7=E5=93=81=E7=B1=BB=E5=9E=8B=E6=A8=A1=E5=9D=97=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3=E5=AE=8C=E6=88=90=E3=80=81=E5=85=AC=E5=85=B1TOOL?= =?UTF-8?q?=E7=B1=BB=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/admin/controller/Works/WorksType.php | 244 +++++++++++++++++++++++ app/common/exception/Tool.php | 109 ++++++---- app/common/model/Works/WorksType.php | 199 ++++++++++++++++++ 3 files changed, 518 insertions(+), 34 deletions(-) create mode 100644 app/admin/controller/Works/WorksType.php create mode 100644 app/common/model/Works/WorksType.php diff --git a/app/admin/controller/Works/WorksType.php b/app/admin/controller/Works/WorksType.php new file mode 100644 index 0000000..4d99f1e --- /dev/null +++ b/app/admin/controller/Works/WorksType.php @@ -0,0 +1,244 @@ +field([ + 'a.works_type_id', + 'a.works_type_guid', + 'a.works_type_name', + 'a.works_type_order', + 'a.works_type_parent_guid', + 'a.works_type_ancestors_guid', + 'b.works_type_name' => "works_type_parent_name", + ]) + ->alias('a') + ->leftjoin('works_type b', 'a.works_type_parent_guid = b.works_type_guid') + ->order('works_type_order') + ->select() + ->toArray(); + + $Traverse = new Traverse('works_type_guid', 'works_type_parent_guid'); + $works_type_tree = $Traverse->tree($works_type, '0', function ($v) { + return [ + 'works_type_name' => $v['works_type_name'], + 'works_type_parent_name' => $v['works_type_parent_name'], + 'works_type_guid' => $v['works_type_guid'], + 'works_type_parent_guid' => $v['works_type_parent_guid'], + 'works_type_ancestors_guid' => $v['works_type_ancestors_guid'], + 'works_type_order' => $v['works_type_order'], + ]; + }); + + return msg("获取作品类型列表成功!", $works_type_tree); + } + + /** + * 编辑作品类型接口 + * + * @param Request request + * @return array + * @date 2023-04-17 + * @author xjh + * @since 1.0.0 + */ + public function editWorksType(Request $request): array + { + Db::startTrans(); + try { + $params = $request->param(); + $this->validate($params, [ + 'works_type_name|作品类型名称' => 'require', + 'works_type_guid|作品类型guid' => 'require', + 'works_type_order|作品类型排序' => 'require', + 'works_type_parent_guid|作品类型父级guid' => 'require', + 'works_type_ancestors_guid|作品类型祖级guid' => 'require' + ]); + + $works_type = ModelWorksType::where('works_type_guid', $params['works_type_guid'])->find(); + if (!$works_type) throwErrorMsg("该作品类型不存在", 1); + $works_type->allowField([ + 'works_type_update_user_guid', + 'works_type_name', + 'works_type_order', + 'works_type_parent_guid', + 'works_type_ancestors_guid', + ])->save($params); + Db::commit(); + return msg('编辑成功!'); + } catch (\Throwable $th) { + Db::rollback(); + throw $th; + } + } + + /** + * 添加作品类型接口 + * + * @param Request request + * @return array + * @date 2023-04-17 + * @author xjh + * @since 1.0.0 + */ + public function addWorksType(Request $request) + { + Db::startTrans(); + try { + $params = $request->param(); + $this->validate($params, [ + 'works_type_name|作品类型名称' => 'require', + 'works_type_order|作品类型排序' => 'require', + 'works_type_parent_guid|作品类型父级guid' => 'require', + ]); + + ModelWorksType::create($params, [ + 'works_type_guid', + 'works_type_create_user_guid', + 'works_type_update_user_guid', + 'works_type_name', + 'works_type_order', + 'works_type_ancestors_guid', + 'works_type_parent_guid' + ]); + Db::commit(); + return msg('添加成功!'); + } catch (\Throwable $th) { + Db::rollback(); + throw $th; + } + } + + /** + * 删除作品类型接口 + * + * @param Request request + * @return array + * @date 2023-04-17 + * @author xjh + * @since 1.0.0 + */ + public function deleteWorksType(Request $request): array + { + Db::startTrans(); + try { + $params = $request->param(); + $this->validate($params, [ + 'works_type_guid' => 'require', + ]); + $works_type = ModelWorksType::where([ + 'works_type_guid' => explode(',', $params['works_type_guid']) + ])->select(); + $works_type->delete(); + Db::commit(); + return msg('删除成功!'); + } catch (\Throwable $th) { + Db::rollback(); + throw $th; + } + } + + /** + * 导出Excel接口 + * + * @param Request request + * @return array + * @date 2023-04-17 + * @author xjh + * @since 1.0.0 + */ + public function exportExcel(Request $request) + { + $params = $request->param(); + $con = []; + if (isset($params['works_type_guids']) && $params['works_type_guids']) { + $con['a.works_type_guid'] = explode(',', $params['works_type_guids']); + } + $select = ModelWorksType::field([ + 'a.works_type_name', + 'a.works_type_order', + 'a.works_type_parent_guid', + 'b.works_type_name' => 'works_type_parent_name', + ]) + ->where($con) + ->alias('a') + ->leftjoin('works_type b', 'a.works_type_parent_guid = b.works_type_guid') + ->order('works_type_order', 'desc') + ->select() + ->toArray(); + + ModelWorksType::exportExcel($select); + } + + /** + * 下载导入模板接口 + * + * @param Request request + * @return array + * @date 2023-04-17 + * @author xjh + * @since 1.0.0 + */ + public function downloadTemplate(Request $request): void + { + $data = [ + array_values(ModelWorksType::EXCELFIELD), + ['', '素描', '1'] + ]; + $excel = (new Excel())->exporTsheet($data); + $excel->save('作品类型导入模板.xlsx'); + } + + /** + * 导入excel接口 + * + * @param Request request + * @return array + * @date 2023-04-17 + * @author xjh + * @since 1.0.0 + */ + public function importExcel(Request $request): array + { + $file = new UploadFile('uploads', 'fileExt:xlsx'); + $file->putFile('works_type'); + + $msg = ModelWorksType::importExcel($file); + return [ + 'code' => 0, + 'msg' => $msg + ]; + } +} diff --git a/app/common/exception/Tool.php b/app/common/exception/Tool.php index 5edd845..ecb4f69 100644 --- a/app/common/exception/Tool.php +++ b/app/common/exception/Tool.php @@ -6,6 +6,7 @@ use DateTime; use think\facade\Request; use think\facade\Log; use think\helper\Arr; +use think\facade\Db; use app\common\arw\adjfut\src\Exception\ErrorMsg; class Tool @@ -347,68 +348,108 @@ class Tool /** * 排序号更换处理 + * * 注意:使用该方法时候要启动事务!! - * @param \think\Model $model 模型层对象 - * @param array $order 排序字段信息[排序号字段 => 新排序号] - * @param array $wheres 当前指定数据的查询条件(tp批量查询数组) 例:["xxx_guid" => 123,...] + * @param string $model 模型层命名空间地址 + * @param string $guid 主键 + * @param int $order 新排序号 * @param array $extra_wheres 当前指定数据的额外查询条件(tp批量查询数组) 例:["xxx_type" => 1,...] */ - public static function sortEditProc(\think\Model $model, array $order, array $wheres, array $extra_wheres = []): void + public static function sortEditProc(string $model, string $guid, int $order, array $extra_wheres = []): void { - $order_field_name = array_keys($order)[0]; + //模型层实例化 + $model = new $model; + //表名 + $table_name = $model->db()->getTable(); + //获取当前的主键字段名 + $guld_field = $model->db()->getPk(); + //排序字段名 + $order_field_name = $model->order_field; //当前数据原排序号 - $original_oreder_value = $model->where($wheres)->where($extra_wheres)->value($order_field_name); - if ($original_oreder_value === null) throwErrorMsg('Tool::sortProcessing() : 找不到该guid数据', 444); - + $original_oreder_find = $model->where($guld_field, $guid)->find(); + if (!$original_oreder_find) throwErrorMsg('Tool::sortEditProc() : 找不到该数据原排序号', 444); //查找当前数据所想更换的新排序号是否已有数据占用 //已被占用,则将它们的排序号互换 - $occupied_order_data = $model->where($order)->where($extra_wheres)->find(); - if ($occupied_order_data) { - $occupied_order_data[$order_field_name] = $original_oreder_value; - $occupied_order_data->save(); + if ($model->where($order_field_name, $order)->where($extra_wheres)->find()) { + Db::name($table_name)->where($order_field_name, $order)->where($extra_wheres)->update([ + $order_field_name => $original_oreder_find[$order_field_name], + $model->parent_guid_field => $original_oreder_find[$model->parent_guid_field], + $model->ancestors_guid_field => $original_oreder_find[$model->ancestors_guid_field], + ]); } } /** * 排序号腾位处理 + * * 注意:使用该方法时候要启动事务!! - * @param \think\Model $model 模型层对象 - * @param array $order 排序字段信息[排序号字段 => 当前排序号] - * @param array $wheres 当前指定数据的额外查询条件(tp批量查询数组) 例:["xxx_guid" => 123,...] + * @param string $model 模型层命名空间地址 + * @param int $order 当前排序号 + * @param array $wheres 当前指定数据的额外查询条件(tp批量查询数组) 例:["xxx_type" => 1,...] */ - public static function sortInsertProc(\think\Model $model, array $order, array $wheres = []): void + public static function sortInsertProc(string $model, int $order, array $wheres = []): void { - $order_field_name = array_keys($order)[0]; + //模型层实例化 + $model = new $model; + //表名 + $table_name = $model->db()->getTable(); + //排序字段名 + $order_field_name = $model->order_field; //新增数据的所属排序号已有数据占用,则腾位处理(已占用的数据及其后面所有数据一起排序号腾位+1) if ($model->where($order)->where($wheres)->value($order_field_name) !== null) { - $model->where($wheres)->where($order_field_name, '>=', $order[$order_field_name])->inc($order_field_name)->save(); + Db::name($table_name) + ->where($wheres) + ->where($order_field_name, '>=', $order) + ->inc($order_field_name) + ->update(); } } /** * 排序号删除处理 * 注意:使用该方法时候要启动事务!! - * @param \think\Model $model 模型层对象 - * @param array $order 排序字段名称 - * @param array $guids 数据guid集合 + * @param string $model 模型层命名空间地址 + * @param array $guid 主键 * @param array $correl_fields 关联字段 例:["xxx_guid",...] 代表删除排序号时会根据这些字段来关联(例:所属xxx类型、所属xxx系列)来进行排序处理 */ - public static function sortDeleteProc(\think\Model $model, string $order_field_name, array $guids, array $correl_fields = []) + public static function sortDeleteProc(string $model, string $guid, array $correl_fields = []): void { - $guld_field_name = array_keys($guids)[0]; + //模型层实例化 + $model = new $model; + //获取当前的主键字段名 + $guld_field_name = $model->db()->getPk(); + //获取当前表排序字段名 + $order_field_name = $model->order_field; //在所删除的数据之后的数据所属排序号将进行减位处理减位-1 - foreach ($guids[$guld_field_name] as $guld) { - $find = $model->where($guld_field_name, $guld)->find(); - if ($find) { - $con = []; - foreach ($correl_fields as $correl_field) { - $con[$correl_field] = $find[$correl_field]; - } - $model->where($order_field_name, '>', $find[$order_field_name]) - ->where($con) - ->dec($order_field_name) - ->save(); + if ($find = $model->where($guld_field_name, $guid)->find()) { + $con = []; + foreach ($correl_fields as $correl_field) { + $con[$correl_field] = $find[$correl_field]; } + $model->where($order_field_name, '>', $find[$order_field_name]) + ->where($con) + ->dec($order_field_name) + ->save(); } } + + /** + * 祖级guid构建 + * @param string 模型层对象 + * @param string $parent_guid 父级guid + * @param string $first_parent 首父级值 默认"0" + */ + public static function buildAncestorsGuid(string $model, string $parent_guid, string $first_parent = "0"): string + { + //模型层实例化 + $model = new $model; + //获取当前的主键字段名 + $guld_field_name = $model->db()->getPk(); + //获取当前祖级主键集字段名 + $ancestors_guid_field = $model->ancestors_guid_field; + if ($parent_guid == $first_parent) return $first_parent; + $parent = $model->where($guld_field_name, $parent_guid)->find(); + if (!$parent) throwErrorMsg('该父级数据不存在!'); + return $parent[$ancestors_guid_field] . ',' . $parent_guid; + } } diff --git a/app/common/model/Works/WorksType.php b/app/common/model/Works/WorksType.php new file mode 100644 index 0000000..6c75a77 --- /dev/null +++ b/app/common/model/Works/WorksType.php @@ -0,0 +1,199 @@ + "int", + "works_type_guid" => "string", + "works_type_name" => "string", + "works_type_order" => "int", + "works_type_create_time" => "datetime", + "works_type_create_user_guid" => "string", + "works_type_update_time" => "datetime", + "works_type_update_user_guid" => "string", + "works_type_delete_time" => "datetime", + "works_type_delete_user_guid" => "string", + "works_type_parent_guid" => "string", + "works_type_ancestors_guid" => "string", + + ]; + // 设置json类型字段 + protected $json = ['']; + // 开启自动写入时间戳字段 + protected $autoWriteTimestamp = 'datetime'; + // 创建时间 + protected $createTime = 'works_type_create_time'; + // 修改时间 + protected $updateTime = 'works_type_update_time'; + + //排序字段 + public $order_field = 'works_type_order'; + //父级主键 + public $parent_guid_field = 'works_type_parent_guid'; + //祖级主键集字段 + public $ancestors_guid_field = 'works_type_ancestors_guid'; + + // excel导入/下载模板表头 + public const EXCELFIELD = [ + 'works_type_parent_name' => '上级类型名称', + 'works_type_name' => '*作品类型名称', + 'works_type_order' => '作品类型排序', + ]; + + /** + * 新增前 + */ + public static function onBeforeInsert(self $model): void + { + Validate::unique(self::class, $model->works_type_guid, $model->getData(), [ + 'works_type_name' => '作品类型名称', + ]); + $model->works_type_ancestors_guid = Tool::buildAncestorsGuid(self::class, $model->works_type_parent_guid); + Tool::sortInsertProc( + self::class, + $model->works_type_order, + ['works_type_parent_guid' => $model->works_type_parent_guid] + ); + $model->completeCreateField(); + } + + /** + * 更新前 + */ + public static function onBeforeUpdate(self $model): void + { + Validate::unique(self::class, $model->works_type_guid, $model->getData(), [ + 'works_type_name' => '作品类型名称', + ]); + $model->works_type_ancestors_guid = Tool::buildAncestorsGuid(self::class, $model->works_type_parent_guid); + Tool::sortEditProc( + self::class, + $model->works_type_guid, + $model->works_type_order, + ["works_type_parent_guid" => $model->works_type_parent_guid], + ); + $model->completeUpdateField(); + } + + /** + * 删除前 + */ + public static function onBeforeDelete(self $model): void + { + Tool::sortDeleteProc(self::class, $model->works_type_guid, ["works_type_parent_guid"]); + $model->completeDeleteField(); + } + + /** + * 导出Excel + * + * @param array $select导出的数据集合 + */ + public static function exportExcel(array $select): void + { + $data = [array_values(self::EXCELFIELD)]; + foreach ($select as $key => $val) { + $data[] = [ + $val['works_type_parent_name'] ?? "无", + $val['works_type_name'], + strval($val['works_type_order']), + ]; + } + $excel = (new Excel())->exporTsheet($data); + $excel->save('作品类型.xlsx'); + } + + /** + * 导入excel + * + * @param \app\common\arw\adjfut\src\UploadFile $file 导入excel下载后的地址 + */ + public static function importExcel(\app\common\arw\adjfut\src\UploadFile $file): string + { + $msg = []; + + Db::startTrans(); + try { + $excel = new Excel($file); + $data = $excel->parseExcel( + Tool::getExcelRule(self::EXCELFIELD), + [ + 'titleLine' => [1] + ] + ); + if (!$data) throwErrorMsg('excel无数据', 1); + $msg = []; + foreach ($data as $line => $value) { + try { + $op = self::importExcelInit($value); + if ($op == 'create') { + $msg[] = "{$line} 新增成功!
"; + } else { + $msg[] = "{$line} 修改成功!
"; + } + } catch (\Throwable $th) { + $msg[] = "{$line} {$th->getMessage()}
"; + } + } + Db::commit(); + return implode(', ', $msg); + } catch (\Throwable $th) { + Db::rollback(); + throw $th; + } + } + + /** + * 导入excel初始化 + * + * @param array $value 每行数据 + */ + public static function importExcelInit(array $value): string + { + $works_type_parent_name = $value['works_type_parent_name']; + $works_type_name = $value['works_type_name']; + $works_type_order = $value['works_type_order']; + + //上级类型验证 + $works_type_parent_guid = "0"; + if ($works_type_parent_name) { + $works_type_parent = self::where('works_type_name', $works_type_parent_name)->find(); + if (!$works_type_parent) throwErrorMsg('该上级类型名称不存在!'); + $works_type_parent_guid = $works_type_parent->works_type_guid; + } + + //修改/新增 + if ($works_type = self::where('works_type_name', $works_type_name)->find()) { + $works_type->works_type_name = $works_type_name; + $works_type->works_type_order = $works_type_order; + $works_type->works_type_parent_guid = $works_type_parent_guid; + $works_type->save(); + return 'update'; + } else { + self::create([ + 'works_type_name' => $works_type_name, + 'works_type_order' => $works_type_order, + 'works_type_parent_guid' => $works_type_parent_guid, + ]); + return 'create'; + } + } +}