项目案例

master
yin5th 2022-10-14 14:00:42 +08:00
parent 3eaf4c1aa2
commit 86b426afe7
14 changed files with 960 additions and 9 deletions

95
app/controller/Cases.php Executable file
View File

@ -0,0 +1,95 @@
<?php
namespace app\controller;
use app\model\{CasesModel, Category};
class Cases extends Base
{
/**
* 详情
*
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\DataNotFoundException
*/
public function detail($id = 0)
{
if ($id <= 0) {
return $this->error('错误页面');
}
$article = CasesModel::getById($id);
if (empty($article)) {
return $this->error('无此案例');
}
$category = Category::getById($article['category_id']);
$description = $article['seo_description'] ?: $this->system['seo_description'];
$keywords = $article['seo_keywords'] ?: $this->system['seo_keywords'];
$title = $article['seo_title'] ?: $article['title'].' | '.$this->system['seo_title'];
$this->data['images'] = json_decode($article['images'], true);
// 相关推荐
$recommendList = $this->recommendList($article, 6, $id);
$this->data['recommendList'] = $recommendList;
$this->setSeo($title, $keywords, $description);
$this->data['item'] = $article;
$this->data['category'] = $category;
$this->data['categoryId'] = $category['id'];
$this->data['categoryPath'] = Category::categoryPath($category['path']);
$this->data['topCategoryId'] = Category::firstGradeId($category['path'], $category['id']);
return $this->view($category['template_detail'] ?? '');
}
/**
* 相关推荐
*
* @param $article
* @param int $num
* @param int $exceptId
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
private function recommendList($article, int $num = 0, int $exceptId = 0): array
{
return CasesModel::where('category_id', $article['category_id'])
->where('visible', 1)
->where('recommend', 1)
->when($exceptId > 0, function ($q) use ($exceptId) {
$q->where('id', '<>', $exceptId);
})
->order('sort', 'desc')
->order('id', 'desc')
->limit($num)
->select()->toArray();
}
//文章列表接口,获取栏目下文章列表
public function getList()
{
$categoryId = input('category_id/d', 0);
$page = input('page/d', 1);
$size = input('size/d', 10);
if ($categoryId <= 0) {
return $this->json(1, '参数错误');
}
$category = Category::getById($categoryId);
if (empty($category)) {
return $this->json(2, '栏目不存在');
}
$items = CasesModel::findListByWhere(["category_id" => $categoryId], $page, $size);
foreach ($items as $item) {
$item['image'] = $this->isMobile ? $item['image_mobile'] : $item['image'];
}
return $this->json(0, 'ok', $items);
}
}

158
app/controller/manager/Cases.php Executable file
View File

@ -0,0 +1,158 @@
<?php
namespace app\controller\manager;
use app\validate\CasesValidate;
use app\model\{CasesModel, Category as MCategory, Log as MLog, System};
use think\exception\ValidateException;
use think\response\Json;
use think\response\View;
/**
* 案例
* Class Cases
* @package app\controller\manager
*/
class Cases extends Base
{
/**
* @return Json|View
*/
public function add()
{
if (request()->isPost()) {
$images = input('img_images/a');
$params = input('post.item/a', []);
$params['image'] = input('img');
$params['image_mobile'] = input('img_mobile');
$params['images'] = json_encode($images, JSON_UNESCAPED_UNICODE);
try {
validate(CasesValidate::class)->check($params);
$newItem = CasesModel::create($params);
MLog::write('cases', 'add', '新增案例ID:'.$newItem->id);
} catch (ValidateException $e) {
return $this->json(1, $e->getError());
}
return $this->json();
} else {
$categoryId = input('category_id/d', 0);
$category = MCategory::getById($categoryId);
$this->getImgSize($categoryId);
$this->data['category'] = $category;
return $this->view();
}
}
/**
* @return Json|View
*/
public function edit()
{
$id = input('param.id/d', 0);
$item = CasesModel::getById($id);
if (count($item) == 0) {
return $this->json(1, '该案例不存在');
}
if (request()->isPost()) {
$params = input('post.item/a', []);
$params['image'] = input('img');
$params['image_mobile'] = input('img_mobile');
$params['images'] = json_encode(array_values(input('img_images/a', [])), JSON_UNESCAPED_UNICODE);
try {
validate(CasesValidate::class)->check($params);
CasesModel::updateById($id, $params);
MLog::write('honour', 'edit', '修改案例ID:'.$id);
} catch (ValidateException $e) {
return $this->json(2, $e->getError());
}
return $this->json();
} else {
$category = MCategory::getById($item['category_id']);
$this->getImgSize($item['category_id']);
$this->data['item'] = $item;
$this->data['category'] = $category;
return $this->view();
}
}
public function sort()
{
if (request()->isPost()) {
$id = input('post.id/d');
$sort = input('post.sort');
$num = input('post.num/d', 1);
if ($num <= 0) {
$num = 1;
}
if (!in_array($sort, ['up', 'down'], true)) {
return $this->json(2, '参数错误');
}
$item = CasesModel::getById($id);
if (empty($item)) {
return $this->json(3, '该案例不存在');
}
if ($sort == 'up') {
$where = "category_id='{$item['category_id']}' and sort < {$item['sort']}";
$order = "sort desc";
} else {
$where = "category_id='{$item['category_id']}' and sort > {$item['sort']}";
$order = "sort asc";
}
$forSortItems = CasesModel::getListByWhereAndOrder($where, $order, $num);
if (!empty($forSortItems)) {
$updateData = [];
$forSortCount = count($forSortItems);
for ($i = 0; $i < $forSortCount; $i++) {
if ($i == 0) {
$updateData[] = [
'id' => $forSortItems[$i]['id'],
'sort' => $item['sort']
];
} else {
$updateData[] = [
'id' => $forSortItems[$i]['id'],
'sort' => $forSortItems[$i - 1]['sort']
];
}
}
$updateData[] = [
'id' => $item['id'],
'sort' => $forSortItems[$i - 1]['sort']
];
if (!empty($updateData)) {
$model = new CasesModel();
$model->saveAll($updateData);
$sortStr = $sort == 'up' ? '上移' : '下调';
MLog::write('cases', 'sort', "案例排序ID{$id} {$sortStr}{$num}");
return $this->json();
}
}
return $this->json(4, '无须调整排序!');
}
return $this->json(1, '无此操作');
}
// 删除
public function del()
{
if (request()->isPost()) {
$historyId = input('param.id/d', 0);
$item = CasesModel::getById($historyId);
if (count($item) == 0) {
return $this->json(2, '该案例不存在');
}
try {
CasesModel::destroy($historyId);
MLog::write('cases', 'del', '删除案例ID:'.$historyId);
} catch (\Exception $e) {
return $this->json(3, '删除失败,'.$e->getMessage());
}
return $this->json();
}
return $this->json(1, '无此操作');
}
}

View File

@ -2,7 +2,7 @@
namespace app\controller\manager; namespace app\controller\manager;
use app\model\{Category, Article, Block, DownloadModel, Log, History, Honour, PositionModel, ProductModel}; use app\model\{CasesModel, Category, Article, Block, DownloadModel, Log, History, Honour, PositionModel, ProductModel};
class Content extends Base class Content extends Base
{ {
@ -255,4 +255,19 @@ class Content extends Base
$this->data['items'] = PositionModel::getPaginateList($categoryId, 20, false); $this->data['items'] = PositionModel::getPaginateList($categoryId, 20, false);
return $this->view(); return $this->view();
} }
// 案例
public function cases()
{
$categoryId = input('param.category_id/d', 0);
$category = Category::getById($categoryId);
if (empty($category)) {
return $this->redirect(url('manager.content/index'));
}
$this->data['categoryId'] = $categoryId;
$this->data['category'] = $category;
$this->data['items'] = CasesModel::getPaginateList($categoryId, 20, false);
return $this->view();
}
} }

122
app/model/CasesModel.php Executable file
View File

@ -0,0 +1,122 @@
<?php
namespace app\model;
use think\Paginator;
class CasesModel extends Base
{
protected $name = 'cases';
public static function onAfterInsert($item)
{
$item->sort = $item->id;
$item->save();
}
public static function getPaginateList($categoryId, $per = 20, $isSample = false)
{
$paginate = [
'list_rows' => $per,
'query' => ['category_id' => $categoryId]
];
return self::where('category_id', $categoryId)->order('sort', 'desc')->paginate($paginate, $isSample);
}
public static function getByCategoryId($categoryId, $onlyVisible = false, $pre = 50)
{
$items = self::where('category_id', $categoryId)
->when($onlyVisible, function($query){
$query->where('visible', 1);
})
->order('sort', 'asc')
->limit($pre)
->select();
return $items->toArray();
}
public static function getByParentId($parentId, $onlyVisible = false, $pre = 50): array
{
$categoryIds = Category::where('parent_id', $parentId)->column('id');
return self::whereIn('category_id', $categoryIds)
->when($onlyVisible, function($query){
$query->where('visible', 1);
})
->order('sort', 'asc')
->limit($pre)
->select()->toArray();
}
/**
* 获取列表
* @param int $categoryId 分类ID
* @param int $per 每页数量
* @param string $keyword 关键词
* @param array $param 类型:置顶、热门、推荐 ['top','hot','recommend']
* @param int $status 状态,-1表示不限制
* @param array $orderList 排序
* @param bool $onlyChild 仅获取下级 默认true false=获取所有后代分类
* @return Paginator
*/
public static function getList(int $categoryId, int $per = 20, string $keyword = '', array $param = [], int $status = -1, array $orderList = ['a.sort' => 'desc'], bool $onlyChild = true, array $queryParam = [])
{
$whereMap = [];
if (is_numeric($categoryId) && $categoryId > 0) {
$children = Category::getChildrenByParentId($categoryId, $onlyChild);
if (!empty($children)) {
$categoryIds = [$categoryId];
foreach ($children as $child) {
if ($child['model_id'] == Model::MODEL_PRODUCT) {
$categoryIds[] = $child['id'];
}
}
$whereMap[] = ['a.category_id', 'in', $categoryIds];
} else {
$whereMap[] = ['a.category_id', '=', $categoryId];
}
}
if (!empty($keyword)) {
$whereMap[] = ['a.title', 'like', '%'.$keyword.'%'];
$pageParam['keyword'] = $keyword;
}
if (is_array($param) && count($param) > 0) {
$pageParam['param'] = $param;
foreach ($param as $vo) {
if (in_array($vo, ['top', 'hot', 'recommend'], true)) {
$whereMap[] = ["a.{$vo}", '=', 1];
}
}
}
$paginate = [
'list_rows' => $per,
'query' => $queryParam
];
return self::alias('a')
->leftJoin('category c', 'c.id = a.category_id')
->when(count($whereMap) > 0, function ($query) use ($whereMap) {
$query->where($whereMap);
})
->when($status != -1, function ($query) use ($status) {
$query->where('a.visible', $status);
})
->order($orderList)
->field('a.*, c.title as category_title')
->paginate($paginate, false);
}
public static function findListByWhere(array $where, int $page = 1, int $size = 10, callable $call = null, array $sortList = ['sort' => 'desc'])
{
$q = new static();
$q = $q->where($where);
if ($call) {
$q = $call($q);
}
if ($size > 0) {
$q = $q->page($page, $size);
}
if (count($sortList)) {
$q = $q->order($sortList);
}
return $q->select();
}
}

18
app/validate/CasesValidate.php Executable file
View File

@ -0,0 +1,18 @@
<?php
namespace app\validate;
use think\Validate;
class CasesValidate extends Validate
{
protected $rule = [
'title' => 'require|length:1,60',
'visible' => 'require|in:0,1',
];
protected $message = [
'title.require' => '标题不能为空',
'visible.require' => '状态必须设置',
'visible.in' => '状态参数错误',
];
}

View File

@ -23,6 +23,7 @@ Route::get('/activity/:id', "article/detail")->pattern(['id' => '\d+']);
Route::get('/news/:id', "article/detail")->pattern(['id' => '\d+']); Route::get('/news/:id', "article/detail")->pattern(['id' => '\d+']);
Route::get('/service/:id', "article/detail")->pattern(['id' => '\d+']); Route::get('/service/:id', "article/detail")->pattern(['id' => '\d+']);
Route::get('/market/:id', "article/detail")->pattern(['id' => '\d+']); Route::get('/market/:id', "article/detail")->pattern(['id' => '\d+']);
Route::get('/cases/:id', "cases/detail")->pattern(['id' => '\d+']);
Route::get('/product/detail/:id', "product/detail")->pattern(['id' => '\d+']); Route::get('/product/detail/:id', "product/detail")->pattern(['id' => '\d+']);
Route::rule('articles/ajaxlist', 'article/ajaxList', 'GET|POST'); Route::rule('articles/ajaxlist', 'article/ajaxList', 'GET|POST');
Route::get('articles/:category_id', "article/index"); Route::get('articles/:category_id', "article/index");

70
view/cases/detail.html Executable file
View File

@ -0,0 +1,70 @@
{layout name="layout" /}
{php}
use app\model\Category;
$childrenMenu = Category::getChildrenByParentId($topCategoryId);
{/php}
{include file="public/about_second" /}
<!-- 简介 -->
<div class="pull-section pull-profile-bg wow fadeInUp">
<div class="company-profile company-culture flex w1360">
<div class="txt">
<div class="profile-title culture-title project-detail-title" style="margin-bottom: 10px;">
<strong class="wow fadeInUp" data-wow-duration="0.8s" data-wow-delay="0">{$item.title}</strong>
</div>
<div class="profile-info culture-info red-property-info wow fadeInUp" data-wow-duration="0.8s" data-wow-delay="0">
<p>入驻时间:{$item.check_in}</p>
<p>建成时间:{$item.built_at}</p>
<p>小区面积:{$item.area}</p>
<p>住户人员:{$item.household}</p>
<p>项目概述:</p>
<p style="text-indent: 2em;">{$item.content|raw}</p>
</div>
</div>
<div class="img scale-img wow fadeInUp" data-wow-duration="0.8s" data-wow-delay="0">
<img src="{$isMobile ? $item.image_mobile : $item.image}" alt="{$item.title}">
</div>
</div>
</div>
<!-- 项目展示 -->
<div class="pull-section pull-content-bg bg-col-f5 wow fadeInUp">
<div class="profile-title culture-title honor-title">
<p class="capitalize font-helvetica color-blue wow fadeInUp" data-wow-duration="0.8s" data-wow-delay="0">Project Display</p>
<strong class="wow fadeInUp" data-wow-duration="0.8s" data-wow-delay="0.2s">项目展示</strong>
</div>
<!-- 项目内容 -->
<div class="rich-txt rich-txt-market project-detail bg-col-white w1360 wow fadeInUp" data-wow-duration="0.8s" data-wow-delay="0">
<!-- 简介 -->
<!-- 图集 -->
<div class="market-atlas wow fadeInUp" data-wow-duration="0.8s" data-wow-delay="0">
<div class="img wow fadeInUp" data-wow-duration="0.8s" data-wow-delay="0">
{foreach $images as $image}
<img src="{$image.src ?? ''}" style="padding-top: 5px;" alt="{$item.title}">
{/foreach}
</div>
</div>
</div>
<!-- 推荐项目 -->
<div class="project-flag wow fadeInUp" data-wow-duration="0.8s" data-wow-delay="0">
{if count($recommendList) > 0}
<div class="title w1360 wow fadeInUp" data-wow-duration="0.8s" data-wow-delay="0.2s">推荐项目</div>
<div class="project-case-list red-property-case flex w1360">
{foreach $recommendList as $recommend}
<a href="/cases/{$recommend.id}.html" class="wow fadeInUp" data-wow-duration="0.8s" data-wow-delay="0">
<div class="img"><img src="{$isMobile ? $recommend['image_mobile'] : $recommend['image']}" alt="{$recommend.title}"></div>
<div class="info bg-col-white">
<div class="txt flex">
<p class="clips1">{$recommend.title}</p>
<span>+</span>
</div>
<p class="color-66 clips2">{$recommend.description}</p>
</div>
</a>
{/foreach}
</div>
{/if}
</div>
</div>

67
view/cases/index.html Executable file
View File

@ -0,0 +1,67 @@
{layout name="layout" /}
<!-- 轮播图 -->
<div class="pull-banner w100">
<img src="{$category.src ?: '__STATIC__/images/banner/banner-solution.jpg'}" alt="{$category.title ?? ''}banner">
<div class="pull-banner-title w1360">
<h2>{$category.title ?? ''}</h2>
<p>{$category.description ?? ''}</p>
<span><a href="/">首页</a> / <a href="/product.html">{$category.title ?? ''}</a> /{$secondInfo.title ?? ''}</span>
</div>
</div>
<!-- 二级导航 -->
<div class="pull-nav pull-nav-other w1360 wow fadeInUp" data-wow-duration=".8s" data-wow-delay="0">
<div class="pull-nav-bg">
<div class="pull-nav-swiper swiper">
<div class="swiper-wrapper">
{foreach $secondMenus as $second}
<div class="swiper-slide">
<a href="/product.html?second={$second.id ?? 0}" {if $secondInfo.id == $second.id}class="active"{/if}>{$second.title ?? ''}</a>
<ins></ins>
</div>
{/foreach}
</div>
</div>
<div class="swiper-button-prev"></div>
<div class="swiper-button-next"></div>
</div>
</div>
<!-- 三级分类 -->
<div class="pull-nav-three w1360 wow fadeInUp" data-wow-duration=".8s" data-wow-delay="0">
<div class="nav-three-bg">
<span>类别筛选</span>
<div class="nav-three-swiper swiper">
<div class="swiper-wrapper">
<div class="swiper-slide">
<a href="/product.html?second={$secondInfo.id ?? 0}" {if $thirdId == 0}class="active"{/if}>全部</a>
</div>
{foreach $thirdMenus as $third}
<div class="swiper-slide">
<a href="/product.html?second={$secondInfo.id ?? 0}&third={$third.id ?? 0}" {if $thirdId == $third.id}class="active"{/if}>{$third.title ?? ''}</a>
</div>
{/foreach}
</div>
</div>
</div>
</div>
<!-- 主体内容 -->
<div class="pull-content w1360 wow fadeInUp" data-wow-duration=".8s" data-wow-delay="0">
<div class="product w1360 wow fadeInUp" data-wow-duration=".8s" data-wow-delay="0">
{if count($items) <= 0}
<div style="text-align: center;padding-top: 10px;">没有内容</div>
{else /}
<ul class="product-list">
{foreach $items as $item}
<li class="wow fadeInUp" data-wow-duration=".8s" data-wow-delay="0">
<a href="/product/detail.html?id={$item.id}">
<h2> {$item.title ?? ''} </h2>
<p class="clips3">{$item.description ?? ''}</p>
</a>
</li>
{/foreach}
</ul>
{/if}
</div>
</div>
{$items->render('', 'class="page-list-bg w1360 wow fadeInUp" data-wow-duration=".8s" data-wow-delay="0"')|raw}

115
view/manager/cases/add.html Executable file
View File

@ -0,0 +1,115 @@
<div class="layui-card layui-col-md12">
<div class="layui-card-body">
<form class="layui-form" data-action="{:url('manager.cases/add')}">
<input type="hidden" name="__token__" value="{$_token}" />
<strong style="color: #f20000; font-size: 12px; display: block; line-height: 1;">注意*号为必填选项!</strong>
<hr style="margin: 20px 0;">
<div class="layui-form-itemBox3 between">
<div class="layui-form-item">
<label class="layui-form-label">标题<em>*</em></label>
<div class="layui-input-block">
<input class="layui-input" type="text" name="item[title]" maxlength="60" value="{$item.title ?? ''}" />
</div>
</div>
<div class="layui-form-item"><div class="layui-form-mid layui-word-aux">标题请勿超过60个字符</div></div>
</div>
<div class="layui-form-itemBox3 between">
<div class="layui-form-item">
<label class="layui-form-label">描述</label>
<div class="layui-input-block">
<textarea name="item[description]" class="layui-textarea"></textarea>
</div>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">封面图</label>
<div class="layui-input-block">
{:widget('manager.upload/image',['imgSize' => $coverSize])}
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">封面图-手机端</label>
<div class="layui-input-block">
{:widget('manager.upload/image',['imgSize' => $mobileCoverSize, 'append' => '_mobile'])}
</div>
</div>
<div class="layui-form-itemBox3 between">
<div class="layui-form-item">
<label class="layui-form-label">入住时间</label>
<div class="layui-input-block">
<input class="layui-input" type="text" name="item[check_in]" maxlength="60" value="{$item.check_in ?? ''}" placeholder="入住时间"/>
</div>
</div>
</div>
<div class="layui-form-itemBox3 between">
<div class="layui-form-item">
<label class="layui-form-label">建成时间</label>
<div class="layui-input-block">
<input class="layui-input" type="text" name="item[built_at]" maxlength="60" value="{$item.built_at ?? ''}" placeholder="建成时间"/>
</div>
</div>
</div>
<div class="layui-form-itemBox3 between">
<div class="layui-form-item">
<label class="layui-form-label">小区面积</label>
<div class="layui-input-block">
<input class="layui-input" type="text" name="item[area]" maxlength="60" value="{$item.area ?? ''}" placeholder="小区面积"/>
</div>
</div>
</div>
<div class="layui-form-itemBox3 between">
<div class="layui-form-item">
<label class="layui-form-label">住户人员</label>
<div class="layui-input-block">
<input class="layui-input" type="text" name="item[household]" maxlength="60" value="{$item.household ?? ''}" placeholder="住户人员 如 2562户"/>
</div>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">推荐</label>
<div class="layui-inline new-inline">
<input type="radio" name="item[recommend]" value="0" title="否" checked/>
<input type="radio" name="item[recommend]" value="1" title="是" />
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">状态</label>
<div class="layui-inline new-inline">
<input type="radio" name="item[visible]" value="0" title="隐藏" />
<input type="radio" name="item[visible]" value="1" title="正常" checked />
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">项目概述</label>
<div class="layui-input-block editor-text">
<textarea name="item[content]" class="layui-textarea tinymce-editor"></textarea>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">项目展示组图</label>
<div class="layui-input-block">
{:widget('manager.upload/multi',['append' => '_images','imgs' => $item.images??'', 'num' => 100, 'imgSize' => '1235px*0px', 'fields' => false])}
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label"></label>
<div class="layui-inline">
<button type="button" class="layui-btn layui-btn-normal" lay-submit lay-filter="submitAll">保存</button>
</div>
</div>
<input type="hidden" class="layui-input" name="item[category_id]" value="{$category.id}" />
</form>
</div>
</div>

114
view/manager/cases/edit.html Executable file
View File

@ -0,0 +1,114 @@
<div class="layui-card layui-col-md12">
<div class="layui-card-body">
<form class="layui-form" data-action="{:url('manager.cases/edit')}">
<input type="hidden" name="__token__" value="{$_token}" />
<strong style="color: #f20000; font-size: 12px; display: block; line-height: 1;">注意*号为必填选项!</strong>
<hr style="margin: 20px 0;">
<div class="layui-form-itemBox3 between">
<div class="layui-form-item">
<label class="layui-form-label">标题<em>*</em></label>
<div class="layui-input-block">
<input class="layui-input" type="text" name="item[title]" maxlength="60" value="{$item.title}" />
</div>
</div>
<div class="layui-form-item"><div class="layui-form-mid layui-word-aux">标题请勿超过60个字符</div></div>
</div>
<div class="layui-form-itemBox3 between">
<div class="layui-form-item">
<label class="layui-form-label">描述</label>
<div class="layui-input-block">
<textarea name="item[description]" class="layui-textarea">{$item.description}</textarea>
</div>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">封面图</label>
<div class="layui-input-block">
{:widget('manager.upload/image',['src' => $item.image??'', 'imgSize' => $coverSize])}
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">封面图-手机端</label>
<div class="layui-input-block">
{:widget('manager.upload/image',['src' => $item.image_mobile??'', 'imgSize' => $mobileCoverSize, 'append'=>'_mobile'])}
</div>
</div>
<div class="layui-form-itemBox3 between">
<div class="layui-form-item">
<label class="layui-form-label">入住时间</label>
<div class="layui-input-block">
<input class="layui-input" type="text" name="item[check_in]" maxlength="60" value="{$item.check_in ?? ''}" placeholder="入住时间"/>
</div>
</div>
</div>
<div class="layui-form-itemBox3 between">
<div class="layui-form-item">
<label class="layui-form-label">建成时间</label>
<div class="layui-input-block">
<input class="layui-input" type="text" name="item[built_at]" maxlength="60" value="{$item.built_at ?? ''}" placeholder="建成时间"/>
</div>
</div>
</div>
<div class="layui-form-itemBox3 between">
<div class="layui-form-item">
<label class="layui-form-label">小区面积</label>
<div class="layui-input-block">
<input class="layui-input" type="text" name="item[area]" maxlength="60" value="{$item.area ?? ''}" placeholder="小区面积"/>
</div>
</div>
</div>
<div class="layui-form-itemBox3 between">
<div class="layui-form-item">
<label class="layui-form-label">住户人员</label>
<div class="layui-input-block">
<input class="layui-input" type="text" name="item[household]" maxlength="60" value="{$item.household ?? ''}" placeholder="住户人员 如 2562户"/>
</div>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">推荐</label>
<div class="layui-inline new-inline">
<input type="radio" name="item[recommend]" value="0" title="否" {if $item.recommend == 0} checked {/if} />
<input type="radio" name="item[recommend]" value="1" title="是" {if $item.recommend == 1} checked {/if} />
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">状态</label>
<div class="layui-inline new-inline">
<input type="radio" name="item[visible]" value="0" title="隐藏" {if $item.visible == 0} checked {/if} />
<input type="radio" name="item[visible]" value="1" title="正常" {if $item.visible == 1} checked {/if} />
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">项目概述</label>
<div class="layui-input-block editor-text">
<textarea name="item[content]" class="layui-textarea tinymce-editor">{$item.content??''}</textarea>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">项目展示组图</label>
<div class="layui-input-block">
{:widget('manager.upload/multi',['append' => '_images','imgs' => $item.images??'', 'num' => $category.num??10, 'imgSize' => '1235px*0px', 'fields' => false])}
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label"></label>
<div class="layui-inline">
<button type="button" class="layui-btn layui-btn-normal" lay-submit lay-filter="submitAll">保存</button>
</div>
</div>
<input type="hidden" class="layui-input" name="id" value="{$item.id}" />
</form>
</div>
</div>

78
view/manager/content/cases.html Executable file
View File

@ -0,0 +1,78 @@
{layout name="manager/layout" /}
{php}
use app\service\Image as CImage;
use app\model\Category as VCategory;
{/php}
<div class="layui-card layui-col-md12">
<div class="layui-card-body">
<div class="layui-col-xs12 between-center">
<div class="layui-inline">
<a id="add-article" class="layui-btn layui-btn-normal" data-href="{:url('manager.cases/add',['category_id'=>$category['id']])}" title="添加案例" data-width="1000"><i class="layui-icon layui-icon-add-1"></i>添加案例</a>
</div>
</div>
<div class="layui-clear"></div>
<hr style="margin: 20px 0;">
{empty name="items"}
无记录
{else /}
<table class="layui-table">
<colgroup>
<col >
<col width="75px">
<col width="75px">
<col width="75px">
<col width="75px">
<col width="410px">
</colgroup>
<thead>
<tr>
<td>标题</td>
<td>封面</td>
<td>封面图-手机</td>
<td>状态</td>
<td>推荐</td>
<td>操作</td>
</tr>
</thead>
{foreach $items as $item}
<tbody class="table-lv1" data-id="{$item.id}" data-url="{:url('manager.cases/sort')}">
<tr>
<td>{$item.title}</td>
<td class="layer-photos">
{if !empty($item['image']) && file_exists('.' . $item['image'])}
<img src="{:CImage::getThumb($item.image, 50, 50)}" layer-src="{$item.image}" width="50" />
{/if}
</td>
<td class="layer-photos">
{if !empty($item['image_mobile']) && file_exists('.' . $item['image_mobile'])}
<img src="{:CImage::getThumb($item.image_mobile, 50, 50)}" layer-src="{$item.image_mobile}" width="50" />
{/if}
</td>
<td>{:$item.visible == 0 ? '<span class="text-warning">隐藏</span>' : '<span class="text-green">正常</span>'}</td>
<td>{$item.recommend == 0 ? '否' : '是'}</td>
<td >
<a class="sort layui-btn layui-btn-primary layui-btn-xs" data-id="{$item.id}" data-sort="up" data-url="{:url('manager.cases/sort')}" href="javascript:void(0);">
<i class=""></i>向上
</a>
<a class="sort layui-btn layui-btn-primary layui-btn-xs" data-id="{$item.id}" data-sort="down" data-url="{:url('manager.cases/sort')}" href="javascript:void(0);">
<i class=""></i>向下
</a>
<a data-href="{:url('manager.cases/edit',['id' => $item['id']])}" class="layui-btn layui-btn-warm layui-btn-xs" title="编辑">
<i class=""></i>编辑
</a>
<a class="del layui-btn layui-btn-danger layui-btn-xs" data-id="{$item.id}" data-url="{:url('manager.cases/del')}" href="javascript:void(0);" >
<i class=""></i>删除
</a>
</td>
</tr>
</tbody>
{/foreach}
</table>
<div class="page top30">{$items->render()|raw}</div>
{/empty}
</div>
</div>

View File

@ -149,7 +149,7 @@ use app\service\Image as WImage;
if(data.data.length > 0){ if(data.data.length > 0){
html += '<div class="layui-card-body"><div class="serverImgsList"><ul id="selectable">' html += '<div class="layui-card-body"><div class="serverImgsList"><ul id="selectable">'
$.each(data.data,function(i,item){ $.each(data.data,function(i,item){
html += '<li><img src="'+item.src+'" data-box="upload_img_list{$append}" data-append="{$append}" onclick="imgListUrl(this, ' + numid + ')"></li>' html += '<li><img src="'+item.src+'" data-box="upload_img_list{$append}" data-append="{$append}" data-field="{:json_encode($fields)}" onclick="imgListUrl(this, ' + numid + ')"></li>'
}) })
html += '</ul></div>'; html += '</ul></div>';
if(data.data.length >= 30){ if(data.data.length >= 30){
@ -186,20 +186,24 @@ use app\service\Image as WImage;
}); });
}); });
function imgListUrl(obj, numid){ function imgListUrl(obj, numid){
console.log(obj,'obj')
let append = $(obj).data('append'); let append = $(obj).data('append');
let fields = $(obj).data('fields');
let fieldsHtml = '';
$.each(fields, function (index, item) {
fieldsHtml += `<input type="text" class="layui-input" name="img${append}[${numid}][${item.name}]" value="${item.name}" placeholder="${item.desc}" />`;
})
var imTpl = '<dd class="item_img" id="img_' + numid +'">'+ var imTpl = '<dd class="item_img" id="img_' + numid +'">'+
'<div class="imgs"><div class="operate"><i onclick="UPLOAD_IMG_DEL(this)" class="close layui-icon"></i></div>'+ '<div class="imgs"><div class="operate"><i onclick="UPLOAD_IMG_DEL(this)" class="close layui-icon"></i></div>'+
'<img src="' + $(obj).attr('src') +'"></div>'+ '<img src="' + $(obj).attr('src') +'"></div>'+
'<div class="info">'+ '<div class="info">'+
'<textarea name="img'+append+'['+numid+'][title]" class="layui-textarea" placeholder="标题"></textarea>' + fieldsHtml+
'<textarea name="img'+append+'['+numid+'][desc]" class="layui-textarea" placeholder="描述"></textarea>' + // '<textarea name="img'+append+'['+numid+'][title]" class="layui-textarea" placeholder="标题"></textarea>' +
'<input type="text" class="layui-input" name="img'+append+'['+numid+'][alt]" value="" placeholder="ALT属性选填" />'+ // '<textarea name="img'+append+'['+numid+'][desc]" class="layui-textarea" placeholder="描述"></textarea>' +
'<input type="text" class="layui-input" name="img'+append+'['+numid+'][link]" value="" placeholder="链接,选填" />'+ // '<input type="text" class="layui-input" name="img'+append+'['+numid+'][alt]" value="" placeholder="ALT属性选填" />'+
// '<input type="text" class="layui-input" name="img'+append+'['+numid+'][link]" value="" placeholder="链接,选填" />'+
// '<input type="text" class="layui-input" name="img'+append+'['+numid+'][taskId]" value="" placeholder="taskId选填" />'+ // '<input type="text" class="layui-input" name="img'+append+'['+numid+'][taskId]" value="" placeholder="taskId选填" />'+
'<input type="hidden" name="img'+append+'['+numid+'][src]" value="' + $(obj).attr('src') + '" />' + '<input type="hidden" name="img'+append+'['+numid+'][src]" value="' + $(obj).attr('src') + '" />' +
'</div></dd>'; '</div></dd>';
console.log(imTpl,'html');
numid++; numid++;
$('#'+$(obj).attr('data-box')).append(imTpl); $('#'+$(obj).attr('data-box')).append(imTpl);
parent.layer.close($(obj).attr('data-id')); parent.layer.close($(obj).attr('data-id'));

94
view/page/caseslist.html Executable file
View File

@ -0,0 +1,94 @@
{layout name="layout"/}
{php}
use app\model\Category;
use app\model\CasesModel;
$childrenMenu = Category::getChildrenByParentId($topCategoryId);
$items = CasesModel::getByParentId($category['id'],true,$category['number'] ?: 6);
{/php}
{include file="public/about_second" /}
<!-- 简介 -->
<div class="pull-section pull-profile-bg wow fadeInUp">
<div class="company-profile company-culture flex w1360">
<div class="txt">
<div class="profile-title culture-title project-title">
<p class="capitalize font-helvetica color-blue wow fadeInUp" data-wow-duration="0.8s" data-wow-delay="0">{$blocks['item_title']['value']}</p>
<strong class="wow fadeInUp" data-wow-duration="0.8s" data-wow-delay="0.2s">{$blocks['item_title']['title']}</strong>
</div>
<div class="profile-info culture-info wow fadeInUp" data-wow-duration="0.8s" data-wow-delay="0">
{$blocks['item_info']['value']|raw}
</div>
</div>
<div class="img scale-img wow fadeInUp" data-wow-duration="0.8s" data-wow-delay="0">
<img src="{$isMobile ? $blocks['item_info_img_mobile']['value'] : $blocks['item_info_img_pc']['value']}" alt="{$blocks['item_title']['title']}">
</div>
</div>
</div>
<!-- 内容 -->
<div class="pull-section pull-content-bg bg-col-f5 wow fadeInUp" data-wow-duration="0.8s" data-wow-delay="0">
<div class="profile-title culture-title honor-title">
<p class="capitalize font-helvetica color-blue wow fadeInUp" data-wow-duration="0.8s" data-wow-delay="0">{$blocks['case_list_title']['value']}</p>
<strong class="wow fadeInUp" data-wow-duration="0.8s" data-wow-delay="0.2s">{$blocks['case_list_title']['title']}</strong>
</div>
<div class="project-case-list red-property-case flex w1360">
{foreach $items as $item}
<a href="/cases/{$item.id}.html" class="wow fadeInUp" data-wow-duration="0.8s" data-wow-delay="0">
<div class="img"><img src="{$isMobile ? $item['image'] : $item['image_mobile']}" alt="{$item.title}"></div>
<div class="info bg-col-white">
<div class="txt flex">
<p class="clips1">{$item.title}</p>
<span>+</span>
</div>
<p class="color-66 clips2">{$item.description}</p>
</div>
</a>
{/foreach}
</div>
<div style="text-align: center;margin-top: 15px;display: none" class="show-msg">没有更多了</div>
<!-- 加载更多 -->
<div class="red-property-more w1360">
<div class="get-more-cases load-more-news bg-col-white color-blue" data-href="/cases/getList?category_id={$category['id']}" data-page="2" data-size="{$category['number'] ?? 6}">点击加载更多</div>
</div>
</div>
<script>
$('body').on('click', '.get-more-cases', function () {
let that = $(this);
let url = that.data('href');
let page = that.data('page');
let size = that.data('size');
$.post(url, {page: page, size: size}, function (res) {
if (res.code === 0) {
if (!res.data || res.data.length <= 0) {
$('.show-msg').show();
setTimeout(function () {
$('.show-msg').hide();
}, 2000)
return false;
}
let html = '';
$.each(res.data, function (index, item) {
html += `
<a href="/cases/${item.id}.html" class="wow fadeInUp" data-wow-duration="0.8s" data-wow-delay="0">
<div class="img"><img src="${item.image}" alt="${item.title}"></div>
<div class="info bg-col-white">
<div class="txt flex">
<p class="clips1">${item.title}</p>
<span>+</span>
</div>
<p class="color-66 clips2">${item.description}</p>
</div>
</a>
`;
})
page++;
that.data('page', page)
$('.show-msg').before(html);
return false;
}
})
})
</script>

View File

@ -15,7 +15,7 @@
<a href="{$path['route'] ?? 'javascript:;'}">{$path['title'] ?? ''}</a> <a href="{$path['route'] ?? 'javascript:;'}">{$path['title'] ?? ''}</a>
{/if} {/if}
{/foreach} {/foreach}
{if !in_array($category['id'],[39,40,41]) && $Request.Action != 'index'} {if !in_array($category['id'],[33,34,39,40,41]) && $Request.Action != 'index'}
<a href="{$category['route'] ?? 'javascript:;'}">{$category['title'] ?? ''}</a> <a href="{$category['route'] ?? 'javascript:;'}">{$category['title'] ?? ''}</a>
{elseif $Request.Action == 'index'} {elseif $Request.Action == 'index'}
{$category['title'] ?? ''} {$category['title'] ?? ''}