From b6e77071f178f88bf753d917d485d6b466b5f83b Mon Sep 17 00:00:00 2001 From: ZF sun <34314687@qq.com> Date: Sat, 10 Jan 2026 08:37:53 +0800 Subject: [PATCH] =?UTF-8?q?chore:=20=E5=88=9D=E5=A7=8B=E5=8C=96=E8=A7=86?= =?UTF-8?q?=E9=A2=91=E5=8F=B7=E5=9F=BA=E6=9C=AC=E4=BF=A1=E6=81=AF=E6=8E=A7?= =?UTF-8?q?=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/diy/RADEME.md | 33 +- src/addon/personnel/config/menu_shop.php | 39 +- src/addon/personnel/data/install.sql | 32 +- src/addon/personnel/data/uninstall.sql | 6 + src/addon/personnel/model/Enterprise.php | 103 +++++ .../personnel/shop/controller/Enterprise.php | 103 ++++- .../shop/view/enterprise/channel/add.html | 364 ++++++++++++++++++ .../shop/view/enterprise/channel/edit.html | 360 +++++++++++++++++ .../shop/view/enterprise/channel/lists.html | 203 ++++++++++ .../shop/view/public/img/mingpian.png | Bin 14387 -> 9574 bytes .../component/controller/WechatChannel.php | 17 + .../view/wechat_channel/css/design.css | 65 ++++ .../component/view/wechat_channel/design.html | 45 +++ .../view/wechat_channel/js/design.js | 91 +++++ 14 files changed, 1455 insertions(+), 6 deletions(-) create mode 100644 src/addon/personnel/shop/view/enterprise/channel/add.html create mode 100644 src/addon/personnel/shop/view/enterprise/channel/edit.html create mode 100644 src/addon/personnel/shop/view/enterprise/channel/lists.html create mode 100644 src/app/component/controller/WechatChannel.php create mode 100644 src/app/component/view/wechat_channel/css/design.css create mode 100644 src/app/component/view/wechat_channel/design.html create mode 100644 src/app/component/view/wechat_channel/js/design.js diff --git a/docs/diy/RADEME.md b/docs/diy/RADEME.md index c9a6a0b2a..e25d92996 100644 --- a/docs/diy/RADEME.md +++ b/docs/diy/RADEME.md @@ -24,4 +24,35 @@ create table if not exists lucky_diy_view_util constraint name unique (name) ) -``` \ No newline at end of file +``` + +## 页面设计及组件展示 + +- src\app\model\web\DiyView.php +- src\app\shop\view\diy\edit.html +- src\public\static\ext\diyview\js\components.js + +## 如何添加新组件 + + +### 1. 添加组件到数据表中 + +```sql +insert into lucky_diy_view_util (name, title, type, value, addon_name, sort, support_diy_view, max_count, is_delete, icon, icon_type) +values ('test', '测试', 'SYSTEM', '{"test": "test"}', '', 0, '', 0, 0, '', 0); +``` + + +### 2. 建立组件的控制器 +在 `src\app\component\controller` 目录下创建对应的控制器文件,处理组件的业务逻辑。 + +例如:创建 `src\app\component\controller\TestController.php` 文件,用于处理测试组件的业务逻辑。 + +### 3. 建立组件的视图 +在 src\app\component\view 目录下创建对应的视图文件,处理组件的前端展示。 + +例如:创建 `src\app\component\view\test.php` 文件,用于展示测试组件。 + + +### 4. 在前端页面中使用组件 +在前端页面中使用组件,需要在页面中添加对应的组件标签。 \ No newline at end of file diff --git a/src/addon/personnel/config/menu_shop.php b/src/addon/personnel/config/menu_shop.php index 1decf3c0e..5159956b0 100644 --- a/src/addon/personnel/config/menu_shop.php +++ b/src/addon/personnel/config/menu_shop.php @@ -112,13 +112,46 @@ return [ ], ] ], + [ + 'name' => 'PERSONNEL_CHANNEL_LIST', + 'title' => '视频号', + 'url' => 'personnel://shop/enterprise/channellists', + 'is_show' => 1, + 'sort' => 4, + 'child_list' => [ + [ + 'name' => 'PERSONNEL_CHANNEL_ADD', + 'title' => '添加视频号', + 'url' => 'personnel://shop/enterprise/channeladd', + 'sort' => 1, + 'is_show' => 0, + 'is_control' => 1, + ], + [ + 'name' => 'PERSONNEL_CHANNEL_EDIT', + 'title' => '编辑视频号', + 'url' => 'personnel://shop/enterprise/channeledit', + 'sort' => 1, + 'is_show' => 0, + 'is_control' => 1, + ], + [ + 'name' => 'PERSONNEL_CHANNEL_DELETE', + 'title' => '删除视频号', + 'url' => 'personnel://shop/enterprise/channeldelete', + 'sort' => 2, + 'is_show' => 0, + 'is_control' => 1, + ], + ] + ], [ 'name' => 'MESSAGE_ROOT', 'title' => '留言列表', 'url' => 'personnel://shop/personnel/message', 'is_show' => 1, - 'sort' => 4, + 'sort' => 5, 'child_list' => [ ], @@ -128,7 +161,7 @@ return [ 'title' => '电子名片', 'url' => 'personnel://shop/personnel/diy', 'is_show' => 1, - 'sort' => 5, + 'sort' => 6, 'child_list' => [ ], @@ -138,7 +171,7 @@ return [ 'title' => '设置', 'url' => 'personnel://shop/personnel/set', 'is_show' => 1, - 'sort' => 6, + 'sort' => 7, 'child_list' => [ ], diff --git a/src/addon/personnel/data/install.sql b/src/addon/personnel/data/install.sql index 22c382dd4..3dc13a20c 100644 --- a/src/addon/personnel/data/install.sql +++ b/src/addon/personnel/data/install.sql @@ -1 +1,31 @@ -SET NAMES 'utf8'; \ No newline at end of file +SET NAMES 'utf8'; + +-- 创建视频号表 +CREATE TABLE IF NOT EXISTS `lucky_personnel_channel` +( + `channel_id` int auto_increment + primary key, + `site_id` int null, + `channel_type` varchar(50) default 'wechat' null comment '视频号类型:wechat-微信视频号,douyin-抖音,kuaishou-快手,redbook-小红书,bilibili-B站', + `channel_name` varchar(255) null, + `avatar_image_type` varchar(20) default 'upload' null comment '头像类型:upload-上传图片,url-URL', + `avatar_url` varchar(255) null, + `video_title` varchar(255) null, + `feed_id` varchar(255) null, + `cover_image_type` varchar(20) default 'upload' null comment '封面类型:upload-上传图片,url-URL', + `cover_url` varchar(255) null, + `sort` int default 0 null comment '排序', + `is_show` tinyint(1) default 1 null comment '是否显示:0-隐藏,1-显示', + `create_time` int null +) + engine = MyISAM + collate = utf8_unicode_ci + comment = '电子名片视频号资源表'; + +-- 插入视频号菜单权限(使用 IGNORE 避免重复插入报错) +INSERT IGNORE INTO `lucky_menu` (`app_module`, `addon`, `title`, `name`, `parent`, `level`, `url`, `is_show`, `sort`, `desc`, `is_icon`, `picture`, `picture_select`, `is_control`) +VALUES +('shop', 'personnel', '视频号', 'PERSONNEL_CHANNEL_LIST', 'PERSONNEL_ROOT', 4, 'personnel://shop/enterprise/channellists', 1, 4, '', 0, '', '', 1), +('shop', 'personnel', '添加视频号', 'PERSONNEL_CHANNEL_ADD', 'PERSONNEL_CHANNEL_LIST', 5, 'personnel://shop/enterprise/channeladd', 0, 1, '', 0, '', '', 1), +('shop', 'personnel', '编辑视频号', 'PERSONNEL_CHANNEL_EDIT', 'PERSONNEL_CHANNEL_LIST', 5, 'personnel://shop/enterprise/channeledit', 0, 1, '', 0, '', '', 1), +('shop', 'personnel', '删除视频号', 'PERSONNEL_CHANNEL_DELETE', 'PERSONNEL_CHANNEL_LIST', 5, 'personnel://shop/enterprise/channeldelete', 0, 2, '', 0, '', '', 1); \ No newline at end of file diff --git a/src/addon/personnel/data/uninstall.sql b/src/addon/personnel/data/uninstall.sql index 0b4cf1b2f..c14f8bb57 100644 --- a/src/addon/personnel/data/uninstall.sql +++ b/src/addon/personnel/data/uninstall.sql @@ -1 +1,7 @@ SET NAMES 'utf8'; + +-- 删除视频号菜单权限 +DELETE FROM `lucky_menu` WHERE `name` IN ('PERSONNEL_CHANNEL_LIST', 'PERSONNEL_CHANNEL_ADD', 'PERSONNEL_CHANNEL_EDIT', 'PERSONNEL_CHANNEL_DELETE'); + +-- 删除视频号表 +DROP TABLE IF EXISTS `lucky_personnel_channel`; \ No newline at end of file diff --git a/src/addon/personnel/model/Enterprise.php b/src/addon/personnel/model/Enterprise.php index 3c877a5d5..70fd166c7 100644 --- a/src/addon/personnel/model/Enterprise.php +++ b/src/addon/personnel/model/Enterprise.php @@ -264,4 +264,107 @@ class Enterprise extends BaseModel return $this->success($res); } + //视频号 + /** + * 获取视频号分页列表 + * @param array $condition + * @param number $page + * @param string $page_size + * @param string $order + * @param string $field + */ + public function getChannelPageList($condition = [], $page = 1, $page_size = PAGE_LIST_ROWS, $order = 'create_time desc', $field = '*') + { + $check_condition = array_column($condition, 2, 0); + $site_id = $check_condition['site_id'] ?? ''; + if ($site_id === '') { + return $this->error('', 'REQUEST_SITE_ID'); + } + + $list = model('personnel_channel')->pageList($condition, $field, $order, $page, $page_size); + return $this->success($list); + } + + /** + * 获取视频号列表 + * @param array $condition + * @param string $field + * @param string $order + * @param string $limit + */ + public function getChannelList($condition = [], $field = '*', $order = '', $limit = null) + { + $list = model('personnel_channel')->getList($condition, $field, $order, '', '', '', $limit); + return $this->success($list); + } + + /** + * 添加视频号 + * @param array $data + */ + public function addChannel($data) + { + $site_id = $data['site_id'] ?? ''; + if ($site_id === '') { + return $this->error('', 'REQUEST_SITE_ID'); + } + + $data['create_time'] = time(); + // 默认视频号类型为微信 + if (!isset($data['channel_type']) || empty($data['channel_type'])) { + $data['channel_type'] = 'wechat'; + } + $channel_id = model('personnel_channel')->add($data); + return $this->success($channel_id); + } + + /** + * 获取视频号信息 + * @param array $condition + * @param string $field + */ + public function getChannelInfo($condition = [], $field = '*') + { + $list = model('personnel_channel')->getInfo($condition, $field); + return $this->success($list); + } + + /** + * 修改视频号 + * @param array $data + */ + public function editChannel($data) + { + $site_id = $data['site_id'] ?? ''; + if ($site_id === '') { + return $this->error('', 'REQUEST_SITE_ID'); + } + + model('personnel_channel')->startTrans(); + try { + model('personnel_channel')->update($data, [ [ 'site_id', '=', $data[ 'site_id' ] ], [ 'channel_id', '=', $data[ 'channel_id' ] ] ]); + model('personnel_channel')->commit(); + return $this->success(); + } catch (\Exception $e) { + model('personnel_channel')->rollback(); + return $this->error('', $e->getMessage()); + } + } + + /** + * 删除视频号 + * @param array $condition + */ + public function deleteChannel($condition) + { + $check_condition = array_column($condition, 2, 0); + $site_id = $check_condition['site_id'] ?? ''; + if ($site_id === '') { + return $this->error('', 'REQUEST_SITE_ID'); + } + + $res = model('personnel_channel')->delete($condition); + return $this->success($res); + } + } \ No newline at end of file diff --git a/src/addon/personnel/shop/controller/Enterprise.php b/src/addon/personnel/shop/controller/Enterprise.php index fb0a35253..8e423200f 100644 --- a/src/addon/personnel/shop/controller/Enterprise.php +++ b/src/addon/personnel/shop/controller/Enterprise.php @@ -168,7 +168,108 @@ class Enterprise extends BaseShop if (request()->isJson()) { $video_id = input('video_id', 0); $model = new EnterpriseModel(); - return $model->deleteVideo([ [ 'video_id', '=', $video_id],['site_id','=',$this->site_id] ]); + return $model->deleteVideo([ [ 'video_id', '=', $video_id ], [ 'site_id', '=', $this->site_id ] ]); + } + } + + /***************************************视频号部分****************************************/ + /** + * 视频号列表 + */ + public function channellists(){ + if (request()->isJson()) { + $page = input('page', 1); + $page_size = input('page_size', PAGE_LIST_ROWS); + $search_text = input('search_text', ''); + $channel_type = input('channel_type', ''); + $is_show = input('is_show', ''); + $order = input('order', ''); + $condition = [ [ 'site_id', '=', $this->site_id ] ]; + if ($search_text) { + $condition[] = [ 'channel_name', 'like', '%' . $search_text . '%' ]; + } + if ($channel_type) { + $condition[] = [ 'channel_type', '=', $channel_type ]; + } + if ($is_show !== '') { + $condition[] = [ 'is_show', '=', $is_show ]; + } + $order_by = $order ? $order : 'create_time desc'; + $model = new EnterpriseModel(); + $list = $model->getChannelPageList($condition, $page, $page_size, $order_by); + return $list; + } else { + return $this->fetch('enterprise/channel/lists'); + } + } + + /** + * 添加视频号 + */ + public function channeladd() + { + $model = new EnterpriseModel(); + if (request()->isJson()) { + $data = [ + 'site_id' => $this->site_id, + 'channel_type' => input('channel_type', 'wechat'), + 'channel_name' => input('channel_name', ''), + 'avatar_image_type' => input('avatar_image_type', 'upload'), + 'avatar_url' => input('avatar_url', ''), + 'video_title' => input('video_title', ''), + 'feed_id' => input('feed_id', ''), + 'cover_image_type' => input('cover_image_type', 'upload'), + 'cover_url' => input('cover_url', ''), + 'sort' => input('sort', 0), + 'is_show' => input('is_show', 1), + 'create_time' => time() + ]; + return $model->addChannel($data); + } else { + return $this->fetch('enterprise/channel/add'); + } + } + + /** + * 编辑视频号 + */ + public function channeledit() + { + $channel_id = input('channel_id', 0); + $model = new EnterpriseModel(); + if (request()->isJson()) { + $data = [ + 'channel_id' => $channel_id, + 'site_id' => $this->site_id, + 'channel_type' => input('channel_type', 'wechat'), + 'channel_name' => input('channel_name', ''), + 'avatar_image_type' => input('avatar_image_type', 'upload'), + 'avatar_url' => input('avatar_url', ''), + 'video_title' => input('video_title', ''), + 'feed_id' => input('feed_id', ''), + 'cover_image_type' => input('cover_image_type', 'upload'), + 'cover_url' => input('cover_url', ''), + 'sort' => input('sort', 0), + 'is_show' => input('is_show', 1), + ]; + return $model->editChannel($data); + } else { + $this->assign('channel_id', $channel_id); + $article_info = $model->getChannelInfo([ [ 'channel_id', '=', $channel_id ] ]); + $this->assign('info', $article_info[ 'data' ]); + return $this->fetch('enterprise/channel/edit'); + } + } + + /** + * 删除视频号 + */ + public function channeldelete() + { + if (request()->isJson()) { + $channel_id = input('channel_id', 0); + $model = new EnterpriseModel(); + return $model->deleteChannel([ [ 'channel_id', '=', $channel_id ], [ 'site_id', '=', $this->site_id ] ]); } } } \ No newline at end of file diff --git a/src/addon/personnel/shop/view/enterprise/channel/add.html b/src/addon/personnel/shop/view/enterprise/channel/add.html new file mode 100644 index 000000000..5a87c4342 --- /dev/null +++ b/src/addon/personnel/shop/view/enterprise/channel/add.html @@ -0,0 +1,364 @@ + + + + + + +
+ + +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ + +
+
+ +
+ +
+ +
+
+ +
+ +
+
+
+
+ +

点击上传

+
+
+ + + x +
+
+
推荐使用 200x200 像素的图片
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ + +
+
+ +
+ +
+ +
+
+ +
+ +
+
+
+
+ +

点击上传

+
+
+ + + x +
+
+
推荐使用 750x420 像素的图片
+
+ +
+ +
+ +
+
数值越小排序越靠前
+
+ +
+ +
+ + +
+
+ +
+ + +
+
+ + diff --git a/src/addon/personnel/shop/view/enterprise/channel/edit.html b/src/addon/personnel/shop/view/enterprise/channel/edit.html new file mode 100644 index 000000000..a86b17d68 --- /dev/null +++ b/src/addon/personnel/shop/view/enterprise/channel/edit.html @@ -0,0 +1,360 @@ + + + + + + +
+ + +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ + +
+
+ +
+ +
+ +
+
+ +
+ +
+
+
+
+ +

点击上传

+
+
+ + + x +
+
+
推荐使用 200x200 像素的图片
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ + +
+
+ +
+ +
+ +
+
+ +
+ +
+
+
+
+ +

点击上传

+
+
+ + + x +
+
+
推荐使用 750x420 像素的图片
+
+ +
+ +
+ +
+
数值越小排序越靠前
+
+ +
+ +
+ + +
+
+ +
+ + +
+
+ + diff --git a/src/addon/personnel/shop/view/enterprise/channel/lists.html b/src/addon/personnel/shop/view/enterprise/channel/lists.html new file mode 100644 index 000000000..06c041400 --- /dev/null +++ b/src/addon/personnel/shop/view/enterprise/channel/lists.html @@ -0,0 +1,203 @@ + +
+ + +
+
+ +
+
+ +
+
+ +
+
+ + +
+
+
+ +
+ + + + + + + + + + + + + + diff --git a/src/addon/personnel/shop/view/public/img/mingpian.png b/src/addon/personnel/shop/view/public/img/mingpian.png index a5452612781e83241e667926d159bc4ed9c9351f..71b4634d785c7ca8a9dde46613356a4f60ff1a0c 100644 GIT binary patch literal 9574 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 diff --git a/src/app/component/controller/WechatChannel.php b/src/app/component/controller/WechatChannel.php new file mode 100644 index 000000000..f967745cc --- /dev/null +++ b/src/app/component/controller/WechatChannel.php @@ -0,0 +1,17 @@ +fetch("wechat_channel/design.html"); + } +} \ No newline at end of file diff --git a/src/app/component/view/wechat_channel/css/design.css b/src/app/component/view/wechat_channel/css/design.css new file mode 100644 index 000000000..ca621147d --- /dev/null +++ b/src/app/component/view/wechat_channel/css/design.css @@ -0,0 +1,65 @@ +.wechat_channel-box .preview-draggable {padding: 0;} +.wechat_channel-box .video-wrap{position: relative;} +.wechat_channel-box .video-wrap .channel-preview img{width: 100%;display: block;} +.wechat_channel-box .video-wrap .channel-info { + position: absolute; + bottom: 0; + left: 0; + right: 0; + background: linear-gradient(to top, rgba(0,0,0,0.7), transparent); + padding: 20px 10px 10px; + color: #fff; + display: flex; + align-items: center; +} +.wechat_channel-box .video-wrap .channel-avatar { + width: 40px; + height: 40px; + border-radius: 50%; + overflow: hidden; + margin-right: 10px; + flex-shrink: 0; +} +.wechat_channel-box .video-wrap .channel-avatar img { + width: 100%; + height: 100%; + object-fit: cover; +} +.wechat_channel-box .video-wrap .channel-text { + flex: 1; + overflow: hidden; +} +.wechat_channel-box .video-wrap .channel-name { + font-size: 14px; + font-weight: bold; + margin-bottom: 4px; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} +.wechat_channel-box .video-wrap .video-title { + font-size: 12px; + opacity: 0.9; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} +.wechat_channel-box .video-wrap .video-placeholder { + width: 100%; + height: 200px; + background: #f5f5f5; + display: flex; + align-items: center; + justify-content: center; + border: 1px dashed #ddd; +} +.wechat_channel-box .video-wrap .placeholder-text { + color: #999; + font-size: 14px; +} +.wechat_channel-box .edit-attribute .attr-wrap .restore-wrap .video-add-box .img-block {width: 200px !important;height: 125px !important;margin-bottom: 30px;margin-right: 0;position: relative;} +.wechat_channel-box .edit-attribute .attr-wrap .restore-wrap .video-add-box .img-block > div {line-height: 125px;height: 125px !important;width: 100%;text-align: center;} +.wechat_channel-box .edit-attribute .attr-wrap .restore-wrap .video-add-box .img-block video {width: 100% !important;height: 125px !important;} +.wechat_channel-box .edit-attribute .attr-wrap .restore-wrap .video-add-box .img-block span{position: absolute;top: 50%;left: 50%;transform: translate(-50%, -50%);} +.wechat_channel-box .video-zhezhao {position: absolute;background: #fff;width: 61%;height: 125px;top: 1px;right: 32px;text-align: center;line-height: 105px;display: none;} +.wechat_channel-box .video-zhezhao span {position: absolute;top: 35px;left: 80px;color: #909399;} \ No newline at end of file diff --git a/src/app/component/view/wechat_channel/design.html b/src/app/component/view/wechat_channel/design.html new file mode 100644 index 000000000..1c4eae6e1 --- /dev/null +++ b/src/app/component/view/wechat_channel/design.html @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/app/component/view/wechat_channel/js/design.js b/src/app/component/view/wechat_channel/js/design.js new file mode 100644 index 000000000..8cad53a14 --- /dev/null +++ b/src/app/component/view/wechat_channel/js/design.js @@ -0,0 +1,91 @@ +var tpl = '
'; + + tpl += '
'; + tpl += '

基础设置

'; + + // 根据微信视频号组件的要求,填写视频号的标题和描述 + + // 填写视频号名称 + tpl += '
'; + tpl += ''; + tpl += '
'; + tpl += ''; + tpl += '
'; + tpl += '
'; + + // 填写视频号头像URL + tpl += '
'; + tpl += ''; + tpl += '
'; + tpl += ''; + tpl += '
'; + tpl += '
'; + + // 填写视频标题 + tpl += '
'; + tpl += ''; + tpl += '
'; + tpl += ''; + tpl += '
'; + tpl += '
'; + + // 填写视频号内容ID + tpl += '
'; + tpl += ''; + tpl += '
'; + tpl += ''; + tpl += '
'; + tpl += '
'; + + + // 视频封面支持选择类型,直接上传或选择 + tpl += '
'; + tpl += ''; + tpl += '
'; + tpl += ''; + tpl += '
'; + tpl += '
'; + + // 填写视频封面URL + tpl += '
'; + tpl += ''; + tpl += '
'; + tpl += ''; + tpl += '
'; + tpl += '
'; + + // 上传视频封面 + tpl += '
'; + tpl += ''; + tpl += ''; + tpl += '
'; + + tpl += '
'; + + tpl += '
'; + +Vue.component("wechat_channel-edit",{ + data: function () { + return { + data: this.$parent.data, + }; + }, + created : function(){ + if(!this.$parent.data.verify) this.$parent.data.verify = []; + this.$parent.data.verify.push(this.verify);//加载验证方法 + + this.$parent.data.ignore = ['textColor','componentBgColor','elementBgColor','elementAngle'];//加载忽略内容 -- 其他设置中的属性设置 + this.$parent.data.ignoreLoad = true; // 等待忽略数组赋值后加载 + }, + methods: { + verify : function () { + var res = { code : true, message : "" }; + // 微信视频号组件暂不需要强制验证 + return res; + } + }, + template: tpl +}); \ No newline at end of file