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 a54526127..71b4634d7 100644 Binary files a/src/addon/personnel/shop/view/public/img/mingpian.png and b/src/addon/personnel/shop/view/public/img/mingpian.png differ 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