Merge: 合并电子名片及新组件微信视频号

This commit is contained in:
2026-01-15 15:21:46 +08:00
parent ef32e31e59
commit 1914cc9958
16 changed files with 732 additions and 137 deletions

View File

@@ -25,3 +25,43 @@ create table if not exists lucky_diy_view_util
unique (name) unique (name)
) )
``` ```
## 页面设计及组件展示
- 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);
--- 微信视频号组件
-- 仅当WechatChannel不存在时添加记录
INSERT INTO lucky_diy_view_util (`name`, `title`, `type`, `value`, `addon_name`, `sort`, `support_diy_view`, `max_count`, `is_delete`, `icon`, `icon_type`)
SELECT 'WechatChannel', '微信视频号', 'SYSTEM', '{ "list": [{ "channelName":"", "finderUserName": "", "avatarImageType": "url", "avatarUrl": "", "videoTitle": "", "coverImageType": "url", "coverUrl": "", "feedId": "", "feedToken": "", "viewCount": 0, "showViewCount": true, "embedMode": false, "channelType":"wechat" }], "rowCount": 2, "showStyle": "fixed", "aspectRatio":"16:9", "titleLineClamp": 1, "showPlayBtn": true}', '', 100110, '', 0, 0, '/public/static/img/svg/xuanxiangka.svg', 0
WHERE NOT EXISTS (
SELECT 1 FROM lucky_diy_view_util WHERE name = 'WechatChannel'
);
```
### 2. 建立组件的控制器
`src\app\component\controller` 目录下创建对应的控制器文件,处理组件的业务逻辑。
例如:创建 `src\app\component\controller\TestController.php` 文件,用于处理测试组件的业务逻辑。
### 3. 建立组件的视图
在 src\app\component\view 目录下创建对应的视图文件,处理组件的前端展示。
例如:创建 `src\app\component\view\test.php` 文件,用于展示测试组件。
### 4. 在前端页面中使用组件
在前端页面中使用组件,需要在页面中添加对应的组件标签。

View File

@@ -1,4 +1,12 @@
<?php <?php
/**
*/
return [ return [

View File

@@ -1,4 +1,13 @@
<?php <?php
/**
*/
return [ return [
'name' => 'personnel', 'name' => 'personnel',
'title' => '电子名片', 'title' => '电子名片',

View File

@@ -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', 'name' => 'MESSAGE_ROOT',
'title' => '留言列表', 'title' => '留言列表',
'url' => 'personnel://shop/personnel/message', 'url' => 'personnel://shop/personnel/message',
'is_show' => 1, 'is_show' => 1,
'sort' => 4, 'sort' => 5,
'child_list' => [ 'child_list' => [
], ],
@@ -128,7 +161,7 @@ return [
'title' => '电子名片', 'title' => '电子名片',
'url' => 'personnel://shop/personnel/diy', 'url' => 'personnel://shop/personnel/diy',
'is_show' => 1, 'is_show' => 1,
'sort' => 5, 'sort' => 6,
'child_list' => [ 'child_list' => [
], ],
@@ -138,7 +171,7 @@ return [
'title' => '设置', 'title' => '设置',
'url' => 'personnel://shop/personnel/set', 'url' => 'personnel://shop/personnel/set',
'is_show' => 1, 'is_show' => 1,
'sort' => 6, 'sort' => 7,
'child_list' => [ 'child_list' => [
], ],

View File

@@ -1 +1,36 @@
SET NAMES 'utf8'; SET NAMES 'utf8';
-- 创建视频号表
CREATE TABLE IF NOT EXISTS `lucky_personnel_channel`
(
`channel_id` int unsigned NOT NULL AUTO_INCREMENT,
`site_id` int unsigned NOT NULL DEFAULT 0 COMMENT '站点ID',
`create_time` int unsigned NOT NULL DEFAULT 0 COMMENT '创建时间',
`channel_type` varchar(30) NOT NULL DEFAULT 'wechat' COMMENT '视频号类型wechat-微信视频号douyin-抖音kuaishou-快手redbook-小红书bilibili-B站',
`channel_name` varchar(200) NOT NULL DEFAULT '' COMMENT '视频号ID',
`feed_id` varchar(500) NOT NULL DEFAULT '' COMMENT '视频号内容ID',
`feed_token` varchar(255) NOT NULL DEFAULT '' COMMENT '视频号视频的标识',
`avatar_image_type` varchar(20) NOT NULL DEFAULT 'upload' COMMENT '头像类型upload-上传图片url-URL',
`avatar_url` varchar(500) NOT NULL DEFAULT '' COMMENT '头像URL',
`video_title` varchar(500) NOT NULL DEFAULT '' COMMENT '视频标题',
`cover_image_type` varchar(20) NOT NULL DEFAULT 'upload' COMMENT '封面类型upload-上传图片url-URL',
`cover_url` varchar(500) NOT NULL DEFAULT '' COMMENT '封面URL',
`view_count` int unsigned NOT NULL DEFAULT 0 COMMENT '视频观看次数',
`show_view_count` tinyint(1) NOT NULL DEFAULT 0 COMMENT '是否显示视频观看次数0-不显示1-显示',
`show_follow` tinyint(1) NOT NULL DEFAULT 0 COMMENT '是否显示关注按钮0-不显示1-显示',
`is_show` tinyint(1) NOT NULL DEFAULT 1 COMMENT '是否显示0-隐藏1-显示',
`sort` int NOT NULL DEFAULT 0 COMMENT '排序,数值越小越靠前',
PRIMARY KEY (`channel_id`),
KEY `idx_site_id` (`site_id`),
KEY `idx_channel_type` (`channel_type`),
KEY `idx_is_show` (`is_show`),
KEY `idx_sort` (`sort`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_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);

View File

@@ -1 +1,7 @@
SET NAMES 'utf8'; 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`;

View File

@@ -1,4 +1,12 @@
<?php <?php
/**
*/
namespace addon\personnel\event; namespace addon\personnel\event;

View File

@@ -1,4 +1,13 @@
<?php <?php
/**
*/
namespace addon\personnel\event; namespace addon\personnel\event;

View File

@@ -264,4 +264,107 @@ class Enterprise extends BaseModel
return $this->success($res); 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);
}
} }

View File

@@ -18,16 +18,20 @@ class Personnel extends BaseModel
*/ */
public function getPersonnelSet($site_id, $app_module) public function getPersonnelSet($site_id, $app_module)
{ {
$DEFAULT_CONFIG_VALUE = '{"is_kefu":1,"is_mp":1,"is_file":1,"is_channel":1,"is_video":1,"is_map":1}';
$config = new ConfigModel(); $config = new ConfigModel();
$res = $config->getConfig([['site_id', '=', $site_id], ['app_module', '=', $app_module], ['config_key', '=', 'DIY_PERSONNEL']]); $res = $config->getConfig([['site_id', '=', $site_id], ['app_module', '=', $app_module], ['config_key', '=', 'DIY_PERSONNEL']]);
if (empty($res['data']['value'])) { if (empty($res['data']['value'])) {
$res['data']['value'] = [ $res['data']['value'] = [
'personnel_bg' => '', 'personnel_bg' => '',
'value'=>'{"is_kefu":1,"is_mp":1,"is_file":1,"is_video":1,"is_map":1}' 'value' => $DEFAULT_CONFIG_VALUE
]; ];
} else { } else {
if(!isset($res['data']['value']['value'])) $res['data']['value']['value'] = '{"is_kefu":1,"is_mp":1,"is_file":1,"is_video":1,"is_map":1}'; if (!isset($res['data']['value']['value']))
$res['data']['value']['value'] = $DEFAULT_CONFIG_VALUE;
} }
//public/static/img/diy_view/member_info_bg.png //public/static/img/diy_view/member_info_bg.png
return $res; return $res;
} }
@@ -101,7 +105,8 @@ class Personnel extends BaseModel
public function deletePersonnel($id, $site_id) public function deletePersonnel($id, $site_id)
{ {
$info = model('personnel')->getInfo([['site_id', '=', $site_id], ['id', '=', $id]], 'id'); $info = model('personnel')->getInfo([['site_id', '=', $site_id], ['id', '=', $id]], 'id');
if (empty($info)) return $this->error('', '未获取到人员信息'); if (empty($info))
return $this->error('', '未获取到人员信息');
$res = model('personnel')->delete([['site_id', '=', $site_id], ['id', '=', $id]]); $res = model('personnel')->delete([['site_id', '=', $site_id], ['id', '=', $id]]);
return $this->success($res); return $this->success($res);
} }
@@ -131,7 +136,8 @@ class Personnel extends BaseModel
public function deleteMessage($id, $site_id) public function deleteMessage($id, $site_id)
{ {
$info = model('personnel_message')->getInfo([['site_id', '=', $site_id], ['id', '=', $id]], 'id'); $info = model('personnel_message')->getInfo([['site_id', '=', $site_id], ['id', '=', $id]], 'id');
if (empty($info)) return $this->error('', '未获取到留言信息'); if (empty($info))
return $this->error('', '未获取到留言信息');
$res = model('personnel_message')->delete([['site_id', '=', $site_id], ['id', '=', $id]]); $res = model('personnel_message')->delete([['site_id', '=', $site_id], ['id', '=', $id]]);
return $this->success($res); return $this->success($res);
} }

View File

@@ -171,4 +171,114 @@ class Enterprise extends BaseShop
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),
'feed_token' => input('feed_token', ''),
'view_count' => input('view_count', 0),
'show_view_count' => input('show_view_count', 0),
'show_follow' => input('show_follow', 0),
'create_time' => time()
];
return $model->addChannel($data);
} else {
return $this->fetch('enterprise/channel/edit');
}
}
/**
* 编辑视频号
*/
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),
'feed_token' => input('feed_token', ''),
'view_count' => input('view_count', 0),
'show_view_count' => input('show_view_count', 0),
'show_follow' => input('show_follow', 0),
];
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' ]);
// 返回统一的 add.html 模板,前端会根据 channel_id 判断是否为编辑模式
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 ] ]);
}
}
} }

View File

@@ -13,7 +13,7 @@
<div class="div-wrap"> <div class="div-wrap">
<div class='diy-view-wrap layui-form' :style="{ backgroundColor : '#f4f6fa' }"> <div class='diy-view-wrap layui-form' :style="{ backgroundColor : '#f4f6fa' }" lay-filter="diy-form">
<div class="preview-head"> <div class="preview-head">
<div class="nav-tabbar style-1 center"> <div class="nav-tabbar style-1 center">
@@ -41,6 +41,10 @@
<img src="{:img('/addon/personnel/shop/view/public/img/video.png')}" style="width: 100%;"></img> <img src="{:img('/addon/personnel/shop/view/public/img/video.png')}" style="width: 100%;"></img>
</div> </div>
<div style="width: 100%;" v-if="is_channel">
<img src="{:img('/addon/personnel/shop/view/public/img/channel.png')}" style="width: 100%;" alt="视频号"></img>
</div>
<div style="width: 100%;" v-if="is_map"> <div style="width: 100%;" v-if="is_map">
<img src="{:img('/addon/personnel/shop/view/public/img/map.png')}" style="width: 100%;"></img> <img src="{:img('/addon/personnel/shop/view/public/img/map.png')}" style="width: 100%;"></img>
</div> </div>
@@ -99,6 +103,89 @@
<div v-else @click="is_video= 1" class="layui-unselect layui-form-checkbox" lay-skin="primary"><i class="layui-icon layui-icon-ok"></i></div> <div v-else @click="is_video= 1" class="layui-unselect layui-form-checkbox" lay-skin="primary"><i class="layui-icon layui-icon-ok"></i></div>
</div> </div>
</div> </div>
<div class="layui-form-item checkbox-wrap custom-popup">
<label class="layui-form-label sm">视频号</label>
<div class="layui-input-block">
<span v-if="is_channel== 0">隐藏</span><span v-else>显示</span>
<div v-if="is_channel!= 0" @click="is_channel= 0" class="layui-unselect layui-form-checkbox layui-form-checked" lay-skin="primary">
<i class="layui-icon layui-icon-ok"></i>
</div>
<div v-else @click="is_channel= 1" class="layui-unselect layui-form-checkbox" lay-skin="primary"><i class="layui-icon layui-icon-ok"></i></div>
</div>
</div>
<!-- 视频号设置 -->
<div v-if="is_channel!= 0" class="channel-settings">
<div class="layui-form-item">
<div class="layui-input-block" style="margin-left: 0;">
<div class="collapse-header" @click="channelCollapsed = !channelCollapsed">
<span class="collapse-title">视频号内容设置</span>
<i class="layui-icon" :class="channelCollapsed ? 'layui-icon-down' : 'layui-icon-up'"></i>
</div>
<div v-show="!channelCollapsed" class="collapse-content">
<div class="layui-form-item">
<label class="layui-form-label sm">显示样式</label>
<div class="layui-input-block">
<select name="channel_display_style" class="layui-select" lay-filter="channel_display_style">
<option value="carousel">轮播</option>
<option value="fixed">固定</option>
<option value="singleSlide">单页</option>
</select>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label sm">封面显示比例</label>
<div class="layui-input-block">
<select name="channel_aspect_ratio" class="layui-select" lay-filter="channel_aspect_ratio">
<option value="16:9">16:9</option>
<option value="3:4">3:4</option>
</select>
</div>
</div>
<div class="layui-form-item checkbox-wrap custom-popup">
<label class="layui-form-label sm">显示观看次数</label>
<div class="layui-input-block">
<span v-if="!channel_show_view_count">隐藏</span><span v-else>显示</span>
<div v-if="channel_show_view_count" @click="channel_show_view_count= false" class="layui-unselect layui-form-checkbox layui-form-checked" lay-skin="primary">
<i class="layui-icon layui-icon-ok"></i>
</div>
<div v-else @click="channel_show_view_count= true" class="layui-unselect layui-form-checkbox" lay-skin="primary"><i class="layui-icon layui-icon-ok"></i></div>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label sm">每行显示数量</label>
<div class="layui-input-block">
<select name="channel_row_count" class="layui-select" lay-filter="channel_row_count">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
</select>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label sm">标题最多行数</label>
<div class="layui-input-block">
<select name="channel_title_line_clamp" class="layui-select" lay-filter="channel_title_line_clamp">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
</div>
</div>
<div class="layui-form-item checkbox-wrap custom-popup">
<label class="layui-form-label sm">显示播放按钮</label>
<div class="layui-input-block">
<span v-if="!channel_show_play_btn">隐藏</span><span v-else>显示</span>
<div v-if="channel_show_play_btn" @click="channel_show_play_btn= false" class="layui-unselect layui-form-checkbox layui-form-checked" lay-skin="primary">
<i class="layui-icon layui-icon-ok"></i>
</div>
<div v-else @click="channel_show_play_btn= true" class="layui-unselect layui-form-checkbox" lay-skin="primary"><i class="layui-icon layui-icon-ok"></i></div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="layui-form-item checkbox-wrap custom-popup"> <div class="layui-form-item checkbox-wrap custom-popup">
<label class="layui-form-label sm">地图导航</label> <label class="layui-form-label sm">地图导航</label>
<div class="layui-input-block"> <div class="layui-input-block">

View File

@@ -0,0 +1,32 @@
.collapse-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 10px 15px;
background-color: #f8f9fa;
border: 1px solid #e9ecef;
border-radius: 4px;
cursor: pointer;
margin-bottom: 10px;
}
.collapse-header:hover {
background-color: #e9ecef;
}
.collapse-title {
font-weight: 600;
color: #333;
}
.collapse-content {
padding: 10px 15px;
border-radius: 4px;
background-color: #fff;
box-sizing: border-box;
border: 1px dashed #8a8a8a;
}
.channel-settings .layui-form-item {
margin-bottom: 15px;
}

View File

@@ -3,7 +3,7 @@
*/ */
var vue = new Vue({ var vue = new Vue({
el: "#diyView", el: "#diyView",
data: { data: () => ({
lazyLoad: false, lazyLoad: false,
global: { global: {
title: "电子名片", title: "电子名片",
@@ -17,25 +17,40 @@ var vue = new Vue({
is_mp: 1, is_mp: 1,
is_file: 1, is_file: 1,
is_video: 1, is_video: 1,
is_channel: 1,
is_map: 1, is_map: 1,
}, // 视频号设置
channel_display_style: 'fixed', // 显示样式carousel, fixed, singleSlide默认fixed
channel_aspect_ratio: '16:9', // 显示比例16:9 和 3:4默认16:9
channel_show_view_count: true, // 是否显示观看次数,默认显示
channel_row_count: 2, // 每行显示数量1,2,3,4默认2
channel_title_line_clamp: 2, // 标题最多行数1,2,3默认2
channel_show_play_btn: true, // 是否显示播放按钮,默认显示
channelCollapsed: false, // 视频号设置是否折叠,默认展开
}),
created: function () { created: function () {
if ($("#guessYouLikeConfig").val()) { if ($("#guessYouLikeConfig").val()) {
$('#diyView').css('visibility', 'visible'); $('#diyView').css('visibility', 'visible');
$('.preview-wrap .preview-restore-wrap').css('visibility', 'visible'); $('.preview-wrap .preview-restore-wrap').css('visibility', 'visible');
var self = this; var self = this;
setTimeout(() => {
var data = JSON.parse($("#guessYouLikeConfig").val()); var data = JSON.parse($("#guessYouLikeConfig").val());
console.log(this.data) this.is_kefu = data.is_kefu;
this.is_kefu = data.is_kefu this.is_mp = data.is_mp;
this.is_mp = data.is_mp this.is_file = data.is_file;
this.is_file = data.is_file this.is_video = data.is_video;
this.is_video = data.is_video this.is_map = data.is_map;
this.is_map = data.is_map this.is_channel = data.is_channel;
// 视频号设置初始化
this.channel_display_style = data.channel_display_style || 'fixed';
this.channel_aspect_ratio = data.channel_aspect_ratio || '16:9';
this.channel_show_view_count = !!data.channel_show_view_count;
this.channel_row_count = data.channel_row_count || 2;
this.channel_title_line_clamp = data.channel_title_line_clamp || 2;
this.channel_show_play_btn = !!data.channel_show_play_btn;
fullScreenSize(function () { fullScreenSize(function () {
self.lazyLoad = true; self.lazyLoad = true;
}); });
}, 10);
} else { } else {
$('#diyView').css('visibility', 'visible'); $('#diyView').css('visibility', 'visible');
$('.preview-wrap .preview-restore-wrap').css('visibility', 'visible'); $('.preview-wrap .preview-restore-wrap').css('visibility', 'visible');
@@ -74,6 +89,47 @@ layui.use(['form'], function () {
fullScreenSize(); fullScreenSize();
// 初始化layui的select元素的默认值和事件绑定
const initLayuiSelectBindings = (() => {
// 特别注意layui的select元素不能使用v-model绑定数据, 只能使用layui的form.on('select')事件监听和form.val()方法设置默认值
[`channel_display_style`, `channel_aspect_ratio`, `channel_row_count`, `channel_title_line_clamp`].forEach((key) => {
// 根据vue数据, 初始化layui的select元素的默认值
if (vue.hasOwnProperty(key)) {
// form.val 必须指定form的lay-filter属性值才能设置默认值
form.val('diy-form', {
[`${key}`]: vue[key]
});
console.log(`form.val(${key}, ${vue[key]})`);
}
// 监听select事件, 并更新vue数据, layui + vue. 针对select元素不能使用v-model绑定数据, 只能使用layui的form.on('select')事件监听
form.on('select(' + key + ')', function (data) {
if (vue.hasOwnProperty(key)) {
vue[key] = data.value;
console.log(`vue.${key} = ${data.value}`);
}
});
});
});
initLayuiSelectBindings(); // 启动默认绑定事件一次
// FIX: 当切换视频号隐藏还是显示时需要重新渲染layui的select元素
// 监听视频号设置是否折叠
form.on('switch(channelCollapsed)', function (data) {
vue.channelCollapsed = data.elem.checked;
form.render('select');
initLayuiSelectBindings();
});
// FIX: 当切换视频号隐藏还是显示时需要重新渲染layui的select元素重新渲染后需要重新绑定初始化数据和事件
vue.$watch('is_channel', function (newVal, oldVal) {
if (newVal !== oldVal) {
form.render('select');
initLayuiSelectBindings();
}
});
$("body").off("click", ".edit-attribute .attr-wrap .restore-wrap .attr-title .tab-wrap span").on("click", ".edit-attribute .attr-wrap .restore-wrap .attr-title .tab-wrap span", function () { $("body").off("click", ".edit-attribute .attr-wrap .restore-wrap .attr-title .tab-wrap span").on("click", ".edit-attribute .attr-wrap .restore-wrap .attr-title .tab-wrap span", function () {
$(this).addClass('active bg-color').siblings().removeClass('active bg-color'); $(this).addClass('active bg-color').siblings().removeClass('active bg-color');
var type = $(this).attr('data-type'); var type = $(this).attr('data-type');
@@ -83,6 +139,7 @@ layui.use(['form'], function () {
}); });
form.on('submit(save)', function (data) { form.on('submit(save)', function (data) {
console.log('submit save:', { data, vue });
if (repeat_flag) return; if (repeat_flag) return;
repeat_flag = true; repeat_flag = true;
var formData = { var formData = {
@@ -90,8 +147,16 @@ layui.use(['form'], function () {
is_mp: vue.is_mp, is_mp: vue.is_mp,
is_file: vue.is_file, is_file: vue.is_file,
is_video: vue.is_video, is_video: vue.is_video,
is_map:vue.is_map is_channel: vue.is_channel,
} is_map: vue.is_map,
// 视频号设置
channel_display_style: vue.channel_display_style,
channel_aspect_ratio: vue.channel_aspect_ratio,
channel_show_view_count: vue.channel_show_view_count,
channel_row_count: vue.channel_row_count,
channel_title_line_clamp: vue.channel_title_line_clamp,
channel_show_play_btn: vue.channel_show_play_btn
};
$.ajax({ $.ajax({
type: "post", type: "post",
url: ns.url('personnel://shop/personnel/diy'), url: ns.url('personnel://shop/personnel/diy'),

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 9.3 KiB

View File

@@ -123,3 +123,47 @@ ALTER DATABASE shop_mallnew CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci
-- 修改表字符集 -- 修改表字符集
ALTER TABLE lucky_aikefu_conversation CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; ALTER TABLE lucky_aikefu_conversation CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
ALTER TABLE lucky_aikefu_message CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; ALTER TABLE lucky_aikefu_message CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- 创建视频号表
CREATE TABLE IF NOT EXISTS `lucky_personnel_channel`
(
`channel_id` int unsigned NOT NULL AUTO_INCREMENT,
`site_id` int unsigned NOT NULL DEFAULT 0 COMMENT '站点ID',
`create_time` int unsigned NOT NULL DEFAULT 0 COMMENT '创建时间',
`channel_type` varchar(30) NOT NULL DEFAULT 'wechat' COMMENT '视频号类型wechat-微信视频号douyin-抖音kuaishou-快手redbook-小红书bilibili-B站',
`channel_name` varchar(200) NOT NULL DEFAULT '' COMMENT '视频号ID',
`feed_id` varchar(500) NOT NULL DEFAULT '' COMMENT '视频号内容ID',
`feed_token` varchar(255) NOT NULL DEFAULT '' COMMENT '视频号视频的标识',
`avatar_image_type` varchar(20) NOT NULL DEFAULT 'upload' COMMENT '头像类型upload-上传图片url-URL',
`avatar_url` varchar(500) NOT NULL DEFAULT '' COMMENT '头像URL',
`video_title` varchar(500) NOT NULL DEFAULT '' COMMENT '视频标题',
`cover_image_type` varchar(20) NOT NULL DEFAULT 'upload' COMMENT '封面类型upload-上传图片url-URL',
`cover_url` varchar(500) NOT NULL DEFAULT '' COMMENT '封面URL',
`view_count` int unsigned NOT NULL DEFAULT 0 COMMENT '视频观看次数',
`show_view_count` tinyint(1) NOT NULL DEFAULT 0 COMMENT '是否显示视频观看次数0-不显示1-显示',
`show_follow` tinyint(1) NOT NULL DEFAULT 0 COMMENT '是否显示关注按钮0-不显示1-显示',
`is_show` tinyint(1) NOT NULL DEFAULT 1 COMMENT '是否显示0-隐藏1-显示',
`sort` int NOT NULL DEFAULT 0 COMMENT '排序,数值越小越靠前',
PRIMARY KEY (`channel_id`),
KEY `idx_site_id` (`site_id`),
KEY `idx_channel_type` (`channel_type`),
KEY `idx_is_show` (`is_show`),
KEY `idx_sort` (`sort`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_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);
-- 微信视频号组件
-- 仅当WechatChannel不存在时添加记录
INSERT INTO lucky_diy_view_util (`name`, `title`, `type`, `value`, `addon_name`, `sort`, `support_diy_view`, `max_count`, `is_delete`, `icon`, `icon_type`)
SELECT 'WechatChannel', '微信视频号', 'SYSTEM', '{ "list": [{ "channelName":"", "finderUserName": "", "avatarImageType": "url", "avatarUrl": "", "videoTitle": "", "coverImageType": "url", "coverUrl": "", "feedId": "", "feedToken": "", "viewCount": 0, "showViewCount": true, "embedMode": false, "channelType":"wechat" }], "rowCount": 2, "showStyle": "fixed", "aspectRatio":"16:9", "titleLineClamp": 1, "showPlayBtn": true}', '', 100110, '', 0, 0, '/public/static/img/svg/xuanxiangka.svg', 0
WHERE NOT EXISTS (
SELECT 1 FROM lucky_diy_view_util WHERE name = 'WechatChannel'
);