From 3a2fcf7142676dacf8c064e41b78766fbdb1ceed Mon Sep 17 00:00:00 2001 From: MiAn Date: Fri, 23 Oct 2026 09:26:22 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E9=87=8D=E6=9E=84=E5=90=8E=E5=8F=B0?= =?UTF-8?q?=E7=AE=A1=E7=90=86=E7=95=8C=E9=9D=A2=E6=A0=B7=E5=BC=8F=E5=B9=B6?= =?UTF-8?q?=E6=96=B0=E5=A2=9E=E5=95=86=E6=88=B7/=E5=B8=96=E5=AD=90?= =?UTF-8?q?=E5=AE=A1=E6=A0=B8=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 重构后台所有管理页面工具栏,移除图标改用纯文字按钮 - 新增商户管理的批量审核功能与商家详情/审核页面 - 新增帖子管理的批量审核/上下架功能与帖子详情/审核页面 - 新增多媒体相册字段的前后台处理逻辑 - 新增微信订阅消息兼容导出层 - 更新站点版本号并优化品牌色变量 - 新增商户/帖子控制器的详情与审核方法 - 新增 .sql 文件忽略规则 --- .gitignore | 1 + application/admin/controller/fc/Merchant.php | 73 +++ application/admin/controller/fc/Post.php | 111 ++++ application/admin/model/FcPost.php | 46 ++ application/admin/view/fc/area/index.html | 4 +- application/admin/view/fc/banner/index.html | 4 +- application/admin/view/fc/category/index.html | 4 +- application/admin/view/fc/comment/index.html | 12 +- .../admin/view/fc/commission/index.html | 4 +- application/admin/view/fc/coupon/index.html | 4 +- .../admin/view/fc/distrelation/index.html | 14 +- application/admin/view/fc/draft/index.html | 4 +- .../admin/view/fc/financeflow/index.html | 18 +- application/admin/view/fc/merchant/add.html | 254 ++++++--- application/admin/view/fc/merchant/audit.html | 178 ++++++ .../admin/view/fc/merchant/detail.html | 183 ++++++ application/admin/view/fc/merchant/edit.html | 261 ++++++--- application/admin/view/fc/merchant/index.html | 22 +- application/admin/view/fc/message/index.html | 4 +- application/admin/view/fc/order/index.html | 14 +- application/admin/view/fc/payview/index.html | 14 +- application/admin/view/fc/plan/index.html | 4 +- application/admin/view/fc/post/add.html | 369 +++++++----- application/admin/view/fc/post/audit.html | 182 ++++++ application/admin/view/fc/post/detail.html | 204 +++++++ application/admin/view/fc/post/edit.html | 376 +++++++----- application/admin/view/fc/post/index.html | 30 +- application/admin/view/fc/report/index.html | 9 +- application/admin/view/fc/userext/index.html | 4 +- application/admin/view/fc/withdraw/edit.html | 133 +++-- application/admin/view/fc/withdraw/index.html | 8 +- application/extra/site.php | 2 +- docs/07-线上服务器部署与同步清单.md | 147 +++++ public/assets/css/backend-theme.css | 535 ++++++++++++++++++ public/assets/js/backend/fc/merchant.js | 269 ++++++--- public/assets/js/backend/fc/post.js | 420 ++++++++------ public/assets/js/backend/fc/report.js | 4 +- public/assets/js/backend/fc/withdraw.js | 4 +- runtime/.gitkeep | 1 - uniapp/common/store/ui.js | 26 + uniapp/common/utils/subscribe.js | 30 +- uniapp/pages/distribution/index.vue | 5 +- uniapp/pages/post/create.vue | 3 +- uniapp/uni.scss | 3 +- 44 files changed, 3080 insertions(+), 917 deletions(-) create mode 100644 application/admin/view/fc/merchant/audit.html create mode 100644 application/admin/view/fc/merchant/detail.html create mode 100644 application/admin/view/fc/post/audit.html create mode 100644 application/admin/view/fc/post/detail.html create mode 100644 docs/07-线上服务器部署与同步清单.md delete mode 100755 runtime/.gitkeep diff --git a/.gitignore b/.gitignore index 08ac1df..775a29f 100755 --- a/.gitignore +++ b/.gitignore @@ -19,6 +19,7 @@ node_modules # 部署仓库补充忽略 *.tar.gz *.zip +*.sql dge.gynhc.com_*.tar.gz # 本地目录,不纳入仓库(AGENTS.md 含账号密码,切勿入库) diff --git a/application/admin/controller/fc/Merchant.php b/application/admin/controller/fc/Merchant.php index 3e3b777..c00538a 100644 --- a/application/admin/controller/fc/Merchant.php +++ b/application/admin/controller/fc/Merchant.php @@ -19,6 +19,12 @@ class Merchant extends Backend */ protected $model = null; + /** + * 无需鉴权的方法(后台登录管理员均可访问) + * @var array + */ + protected $noNeedRight = ['detail', 'audit', 'recommend']; + public function _initialize() { parent::_initialize(); @@ -37,6 +43,73 @@ class Merchant extends Backend /** * 审核商家资质 */ + /** + * 获取单个商家的入驻资质与质检详情 + * + * @param int|null $ids 商家ID + * @return string|\think\response\Json + */ + public function detail($ids = null) + { + $id = $this->request->param('ids', 0) ?: $this->request->param('id/d', 0); + if (!$id) { + $this->error('缺少参数ID'); + } + $row = $this->model->where('id', $id)->find(); + if (!$row) { + $this->error('商家不存在或已删除'); + } + + $userInfo = [ + 'id' => $row->user_id, + 'nickname' => '未知用户', + 'mobile' => '', + 'avatar' => '/assets/img/avatar.png' + ]; + $user = Db::name('user')->where('id', $row->user_id)->field('id,nickname,mobile,avatar')->find(); + if ($user) { + $userInfo['nickname'] = $user['nickname'] ?: $userInfo['nickname']; + $userInfo['mobile'] = $user['mobile'] ?: ''; + $userInfo['avatar'] = $user['avatar'] ?: $userInfo['avatar']; + } + + if ($this->request->param('format') === 'json') { + $data = [ + 'id' => $row->id, + 'name' => $row->name, + 'logo' => $row->logo, + 'banner' => $row->banner, + 'contact' => $row->contact, + 'category' => $row->category, + 'license' => $row->license, + 'notice' => $row->notice, + 'recommend' => $row->recommend, + 'audit_status' => $row->audit_status, + 'audit_reason' => $row->audit_reason, + 'shop_status' => $row->shop_status, + 'violations' => $row->violations, + 'post_count' => $row->post_count, + 'createtime_text' => date('Y-m-d H:i:s', $row->createtime), + 'user' => $userInfo + ]; + $this->success('获取成功', null, $data); + } + + // 区分模式:audit=专属审核界面,view=纯净详情档案界面 + $mode = $this->request->param('mode', ''); + if (!$mode) { + $mode = ((int)$row->audit_status === 0) ? 'audit' : 'view'; + } + + $this->view->assign('mode', $mode); + $this->view->assign('row', $row); + $this->view->assign('userInfo', $userInfo); + if ($mode === 'audit') { + return $this->view->fetch('audit'); + } + return $this->view->fetch('detail'); + } + public function audit() { $ids = $this->request->post('ids'); diff --git a/application/admin/controller/fc/Post.php b/application/admin/controller/fc/Post.php index a899661..1fb606b 100644 --- a/application/admin/controller/fc/Post.php +++ b/application/admin/controller/fc/Post.php @@ -19,6 +19,12 @@ class Post extends Backend */ protected $model = null; + /** + * 无需鉴权的方法(后台登录管理员均可访问) + * @var array + */ + protected $noNeedRight = ['detail', 'audit', 'top', 'offline']; + public function _initialize() { parent::_initialize(); @@ -38,6 +44,111 @@ class Post extends Backend /** * 审核信息 */ + /** + * 查看信息详情或进入审核工作台 + * + * @param int|null $ids 信息ID + * @return string|\think\response\Json + */ + public function detail($ids = null) + { + $id = $this->request->param('ids', 0) ?: $this->request->param('id/d', 0); + if (!$id) { + $this->error('缺少参数ID'); + } + $row = $this->model->where('id', $id)->find(); + if (!$row) { + $this->error('信息不存在或已删除'); + } + + // 补齐分类名称 + if ($row->category_id) { + $category = Db::name('fc_category')->where('id', $row->category_id)->find(); + $row->category_name = $category ? $category['name'] : '未分类'; + } else { + $row->category_name = '未分类'; + } + + // 解析多图相册 + $mediaList = []; + $rawMedia = $row->getData('media'); + if (!empty($rawMedia)) { + $decoded = is_string($rawMedia) ? json_decode($rawMedia, true) : $rawMedia; + if (is_array($decoded)) { + $mediaList = array_values(array_filter($decoded)); + } else { + $mediaList = array_values(array_filter(explode(',', (string)$rawMedia))); + } + } + if (empty($mediaList) && !empty($row->cover)) { + $mediaList[] = $row->cover; + } + + // 获取用户画像 + $userInfo = [ + 'id' => $row->user_id, + 'nickname' => $row->user_name ?: '未知用户', + 'mobile' => '', + 'avatar' => '/assets/img/avatar.png', + 'post_count' => 0 + ]; + $user = Db::name('user')->where('id', $row->user_id)->field('id,nickname,mobile,avatar')->find(); + if ($user) { + $userInfo['nickname'] = $user['nickname'] ?: $userInfo['nickname']; + $userInfo['mobile'] = $user['mobile'] ?: ''; + $userInfo['avatar'] = $user['avatar'] ?: $userInfo['avatar']; + $userInfo['post_count'] = Db::name('fc_post')->where('user_id', $user['id'])->count(); + } + + // 支持请求 JSON 详情 + if ($this->request->param('format') === 'json') { + $data = [ + 'id' => $row->id, + 'title' => $row->title, + 'content' => $row->content, + 'category_name' => $row->category_name, + 'price' => $row->price, + 'price_unit' => $row->price_unit, + 'area' => $row->area, + 'address' => $row->address, + 'contact' => $row->contact, + 'phone' => $row->phone, + 'wechat' => $row->wechat, + 'tags' => $row->tags ? explode(',', $row->tags) : [], + 'is_paid' => $row->is_paid, + 'amount' => $row->amount, + 'pay_type' => $row->pay_type, + 'audit_status' => $row->audit_status, + 'audit_reason' => $row->audit_reason, + 'status' => $row->status, + 'is_top' => $row->is_top, + 'views' => $row->views, + 'likes' => $row->likes, + 'createtime_text' => date('Y-m-d H:i:s', $row->createtime), + 'media_list' => $mediaList, + 'user' => $userInfo + ]; + $this->success('获取成功', null, $data); + } + + // 区分模式:audit=专属审核界面,view=纯净详情档案界面 + $mode = $this->request->param('mode', ''); + if (!$mode) { + $mode = ((int)$row->audit_status === 0) ? 'audit' : 'view'; + } + + $this->view->assign('mode', $mode); + $this->view->assign('row', $row); + $this->view->assign('userInfo', $userInfo); + $this->view->assign('mediaList', $mediaList); + + // 如果是审核模式渲染 audit.html,详情模式渲染 detail.html + if ($mode === 'audit') { + return $this->view->fetch('audit'); + } + return $this->view->fetch('detail'); + } + public function audit() { $ids = $this->request->post('ids'); diff --git a/application/admin/model/FcPost.php b/application/admin/model/FcPost.php index 69efd04..4369f0a 100644 --- a/application/admin/model/FcPost.php +++ b/application/admin/model/FcPost.php @@ -40,6 +40,52 @@ class FcPost extends Model return FcRelation::categoryName(isset($data['category_id']) ? $data['category_id'] : 0); } + /** + * 读取多媒体相册属性(兼容 JSON 数组与逗号分隔格式,供后台上传控件预览) + * + * @param mixed $value 数据库原始值 + * @return string 逗号分隔的图片路径字符串 + */ + public function getMediaAttr($value) + { + if (empty($value)) { + return ''; + } + if (is_array($value)) { + return implode(',', array_filter($value)); + } + $decoded = json_decode((string)$value, true); + if (is_array($decoded)) { + return implode(',', array_filter($decoded)); + } + return (string)$value; + } + + /** + * 写入多媒体相册属性(保存为标准 JSON 字符串,兼容移动端与接口) + * + * @param mixed $value 前端提交的值 + * @return string 标准 JSON 格式存储 + */ + public function setMediaAttr($value) + { + if (is_array($value)) { + return json_encode(array_values(array_filter($value)), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); + } + if (is_string($value)) { + $trimmed = trim($value); + if ($trimmed === '') { + return '[]'; + } + if (strpos($trimmed, '[') === 0) { + return $trimmed; + } + $arr = array_filter(array_map('trim', explode(',', $trimmed))); + return json_encode(array_values($arr), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); + } + return '[]'; + } + protected static function init() { $syncArea = function ($row) { diff --git a/application/admin/view/fc/area/index.html b/application/admin/view/fc/area/index.html index 13eddfb..2f88f44 100644 --- a/application/admin/view/fc/area/index.html +++ b/application/admin/view/fc/area/index.html @@ -6,8 +6,8 @@
- - {:__('Add')} + 刷新 + 添加 {:__('Edit')} {:__('Delete')} diff --git a/application/admin/view/fc/banner/index.html b/application/admin/view/fc/banner/index.html index 8e01057..183ddfb 100644 --- a/application/admin/view/fc/banner/index.html +++ b/application/admin/view/fc/banner/index.html @@ -6,8 +6,8 @@
- - {:__('Add')} + 刷新 + 添加 {:__('Edit')} {:__('Delete')} diff --git a/application/admin/view/fc/category/index.html b/application/admin/view/fc/category/index.html index 0321aab..5a58dc4 100644 --- a/application/admin/view/fc/category/index.html +++ b/application/admin/view/fc/category/index.html @@ -6,8 +6,8 @@
- - {:__('Add')} + 刷新 + 添加 {:__('Edit')} {:__('Delete')} diff --git a/application/admin/view/fc/comment/index.html b/application/admin/view/fc/comment/index.html index 3618706..8cb38c4 100644 --- a/application/admin/view/fc/comment/index.html +++ b/application/admin/view/fc/comment/index.html @@ -6,17 +6,7 @@
- - {:__('Add')} + 刷新 + 添加 {:__('Edit')} {:__('Delete')} diff --git a/application/admin/view/fc/coupon/index.html b/application/admin/view/fc/coupon/index.html index 76a3dd0..be7df98 100644 --- a/application/admin/view/fc/coupon/index.html +++ b/application/admin/view/fc/coupon/index.html @@ -6,8 +6,8 @@
diff --git a/application/admin/view/fc/distrelation/index.html b/application/admin/view/fc/distrelation/index.html index 7df8e58..179fee5 100644 --- a/application/admin/view/fc/distrelation/index.html +++ b/application/admin/view/fc/distrelation/index.html @@ -6,19 +6,11 @@
diff --git a/application/admin/view/fc/draft/index.html b/application/admin/view/fc/draft/index.html index 25fbd60..6f36f9d 100644 --- a/application/admin/view/fc/draft/index.html +++ b/application/admin/view/fc/draft/index.html @@ -6,8 +6,8 @@
- - {:__('Add')} + 刷新 + 添加 {:__('Edit')} {:__('Delete')} diff --git a/application/admin/view/fc/financeflow/index.html b/application/admin/view/fc/financeflow/index.html index c4910f0..2c4621f 100644 --- a/application/admin/view/fc/financeflow/index.html +++ b/application/admin/view/fc/financeflow/index.html @@ -6,26 +6,18 @@
diff --git a/application/admin/view/fc/merchant/add.html b/application/admin/view/fc/merchant/add.html index 1c29d71..b433ee6 100644 --- a/application/admin/view/fc/merchant/add.html +++ b/application/admin/view/fc/merchant/add.html @@ -1,105 +1,177 @@ -
+ -
- -
- + +
+
+ 1 + 主体身份与营业资质
-
-
- -
- -
-
-
- -
- -
-
-
- -
- -
-
-
- -
- -
-
-
- -
- -
-
-
- -
- -
-
-
- -
- -
-
-
- -
- -
-
-
- -
- -
-
-
- -
- -
-
-
- -
-
- -
- - +
+
+
+
+ +
+ +
+
+
+
+
+ +
+ +
+
+
+
+ +
+
+
+ +
+ +
+
+
+
+
+ +
+ +
+
+
+
+ +
+ +
+
+ +
+ + +
+ +
+ +
+
+ +
+ +
+
+ +
+ + +
+ +
+
    -
    -
      -
      - -
      - + + +
      +
      + 2 + 店铺主页装修 +
      +
      +
      + +
      +
      + +
      + + +
      + +
      +
        +
        +
        + +
        + +
        + +
        +
        -
        - -
        - - - - - {:__('开启后该商家会出现在「推荐商家」位置。')} + + +
        +
        + 3 + 运营与审核状态 +
        +
        +
        +
        +
        + +
        +
        + + + +
        +
        +
        +
        +
        +
        + +
        +
        + + +
        +
        +
        +
        +
        + +
        +
        +
        + +
        + + + + + 开启后推荐展示在同城商家专区 +
        +
        +
        +
        +
        + +
        + +
        +
        +
        +
        -