添加:文章相关内容

优化:site_id强制为1
添加:注册承诺书
This commit is contained in:
wuhui_zzw 2023-02-21 15:19:17 +08:00
parent ac649c026d
commit 275600839d
36 changed files with 2567 additions and 13 deletions

View File

@ -0,0 +1,215 @@
<?php
namespace addon\article\api\controller;
use addon\article\model\ArticleCategory;
use addon\article\model\ArticleFabulous;
use addon\article\model\ArticleHistory;
use addon\article\model\ArticleShareRecord;
use addon\article\model\ArticleShareRewardRecord;
use addon\businesscard\model\Record;
use addon\fenxiao\newModel\Fenxiao;
use app\api\controller\BaseApi;
use addon\article\model\Article;
use app\model\newModel\Config;
use app\model\newModel\member\Member;
use app\model\newModel\common\ShareRecord;
use app\model\newModel\common\CaChe;
class Index extends BaseApi{
/**
* Common: 分类列表
* Author: wu-hui
* Time: 2022/10/21 15:40
* @return false|string
* @throws \think\db\exception\DbException
*/
public function cateList(){
$list = (new ArticleCategory())->apiGetList();
return $this->response($list);
}
/**
* Common: 获取设置信息
* Author: wu-hui
* Time: 2022/10/21 16:03
* @return false|string
*/
public function setInfo(){
$info = (new Config())->getConfigInfo('ARTICLE_SETTING');
return $this->response($this->success($info));
}
/**
* Common: 获取文章列表
* Author: wu-hui
* Time: 2022/10/17 14:25
* @return false|string
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function articleList(){
// 缓存名称
$cacheTag = CaChe::tag($this->params);
$list = CaChe::get('article_list',$cacheTag);
if($list){
// 存在缓存时的处理
$list = json_decode($list,TRUE);
}else{
$list = (new Article())->getList();
// 记录缓存
CaChe::set('article_list',json_encode($list,JSON_UNESCAPED_UNICODE),$cacheTag);
}
return $this->response($list);
}
/**
* Common: 获取详细信息
* Author: wu-hui
* Time: 2022/10/17 14:35
* @return false|string
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function details(){
// 获取用户登录信息
$checkToken = $this->checkToken();
if ($checkToken[ 'code' ] < 0) return $this->response($checkToken);
// 参数获取
$id = input('article_id');
$sourceMember = input('source_member',0);
// 获取文章信息
$field = [
'article_id',
'article_title',
'article_content',
'article_abstract',
'cover_img',
'is_show_release_time',
'is_show_read_num',
'is_show_dianzan_num',
"(read_num + initial_read_num) as read_num",
"(dianzan_num + initial_dianzan_num) as dianzan_num",
'create_time'
];
$info = (new Article())->singleInfo($id,$field);
$info['data']['is_fabulous'] = (new ArticleFabulous())->isFabulous($id,$this->member_id);
// 获取用户信息
$info['member'] = (new Member())->getArticleMemberInfo($this->member_id);
// 文章浏览信息处理
(new ArticleHistory())->addInfo($this->member_id,$id);
// 记录用户浏览信息
if($this->member_id != $sourceMember) (new Record())->addInfo($this->member_id,$sourceMember);
if(empty($info['data'])) return $this->response($this->error('', '文章不存在'));
return $this->response($info);
}
/**
* Common: 点赞 || 取消点赞
* Author: wu-hui
* Time: 2022/11/03 15:18
* @return false|string
*/
public function fabulous(){
// 获取用户登录信息
$checkToken = $this->checkToken();
if ($checkToken[ 'code' ] < 0) return $this->response($checkToken);
// 参数获取
$id = input('article_id');
$result = (new ArticleFabulous())->fabulousOperation($id,$this->member_id);
return $this->response($result);
}
/**
* Common: 获取用户分享、点赞、浏览记录
* Author: wu-hui
* Time: 2022/11/07 14:33
* @return false|string
*/
public function getRecordList(){
// 获取用户登录信息
$checkToken = $this->checkToken();
if ($checkToken[ 'code' ] < 0) return $this->response($checkToken);
// 参数获取
$recordType = input('record_type');// share=分享;fabulous=点赞;browse=浏览
switch($recordType){
case 'share':$list = (new ShareRecord())->articleRecord($this->member_id);break;
case 'fabulous':$list = (new ArticleFabulous())->record($this->member_id);break;
case 'browse':$list = (new ArticleHistory())->record($this->member_id);break;
default: $list = $this->error('','记录类型错误!');
}
return $this->response($list);
}
/**
* Common: 删除浏览记录、取消点赞
* Author: wu-hui
* Time: 2022/11/07 15:09
* @return false|string
*/
public function delRecordInfo(){
// 获取用户登录信息
$checkToken = $this->checkToken();
if ($checkToken[ 'code' ] < 0) return $this->response($checkToken);
// 参数获取
$recordType = input('record_type');// share=分享;fabulous=点赞;browse=浏览
$articleId = input('article_id');
switch($recordType){
case 'fabulous':$list = (new ArticleFabulous())->fabulousOperation($articleId,$this->member_id);break;
case 'browse':$list = (new ArticleHistory())->delRecord($articleId,$this->member_id);break;
default: $list = $this->error('','记录类型错误!');
}
return $this->response($list);
}
/**
* Common: 分享奖励发放
* Author: wu-hui
* Time: 2022/12/09 15:09
* @return false|string
*/
public function getShareReward(){
// 获取用户登录信息
$checkToken = $this->checkToken();
if ($checkToken[ 'code' ] < 0) return $this->response($checkToken);
// 参数获取
$ArticleShareRecordModel = new ArticleShareRecord();
$ArticleShareRewardRecordModel = new ArticleShareRewardRecord();
$articleId = input('article_id');
$shareId = input('share_id');
$sourceMember = input('source_member');
$set = (new Config())->getConfigInfo('ARTICLE_SETTING');
if((float)$set['integral'] > 0){
// 判断:用户是否通过今日分享信息进入
[$startTime,$endTime] = getTimeStamp('today');
$isHas = $ArticleShareRecordModel
->where('share_time','>=',$startTime)
->where('share_time','<',$endTime)
->where('share_id','=',$shareId)
->value('id');
// 判断:用户是否已经领取过当前用户的分享奖励
$isGet = (float)$ArticleShareRewardRecordModel->isReceive($articleId,$this->member_id,$sourceMember);
if($isHas > 0 && !$isGet){
// 正常领取奖励
$res = $ArticleShareRewardRecordModel->shareReward($articleId,$this->member_id,$sourceMember,(float)$set['integral']);
if($set['parent_integral'] > 0 && $res['code'] == 0){
// 上级领取奖励
$parentMemberId = (new Fenxiao())->getParentMemberId($sourceMember);
$res = $ArticleShareRewardRecordModel->shareReward($articleId,$this->member_id,$parentMemberId,(float)$set['parent_integral'],1);
}
return $this->response($res);
}
return $this->response($this->error('','不符合领取条件'));
}
return $this->response($this->error('','未开启文章分享奖励积分'));
}
}

View File

@ -0,0 +1,46 @@
<?php
/** ZJMall商城系统 - 团队十年电商经验汇集巨献!
* =========================================================
* Copy right 2022-2032 四川正今科技有限公司, 保留所有权利。
* ----------------------------------------------
* 官方网址: https://www.zjphp.com
* 这不是自由软件!未经允许不得用于商业目或程序代码摘取及修改。
* 任何企业和个人不允许对程序代码以任何形式任何目的再发布传播。
* 唯一发布渠道官方颁发授权证书,无纸质授权凭证书视为侵权行为。
* =========================================================
*/
return [
'template' => [],
'util' => [
// [
// 'name' => 'ArticleInfo',
// 'title' => '文章管理',
// 'type' => 'PROMOTION',
// 'value' => '{}',
// 'sort' => '12007',
// 'support_diy_view' => '',
// 'max_count' => 1,
// 'icon' => 'iconzhibojian'
// ]
],
'link' => [
// [
// 'name' => 'ARTICLE',
// 'title' => '文章',
// 'parent' => 'MARKETING_LINK',
// 'wap_url' => '',
// 'web_url' => '',
// 'sort' => 0,
// 'child_list' => [
// [
// 'name' => 'ARTICLE_LIST',
// 'title' => '文章',
// 'parent' => '',
// 'wap_url' => '/pages_tool/article/info',
// 'web_url' => '',
// 'sort' => 0
// ]
// ]
// ]
]
];

View File

@ -0,0 +1,26 @@
<?php
// 事件定义文件
return [
'bind' => [
],
'listen' => [
//展示活动
'ShowPromotion' => [
'addon\article\event\ShowPromotion',
],
// 文章发布通知
'HandleArticleMessage' => [
'addon\article\event\HandleArticleMessage',
],
],
'subscribe' => [
],
];

View File

@ -0,0 +1,22 @@
<?php
/** ZJMall商城系统 - 团队十年电商经验汇集巨献!
* =========================================================
* Copy right 2022-2032 四川正今科技有限公司, 保留所有权利。
* ----------------------------------------------
* 官方网址: https://www.zjphp.com
* 这不是自由软件!未经允许不得用于商业目或程序代码摘取及修改。
* 任何企业和个人不允许对程序代码以任何形式任何目的再发布传播。
* 唯一发布渠道官方颁发授权证书,无纸质授权凭证书视为侵权行为。
* =========================================================
*/
return [
'name' => 'article',
'title' => '文章管理',
'description' => '文章管理',
'type' => 'promotion', //插件类型 system :系统插件(自动安装), promotion:扩展营销插件 tool:工具插件
'status' => 1,
'author' => '',
'version' => '5.0.2',
'version_no' => '520220819001',
'content' => '',
];

View File

@ -0,0 +1,85 @@
<?php
// +----------------------------------------------------------------------
// | 菜单设置
// +----------------------------------------------------------------------
return [
[
'name' => 'ARTICLE_ROOT',
'title' => '文章管理',
'url' => 'article://shop/index/index', // 入口方法
'picture' => 'addon/article/shop/view/public/img/live_new.png', // 图标
'picture_selected' => 'addon/live/shop/view/public/img/live_select.png', // 选中图标
'parent' => 'PROMOTION_TOOL',
'is_show' => 1,
'sort' => 1,
'child_list' => [
[
'name' => 'ARTICLE_INDEX',
'title' => '文章列表',
'url' => 'article://shop/index/index',
'is_show' => 1,
'sort' => 1,
'child_list' => [
[
'name' => 'ARTICLE_ADD',
'title' => '添加文章',
'url' => 'article://shop/index/editArticle',
'sort' => 1,
'is_show' => 0
],
[
'name' => 'ARTICLE_EDIT',
'title' => '编辑文章',
'url' => 'article://shop/index/editArticle',
'sort' => 2,
'is_show' => 0
],
[
'name' => 'ARTICLE_DELETE',
'title' => '删除文章',
'url' => 'article://shop/index/delete',
'sort' => 3,
'is_show' => 0
]
]
],
[
'name' => 'ARTICLE_CATE',
'title' => '文章分类',
'url' => 'article://shop/cate/index',
'is_show' => 1,
'sort' => 2,
'child_list' => [
[
'name' => 'ARTICLE_CATE_ADD',
'title' => '添加文章分类',
'url' => 'article://shop/cate/editInfo',
'sort' => 1,
'is_show' => 0
],
[
'name' => 'ARTICLE_CATE_EDIT',
'title' => '编辑文章分类',
'url' => 'article://shop/cate/editInfo',
'sort' => 2,
'is_show' => 0
],
[
'name' => 'ARTICLE_CATE_DELETE',
'title' => '删除文章分类',
'url' => 'article://shop/cate/delete',
'sort' => 3,
'is_show' => 0
]
]
],
[
'name' => 'ARTICLE_SET',
'title' => '基本设置',
'url' => 'article://shop/index/set',
'is_show' => 1,
'sort' => 3,
],
]
]
];

View File

@ -0,0 +1 @@
SET NAMES 'utf8';

View File

@ -0,0 +1 @@
SET NAMES 'utf8';

View File

@ -0,0 +1,27 @@
<?php
/** ZJMall商城系统 - 团队十年电商经验汇集巨献!
* =========================================================
* Copy right 2022-2032 四川正今科技有限公司, 保留所有权利。
* ----------------------------------------------
* 官方网址: https://www.zjphp.com
* 这不是自由软件!未经允许不得用于商业目或程序代码摘取及修改。
* 任何企业和个人不允许对程序代码以任何形式任何目的再发布传播。
* 唯一发布渠道官方颁发授权证书,无纸质授权凭证书视为侵权行为。
* =========================================================
*/
namespace addon\article\event;
use addon\article\model\Article;
class HandleArticleMessage{
public function handle($param){
(new Article())->sendMessage();
return $param;
}
}

View File

@ -0,0 +1,27 @@
<?php
/** ZJMall商城系统 - 团队十年电商经验汇集巨献!
* =========================================================
* Copy right 2022-2032 四川正今科技有限公司, 保留所有权利。
* ----------------------------------------------
* 官方网址: https://www.zjphp.com
* 这不是自由软件!未经允许不得用于商业目或程序代码摘取及修改。
* 任何企业和个人不允许对程序代码以任何形式任何目的再发布传播。
* 唯一发布渠道官方颁发授权证书,无纸质授权凭证书视为侵权行为。
* =========================================================
*/
namespace addon\article\event;
/**
* 应用安装
*/
class Install
{
/**
* 执行安装
*/
public function handle()
{
return success();
}
}

View File

@ -0,0 +1,54 @@
<?php
/** ZJMall商城系统 - 团队十年电商经验汇集巨献!
* =========================================================
* Copy right 2022-2032 四川正今科技有限公司, 保留所有权利。
* ----------------------------------------------
* 官方网址: https://www.zjphp.com
* 这不是自由软件!未经允许不得用于商业目或程序代码摘取及修改。
* 任何企业和个人不允许对程序代码以任何形式任何目的再发布传播。
* 唯一发布渠道官方颁发授权证书,无纸质授权凭证书视为侵权行为。
* =========================================================
*/
namespace addon\article\event;
/**
* 活动展示
*/
class ShowPromotion
{
/**
* 活动展示
* @return array
*/
public function handle()
{
$data = [
'admin' => [
],
'shop' => [
[
//插件名称
'name' => 'article',
//展示分类根据平台端设置admin平台营销shop店铺营销member:会员营销, tool:应用工具)
'show_type' => 'tool',
//展示主题
'title' => '文章管理',
//展示介绍
'description' => '文章管理',
//展示图标
'icon' => 'addon/article/icon.png',
//跳转链接
'url' => 'article://shop/index/index',
],
],
];
return $data;
}
}

View File

@ -0,0 +1,27 @@
<?php
/** ZJMall商城系统 - 团队十年电商经验汇集巨献!
* =========================================================
* Copy right 2022-2032 四川正今科技有限公司, 保留所有权利。
* ----------------------------------------------
* 官方网址: https://www.zjphp.com
* 这不是自由软件!未经允许不得用于商业目或程序代码摘取及修改。
* 任何企业和个人不允许对程序代码以任何形式任何目的再发布传播。
* 唯一发布渠道官方颁发授权证书,无纸质授权凭证书视为侵权行为。
* =========================================================
*/
namespace addon\article\event;
/**
* 应用卸载
*/
class UnInstall
{
/**
* 执行卸载
*/
public function handle()
{
return success();
}
}

BIN
addon/article/icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

View File

@ -0,0 +1,232 @@
<?php
/** ZJMall商城系统 - 团队十年电商经验汇集巨献!
* =========================================================
* Copy right 2022-2032 四川正今科技有限公司, 保留所有权利。
* ----------------------------------------------
* 官方网址: https://www.zjphp.com
* 这不是自由软件!未经允许不得用于商业目或程序代码摘取及修改。
* 任何企业和个人不允许对程序代码以任何形式任何目的再发布传播。
* 唯一发布渠道官方颁发授权证书,无纸质授权凭证书视为侵权行为。
* =========================================================
*/
namespace addon\article\model;
use app\model\NewBaseModel;
use app\model\newModel\common\CaChe;
use app\model\system\Cron;
use think\facade\Db;
use think\facade\Log;
class Article extends NewBaseModel{
protected $pk = 'article_id';
protected $caCheName = 'article_list';
protected $append = [
'category_name'
];
/**
* Common: 列表获取
* Author: wu-hui
* Time: 2022/11/03 16:39
* @param array $field
* @return array
* @throws \think\db\exception\DbException
*/
public function getList(){
// 参数获取
$page = input('page',1);
$pageSize = input('page_size',PAGE_LIST_ROWS);
$status = (int)input('status',-1);
$searchText = (string)trim(input('search_text'));
$ids = (string)trim(input('ids'),',');
$cateIds = (string)trim(input('cate_ids'),',');
$orders = (string)input('orders','');
$sort = (string)input('sort');
$isRand = (boolean)input('is_rand');
// 排序
$order = ['create_time'=>'DESC'];
if($sort) $order = ['sort'=>$sort];
else if($orders == 'new') $order = ['create_time'=>'DESC'];// 最新
else if($orders == 'recommend') $order = ['sort'=>'DESC','create_time'=>'DESC'];// 推荐
else if($orders == 'hot') $order = ['read_num'=>'DESC','create_time'=>'DESC'];// 热门
else if($orders == 'fabulous') $order = ['dianzan_num'=>'ASC','create_time'=>'DESC'];// 点赞
// 列表获取
$field = [
'article_id',
'article_title',
'category_id',
'status',
'sort',
'create_time',
'update_time',
'article_abstract',
'cover_img',
'is_show_release_time',
'is_show_read_num',
'is_show_dianzan_num',
"(read_num + initial_read_num) as read_num",
"(dianzan_num + initial_dianzan_num) as dianzan_num",
];
$result = $this
->field($field)
->where('site_id',$this->site_id)
->when($status >= 0,function($query) use ($status){
$query->where('status','=',$status);
})
->when(strlen($searchText) > 0,function($query) use ($searchText){
$query->where('article_title','like',"%{$searchText}%");
})
->when($ids,function($query) use ($ids){
$query->where('article_id','in',explode(',',$ids));
})
->when($cateIds,function($query) use ($cateIds){
$query->where('category_id','in',explode(',',$cateIds));
})
->when($isRand,function($query){
$query->orderRaw('rand()');
},function($query) use ($order){
$query->order($order);
})
->paginate(['list_rows' => $pageSize,'page' => $page]);
if($result) {
$result = $result->toArray();
$categoryIds = array_column($result['data'],'category_id');
$cateList = (new ArticleCategory())->getListCateList($categoryIds);
foreach($result['data'] as &$item){
$item['category_name'] = $cateList[$item['category_id']];
}
}
$list = [
'count' => $result['total'],
'list' => $result['data'],
'page_count' => $result['last_page'],
];
return $this->success($list);
}
/**
* Common: 编辑信息
* Author: wu-hui
* Time: 2022/11/07 16:47
* @param $info
* @return array
*/
public function editInfo($info){
// 添加文章的操作
$this->startTrans();
try{
// 判断是添加还是修改
if((int)$info[$this->pk] > 0) {
self::update($info, [$this->pk => $info[$this->pk]]);// 修改内容
}else {
$res = self::create($info);
if($info['status'] == 1) $this->messageRecord($info,$res->article_id);
}
$this->commit();
//清除缓存
CaChe::del('article_list');
return $this->success();
}catch(\Exception $e){
$this->rollback();
return $this->error('',$e->getMessage());
}
}
/**
* Common: 删除信息
* Author: wu-hui
* Time: 2022/11/07 16:44
* @param $id
* @return array
*/
public function delInfo($id){
//清除缓存
CaChe::del('article_list');
//编辑信息
return parent::delInfo($id);
}
/**
* Common: 添加模板消息通知
* Author: wu-hui
* Time: 2022/11/10 15:01
* @param $info
* @param $articleId
* @return int
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function messageRecord($info,$articleId){
// 获取所有存在openid 的用户
$list = Db::name('member')
->field('member_id,nickname,wx_openid')
->where('site_id','=',$info['site_id'])
->where('wx_openid','<>','')
->select();
$insert = [];
foreach($list as $item){
$insert[] = [
'member_id' => $item['member_id'],
'nickname' => $item['nickname'],
'wx_openid' => $item['wx_openid'],
'article_id' => $articleId,
'article_title' => $info['article_title'],
'create_time' => time(),
];
}
Db::name('article_message')->insertAll($insert);
// 开启计划任务
$cronWhere = [
'event' => 'HandleArticleMessage',
];
$cronId = model('cron')->getValue($cronWhere,'id');
if($cronId <= 0) (new Cron())->addCron(2, 5, "处理文章通知消息", "HandleArticleMessage", time(),0);
}
/**
* Common: 发送模板消息通知
* Author: wu-hui
* Time: 2022/11/10 18:46
* @throws \think\db\exception\DbException
*/
public function sendMessage(){
Log::write("文章消息通知 - 开始");
// 基本信息
$messageTemplate = Model('message_template')->getValue([['keywords','=','ARTICLE_MESSAGE']],'wechat_json');
$data["site_id"] = (int)request()->siteid();
$data["message_info"] = Model('message')->getInfo([['keywords','=','ARTICLE_MESSAGE']]);
$data["message_info"]['wechat_json'] = $messageTemplate;
// 获取列表
$list = Db::name('article_message')
->order('id','ASC')
->limit(30)
->select();
if($list) $list = $list->toArray();
$successIds = [];
foreach($list as $item){
$data["openid"] = $item['wx_openid'];
$data["template_data"] = [
'keyword1' => $item['article_title'],
'keyword2' => '成功发布',
'keyword3' => date('Y-m-d H:i:s',$item['create_time']),
];
$data["page"] = '#/pages_aijiu/article/detail?article_id='.$item['article_id'];
$res = (new \addon\wechat\model\Message())->sendMessage($data);
///if($res['code'] === 0) $successIds[] = $item['id'];
$successIds[] = $item['id'];// 由于积累问题 每次通知只会发布一次,无论成功失败 然后删除
}
Log::debug("文章消息通知 - 删除",$successIds);
if(count($successIds) > 0) Db::name('article_message')->where([['id','in',$successIds]])->delete();
Log::debug("文章消息通知 - 结束",$successIds);
}
}

View File

@ -0,0 +1,119 @@
<?php
/** ZJMall商城系统 - 团队十年电商经验汇集巨献!
* =========================================================
* Copy right 2022-2032 四川正今科技有限公司, 保留所有权利。
* ----------------------------------------------
* 官方网址: https://www.zjphp.com
* 这不是自由软件!未经允许不得用于商业目或程序代码摘取及修改。
* 任何企业和个人不允许对程序代码以任何形式任何目的再发布传播。
* 唯一发布渠道官方颁发授权证书,无纸质授权凭证书视为侵权行为。
* =========================================================
*/
namespace addon\article\model;
use app\model\NewBaseModel;
class ArticleCategory extends NewBaseModel{
protected $pk = 'category_id';
/**
* Common: 列表获取
* Author: wu-hui
* Time: 2022/10/18 14:45
* @param $siteId
* @param false $isPage
* @return array
* @throws \think\db\exception\DbException
*/
public function getList($siteId,$isPage = true){
// 参数获取
$page = input('page',1);
$pageSize = input('page_size',PAGE_LIST_ROWS);
$categoryName = (string)input('category_name');
$sort = (string)input('sort');
$order = ['create_time'=>'DESC'];
if($sort) $order = ['sort'=>$sort];
// 列表获取
$model = $this
->field('category_id,category_name,sort,create_time,update_time')
->where('site_id',$siteId)
->where('category_name','LIKE',"%{$categoryName}%")
->withCount(['relevanceArticle'=>'article_count'])
->order($order);
if($isPage){
$result = $model->paginate(['list_rows' => $pageSize,'page' => $page]);
if($result) $result = $result->toArray();
$list = [
'count' => $result['total'],
'list' => $result['data'],
'page_count' => $result['last_page'],
];
}else{
$list = $model->select();
if($list) $list = $list->toArray();
}
return $this->success($list);
}
/**
* Common: 关联文章表
* Author: wu-hui
* Time: 2022/10/17 11:10
*/
public function relevanceArticle(){
return $this->hasMany(Article::class, 'category_id','category_id');
}
/**
* Common: 根据id获取分类列表
* Author: wu-hui
* Time: 2022/11/03 16:50
* @param $ids
* @return array 返回由分类id为键 分类名称为值的内容
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function getListCateList($ids){
$list = (new ArticleCategory())
->field('category_id,category_name')
->whereIn('category_id',$ids)
->select();
if($list){
$list = $list->toArray();
return array_column($list,'category_name','category_id');
}
return [];
}
/**
* Common: 客户端文章列表获取全部分类
* Author: wu-hui
* Time: 2022/11/07 15:28
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function apiGetList(){
// 列表获取
$list = $this
->field('category_id,category_name')
->where('site_id',$this->site_id)
->order(['sort'=>'desc','create_time'=>'DESC'])
->select();
if($list) $list = $list->toArray();
return $this->success($list);
}
}

View File

@ -0,0 +1,113 @@
<?php
/** ZJMall商城系统 - 团队十年电商经验汇集巨献!
* =========================================================
* Copy right 2022-2032 四川正今科技有限公司, 保留所有权利。
* ----------------------------------------------
* 官方网址: https://www.zjphp.com
* 这不是自由软件!未经允许不得用于商业目或程序代码摘取及修改。
* 任何企业和个人不允许对程序代码以任何形式任何目的再发布传播。
* 唯一发布渠道官方颁发授权证书,无纸质授权凭证书视为侵权行为。
* =========================================================
*/
namespace addon\article\model;
use app\model\NewBaseModel;
use think\Exception;
class ArticleFabulous extends NewBaseModel{
protected $pk = 'id';
protected $autoWriteTimestamp = false; // 开启自动时间戳
protected $deleteTime = false; // 软删除字段
protected $type = [
'time' => 'timestamp:Y-m-d H:i',
];
/**
* Common: 判断当前用户是否对该文章点赞
* Author: wu-hui
* Time: 2022/11/03 15:11
* @param $articleId
* @param $memberId
* @return bool
*/
public function isFabulous($articleId,$memberId){
return (int)$this
->where('article_id',$articleId)
->where('member_id',$memberId)
->value('id');
}
/**
* Common: 点赞 || 取消点赞
* Author: wu-hui
* Time: 2022/11/03 15:18
* @param $id
* @param $memberId
* @return array
*/
public function fabulousOperation($id,$memberId){
$articleModel = new Article();
$this->startTrans();
try{
$fabulousId = $this->isFabulous($id,$memberId);
if($fabulousId > 0) {
// 已点赞 取消点赞
$this->where('id',$fabulousId)->delete();
// 减少点赞数量
$articleModel->where('article_id', $id)->dec('dianzan_num', 1)->update();
}else{
// 未点赞 进行点赞操作
$data = [
'article_id' => $id,
'member_id' => $memberId,
'create_time' => time(),
];
$this->insert($data);
// 增加点赞数量
$articleModel->where('article_id', $id)->inc('dianzan_num', 1)->update();
}
$this->commit();
return $this->success();
}catch(Exception $e){
$this->rollback();
return $this->error('',$e->getMessage());
}
}
/**
* Common: 获取用户点赞记录
* Author: wu-hui
* Time: 2022/11/07 14:29
* @param $memberId
* @return array
*/
public function record($memberId){
// 参数获取
$page = input('page',1);
$pageSize = input('page_size',PAGE_LIST_ROWS);
$searchText = (string)trim(input('search_text'));
// 列表获取
$result = $this->alias('af')
->field('a.article_id,a.article_title,a.cover_img,af.create_time as time')
->join('article a','a.article_id = af.article_id','LEFT')
->where('a.status',1)
->where('a.site_id',$this->site_id)
->where('af.member_id',$memberId)
->when(strlen($searchText) > 0,function($query) use ($searchText){
$query->where('a.article_title','like',"%{$searchText}%");
})
->order('af.create_time','DESC')
->paginate(['list_rows' => $pageSize,'page' => $page]);
if($result) $result = $result->toArray();
$list = [
'count' => $result['total'],
'list' => $result['data'],
'page_count' => $result['last_page'],
];
return $this->success($list);
}
}

View File

@ -0,0 +1,112 @@
<?php
/** ZJMall商城系统 - 团队十年电商经验汇集巨献!
* =========================================================
* Copy right 2022-2032 四川正今科技有限公司, 保留所有权利。
* ----------------------------------------------
* 官方网址: https://www.zjphp.com
* 这不是自由软件!未经允许不得用于商业目或程序代码摘取及修改。
* 任何企业和个人不允许对程序代码以任何形式任何目的再发布传播。
* 唯一发布渠道官方颁发授权证书,无纸质授权凭证书视为侵权行为。
* =========================================================
*/
namespace addon\article\model;
use app\model\NewBaseModel;
class ArticleHistory extends NewBaseModel{
protected $pk = 'id';
//protected $autoWriteTimestamp = false; // 开启自动时间戳
protected $createTime = 'create_time'; // 默认添加时间字段
protected $updateTime = 'update_time'; // 默认编辑时间字段
protected $deleteTime = false; // 软删除字段
protected $type = [
'time' => 'timestamp:Y-m-d H:i',
];
/**
* Common: 文章浏览历史变更
* Author: wu-hui
* Time: 2022/11/04 14:10
* @param $memberId
* @param $id
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function addInfo($memberId,$id){
// 阅读数量添加
(new Article())->where('article_id', $id)->inc('read_num', 1)->update();
// 记录浏览历史
$info = $this
->where('article_id',$id)
->where('member_id',$memberId)
->find();
if(!$info) $info = new self();
$info->article_id = $id;
$info->member_id = $memberId;
$info->frequency += 1;
$info->article_id = $id;
$info->save();
}
/**
* Common: 获取用户浏览记录
* Author: wu-hui
* Time: 2022/11/07 14:32
* @param $memberId
* @return array
*/
public function record($memberId){
// 参数获取
$page = input('page',1);
$pageSize = input('page_size',PAGE_LIST_ROWS);
$searchText = (string)trim(input('search_text'));
// 列表获取
$result = $this->alias('ah')
->field('a.article_id,a.article_title,a.cover_img,ah.create_time as time')
->join('article a','a.article_id = ah.article_id','LEFT')
->where('a.status',1)
->where('a.site_id',$this->site_id)
->where('ah.member_id',$memberId)
->when(strlen($searchText) > 0,function($query) use ($searchText){
$query->where('a.article_title','like',"%{$searchText}%");
})
->order('ah.create_time','DESC')
->paginate(['list_rows' => $pageSize,'page' => $page]);
if($result) $result = $result->toArray();
$list = [
'count' => $result['total'],
'list' => $result['data'],
'page_count' => $result['last_page'],
];
return $this->success($list);
}
/**
* Common: 删除浏览记录
* Author: wu-hui
* Time: 2022/11/07 14:54
* @param $articleId
* @param $memberId
* @return array
*/
public function delRecord($articleId,$memberId){
$res = $this->where('article_id',$articleId)
->where('member_id',$memberId)
->delete();
return $this->success($res);
}
/**
* Common: 关联文章表
* Author: wu-hui
* Time: 2022/11/08 20:06
* @return \think\model\relation\HasOne
*/
public function article(){
return $this->hasOne(Article::class,'article_id','article_id');
}
}

View File

@ -0,0 +1,57 @@
<?php
/** ZJMall商城系统 - 团队十年电商经验汇集巨献!
* =========================================================
* Copy right 2022-2032 四川正今科技有限公司, 保留所有权利。
* ----------------------------------------------
* 官方网址: https://www.zjphp.com
* 这不是自由软件!未经允许不得用于商业目或程序代码摘取及修改。
* 任何企业和个人不允许对程序代码以任何形式任何目的再发布传播。
* 唯一发布渠道官方颁发授权证书,无纸质授权凭证书视为侵权行为。
* =========================================================
*/
namespace addon\article\model;
use app\model\NewBaseModel;
class ArticleShareRecord extends NewBaseModel{
protected $pk = 'id';
protected $autoWriteTimestamp = false; // 开启自动时间戳
protected $deleteTime = false; // 软删除字段
/**
* Common: 文章分享记录
* Author: wu-hui
* Time: 2022/11/08 20:39
* @param $params
* @return int|string
*/
public function addInfo($params){
$data = [
'site_id' => $this->site_id,
'article_id' => $params['article_id'],
'member_id' => $params['member_id'],
'share_time' => time(),
'share_id' => $params['share_id'],
];
return $this->insertGetId($data);
}
/**
* Common: 根据条件 获取统计信息
* Author: wu-hui
* Time: 2022/11/08 20:43
* @param $memberId
* @param array $where
* @return int
* @throws \think\db\exception\DbException
*/
public function getCount($memberId,$where = []){
return $this
->where(['member_id'=>$memberId])
->where($where)
->count();
}
}

View File

@ -0,0 +1,105 @@
<?php
/** ZJMall商城系统 - 团队十年电商经验汇集巨献!
* =========================================================
* Copy right 2022-2032 四川正今科技有限公司, 保留所有权利。
* ----------------------------------------------
* 官方网址: https://www.zjphp.com
* 这不是自由软件!未经允许不得用于商业目或程序代码摘取及修改。
* 任何企业和个人不允许对程序代码以任何形式任何目的再发布传播。
* 唯一发布渠道官方颁发授权证书,无纸质授权凭证书视为侵权行为。
* =========================================================
*/
namespace addon\article\model;
use app\model\member\MemberAccount as MemberAccountModel;
use app\model\NewBaseModel;
use app\model\newModel\Config;
class ArticleShareRewardRecord extends NewBaseModel{
protected $pk = 'id';
protected $autoWriteTimestamp = false; // 开启自动时间戳
protected $deleteTime = false; // 软删除字段
/**
* Common: 判断:分享用户是否已经领取当前用户的文章分享奖励
* Author: wu-hui
* Time: 2022/12/09 14:21
* @param $articleId
* @param $memberId
* @param $sourceMember
* @return bool
*/
public function isReceive($articleId,$memberId,$sourceMember){
$id = (int)$this->where('article_id',$articleId)
->where('member_id',$memberId)
->where('hierarchy',0)
->where('reward_member_id',$sourceMember)
->value('id');
return $id > 0;
}
/**
* Common: 领取分享奖励
* Author: wu-hui
* Time: 2022/12/09 15:09
* @param $articleId
* @param $member_id
* @param $sourceMember
* @param $integral
* @param int $hierarchy
* @return array
*/
public function shareReward($articleId,$member_id,$sourceMember,$integral,$hierarchy = 0){
$this->startTrans();
try{
if($member_id == $sourceMember) return $this->error('','领取失败,同一个用户!');
// 判断:今天是否进行达标
$set = (new Config())->getConfigInfo('ARTICLE_SETTING');
$maxIntegral = (float)$set['max_integral'];
if($maxIntegral > 0){
// 今天已经获取的数量
[$startTime,$endTime] = getTimeStamp('today');
$toDayIntegral = (float)$this
->where('reward_member_id',$sourceMember)
->where('create_time','>=',$startTime)
->where('create_time','<',$endTime)
->sum('integral');
if($toDayIntegral >= $maxIntegral) {
return $this->error('','超出领取限制');
}
else {
$surplus = (float)($maxIntegral - $toDayIntegral);// 今日剩余可以获取的奖励积分
$integral = $surplus >= $integral ? $integral : $surplus;
}
}
// 添加奖励记录
$data = [
'site_id' => $this->site_id,
'article_id' => $articleId,
'member_id' => $member_id,
'hierarchy' => $hierarchy,
'reward_member_id' => $sourceMember,
'create_time' => time(),
'integral' => $integral,
];
$this->insert($data);
// 奖励发放
$remark = '文章分享奖励';
(new MemberAccountModel())->addMemberAccount($this->site_id, $sourceMember, 'point', $integral, 'share_article', 0, $remark);
$this->commit();
return $this->success();
}catch(\Exception $e){
$this->rollback();
return $this->error('',$e->getMessage());
}
}
}

View File

@ -0,0 +1,46 @@
<?php
/** ZJMall商城系统 - 团队十年电商经验汇集巨献!
* =========================================================
* Copy right 2022-2032 四川正今科技有限公司, 保留所有权利。
* ----------------------------------------------
* 官方网址: https://www.zjphp.com
* 这不是自由软件!未经允许不得用于商业目或程序代码摘取及修改。
* 任何企业和个人不允许对程序代码以任何形式任何目的再发布传播。
* 唯一发布渠道官方颁发授权证书,无纸质授权凭证书视为侵权行为。
* =========================================================
*/
namespace addon\article\shop\controller;
use addon\article\model\ArticleCategory;
use app\shop\controller\NewBaseShop;
class Cate extends NewBaseShop{
public function __construct(){
parent::__construct();
// 输出菜单
$this->forthMenu();
// 实例化默认模型
$this->thisDefaultModel = new ArticleCategory();
}
/**
* Common: 分类列表
* Author: wu-hui
* Time: 2022/10/14 15:29
* @return array|mixed
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function index(){
if(request()->isAjax()) return parent::index();
return $this->fetch('cate/index');
}
}

View File

@ -0,0 +1,152 @@
<?php
/** ZJMall商城系统 - 团队十年电商经验汇集巨献!
* =========================================================
* Copy right 2022-2032 四川正今科技有限公司, 保留所有权利。
* ----------------------------------------------
* 官方网址: https://www.zjphp.com
* 这不是自由软件!未经允许不得用于商业目或程序代码摘取及修改。
* 任何企业和个人不允许对程序代码以任何形式任何目的再发布传播。
* 唯一发布渠道官方颁发授权证书,无纸质授权凭证书视为侵权行为。
* =========================================================
*/
namespace addon\article\shop\controller;
use addon\fenxiao\model\FenxiaoOrder;
use app\model\newModel\common\CaChe;
use app\model\newModel\Config;
use addon\article\model\Article;
use addon\article\model\ArticleCategory;
use app\shop\controller\NewBaseShop;
use think\facade\Log;
class Index extends NewBaseShop{
public function __construct(){
parent::__construct();
// 输出菜单
$this->forthMenu();
// 实例化默认模型
$this->thisDefaultModel = new Article();
}
/**
* Common: 文章列表
* Author: wu-hui
* Time: 2022/10/18 15:28
* @return array|mixed
* @throws \think\db\exception\DbException
*/
public function index(){
if (request()->isAjax()) {
$params = input('');
// 缓存名称
$cacheTag = CaChe::tag($params);
$list = CaChe::get('article_list',$cacheTag);
if($list){
// 存在缓存时的处理
$list = json_decode($list,TRUE);
}else{
$list = $this->thisDefaultModel->getList();
// 记录缓存
CaChe::set('article_list',json_encode($list,JSON_UNESCAPED_UNICODE),$cacheTag);
}
return $list;
}
return $this->fetch('article/index');
}
/**
* Common: 添加编辑文章信息
* Author: wu-hui
* Time: 2022/10/14 15:44
* @return array|mixed
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function editInfo(){
if(request()->isAjax()) return parent::editInfo();
parent::editInfo();
// 获取分类
$field = ['category_id', 'category_name'];
$categoryList = (new ArticleCategory())
->field($field)
->where('site_id',$this->site_id)
->order('create_time','DESC')
->select();
if($categoryList) $categoryList = $categoryList->toArray();
$this->assign('category_list',$categoryList ?? []);
return $this->fetch('article/edit');
}
/**
* Common: 装修 —— 文章选择器
* Author: wu-hui
* Time: 2022/10/17 15:18
* @return array|mixed
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function selectInfo(){
if (request()->isAjax()) {
// 获取已选择列表
return parent::index();
}
else {
//已经选择的商品sku数据
$ids = (string)trim(input('ids'));
$this->assign('ids', $ids);
// 获取已选择列表
if(strlen($ids) > 0){
$result = parent::index();;
$this->assign('article_list', $result['data']['list']);
}else{
$this->assign('article_list', []);
}
return $this->fetch("article/select");
}
}
/**
* Common: 文章基本设置
* Author: wu-hui
* Time: 2022/10/21 14:18
* @return array|mixed
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function set(){
$key = 'ARTICLE_SETTING';
$configModel = new Config();
if (request()->isAjax()) {
// 参数获取
$info = input('info',[]);
$params = [
'site_id' => $this->site_id,
'app_module' => 'shop',
'config_key' => $key,
'value' => json_encode($info,JSON_UNESCAPED_UNICODE),
'config_desc' => '文章基本设置',
'is_use' => 1,
];
return $configModel->setConfigInfo($params);
}
else {
$info = $configModel->getConfigInfo($key);
$this->assign('info',$info);
return $this->fetch('article/set');
}
}
}

View File

@ -0,0 +1,286 @@
{extend name="app/shop/view/base.html"/}
{block name="resources"}
<style>
.layui-form-selected dl{z-index: 1000;}
.upload-img-block .upload-img-box .upload-default{position: absolute;top: 50%;left: 50%;transform: translate(-50%, -50%);}
.multiple-uploading{display: flex;flex-wrap: wrap;}
.multiple-uploading .multiple-item{position: relative;display: flex;justify-content: center;align-items: center;flex-direction: column;margin-bottom: 10px;padding: 10px;width: 100px;height: 100px;border: 1px dashed #ddd;text-align: center;box-sizing: border-box;line-height: 1;color: #5a5a5a;}
.multiple-uploading .multiple-item p{line-height: 20px;margin-top: 5px;}
.multiple-uploading .multiple-item span{display: none;position: absolute;top: -10px;right: -7px;width: 20px;height: 20px;border: 1px solid #999;color: #999;background-color: #fff;border-radius: 50%;line-height: 1;font-size: 18px;cursor: pointer;}
.multiple-uploading .multiple-item:hover .icon{display: block;}
.multiple-uploading .multiple-item ~ .multiple-item{margin-left: 10px;}
.multiple-uploading .iconfont{font-size: 30px;color: #6D7278;}
#multiple_uploading{cursor: pointer;}
.multiple-item img{max-width: 100%;max-height: 100%;}
</style>
{/block}
{block name="main"}
<div class="layui-form form-wrap">
<div class="layui-form-item">
<label class="layui-form-label img-upload-lable short-label"><span class="required">*</span>文章标题:</label>
<div class="layui-input-inline">
<input type="text" name="info[article_title]" value="{$info.article_title}" lay-verify="required" maxlength="40" autocomplete="off" placeholder="文章标题最多40个字" class="layui-input len-long">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label img-upload-lable short-label">摘要:</label>
<div class="layui-input-block">
<textarea name="info[article_abstract]" class="layui-textarea len-long" maxlength="100">{$info.article_abstract}</textarea>
</div>
<div class="word-aux">文章摘要最多可输入100个字</div>
</div>
<!-- 图片上传 -->
<div class="layui-form-item">
<label class="layui-form-label"><span class="required">*</span>封面:</label>
<div class="layui-input-block img-upload">
<div class="upload-img-block square simple-uploading">
<div class="upload-img-box" id="img">
<div class="upload-default">
<i class="iconfont iconshangchuan"></i>
<p>点击上传</p>
</div>
</div>
<input type="hidden" name="image" />
<i class="del">x</i>
</div>
</div>
<div class="word-aux">推荐使用 750x420 像素的图片</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label"><span class="required">*</span>文章分类:</label>
<div class="layui-input-inline">
<select name="info[category_id]" lay-verify="required">
<option value="">请选择</option>
{foreach $category_list as $v}
<option value="{$v['category_id']}" {if $info.category_id == $v.category_id} selected {/if}>{$v['category_name']}</option>
{/foreach}
</select>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label"><span class="required">*</span>文章内容:</label>
<div class="layui-input-inline">
<script id="editor" type="text/plain" class="special-length" style="height:500px;"></script>
<input type="hidden" name="info[article_content]" id="article_content" value="{$info.article_content}"/>
</div>
</div>
<!-- <div class="layui-form-item">-->
<!-- <label class="layui-form-label">发布时间:</label>-->
<!-- <div class="layui-input-inline">-->
<!-- <input type="radio" name="info[is_show_release_time]" value="1" title="显示" {if $info.is_show_release_time == 1} checked {/if}>-->
<!-- <input type="radio" name="info[is_show_release_time]" value="0" title="不显示" {if $info.is_show_release_time == 0} checked {/if}>-->
<!-- </div>-->
<!-- </div>-->
<!-- <div class="layui-form-item">-->
<!-- <label class="layui-form-label">阅读次数:</label>-->
<!-- <div class="layui-input-inline">-->
<!-- <input type="radio" name="info[is_show_read_num]" value="1" title="显示" {if $info.is_show_read_num == 1} checked {/if}>-->
<!-- <input type="radio" name="info[is_show_read_num]" value="0" title="不显示" {if $info.is_show_read_num == 0} checked {/if}>-->
<!-- </div>-->
<!-- </div>-->
<!-- <div class="layui-form-item">-->
<!-- <label class="layui-form-label">点赞次数:</label>-->
<!-- <div class="layui-input-inline">-->
<!-- <input type="radio" name="info[is_show_dianzan_num]" value="1" title="显示" {if $info.is_show_dianzan_num == 1} checked {/if}>-->
<!-- <input type="radio" name="info[is_show_dianzan_num]" value="0" title="不显示" {if $info.is_show_dianzan_num == 0} checked {/if}>-->
<!-- </div>-->
<!-- </div>-->
<div class="layui-form-item">
<label class="layui-form-label">虚拟阅读数:</label>
<div class="layui-input-inline">
<input type="number" min="0" name="info[initial_read_num]" value="{$info.initial_read_num}" onchange="detectionNumType(this,'integral')" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">虚拟点赞数:</label>
<div class="layui-input-inline">
<input type="number" min="0" name="info[initial_dianzan_num]" value="{$info.initial_dianzan_num}" onchange="detectionNumType(this,'integral')" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">排序:</label>
<div class="layui-input-inline">
<input type="number" min="0" name="info[sort]" value="{$info.sort}" class="layui-input">
</div>
</div>
<input type="hidden" name="info[article_id]" value="{$info.article_id}" />
<div class="form-row">
{if $info.status == 1}
<button class="layui-btn" lay-submit lay-filter="save">立即发布</button>
{else /}
<button class="layui-btn" lay-submit lay-filter="saveDrafts">保存至草稿箱</button>
<button class="layui-btn" lay-submit lay-filter="save">立即发布</button>
{/if}
<button class="layui-btn layui-btn-primary" onclick="back()">返回</button>
</div>
</div>
{/block}
{block name="script"}
<script type="text/javascript" charset="utf-8" src="STATIC_EXT/ueditor/ueditor.config.js"></script>
<script type="text/javascript" charset="utf-8" src="STATIC_EXT/ueditor/ueditor.all.js"></script>
<script type="text/javascript" charset="utf-8" src="STATIC_EXT/ueditor/lang/zh-cn/zh-cn.js"></script>
<script>
var form,upload,
IMAGE_MAX = 9, //最多可以上传多少张图片
imageCollection = [], //图片集合
selectedGoodsId = [],
goods_id=[],
repeat_flag = false,
coverImg = '{$info.cover_img}';
initImg();//初始化图片
function initImg(){
if(coverImg.length > 0){
$("#img").html("<img src=" + ns.img(coverImg) + " >");
imageCollection = [coverImg];
}
}
//实例化富文本
var ue = UE.getEditor('editor');
if($("#article_content").val()){
ue.ready(function() {
ue.setContent($("#article_content").val());
});
}
layui.use(['form'], function() {
form = layui.form;
form.render();
/**
* 图片切换
*/
form.on('radio(cover_type)', function(data){
if(imageCollection.length) {
imageCollection.splice(1, imageCollection.length);
var val = '<img src="' + ns.img(imageCollection[0]) + '" alt="">';
$("#img").html(val);
}
$(".simple-uploading").removeClass("layui-hide");
$(".multiple-uploading").addClass("layui-hide");
$(".simple-uploading").parents(".layui-form-item").find('.word-aux').text('推荐使用 750x420 像素的图片 最多上传1张');
});
// 单图上传
$("body").on("click", "#img", function () {
var html = '';
openAlbum(function (data) {
imageCollection = [];
imageCollection.push(data[0].pic_path);
imageCollection.splice(1, imageCollection.length);
var val = '<img src="' + ns.img(imageCollection[0]) + '" alt="">';
$("#img").html(val);
}, 1);
});
/**
* 表单提交(立即发布)
*/
form.on('submit(save)', function(data){
field = data.field;
field['info[status]'] = 1
formSubmit(field)
});
/**
* 表单提交(草稿箱)
*/
form.on('submit(saveDrafts)', function(data){
field = data.field;
field['info[status]'] = 0
formSubmit(field)
});
});
/**
* 提交
*/
function formSubmit(field) {
console.log(imageCollection.length)
if (!imageCollection.length){
layer.msg('请选择封面图!', {icon: 5, anim: 6});
return;
}
field['info[cover_img]'] = imageCollection.join();
if (!ue.getContent()){
layer.msg("文章内容不能为空");
return false;
}
if(field.sort < 0){
layer.msg("排序号不能小于0");
return false;
}
field['info[article_content]'] = ue.getContent();
field['info[is_show_release_time]'] = 1;
field['info[is_show_read_num]'] = 1;
field['info[is_show_dianzan_num]'] = 1;
if(repeat_flag) return;
repeat_flag = true;
$.ajax({
type: 'POST',
dataType: 'JSON',
url: ns.url("article://shop/index/editInfo"),
data: field,
async: false,
success: function(res){
repeat_flag = false;
if (res.code == 0) {
layer.confirm('编辑成功', {
title:'操作提示',
btn: ['返回列表', '继续编辑'],
yes: function(){
location.href = ns.url("article://shop/index/index");
},
btn2: function() {
location.reload();
}
});
}else{
layer.msg(res.message);
}
}
})
}
function back() {
location.href = ns.url("article://shop/index/index");
}
//检测数据类型
function detectionNumType(el, type) {
var value = $(el).val();
//大于零 且 不是小数
if (value < 0 && type == 'integral')
$(el).val(0);
else if (type == 'integral')
$(el).val(Math.round(value));
//大于1 且 不是小数
if (value < 1 && type == 'positiveInteger')
$(el).val(1);
else if (type == 'positiveInteger')
$(el).val(Math.round(value));
//大于零可以是小数
if (type == 'positiveNumber') {
value = parseFloat(value).toFixed(2);
if (value < 0)
$(el).val(0);
else
$(el).val(value);
}
}
</script>
{/block}

View File

@ -0,0 +1,209 @@
{extend name="app/shop/view/base.html"/}
{block name="resources"}
<style>
.prompt-block .prompt {
display: inline-block;
}
.prompt-block .prompt {
width: 18px;
height: 18px;
line-height: 18px;
position: relative;
}
.layui-table-box {
overflow: inherit;
}
.layui-table-header {
overflow: inherit;
}
.layui-table-cell, .layui-table-tool-panel li {
overflow: inherit;
}
.layui-table-view .layui-table td{
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
}
</style>
{/block}
{block name="main"}
<!-- 搜索框 -->
<div class="single-filter-box top">
<button class="layui-btn" onclick="add()">添加文章</button>
<div class="layui-form">
<div class="layui-input-inline">
<select name="status">
<option value="-1">全部</option>
<option value="0">草稿</option>
<option value="1">已发布</option>
</select>
</div>
<div class="layui-input-inline">
<input type="text" name="search_text" placeholder="请输入文章标题" autocomplete="off" class="layui-input">
<button type="button" class="layui-btn layui-btn-primary" lay-filter="search" lay-submit>
<i class="layui-icon">&#xe615;</i>
</button>
</div>
</div>
</div>
<!-- 列表 -->
<table id="article_list" lay-filter="article_list"></table>
<!-- 操作 -->
<script type="text/html" id="operation">
<div class="table-btn">
<a class="layui-btn" lay-event="edit">编辑</a>
<a class="layui-btn" lay-event="delete">删除</a>
</div>
</script>
<script type="text/html" id="sort">
<input style="width: 100%!important;min-width: 60px;" name="sort" type="number" onchange="editSort({{d.article_id}},this)" value="{{d.sort}}" placeholder="请输入排序" class="layui-input edit-sort len-short">
</script>
{/block}
{block name="script"}
<script>
var table, repeat_flag = false;//防重复标识;
layui.use('form', function() {
var form = layui.form;
form.render();
table = new Table({
elem: '#article_list',
url: ns.url("article://shop/index/index"),
cols: [[
{align: 'center', field: 'article_id', title: 'ID', width: '5%', unresize: 'false'},
{align: 'center', field: 'article_title', title: '文章标题', width: '25%', unresize: 'false'},
{
align: 'center',
field: 'category_name',
title: '状态',
width: '5%',
unresize: 'false',
templet: function (data) {
// 状态0草稿箱 1发布
if(data.status === 1) return '<span class="layui-badge layui-bg-blue">已发布</span>';
else return '<span class="layui-badge layui-bg-gray">草稿箱</span>';
}
},
{align: 'center', field: 'category_name', title: '文章分类', width: '10%', unresize: 'false'},
{
align: 'center',
field: 'sort',
title: '排序',
width: '5%',
sort: true,
unresize: 'false',
templet: '#sort'
},
{align: 'center', field: 'create_time', title: '创建时间', width: '20%', unresize: 'false'},
{align: 'center', field: 'update_time', title: '编辑时间', width: '20%', unresize: 'false'},
{title: '操作', toolbar: '#operation', unresize: 'false', align: 'right'}
]],
});
/**
* 搜索功能
*/
form.on('submit(search)', function(data) {
table.reload({
page: {
curr: 1
},
where: data.field
});
});
table.on("sort",function (obj) {
table.reload({
page: {
curr: 1
},
where: {
order:obj.field,
sort:obj.type
}
});
});
/**
* 监听工具栏操作
*/
table.tool(function(obj) {
var data = obj.data;
switch (obj.event) {
case 'edit': //编辑
location.href = ns.url("article://shop/index/editInfo?id=" + data.article_id);
break;
case 'delete': //删除
deleteArticle(data.article_id);
break;
}
});
});
/**
* 删除
*/
function deleteArticle(article_id) {
if (repeat_flag) return false;
repeat_flag = true;
layer.confirm('确定要删除该文章内容吗?', function() {
$.ajax({
url: ns.url("article://shop/index/delete"),
data: { id:article_id },
dataType: 'JSON',
type: 'POST',
success: function(res) {
layer.msg(res.message);
repeat_flag = false;
if (res.code == 0) {
layer.close(layer.index - 1);
table.reload();
}
}
});
},
function() {
repeat_flag = false;
layer.close();
});
}
// 监听单元格编辑
function editSort(article_id, event) {
var data = $(event).val();
if (!new RegExp("^-?[1-9]\\d*$").test(data)) {
layer.msg("排序号只能是整数");
return;
}
if(data < 0){
layer.msg("排序号必须大于0");
return ;
}
$.ajax({
type: 'POST',
url: ns.url("article://shop/index/editInfo"),
data: {
info:{
sort: data,
article_id: article_id
}
},
dataType: 'JSON',
success: function(res) {
layer.msg(res.message);
if (res.code == 0) {
location.reload();
}
}
});
}
function add() {
location.href = ns.url("article://shop/index/editInfo");
}
</script>
{/block}

View File

@ -0,0 +1,165 @@
{extend name="app/shop/view/base.html"/}
{block name="resources"}
<style>
.select-article{margin: 20px;}
.select-article .single-filter-box{padding: 0;}
.select-article .single-filter-box .layui-form{margin: inherit;}
.select-article .single-filter-box .layui-form div{margin: 0;}
</style>
{/block}
{block name="body"}
<div class="select-article">
<div class="single-filter-box">
<div class="layui-form">
<div class="layui-input-inline">
<input type="text" name="search_text" placeholder="请输入文章名称" autocomplete="off" class="layui-input">
<button type="button" class="layui-btn layui-btn-primary" lay-filter="search" lay-submit>
<i class="layui-icon">&#xe615;</i>
</button>
</div>
</div>
</div>
<table id="article_list" lay-filter="article_list"></table>
</div>
{/block}
{block name="script"}
<script type="text/html" id="checkbox">
<input type="checkbox" data-article-id="{{d.article_id}}" name="article_checkbox" lay-skin="primary" lay-filter="article_checkbox">
<input type="hidden" data-article-id="{{d.article_id}}" name="article_json" value='{{ JSON.stringify(d) }}' />
</script>
<script>
var ids = "{$ids}", //选中文章id
articleList ={:json_encode($article_list)},
selectList = {}, //选中文章所有数据res
articleIdArr = ids.length ? ids.split(',') : [], //已选中的文章id
table, form,laytpl,element;
$(function () {
for (var k in articleList) {
selectList['article_id_' + articleList[k].article_id] = {
article_id: articleList[k].article_id,
article_title: articleList[k].article_title,
cover_img: articleList[k].cover_img,
article_abstract: articleList[k].article_abstract,
read_num: articleList[k].read_num,
}
}
layui.use(['form', 'laytpl', 'element'], function () {
form = layui.form;
laytpl = layui.laytpl;
element = layui.element;
table = new Table({
elem: '#article_list',
//url: '{:addon_url("article://shop/index/selectInfo")}',
url: ns.url("article://shop/index/selectInfo", {"status": 1}),
cols: [
[
{
title: '<input type="checkbox" name="article_checkbox_all" lay-skin="primary" lay-filter="article_checkbox_all">',
width: "8%",
templet: '#checkbox'
},
{
field: 'article_title',
title: '文章名称',
width: '35%'
},
{
field: 'category_name',
title: '文章分类',
width: '30%'
},
{
field: 'cover_img',
title: '封面图',
width: '20%',
templet: function (d) {
return `<img layer-src src="${ns.img(d.cover_img)}"/>`;
}
},
]
],
callback: function (res) {
// 更新复选框状态
for (var i = 0; i < articleIdArr.length; i++) {
var selected_article = $("input[name='article_checkbox'][data-article-id='" + articleIdArr[i] + "']");
if (selected_article.length) {
selected_article.prop("checked", true);
}
}
form.render();
dealWithTableSelectedNum();
}
});
form.on('submit(search)', function (data) {
formSearch();
return false;
});
//公共搜索方法
function formSearch() {
var data = {};
data.search_text = $("input[name='search_text']").val();
data.ids = articleIdArr.toString();
table.reload({
page: {
curr: 1
},
where: data
});
}
// 勾选文章
form.on('checkbox(article_checkbox_all)', function (data) {
var all_checked = data.elem.checked;
$("input[name='article_checkbox']").each(function () {
var checked = $(this).prop('checked');
if (all_checked != checked) {
$(this).next().click();
}
})
});
// 勾选文章
form.on('checkbox(article_checkbox)', function (data) {
var article_id = $(data.elem).attr("data-article-id");
var spuLen = $("input[name='article_checkbox'][data-article-id=" + article_id + "]:checked").length;
if (spuLen) {
var item = JSON.parse($("input[name='article_json'][data-article-id=" + article_id + "]").val());
delete item.LAY_INDEX;
delete item.LAY_TABLE_INDEX;
selectList['article_id_' + article_id] = item;
} else {
delete selectList['article_id_' + article_id];
}
dealWithTableSelectedNum();
});
});
});
function selectArticle(callback) {
articleIdArr = [];
for (var key in selectList){
articleIdArr.push(selectList[key].article_id);
}
if(articleIdArr.length == 0) {
layer.msg('请选择文章');
return;
}
callback({
articleIds: articleIdArr,
list: selectList
});
}
//在表格底部增加了一个容器
function dealWithTableSelectedNum() {
$(".layui-table-bottom-left-container").html('已选择 '+ Object.keys(selectList).length +' 个文章');
}
</script>
{/block}

View File

@ -0,0 +1,92 @@
{extend name="app/shop/view/base.html"/}
{block name="resources"}
<style>
.tips{
font-size: 13px;
color: #cfcfcf;
}
</style>
{/block}
{block name="main"}
<div class="layui-form form-wrap" lay-filter="formInfo">
<!-- 基本设置 -->
<div class="layui-form-item">
<label class="layui-form-label">首页轮播:</label>
<div class="layui-input-block">
{include file='app/shop/view/template/batch_image.html'}
</div>
</div>
<!-- 文字设置 -->
<fieldset class="layui-elem-field layui-field-title">
<legend>文字设置</legend>
</fieldset>
<div class="layui-form-item">
<label class="layui-form-label img-upload-lable short-label">浏览量:</label>
<div class="layui-input-inline">
<input type="text" name="info[browse_text]" value="{$info.browse_text}" placeholder="浏览量" class="layui-input len-long">
</div>
</div>
<!-- 积分设置 -->
<fieldset class="layui-elem-field layui-field-title">
<legend>积分设置</legend>
</fieldset>
<div class="layui-form-item">
<label class="layui-form-label img-upload-lable short-label">分享奖励积分:</label>
<div class="layui-input-inline">
<input type="text" name="info[integral]" value="{$info.integral}" placeholder="分享文章可获得积分" class="layui-input len-long">
<div class="tips">分享文章给其他用户,其他用户点击后会获得积分奖励。</div>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label img-upload-lable short-label">直推上级奖励积分:</label>
<div class="layui-input-inline">
<input type="text" name="info[parent_integral]" value="{$info.parent_integral}" placeholder="分享文章可获得积分" class="layui-input len-long">
<div class="tips">用户获得分享奖励积分时,上级获得的积分奖励。</div>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label img-upload-lable short-label">每日积分获取上限:</label>
<div class="layui-input-inline">
<input type="text" name="info[max_integral]" value="{$info.max_integral}" placeholder="每日积分获取上限" class="layui-input len-long">
<div class="tips">每日获取的积分奖励上限,包括分享奖励和上级奖励。</div>
</div>
</div>
<!--操作按钮-->
<div class="form-row">
<button class="layui-btn" lay-submit lay-filter="save">提交</button>
</div>
</div>
{/block}
{block name="script"}
<script>
var form;
{if $info['banner_list']}
BANNER_LIST = {$info['banner_list']|raw};
{else}
BANNER_LIST = [];
{/if}
layui.use(['form'], function() {
form = layui.form;
form.render();
// 点击搜索
form.on('submit(save)', function(data){
var field = data.field;
field['info[banner_list]'] = JSON.stringify(BANNER_LIST);
$.ajax({
type: 'POST',
url: ns.url("article://shop/index/set",field),
data: field,
dataType: 'JSON',
success: function (res) {
layer.msg(res.message);
history.go(0);
}
});
});
});
</script>
{/block}

View File

@ -0,0 +1,318 @@
{extend name="app/shop/view/base.html"/}
{block name="resources"}
{/block}
{block name="main"}
<!-- 搜索框 -->
<div class="single-filter-box top">
<button class="layui-btn" onclick="addCategory()">添加分类</button>
<div class="layui-form">
<div class="layui-input-inline">
<input type="text" name="category_name" placeholder="请输入文章分类" autocomplete="off" class="layui-input">
<button type="button" class="layui-btn layui-btn-primary" lay-filter="search" lay-submit>
<i class="layui-icon">&#xe615;</i>
</button>
</div>
</div>
</div>
<!-- 列表 -->
<table id="article_category_list" lay-filter="article_category_list"></table>
<!-- 编辑排序 -->
<script type="text/html" id="editSort">
<input name="sort" type="number" onchange="editSort({{d.category_id}}, this)" value="{{d.sort}}" class="layui-input edit-sort len-short">
</script>
<!-- 操作 -->
<script type="text/html" id="operation">
<div class="table-btn">
<a class="layui-btn" lay-event="edit">编辑</a>
<a class="layui-btn" lay-event="delete">删除</a>
</div>
</script>
<script type="text/html" id="addCategory">
<div class="layui-form">
<div class="layui-form-item">
<label class="layui-form-label mid"><span class="required">*</span>分类名称:</label>
<div class="layui-input-block">
<input name="category_name" type="text" placeholder="请输入分类名称" lay-verify="required" class="layui-input len-mid">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label mid">排序:</label>
<div class="layui-input-block">
<input name="sort" type="number" class="layui-input edit-sort len-short">
</div>
</div>
<div class="form-row mid">
<button class="layui-btn" lay-submit lay-filter="save">保存</button>
<button class="layui-btn layui-btn-primary" onclick="closeAttrLayer()">返回</button>
</div>
</div>
</script>
<script type="text/html" id="editCategory">
<div class="layui-form">
<div class="layui-form-item">
<label class="layui-form-label mid"><span class="required">*</span>文章分类:</label>
<div class="layui-input-block">
<input name="category_name" type="text" value="{{ d.category_name }}" placeholder="请输入文章分类名称" lay-verify="required" class="layui-input len-mid">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label mid">排序:</label>
<div class="layui-input-block">
<input name="sort" type="number" value="{{ d.sort }}" class="layui-input edit-sort len-short">
</div>
</div>
<input type="hidden" name="category_id" value="{{ d.category_id }}">
<div class="form-row mid">
<button class="layui-btn" lay-submit lay-filter="edit_save">保存</button>
<button class="layui-btn layui-btn-primary" onclick="closeAttrLayer()">返回</button>
</div>
</div>
</script>
{/block}
{block name="script"}
<script>
var laytpl, add_category_index = -1,
form, table;
layui.use(['form', 'laytpl'], function() {
var repeat_flag = false; //防重复标识
laytpl = layui.laytpl;
form = layui.form;
form.render();
table = new Table({
elem: '#article_category_list',
url: ns.url("article://shop/cate/index"),
cols: [
[ {
field: 'category_name',
title: '分类名称',
unresize: 'false'
},{
field: 'article_count',
title: '文章总数',
unresize: 'false'
},{
field: 'sort',
sort : true,
unresize:'false',
title: '排序',
width: '20%',
align: 'center',
templet: '#editSort'
},{
title: '操作',
toolbar: '#operation',
unresize: 'false',
align:'right'
}]
]
});
/**
* 监听工具栏操作
*/
table.tool(function(obj) {
var data = obj.data;
switch (obj.event) {
case 'edit':
editCategory(data);
break;
case 'delete':
deleteGroup(data.category_id);
break;
}
});
/**
* 删除
*/
function deleteGroup(category_id) {
layer.confirm('确认删除该分类吗?', function() {
$.ajax({
url: ns.url("article://shop/cate/delete"),
data: {
id:category_id
},
dataType: 'JSON',
type: 'POST',
success: function(res) {
layer.msg(res.message);
if (res.code == 0) {
table.reload({
page: {
curr: 1
},
});
}
}
});
});
}
table.on("sort",function (obj) {
table.reload({
page: {
curr: 1
},
where: {
order:obj.field,
sort:obj.type
}
});
});
/**
* 搜索功能
*/
form.on('submit(search)', function(data) {
table.reload({
page: {
curr: 1
},
where: data.field
});
});
form.on('submit(save)', function(data) {
if (repeat_flag) return false;
repeat_flag = true;
$.ajax({
url: '{:addon_url("article://shop/cate/editInfo")}',
data: { info: data.field},
dataType: 'JSON',
type: 'POST',
success: function(data) {
layer.msg(data.message);
if (data.code == 0) {
table.reload();
layer.close(add_category_index);
}
repeat_flag = false;
}
});
return false;
});
form.on('submit(edit_save)', function(data) {
if (repeat_flag) return false;
repeat_flag = true;
$.ajax({
url: '{:addon_url("article://shop/cate/editInfo")}',
data: { info: data.field},
dataType: 'JSON',
type: 'POST',
success: function(data) {
layer.msg(data.message);
if (data.code == 0) {
table.reload();
layer.close(add_category_index);
}
repeat_flag = false;
}
});
return false;
});
/**
* 表单验证
*/
form.verify({
num: function(value) {
if (value == '') {
return;
}
if (value % 1 != 0) {
return '排序数值必须为整数';
}
if (value < 0) {
return '排序数值必须为大于0';
}
}
});
});
function addCategory() {
var add_group = $("#addCategory").html();
laytpl(add_group).render({}, function(html) {
add_category_index = layer.open({
title: '添加文章分类',
skin: 'layer-tips-class',
type: 1,
area: ['500px'],
content: html
});
});
}
function editCategory(data) {
var add_group = $("#editCategory").html();
laytpl(add_group).render(data, function(html) {
add_category_index = layer.open({
title: '编辑文章分类',
skin: 'layer-tips-class',
type: 1,
area: ['500px'],
content: html
});
});
}
function closeAttrLayer() {
layer.close(add_category_index);
}
// 监听单元格编辑
function editSort(category_id, event){
var data = $(event).val();
if (data == '') {
$(event).val(0);
data = 0;
}
if(!new RegExp("^-?[0-9]\\d*$").test(data)){
layer.msg("排序号只能是整数");
return ;
}
if(data<0){
layer.msg("排序号必须大于0");
return ;
}
$.ajax({
type: 'POST',
url: ns.url("article://shop/cate/editInfo"),
data: {
info:{
sort: data,
category_id: category_id
}
},
dataType: 'JSON',
success: function(res) {
layer.msg(res.message);
if(res.code==0){
table.reload();
}
}
});
}
</script>
{/block}

Binary file not shown.

After

Width:  |  Height:  |  Size: 402 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -9,7 +9,7 @@ class Captcha extends BaseModel
public function __construct()
{
//获取参数
$this->site_id = request()->siteid(input('site_id',0));
$this->site_id = request()->siteid(input('site_id',1));
$this->params = input();
$this->params[ 'site_id' ] = $this->site_id;
}

View File

@ -48,7 +48,7 @@ class Weapp extends BaseModel
// 站点ID
private $site_id;
public function __construct($site_id = 0)
public function __construct($site_id = 1)
{
$this->site_id = $site_id;
//微信小程序配置

View File

@ -55,7 +55,7 @@ class Wechat extends BaseModel
'open_shake' => "是否开通微信摇一摇功能",
);
public function __construct($site_id = 0)
public function __construct($site_id = 1)
{
$this->site_id = $site_id;
// $response = $this->app->server->serve();

View File

@ -33,11 +33,12 @@ class Request extends \think\Request
*/
public function siteid($siteid = '')
{
if(!empty($siteid)){
$this->site_id=$siteid;
}else if($siteid=='' && $this->site_id==''){
$this->site_id=input('site_id',1);
}
// if(!empty($siteid)){
// $this->site_id=$siteid;
// }else if($siteid=='' && $this->site_id==''){
// $this->site_id=input('site_id',1);
// }
$this->site_id = 1;
return $this->site_id;
}

View File

@ -176,7 +176,7 @@ class BaseShop extends Controller
*/
public function initConstructInfo()
{
$this->site_id = input('site_id', 0);
$this->site_id = input('site_id', 1);
$config_model = new ConfigModel();
$base = $config_model->getStyle($this->site_id);
$this->assign('base', $base);

View File

@ -38,7 +38,7 @@ class Login extends Controller
//检测基础登录
$this->site_id = request()->siteid();
if (empty($this->site_id)) {
$this->site_id = input("site_id", 0);
$this->site_id = input("site_id", 1);
request()->siteid($this->site_id);
}
$this->assign('app_module', $this->app_module);

View File

@ -555,6 +555,7 @@ class Member extends BaseShop
'third_party' => input('third_party', 0),
'bind_mobile' => input('bind_mobile', 0),
'alipay_bind_mobile' => input('alipay_bind_mobile', 0),
'promise' => input('promise', ''),
);
return $config_model->setRegisterConfig($data, $this->site_id, 'shop');
} else {

View File

@ -49,7 +49,6 @@
</div>
</div>
<div class="layui-card card-common card-brief ">
<div class="layui-card-header">
<div>
@ -90,7 +89,6 @@
</div>
</div>
<div class="layui-card card-common card-brief">
<div class="layui-card-header">
<div>
@ -119,7 +117,24 @@
</div>
</div>
</div>
<div class="layui-card card-common card-brief">
<div class="layui-card-header">
<div>
<span class="card-title">承诺书</span>
</div>
</div>
<div class="layui-card-body">
<div class="desc text-color border-color bg-color-diaphaneity">
用户注册时必须输入该承诺书才能进行注册。
</div>
<div class="layui-form-item">
<label class="layui-form-label">承诺书:</label>
<div class="layui-input-block">
<textarea name="promise" maxlength="150" class="layui-textarea len-long" rows="10" >{$value.promise ?? ''}</textarea>
</div>
</div>
</div>
</div>
<div class="form-row">
<button type="button" class="layui-btn" lay-submit lay-filter="save">保存</button>
</div>