更新网站架构
227
app/admin/controller/Cms/Domain/DomainPoolController.php
Normal file
@ -0,0 +1,227 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace app\admin\controller\Cms\Domain;
|
||||
|
||||
use app\admin\BaseController;
|
||||
use think\facade\Db;
|
||||
use think\Request;
|
||||
use app\model\System\SystemDomainPool;
|
||||
|
||||
/**
|
||||
* 主域名池管理控制器
|
||||
*/
|
||||
class DomainPoolController extends BaseController
|
||||
{
|
||||
/**
|
||||
* 获取域名池列表
|
||||
*/
|
||||
public function index(Request $request)
|
||||
{
|
||||
$page = $request->param('page', 1, 'int');
|
||||
$pageSize = $request->param('pageSize', 10, 'int');
|
||||
$mainDomain = $request->param('main_domain', '');
|
||||
$status = $request->param('status', '');
|
||||
|
||||
$where = [['delete_time', '=', null]];
|
||||
|
||||
if ($mainDomain) {
|
||||
$where[] = ['main_domain', 'like', "%$mainDomain%"];
|
||||
}
|
||||
if ($status !== '' && $status !== null) {
|
||||
$where[] = ['status', '=', $status];
|
||||
}
|
||||
|
||||
$list = SystemDomainPool::where($where)
|
||||
->page($page, $pageSize)
|
||||
->order('id', 'desc')
|
||||
->select()
|
||||
->toArray();
|
||||
|
||||
$total = SystemDomainPool::where($where)
|
||||
->count();
|
||||
|
||||
return json([
|
||||
'code' => 200,
|
||||
'msg' => 'success',
|
||||
'data' => [
|
||||
'list' => $list,
|
||||
'total' => $total
|
||||
]
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取启用状态的主域名列表(供租户选择)
|
||||
*/
|
||||
public function getEnabledDomains()
|
||||
{
|
||||
$list = SystemDomainPool::where('status', 1)
|
||||
->where('delete_time', null)
|
||||
->select()
|
||||
->toArray();
|
||||
|
||||
return json([
|
||||
'code' => 200,
|
||||
'msg' => 'success',
|
||||
'data' => $list
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建主域名
|
||||
*/
|
||||
public function create(Request $request)
|
||||
{
|
||||
$mainDomain = $request->param('main_domain', '');
|
||||
|
||||
if (empty($mainDomain)) {
|
||||
return json([
|
||||
'code' => 400,
|
||||
'msg' => '主域名不能为空'
|
||||
]);
|
||||
}
|
||||
|
||||
// 检查域名是否已存在
|
||||
$exists = SystemDomainPool::where('main_domain', $mainDomain)
|
||||
->where('delete_time', null)
|
||||
->find();
|
||||
|
||||
if ($exists) {
|
||||
return json([
|
||||
'code' => 400,
|
||||
'msg' => '该域名已存在'
|
||||
]);
|
||||
}
|
||||
|
||||
$now = date('Y-m-d H:i:s');
|
||||
$id = SystemDomainPool::insertGetId([
|
||||
'main_domain' => $mainDomain,
|
||||
'status' => 1,
|
||||
'create_time' => $now,
|
||||
'update_time' => $now
|
||||
]);
|
||||
|
||||
return json([
|
||||
'code' => 200,
|
||||
'msg' => '创建成功',
|
||||
'data' => ['id' => $id]
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑主域名
|
||||
*/
|
||||
public function update(Request $request)
|
||||
{
|
||||
$id = $request->param('id', 0, 'int');
|
||||
$mainDomain = $request->param('main_domain', '');
|
||||
$status = $request->param('status', null);
|
||||
|
||||
if ($id <= 0) {
|
||||
return json([
|
||||
'code' => 400,
|
||||
'msg' => '参数错误'
|
||||
]);
|
||||
}
|
||||
|
||||
if (empty($mainDomain)) {
|
||||
return json([
|
||||
'code' => 400,
|
||||
'msg' => '主域名不能为空'
|
||||
]);
|
||||
}
|
||||
|
||||
// 检查域名是否与其他记录重复
|
||||
$exists = SystemDomainPool::where('main_domain', $mainDomain)
|
||||
->where('id', '<>', $id)
|
||||
->where('delete_time', null)
|
||||
->find();
|
||||
|
||||
if ($exists) {
|
||||
return json([
|
||||
'code' => 400,
|
||||
'msg' => '该域名已存在'
|
||||
]);
|
||||
}
|
||||
|
||||
$data = [
|
||||
'main_domain' => $mainDomain,
|
||||
'update_time' => date('Y-m-d H:i:s')
|
||||
];
|
||||
|
||||
if ($status !== null) {
|
||||
$data['status'] = $status;
|
||||
}
|
||||
|
||||
SystemDomainPool::where('id', $id)->update($data);
|
||||
|
||||
return json([
|
||||
'code' => 200,
|
||||
'msg' => '更新成功'
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除主域名(软删除)
|
||||
*/
|
||||
public function delete($id)
|
||||
{
|
||||
if ($id <= 0) {
|
||||
return json([
|
||||
'code' => 400,
|
||||
'msg' => '参数错误'
|
||||
]);
|
||||
}
|
||||
|
||||
SystemDomainPool::where('id', $id)
|
||||
->update([
|
||||
'delete_time' => date('Y-m-d H:i:s')
|
||||
]);
|
||||
|
||||
return json([
|
||||
'code' => 200,
|
||||
'msg' => '删除成功'
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 切换主域名状态
|
||||
*/
|
||||
public function toggleStatus(Request $request)
|
||||
{
|
||||
$id = $request->param('id', 0, 'int');
|
||||
|
||||
if ($id <= 0) {
|
||||
return json([
|
||||
'code' => 400,
|
||||
'msg' => '参数错误'
|
||||
]);
|
||||
}
|
||||
|
||||
$domain = SystemDomainPool::where('id', $id)
|
||||
->find();
|
||||
|
||||
if (!$domain) {
|
||||
return json([
|
||||
'code' => 404,
|
||||
'msg' => '域名不存在'
|
||||
]);
|
||||
}
|
||||
|
||||
$newStatus = $domain['status'] == 1 ? 0 : 1;
|
||||
|
||||
SystemDomainPool::where('id', $id)
|
||||
->update([
|
||||
'status' => $newStatus,
|
||||
'update_time' => date('Y-m-d H:i:s')
|
||||
]);
|
||||
|
||||
return json([
|
||||
'code' => 200,
|
||||
'msg' => '状态更新成功',
|
||||
'data' => ['status' => $newStatus]
|
||||
]);
|
||||
}
|
||||
}
|
||||
311
app/admin/controller/Cms/Domain/TenantDomainController.php
Normal file
@ -0,0 +1,311 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace app\admin\controller\Cms\Domain;
|
||||
|
||||
use app\admin\BaseController;
|
||||
use think\facade\Db;
|
||||
use think\Request;
|
||||
use think\facade\Session;
|
||||
|
||||
/**
|
||||
* 租户域名绑定控制器
|
||||
*/
|
||||
class TenantDomainController extends BaseController
|
||||
{
|
||||
/**
|
||||
* 获取租户域名列表(管理员查看所有)
|
||||
*/
|
||||
public function index(Request $request)
|
||||
{
|
||||
$page = $request->param('page', 1, 'int');
|
||||
$pageSize = $request->param('pageSize', 10, 'int');
|
||||
$tenantId = $request->param('tenant_id', 0, 'int');
|
||||
$status = $request->param('status', '');
|
||||
$subDomain = $request->param('sub_domain', '');
|
||||
|
||||
$where = [['delete_time', '=', null]];
|
||||
|
||||
if ($tenantId > 0) {
|
||||
$where[] = ['tenant_id', '=', $tenantId];
|
||||
}
|
||||
if ($status !== '' && $status !== null) {
|
||||
$where[] = ['status', '=', $status];
|
||||
}
|
||||
if ($subDomain) {
|
||||
$where[] = ['sub_domain', 'like', "%$subDomain%"];
|
||||
}
|
||||
|
||||
$list = Db::name('mete_tenant_domain')
|
||||
->where($where)
|
||||
->page($page, $pageSize)
|
||||
->order('id', 'desc')
|
||||
->select()
|
||||
->toArray();
|
||||
|
||||
$total = Db::name('mete_tenant_domain')
|
||||
->where($where)
|
||||
->count();
|
||||
|
||||
// 获取租户名称
|
||||
$tenantIds = array_column($list, 'tenant_id');
|
||||
$tenants = [];
|
||||
if ($tenantIds) {
|
||||
$tenantList = Db::name('mete_tenant')
|
||||
->whereIn('id', $tenantIds)
|
||||
->select()
|
||||
->toArray();
|
||||
$tenants = array_column($tenantList, null, 'id');
|
||||
}
|
||||
|
||||
// 附加租户名称
|
||||
foreach ($list as &$item) {
|
||||
$item['tenant_name'] = $tenants[$item['tenant_id']]['tenant_name'] ?? '';
|
||||
}
|
||||
|
||||
return json([
|
||||
'code' => 200,
|
||||
'msg' => 'success',
|
||||
'data' => [
|
||||
'list' => $list,
|
||||
'total' => $total
|
||||
]
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前租户的域名列表(租户端)
|
||||
*/
|
||||
public function myDomains(Request $request)
|
||||
{
|
||||
$tid = $request->param('tid', 0, 'int');
|
||||
|
||||
if ($tid <= 0) {
|
||||
return json([
|
||||
'code' => 400,
|
||||
'msg' => '租户ID不能为空'
|
||||
]);
|
||||
}
|
||||
|
||||
$list = Db::name('mete_tenant_domain')
|
||||
->where('tenant_id', $tid)
|
||||
->where('delete_time', null)
|
||||
->order('id', 'desc')
|
||||
->select()
|
||||
->toArray();
|
||||
|
||||
return json([
|
||||
'code' => 200,
|
||||
'msg' => 'success',
|
||||
'data' => $list
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 租户申请二级域名
|
||||
*/
|
||||
public function apply(Request $request)
|
||||
{
|
||||
$tid = $request->param('tenant_id', 0, 'int');
|
||||
$subDomain = $request->param('sub_domain', '');
|
||||
$mainDomain = $request->param('main_domain', '');
|
||||
|
||||
if ($tid <= 0) {
|
||||
return json([
|
||||
'code' => 400,
|
||||
'msg' => '租户ID不能为空'
|
||||
]);
|
||||
}
|
||||
|
||||
if (empty($subDomain)) {
|
||||
return json([
|
||||
'code' => 400,
|
||||
'msg' => '二级域名前缀不能为空'
|
||||
]);
|
||||
}
|
||||
|
||||
if (empty($mainDomain)) {
|
||||
return json([
|
||||
'code' => 400,
|
||||
'msg' => '请选择主域名'
|
||||
]);
|
||||
}
|
||||
|
||||
// 验证域名格式(只能包含字母、数字、连字符)
|
||||
if (!preg_match('/^[a-zA-Z0-9][a-zA-Z0-9-]{0,61}[a-zA-Z0-9]$/', $subDomain)) {
|
||||
return json([
|
||||
'code' => 400,
|
||||
'msg' => '二级域名前缀格式不正确'
|
||||
]);
|
||||
}
|
||||
|
||||
// 检查主域名是否存在且启用
|
||||
$mainDomainInfo = Db::name('mete_system_domain_pool')
|
||||
->where('main_domain', $mainDomain)
|
||||
->where('status', 1)
|
||||
->where('delete_time', null)
|
||||
->find();
|
||||
|
||||
if (!$mainDomainInfo) {
|
||||
return json([
|
||||
'code' => 400,
|
||||
'msg' => '主域名不存在或已禁用'
|
||||
]);
|
||||
}
|
||||
|
||||
// 检查二级域名是否已被使用
|
||||
$exists = Db::name('mete_tenant_domain')
|
||||
->where('sub_domain', $subDomain)
|
||||
->where('main_domain', $mainDomain)
|
||||
->where('delete_time', null)
|
||||
->find();
|
||||
|
||||
if ($exists) {
|
||||
return json([
|
||||
'code' => 400,
|
||||
'msg' => '该二级域名已被使用'
|
||||
]);
|
||||
}
|
||||
|
||||
$fullDomain = $subDomain . '.' . $mainDomain;
|
||||
$now = date('Y-m-d H:i:s');
|
||||
|
||||
$id = Db::name('mete_tenant_domain')->insertGetId([
|
||||
'tenant_id' => $tid,
|
||||
'sub_domain' => $subDomain,
|
||||
'main_domain' => $mainDomain,
|
||||
'full_domain' => $fullDomain,
|
||||
'status' => 0, // 审核中
|
||||
'create_time' => $now,
|
||||
'update_time' => $now
|
||||
]);
|
||||
|
||||
return json([
|
||||
'code' => 200,
|
||||
'msg' => '申请提交成功,等待审核',
|
||||
'data' => ['id' => $id]
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 审核租户域名(通过/拒绝)
|
||||
*/
|
||||
public function audit(Request $request)
|
||||
{
|
||||
$id = $request->param('id', 0, 'int');
|
||||
$action = $request->param('action', ''); // 'approve' 或 'reject'
|
||||
|
||||
if ($id <= 0) {
|
||||
return json([
|
||||
'code' => 400,
|
||||
'msg' => '参数错误'
|
||||
]);
|
||||
}
|
||||
|
||||
$domain = Db::name('mete_tenant_domain')
|
||||
->where('id', $id)
|
||||
->find();
|
||||
|
||||
if (!$domain) {
|
||||
return json([
|
||||
'code' => 404,
|
||||
'msg' => '域名不存在'
|
||||
]);
|
||||
}
|
||||
|
||||
if ($domain['status'] != 0) {
|
||||
return json([
|
||||
'code' => 400,
|
||||
'msg' => '该域名已审核过了'
|
||||
]);
|
||||
}
|
||||
|
||||
$newStatus = $action === 'approve' ? 1 : 2; // 1-已生效 2-已拒绝
|
||||
|
||||
Db::name('mete_tenant_domain')
|
||||
->where('id', $id)
|
||||
->update([
|
||||
'status' => $newStatus,
|
||||
'update_time' => date('Y-m-d H:i:s')
|
||||
]);
|
||||
|
||||
$msg = $action === 'approve' ? '审核通过' : '已拒绝';
|
||||
|
||||
return json([
|
||||
'code' => 200,
|
||||
'msg' => $msg
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 禁用/启用租户域名
|
||||
*/
|
||||
public function toggleStatus(Request $request)
|
||||
{
|
||||
$id = $request->param('id', 0, 'int');
|
||||
|
||||
if ($id <= 0) {
|
||||
return json([
|
||||
'code' => 400,
|
||||
'msg' => '参数错误'
|
||||
]);
|
||||
}
|
||||
|
||||
$domain = Db::name('mete_tenant_domain')
|
||||
->where('id', $id)
|
||||
->find();
|
||||
|
||||
if (!$domain) {
|
||||
return json([
|
||||
'code' => 404,
|
||||
'msg' => '域名不存在'
|
||||
]);
|
||||
}
|
||||
|
||||
// 只有已生效的域名才能被禁用
|
||||
if ($domain['status'] != 1) {
|
||||
return json([
|
||||
'code' => 400,
|
||||
'msg' => '只有已生效的域名才能被禁用'
|
||||
]);
|
||||
}
|
||||
|
||||
// 切换为禁用状态
|
||||
Db::name('mete_tenant_domain')
|
||||
->where('id', $id)
|
||||
->update([
|
||||
'status' => 2,
|
||||
'update_time' => date('Y-m-d H:i:s')
|
||||
]);
|
||||
|
||||
return json([
|
||||
'code' => 200,
|
||||
'msg' => '已禁用'
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除租户域名(软删除)
|
||||
*/
|
||||
public function delete($id)
|
||||
{
|
||||
if ($id <= 0) {
|
||||
return json([
|
||||
'code' => 400,
|
||||
'msg' => '参数错误'
|
||||
]);
|
||||
}
|
||||
|
||||
Db::name('mete_tenant_domain')
|
||||
->where('id', $id)
|
||||
->update([
|
||||
'delete_time' => date('Y-m-d H:i:s')
|
||||
]);
|
||||
|
||||
return json([
|
||||
'code' => 200,
|
||||
'msg' => '删除成功'
|
||||
]);
|
||||
}
|
||||
}
|
||||
@ -2,7 +2,7 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace app\admin\controller;
|
||||
namespace app\admin\controller\Cms\Theme;
|
||||
|
||||
use app\admin\BaseController;
|
||||
use app\service\ThemeService;
|
||||
@ -20,14 +20,18 @@ class ThemeController extends BaseController
|
||||
$this->themeService = new ThemeService();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 获取模板列表(后台管理)
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$tid = Request::get('tid', 0, 'int');
|
||||
|
||||
$themes = $this->themeService->getThemeList();
|
||||
$currentTheme = $this->themeService->getCurrentTheme();
|
||||
$currentTheme = $this->themeService->getCurrentTheme($tid);
|
||||
|
||||
return json([
|
||||
'code' => 200,
|
||||
@ -45,6 +49,7 @@ class ThemeController extends BaseController
|
||||
*/
|
||||
public function switch()
|
||||
{
|
||||
$tid = Request::post('tid', 0, 'int');
|
||||
$themeKey = Request::post('theme_key', '');
|
||||
|
||||
if (empty($themeKey)) {
|
||||
@ -54,7 +59,7 @@ class ThemeController extends BaseController
|
||||
]);
|
||||
}
|
||||
|
||||
$result = $this->themeService->switchTheme($themeKey);
|
||||
$result = $this->themeService->switchTheme($tid, $themeKey);
|
||||
|
||||
if ($result) {
|
||||
return json([
|
||||
@ -75,9 +80,10 @@ class ThemeController extends BaseController
|
||||
*/
|
||||
public function getData()
|
||||
{
|
||||
$tid = Request::get('tid', 0, 'int');
|
||||
$themeKey = Request::get('theme_key', '');
|
||||
|
||||
$themeData = $this->themeService->getThemeData($themeKey ?: null);
|
||||
$themeData = $this->themeService->getThemeData($tid, $themeKey ?: null);
|
||||
|
||||
return json([
|
||||
'code' => 200,
|
||||
@ -92,6 +98,7 @@ class ThemeController extends BaseController
|
||||
*/
|
||||
public function saveData()
|
||||
{
|
||||
$tid = Request::post('tid', 0, 'int');
|
||||
$themeKey = Request::post('theme_key', '');
|
||||
$fieldKey = Request::post('field_key', '');
|
||||
$fieldValue = Request::post('field_value', '');
|
||||
@ -103,7 +110,7 @@ class ThemeController extends BaseController
|
||||
]);
|
||||
}
|
||||
|
||||
$result = $this->themeService->saveThemeField($themeKey, $fieldKey, $fieldValue);
|
||||
$result = $this->themeService->saveThemeField($tid, $themeKey, $fieldKey, $fieldValue);
|
||||
|
||||
if ($result) {
|
||||
return json([
|
||||
@ -13,6 +13,8 @@ use think\db\exception\DbException;
|
||||
use think\Request;
|
||||
use app\model\Tenant\Tenant;
|
||||
use app\model\AdminUser;
|
||||
use app\model\Template\TemplateSiteConfig;
|
||||
use app\model\Template\TemplateSiteConfig;
|
||||
|
||||
class TenantController extends BaseController
|
||||
{
|
||||
@ -64,6 +66,9 @@ class TenantController extends BaseController
|
||||
$data = $this->request->post();
|
||||
$tenant = Tenant::create($data);
|
||||
if ($tenant) {
|
||||
// 创建租户默认数据
|
||||
$this->createTenantDefaultData($tenant->id);
|
||||
|
||||
return json([
|
||||
'code' => 200,
|
||||
'msg' => '创建成功',
|
||||
@ -76,6 +81,24 @@ class TenantController extends BaseController
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建租户默认数据
|
||||
* @param int $tenantId 租户ID
|
||||
*/
|
||||
private function createTenantDefaultData(int $tenantId)
|
||||
{
|
||||
$now = date('Y-m-d H:i:s');
|
||||
|
||||
// 创建租户默认模板配置
|
||||
TemplateSiteConfig::create([
|
||||
'tid' => $tenantId,
|
||||
'key' => 'current_theme',
|
||||
'value' => 'default',
|
||||
'create_time' => $now,
|
||||
'update_time' => $now
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑租户
|
||||
|
||||
22
app/admin/route/routes/domain.php
Normal file
@ -0,0 +1,22 @@
|
||||
<?php
|
||||
use think\facade\Route;
|
||||
|
||||
// 主域名池管理路由
|
||||
Route::group('domain/pool', function () {
|
||||
Route::get('index', 'app\admin\controller\Cms\Domain\DomainPoolController/index');
|
||||
Route::get('getEnabledDomains', 'app\admin\controller\Cms\Domain\DomainPoolController/getEnabledDomains');
|
||||
Route::post('create', 'app\admin\controller\Cms\Domain\DomainPoolController/create');
|
||||
Route::post('update', 'app\admin\controller\Cms\Domain\DomainPoolController/update');
|
||||
Route::delete('delete/:id', 'app\admin\controller\Cms\Domain\DomainPoolController/delete');
|
||||
Route::post('toggleStatus', 'app\admin\controller\Cms\Domain\DomainPoolController/toggleStatus');
|
||||
});
|
||||
|
||||
// 租户域名绑定路由
|
||||
Route::group('domain/tenant', function () {
|
||||
Route::get('index', 'app\admin\controller\Cms\Domain\TenantDomainController/index');
|
||||
Route::get('myDomains', 'app\admin\controller\Cms\Domain\TenantDomainController/myDomains');
|
||||
Route::post('apply', 'app\admin\controller\Cms\Domain\TenantDomainController/apply');
|
||||
Route::post('audit', 'app\admin\controller\Cms\Domain\TenantDomainController/audit');
|
||||
Route::post('toggleStatus', 'app\admin\controller\Cms\Domain\TenantDomainController/toggleStatus');
|
||||
Route::delete('delete/:id', 'app\admin\controller\Cms\Domain\TenantDomainController/delete');
|
||||
});
|
||||
@ -2,7 +2,7 @@
|
||||
use think\facade\Route;
|
||||
|
||||
// 模板管理路由
|
||||
Route::get('theme', 'app\admin\controller\ThemeController@index');
|
||||
Route::post('theme/switch', 'app\admin\controller\ThemeController@switch');
|
||||
Route::get('theme/data', 'app\admin\controller\ThemeController@getData');
|
||||
Route::post('theme/data', 'app\admin\controller\ThemeController@saveData');
|
||||
Route::get('theme', 'app\admin\controller\Cms\Theme\ThemeController@index');
|
||||
Route::post('theme/switch', 'app\admin\controller\Cms\Theme\ThemeController@switch');
|
||||
Route::get('theme/data', 'app\admin\controller\Cms\Theme\ThemeController@getData');
|
||||
Route::post('theme/data', 'app\admin\controller\Cms\Theme\ThemeController@saveData');
|
||||
|
||||
56
app/common/middleware/DomainParse.php
Normal file
@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace app\common\middleware;
|
||||
|
||||
use think\facade\Db;
|
||||
use think\Request;
|
||||
|
||||
/**
|
||||
* 域名解析中间件
|
||||
* 通过访问域名自动识别租户
|
||||
*/
|
||||
class DomainParse
|
||||
{
|
||||
public function handle(Request $request, \Closure $next)
|
||||
{
|
||||
$host = $request->host(true); // 获取完整域名,不带端口
|
||||
|
||||
// 排除后台域名和平台官网域名
|
||||
$adminDomains = ['admin.xxx.com']; // TODO: 配置后台域名
|
||||
$platformDomains = ['www.xxx.com', 'xxx.com']; // TODO: 配置平台官网域名
|
||||
|
||||
if (in_array($host, $adminDomains) || in_array($host, $platformDomains)) {
|
||||
return $next($request);
|
||||
}
|
||||
|
||||
// 解析二级域名
|
||||
$domainParts = explode('.', $host);
|
||||
|
||||
// 至少需要三级域名(如 sub.domain.com)
|
||||
if (count($domainParts) < 3) {
|
||||
return $next($request);
|
||||
}
|
||||
|
||||
$subDomain = $domainParts[0];
|
||||
$mainDomain = implode('.', array_slice($domainParts, 1));
|
||||
|
||||
// 查询租户域名绑定记录
|
||||
$tenantDomain = Db::name('mete_tenant_domain')
|
||||
->where('full_domain', $host)
|
||||
->where('status', 1) // 只有已生效的域名才能访问
|
||||
->where('delete_time', null)
|
||||
->find();
|
||||
|
||||
if ($tenantDomain) {
|
||||
// 将租户ID写入请求对象,供后续控制器使用
|
||||
$request->tenantId = $tenantDomain['tenant_id'];
|
||||
|
||||
// 同时写入header,方便前端获取
|
||||
$request->header['X-Tenant-Id', $tenantDomain['tenant_id']);
|
||||
}
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
}
|
||||
@ -12,6 +12,8 @@ use app\model\System\SystemSiteSettings;
|
||||
use app\service\ThemeService;
|
||||
use think\db\exception\DbException;
|
||||
use think\facade\Env;
|
||||
use think\facade\Request;
|
||||
use app\model\Template\TemplateSiteConfig;
|
||||
|
||||
class Index extends BaseController
|
||||
{
|
||||
@ -33,16 +35,34 @@ class Index extends BaseController
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
// 直接返回默认模板数据
|
||||
// 获取租户ID(从请求参数)
|
||||
$tid = Request::param('tid', 0, 'int');
|
||||
|
||||
// 从TemplateSiteConfig获取配置(根据租户ID)
|
||||
$config = null;
|
||||
if ($tid > 0) {
|
||||
$config = TemplateSiteConfig::where('tid', $tid)
|
||||
->where('key', 'current_theme')
|
||||
->find();
|
||||
}
|
||||
|
||||
$themeKey = $config['value'] ?? 'default';
|
||||
|
||||
// 模板路径:/themes/{theme_key}/,优先使用index.php,其次index.html
|
||||
$themeBasePath = root_path() . 'public' . DIRECTORY_SEPARATOR . 'themes' . DIRECTORY_SEPARATOR . $themeKey;
|
||||
|
||||
if (is_file($themeBasePath . DIRECTORY_SEPARATOR . 'index.php')) {
|
||||
$themePath = '/themes/' . $themeKey . '/index.php';
|
||||
} else {
|
||||
$themePath = '/themes/' . $themeKey . '/index.html';
|
||||
}
|
||||
|
||||
return json([
|
||||
'code' => 200,
|
||||
'msg' => 'success',
|
||||
'data' => [
|
||||
'theme_key' => 'default',
|
||||
'theme_path' => '/themes/default/index.html',
|
||||
'data' => [
|
||||
'site_name' => '企业官网'
|
||||
]
|
||||
'theme_key' => $themeKey,
|
||||
'theme_path' => $themePath
|
||||
]
|
||||
]);
|
||||
}
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
<?php
|
||||
return [
|
||||
\app\common\middleware\AllowCrossDomain::class,
|
||||
\app\common\middleware\DomainParse::class,
|
||||
\think\middleware\SessionInit::class,
|
||||
];
|
||||
37
app/model/System/SystemDomainPool.php
Normal file
@ -0,0 +1,37 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006-2018 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: Liu21st <liu21st@gmail.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace app\model\System;
|
||||
|
||||
use think\Model;
|
||||
use think\model\concern\SoftDelete;
|
||||
|
||||
/**
|
||||
* 系统域名池模型
|
||||
*/
|
||||
class SystemDomainPool extends Model
|
||||
{
|
||||
|
||||
// 数据库表名
|
||||
protected $name = 'mete_system_domain_pool';
|
||||
|
||||
// 字段类型转换
|
||||
protected $type = [
|
||||
'id' => 'integer',
|
||||
'main_domain' => 'string',
|
||||
'status' => 'integer',
|
||||
'create_time' => 'datetime',
|
||||
'update_time' => 'datetime',
|
||||
'delete_time' => 'datetime',
|
||||
];
|
||||
|
||||
|
||||
}
|
||||
25
app/model/Template/TemplateSiteConfig.php
Normal file
@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace app\model\Template;
|
||||
|
||||
use think\Model;
|
||||
use think\model\concern\SoftDelete;
|
||||
|
||||
class TemplateSiteConfig extends Model
|
||||
{
|
||||
use SoftDelete;
|
||||
|
||||
protected $name = 'mete_template_site_config';
|
||||
|
||||
protected $type = [
|
||||
'id' => 'integer',
|
||||
'tid' => 'integer',
|
||||
'key' => 'string',
|
||||
'value' => 'string',
|
||||
'create_time' => 'datetime',
|
||||
'update_time' => 'datetime',
|
||||
'delete_time' => 'datetime',
|
||||
];
|
||||
}
|
||||
25
app/model/Template/TemplateThemeData.php
Normal file
@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace app\model\Template;
|
||||
|
||||
use think\Model;
|
||||
use think\model\concern\SoftDelete;
|
||||
|
||||
class TemplateThemeData extends Model
|
||||
{
|
||||
use SoftDelete;
|
||||
|
||||
protected $name = 'mete_template_theme_data';
|
||||
|
||||
protected $type = [
|
||||
'id' => 'integer',
|
||||
'theme_key' => 'string',
|
||||
'field_key' => 'string',
|
||||
'field_value' => 'string',
|
||||
'create_time' => 'datetime',
|
||||
'update_time' => 'datetime',
|
||||
'delete_time' => 'datetime',
|
||||
];
|
||||
}
|
||||
36
app/model/Tenant/TenantDomain.php
Normal file
@ -0,0 +1,36 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006-2018 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: Liu21st <liu21st@gmail.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace app\model\Tenant;
|
||||
|
||||
use think\Model;
|
||||
|
||||
/**
|
||||
* 租户域名模型
|
||||
*/
|
||||
class TenantDomain extends Model
|
||||
{
|
||||
// 数据库表名
|
||||
protected $name = 'mete_tenant_domain';
|
||||
|
||||
// 字段类型转换
|
||||
protected $type = [
|
||||
'id' => 'integer',
|
||||
'tenant_id' => 'integer',
|
||||
'sub_domain' => 'string',
|
||||
'main_domain' => 'string',
|
||||
'full_domain' => 'string',
|
||||
'status' => 'integer',
|
||||
'create_time' => 'datetime',
|
||||
'update_time' => 'datetime',
|
||||
'delete_time' => 'datetime',
|
||||
];
|
||||
}
|
||||
@ -67,7 +67,8 @@ class ThemeService
|
||||
}
|
||||
|
||||
$fullPath = $this->themesPath . DIRECTORY_SEPARATOR . $item;
|
||||
if (is_dir($fullPath) && is_file($fullPath . DIRECTORY_SEPARATOR . 'index.html')) {
|
||||
// 检查是否有 index.html 或 index.php
|
||||
if (is_dir($fullPath) && (is_file($fullPath . DIRECTORY_SEPARATOR . 'index.html') || is_file($fullPath . DIRECTORY_SEPARATOR . 'index.php'))) {
|
||||
$dirs[] = $item;
|
||||
}
|
||||
}
|
||||
@ -114,14 +115,18 @@ class ThemeService
|
||||
|
||||
/**
|
||||
* 获取当前激活的模板Key
|
||||
* @param int $tid 租户ID
|
||||
* @return string
|
||||
*/
|
||||
public function getCurrentTheme(): string
|
||||
public function getCurrentTheme(int $tid = 0): string
|
||||
{
|
||||
try {
|
||||
$where = [['key', '=', 'current_theme'], ['delete_time', '=', null]];
|
||||
if ($tid > 0) {
|
||||
$where[] = ['tid', '=', $tid];
|
||||
}
|
||||
$config = Db::name('mete_template_site_config')
|
||||
->where('key', 'current_theme')
|
||||
->where('delete_time', null)
|
||||
->where($where)
|
||||
->find();
|
||||
return $config['value'] ?? 'default';
|
||||
} catch (\Exception $e) {
|
||||
@ -131,10 +136,11 @@ class ThemeService
|
||||
|
||||
/**
|
||||
* 切换当前模板
|
||||
* @param int $tid 租户ID
|
||||
* @param string $themeKey
|
||||
* @return bool
|
||||
*/
|
||||
public function switchTheme(string $themeKey): bool
|
||||
public function switchTheme(int $tid, string $themeKey): bool
|
||||
{
|
||||
// 验证模板是否存在
|
||||
$themes = $this->getThemeList();
|
||||
@ -152,9 +158,12 @@ class ThemeService
|
||||
|
||||
try {
|
||||
// 查找或创建配置记录
|
||||
$where = [['key', '=', 'current_theme'], ['delete_time', '=', null]];
|
||||
if ($tid > 0) {
|
||||
$where[] = ['tid', '=', $tid];
|
||||
}
|
||||
$config = Db::name('mete_template_site_config')
|
||||
->where('key', 'current_theme')
|
||||
->where('delete_time', null)
|
||||
->where($where)
|
||||
->find();
|
||||
|
||||
$now = date('Y-m-d H:i:s');
|
||||
@ -181,17 +190,21 @@ class ThemeService
|
||||
|
||||
/**
|
||||
* 获取模板数据(用于前端渲染)
|
||||
* @param int $tid 租户ID
|
||||
* @param string|null $themeKey
|
||||
* @return array
|
||||
*/
|
||||
public function getThemeData(?string $themeKey = null): array
|
||||
public function getThemeData(int $tid = 0, ?string $themeKey = null): array
|
||||
{
|
||||
$themeKey = $themeKey ?? $this->getCurrentTheme();
|
||||
$themeKey = $themeKey ?? $this->getCurrentTheme($tid);
|
||||
|
||||
try {
|
||||
$where = [['theme_key', '=', $themeKey], ['delete_time', '=', null]];
|
||||
if ($tid > 0) {
|
||||
$where[] = ['tid', '=', $tid];
|
||||
}
|
||||
$themeData = Db::name('mete_template_theme_data')
|
||||
->where('theme_key', $themeKey)
|
||||
->where('delete_time', null)
|
||||
->where($where)
|
||||
->select()
|
||||
->toArray();
|
||||
|
||||
@ -216,18 +229,25 @@ class ThemeService
|
||||
|
||||
/**
|
||||
* 保存模板字段数据
|
||||
* @param int $tid 租户ID
|
||||
* @param string $themeKey
|
||||
* @param string $fieldKey
|
||||
* @param mixed $fieldValue
|
||||
* @return bool
|
||||
*/
|
||||
public function saveThemeField(string $themeKey, string $fieldKey, $fieldValue): bool
|
||||
public function saveThemeField(int $tid, string $themeKey, string $fieldKey, $fieldValue): bool
|
||||
{
|
||||
try {
|
||||
$where = [
|
||||
['theme_key', '=', $themeKey],
|
||||
['field_key', '=', $fieldKey],
|
||||
['delete_time', '=', null]
|
||||
];
|
||||
if ($tid > 0) {
|
||||
$where[] = ['tid', '=', $tid];
|
||||
}
|
||||
$existing = Db::name('mete_template_theme_data')
|
||||
->where('theme_key', $themeKey)
|
||||
->where('field_key', $fieldKey)
|
||||
->where('delete_time', null)
|
||||
->where($where)
|
||||
->find();
|
||||
|
||||
$value = is_array($fieldValue) ? json_encode($fieldValue, JSON_UNESCAPED_UNICODE) : $fieldValue;
|
||||
@ -242,6 +262,7 @@ class ThemeService
|
||||
]);
|
||||
} else {
|
||||
Db::name('mete_template_theme_data')->insert([
|
||||
'tid' => $tid,
|
||||
'theme_key' => $themeKey,
|
||||
'field_key' => $fieldKey,
|
||||
'field_value' => $value,
|
||||
|
||||
2212
public/themes/default/assets/css/LineIcons.2.0.css
Normal file
3123
public/themes/default/assets/css/animate.css
vendored
Normal file
7
public/themes/default/assets/css/bootstrap-5.0.0-beta1.min.css
vendored
Normal file
1
public/themes/default/assets/css/glightbox.min.css
vendored
Normal file
2394
public/themes/default/assets/css/lindy-uikit.css
Normal file
3
public/themes/default/assets/css/tiny-slider.css
Normal file
@ -0,0 +1,3 @@
|
||||
.tns-outer{padding:0 !important}.tns-outer [hidden]{display:none !important}.tns-outer [aria-controls],.tns-outer [data-action]{cursor:pointer}.tns-slider{-webkit-transition:all 0s;-moz-transition:all 0s;transition:all 0s}.tns-slider>.tns-item{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.tns-horizontal.tns-subpixel{white-space:nowrap}.tns-horizontal.tns-subpixel>.tns-item{display:inline-block;vertical-align:top;white-space:normal}.tns-horizontal.tns-no-subpixel:after{content:'';display:table;clear:both}.tns-horizontal.tns-no-subpixel>.tns-item{float:left}.tns-horizontal.tns-carousel.tns-no-subpixel>.tns-item{margin-right:-100%}.tns-no-calc{position:relative;left:0}.tns-gallery{position:relative;left:0;min-height:1px}.tns-gallery>.tns-item{position:absolute;left:-100%;-webkit-transition:transform 0s, opacity 0s;-moz-transition:transform 0s, opacity 0s;transition:transform 0s, opacity 0s}.tns-gallery>.tns-slide-active{position:relative;left:auto !important}.tns-gallery>.tns-moving{-webkit-transition:all 0.25s;-moz-transition:all 0.25s;transition:all 0.25s}.tns-autowidth{display:inline-block}.tns-lazy-img{-webkit-transition:opacity 0.6s;-moz-transition:opacity 0.6s;transition:opacity 0.6s;opacity:0.6}.tns-lazy-img.tns-complete{opacity:1}.tns-ah{-webkit-transition:height 0s;-moz-transition:height 0s;transition:height 0s}.tns-ovh{overflow:hidden}.tns-visually-hidden{position:absolute;left:-10000em}.tns-transparent{opacity:0;visibility:hidden}.tns-fadeIn{opacity:1;filter:alpha(opacity=100);z-index:0}.tns-normal,.tns-fadeOut{opacity:0;filter:alpha(opacity=0);z-index:-1}.tns-vpfix{white-space:nowrap}.tns-vpfix>div,.tns-vpfix>li{display:inline-block}.tns-t-subp2{margin:0 auto;width:310px;position:relative;height:10px;overflow:hidden}.tns-t-ct{width:2333.3333333%;width:-webkit-calc(100% * 70 / 3);width:-moz-calc(100% * 70 / 3);width:calc(100% * 70 / 3);position:absolute;right:0}.tns-t-ct:after{content:'';display:table;clear:both}.tns-t-ct>div{width:1.4285714%;width:-webkit-calc(100% / 70);width:-moz-calc(100% / 70);width:calc(100% / 70);height:10px;float:left}
|
||||
|
||||
/*# sourceMappingURL=sourcemaps/tiny-slider.css.map */
|
||||
BIN
public/themes/default/assets/fonts/LineIcons.eot
Normal file
1562
public/themes/default/assets/fonts/LineIcons.svg
Normal file
|
After Width: | Height: | Size: 596 KiB |
BIN
public/themes/default/assets/fonts/LineIcons.ttf
Normal file
BIN
public/themes/default/assets/fonts/LineIcons.woff
Normal file
BIN
public/themes/default/assets/fonts/LineIcons.woff2
Normal file
|
After Width: | Height: | Size: 43 KiB |
1
public/themes/default/assets/img/clients/brands.svg
Normal file
|
After Width: | Height: | Size: 26 KiB |
1
public/themes/default/assets/img/favicon.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg fill="none" height="44" viewBox="0 0 45 44" width="45" xmlns="http://www.w3.org/2000/svg"><g fill="#0067f4"><path d="m28.9548 22.4531v-.8684c0-6.4427-2.106-12.74067-6.0912-18.20787-.2052-.27872-.5292-.44488-.8748-.44488s-.6696.16616-.8748.44488c-3.9852 5.4672-6.0912 11.76517-6.0912 18.20787v.8684c-4.9356 2.7068-5.65384 9.0423-5.68084 9.3264-.0324.3001.0702.6003.27.8254.2052.2251.49684.3538.79924.3538h23.139c.3078 0 .5994-.1287.7992-.3538.2052-.2251.3024-.5253.27-.8254-.0162-.2841-.729-6.6196-5.6646-9.3264zm-13.932 2.5835v5.7781h-3.3102c.3618-1.5008 1.2474-4.1004 3.3102-5.7781zm2.16-3.4519c0-5.4993 1.6578-10.8915 4.806-15.68331 3.1482 4.79181 4.806 10.18401 4.806 15.68331v9.23h-9.612zm11.772 9.23v-5.7781c2.052 1.6777 2.9484 4.2773 3.3102 5.7781z"/><path d="m23.112 15.0294h-2.7378c-.594 0-1.08.4824-1.08 1.072s.486 1.072 1.08 1.072h2.7378c.594 0 1.08-.4824 1.08-1.072s-.4806-1.072-1.08-1.072z"/><path d="m18.2088 35.3975c-.594 0-1.08.4824-1.08 1.072v6.0943c0 .5896.486 1.072 1.08 1.072s1.08-.4824 1.08-1.072v-6.0943c0-.5896-.486-1.072-1.08-1.072z"/><path d="m21.9888 35.3975c-.594 0-1.08.4824-1.08 1.072v6.0943c0 .5896.486 1.072 1.08 1.072s1.08-.4824 1.08-1.072v-6.0943c0-.5896-.486-1.072-1.08-1.072z"/><path d="m25.7688 35.3975c-.594 0-1.08.4824-1.08 1.072v6.0943c0 .5896.486 1.072 1.08 1.072s1.08-.4824 1.08-1.072v-6.0943c0-.5896-.4806-1.072-1.08-1.072z"/><path d="m6.4476 16.8733h-1.6038v-1.5919c0-.5896-.486-1.072-1.08-1.072s-1.08.4824-1.08 1.072v1.5919h-1.6038c-.594 0-1.08.4824-1.08 1.072s.486 1.072 1.08 1.072h1.6038v1.5919c0 .5896.486 1.072 1.08 1.072s1.08-.4824 1.08-1.072v-1.5919h1.6038c.594 0 1.08-.4824 1.08-1.072s-.4806-1.072-1.08-1.072z"/><path d="m28.3824 3.92888h.7182v.71288c0 .5896.486 1.072 1.08 1.072s1.08-.4824 1.08-1.072v-.71288h.7182c.594 0 1.08-.4824 1.08-1.072s-.486-1.072-1.08-1.072h-.7182v-.71288c0-.5896-.486-1.072-1.08-1.072s-1.08.4824-1.08 1.072v.71288h-.7182c-.594 0-1.08.4824-1.08 1.072s.4806 1.072 1.08 1.072z"/><path d="m43.1676 10.3073h-2.7432v-2.72291c0-.5896-.486-1.072-1.08-1.072s-1.08.4824-1.08 1.072v2.72291h-2.7432c-.594 0-1.08.4824-1.08 1.072s.486 1.072 1.08 1.072h2.7432v2.7229c0 .5896.486 1.072 1.08 1.072s1.08-.4824 1.08-1.072v-2.7229h2.7432c.594 0 1.08-.4824 1.08-1.072s-.486-1.072-1.08-1.072z"/></g></svg>
|
||||
|
After Width: | Height: | Size: 2.2 KiB |
1
public/themes/default/assets/img/hero/hero-5/hero-bg.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg fill="none" height="767" viewBox="0 0 1440 767" width="1440" xmlns="http://www.w3.org/2000/svg"><path d="m-14.8936 273.223c3.6985-23.916 20.64073-43.806 39.6425-58.829 52.1994-41.35 125.4821-54.514 188.8431-33.939 63.362 20.576 126.106 43.663 143.978 107.78 6.113 21.881 8.527 44.758 16.167 66.152 20.043 56.063 78.466 96.02 138.04 94.405 76.273-2.058 128.14-59.891 191.368-93.277 45.844-24.204 114.163-1.515 139.233 56.119 22.523 51.749-14.13 106.529-25.956 156.132-12.114 50.842 7.818 101.153 49.232 133.123 41.746 32.257 105.13 48.452 156.846 35.797 50.03-12.235 84.13-49.846 122.07-81.861 49.16-41.483 127.43-43.319 187.69-35.443 28.79 3.761 58.22 9.823 86.53 3.407 49.23-11.15 57.18-52.412 57.67-95.776.68-60.09.02-120.202-1.11-180.27-2.24-118.233-6.42-236.444-6.42-354.72131h-1483.8014v281.20131z" fill="#ebf4ff"/><path d="m1524.87 305.304c-22.19 75.665-103.56 116.861-179.92 136.795-49.59 12.943-101.32 20.687-152.17 14.16s-100.97-28.518-134.41-67.325c-29.47-34.204-44.4-79.028-74.01-113.122-41.481-47.811-107.788-68.674-171.105-67.435s-124.552 22.102-183.13 46.151c-33.84 13.895-68.61 29.227-105.196 28.143-43.252-1.284-82.562-25.488-115.317-53.741-32.755-28.23-61.457-61.306-96.847-86.174-96.78-68.055-240.0465-60.0459-328.6549 18.341v-169.09706h1511.8599z" fill="#2f80ed" opacity=".3"/><path d="m623.282 521.593c2.635 9.624 7.264 18.938 13.088 27.169 23.587 33.363 62.144 64.094 105.174 47.412 32.777-12.699 57.183-48.872 70.869-79.891 10.343-23.43 11.561-49.514-2.103-72.059-23.299-38.452-72.375-43.276-109.958-24.713-25.004 12.345-50.428 31.77-68.212 53.342-11.914 14.491-13.398 32.08-8.858 48.74z" fill="#ebf4ff"/><g fill="#2f80ed"><path d="m1234.25 386.58c0-4.47-3.08-7.545-7.55-7.545 4.47 0 7.55-3.075 7.55-7.544 0 4.469 3.08 7.544 7.55 7.544-4.47 0-7.55 3.075-7.55 7.545z"/><path d="m1286.11 440.453c0-4.469-3.07-7.545-7.55-7.545 4.48 0 7.55-3.075 7.55-7.544 0 4.469 3.08 7.544 7.56 7.544-4.45 0-7.56 3.076-7.56 7.545z"/><path d="m1313.64 305.073c0-4.469-3.08-7.544-7.55-7.544 4.47 0 7.55-3.075 7.55-7.545 0 4.47 3.08 7.545 7.55 7.545-4.47 0-7.55 3.075-7.55 7.544z"/><path d="m1101.55 354.875c0-4.469-3.08-7.544-7.56-7.544 4.48 0 7.56-3.075 7.56-7.544 0 4.469 3.07 7.544 7.55 7.544-4.48 0-7.55 3.097-7.55 7.544z"/><path d="m1180.63 270.537c0-4.469-3.08-7.544-7.55-7.544 4.47 0 7.55-3.076 7.55-7.545 0 4.469 3.08 7.545 7.55 7.545-4.47 0-7.55 3.097-7.55 7.544z"/><path d="m1135.52 318.791c0-7.987-5.52-13.496-13.51-13.496 7.99 0 13.51-5.509 13.51-13.496 0 7.987 5.51 13.496 13.51 13.496-7.98 0-13.51 5.509-13.51 13.496z"/><path d="m1250.61 297.529c0-7.987-5.51-13.496-13.51-13.496 8 0 13.51-5.509 13.51-13.496 0 7.987 5.52 13.496 13.51 13.496-7.97 0-13.51 5.509-13.51 13.496z"/><path d="m1293.67 365.252c0-6.128-4.26-10.376-10.39-10.376 6.16 0 10.39-4.248 10.39-10.377 0 6.151 4.25 10.377 10.38 10.377-6.13 0-10.38 4.248-10.38 10.376z"/><path d="m1200.78 324.985c0-5.31-3.67-8.96-8.97-8.96 5.32 0 8.97-3.651 8.97-8.96 0 5.309 3.66 8.96 8.97 8.96-5.29-.022-8.97 3.65-8.97 8.96z"/><path d="m859.646 718.325c0-4.004 2.769-6.77 6.777-6.77-4.008 0-6.777-2.765-6.777-6.77 0 4.005-2.768 6.77-6.777 6.77 4.009 0 6.777 2.766 6.777 6.77z"/><path d="m813.05 766.711c0-4.004 2.768-6.77 6.777-6.77-4.009 0-6.777-2.765-6.777-6.77 0 4.005-2.768 6.77-6.777 6.77 4.009 0 6.777 2.766 6.777 6.77z"/><path d="m788.334 645.116c0-4.005 2.769-6.77 6.777-6.77-4.008 0-6.777-2.766-6.777-6.77 0 4.004-2.768 6.77-6.776 6.77 4.008 0 6.776 2.765 6.776 6.77z"/><path d="m978.861 689.852c0-4.005 2.769-6.771 6.777-6.771-4.008 0-6.777-2.765-6.777-6.77 0 4.005-2.768 6.77-6.776 6.77 4.008 0 6.776 2.766 6.776 6.771z"/><path d="m907.837 614.097c0-4.004 2.769-6.77 6.777-6.77-4.008 0-6.777-2.765-6.777-6.77 0 4.005-2.768 6.77-6.777 6.77 4.009 0 6.777 2.766 6.777 6.77z"/><path d="m948.344 657.438c0-7.168 4.96-12.124 12.136-12.124-7.176 0-12.136-4.956-12.136-12.124 0 7.168-4.961 12.124-12.137 12.124 7.176 0 12.137 4.956 12.137 12.124z"/><path d="m844.941 638.346c0-7.169 4.961-12.124 12.137-12.124-7.176 0-12.137-4.956-12.137-12.125 0 7.169-4.961 12.125-12.136 12.125 7.175 0 12.136 4.955 12.136 12.124z"/><path d="m806.273 699.188c0-5.509 3.809-9.315 9.324-9.315-5.515 0-9.324-3.805-9.324-9.314 0 5.509-3.809 9.314-9.346 9.314 5.537-.022 9.346 3.806 9.346 9.315z"/><path d="m889.699 662.992c0-4.757 3.3-8.054 8.062-8.054-4.762 0-8.062-3.296-8.062-8.053 0 4.757-3.299 8.053-8.061 8.053 4.784 0 8.061 3.297 8.061 8.054z"/></g></svg>
|
||||
|
After Width: | Height: | Size: 4.3 KiB |
|
After Width: | Height: | Size: 22 KiB |
1
public/themes/default/assets/img/logo/logo.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg fill="none" height="43" viewBox="0 0 173 43" width="173" xmlns="http://www.w3.org/2000/svg"><g fill="#2f80ed"><path d="m63.375 37.6-21.6-36c-.5-1.1-1.6-1.6-2.9-1.6-1.1 0-2.1.5-2.9 1.6l-9.3 16.3-4.5-7.2c-.5-1.1-1.6-1.6-2.9-1.6-1.1 0-2.1.5-2.9 1.6l-16 26.9c-.5 1.1-.5 2.4 0 3.5.8 1.1 1.9 1.6 3.2 1.6h57.1c1.3 0 2.4-.5 2.9-1.6.3-1.1.3-2.5-.2-3.5zm-56.8-.3 12.5-21.1 4.5 7.5c.5 1.1 1.6 1.6 2.9 1.6 1.1 0 2.4-.5 2.9-1.6l9.6-16.3 18 29.9z"/><path d="m79.339 14.558-2.646-4.94899h-.196l.49 4.94899v22.442h-3.822v-34.83899h2.156l16.415 22.88299 2.548 4.704h.245l-.539-4.704v-22.34399h3.822v34.83899h-2.156z"/><path d="m104.371 24.75c0-4.1487.914-7.3173 2.744-9.506 1.862-2.2213 4.524-3.332 7.987-3.332 1.829 0 3.413.3103 4.753.931 1.372.588 2.499 1.4537 3.381 2.597.882 1.1107 1.535 2.4663 1.96 4.067.424 1.568.637 3.3157.637 5.243 0 4.1487-.931 7.3337-2.793 9.555-1.83 2.1887-4.476 3.283-7.938 3.283-1.83 0-3.43-.294-4.802-.882-1.34-.6207-2.45-1.4863-3.332-2.597-.882-1.1433-1.536-2.499-1.96-4.067-.425-1.6007-.637-3.3647-.637-5.292zm4.067 0c0 1.2413.114 2.4337.343 3.577.261 1.1433.653 2.1397 1.176 2.989.522.8493 1.208 1.5353 2.058 2.058.849.5227 1.878.784 3.087.784 4.442.0327 6.664-3.1033 6.664-9.408 0-1.274-.131-2.4827-.392-3.626-.229-1.1433-.605-2.1397-1.127-2.989-.523-.8493-1.209-1.519-2.058-2.009-.85-.5227-1.879-.784-3.087-.784-4.443-.0327-6.664 3.1033-6.664 9.408z"/><path d="m138.495 26.857 1.372 4.655h.049l1.225-4.753 5.488-14.259h4.214l-10.437 25.039h-1.666l-10.633-25.039h4.508z"/><path d="m154.686 14.313c1.241-.7513 2.678-1.3067 4.312-1.666 1.666-.3593 3.397-.539 5.194-.539 1.698 0 3.054.2287 4.067.686 1.045.4573 1.829 1.0617 2.352 1.813.555.7187.914 1.519 1.078 2.401.196.882.294 1.764.294 2.646 0 1.96-.049 3.871-.147 5.733s-.147 3.626-.147 5.292c0 1.2087.049 2.352.147 3.43s.277 2.0743.539 2.989h-2.891l-1.029-3.43h-.245c-.294.4573-.67.9147-1.127 1.372-.425.4247-.948.8167-1.568 1.176-.621.3267-1.34.6043-2.156.833-.817.2287-1.748.343-2.793.343-1.046 0-2.026-.1633-2.94-.49-.882-.3267-1.65-.784-2.303-1.372-.654-.6207-1.176-1.3557-1.568-2.205-.36-.8493-.539-1.813-.539-2.891 0-1.4373.294-2.6297.882-3.577.588-.98 1.404-1.7477 2.45-2.303 1.078-.588 2.352-.9963 3.822-1.225 1.502-.2613 3.152-.392 4.949-.392h1.323c.457 0 .914.0327 1.372.098.098-.98.147-1.862.147-2.646 0-1.7967-.36-3.0543-1.078-3.773-.719-.7187-2.026-1.078-3.92-1.078-.556 0-1.16.049-1.813.147-.621.0653-1.274.1797-1.96.343-.654.1307-1.291.3103-1.911.539-.588.196-1.111.4247-1.568.686zm6.958 19.649c.914 0 1.731-.1143 2.45-.343.718-.2613 1.339-.5717 1.862-.931.522-.392.947-.8167 1.274-1.274.359-.4573.62-.8983.784-1.323v-4.067c-.458-.0327-.931-.049-1.421-.049-.458-.0327-.915-.049-1.372-.049-1.013 0-2.009.0653-2.989.196-.948.098-1.797.3103-2.548.637-.719.294-1.307.7187-1.764 1.274-.425.5227-.637 1.1923-.637 2.009 0 1.1433.408 2.0907 1.225 2.842.816.7187 1.862 1.078 3.136 1.078z"/></g></svg>
|
||||
|
After Width: | Height: | Size: 2.8 KiB |
7
public/themes/default/assets/js/bootstrap-5.0.0-beta1.min.js
vendored
Normal file
1
public/themes/default/assets/js/count-up.min.js
vendored
Normal file
@ -0,0 +1 @@
|
||||
function counterUp(t){"use strict";this.defaults={duration:3e3,prepend:"",append:"%",selector:".countup",start:0,end:100,intvalues:!1,interval:100};var e=this;this.upating=!1,this.intervalID=null,this.props={};for(var r in this.defaults)"undefined"!=typeof r&&(e.props[r]=e.defaults[r],t.hasOwnProperty(r)&&e.props.hasOwnProperty(r)&&(e.props[r]=t[r]));this.domelems=document.querySelectorAll(this.props.selector),this.elems=[];var n={};this.domelems.forEach(function(t){n.obj=t;var r=parseInt(t.getAttribute("cup-start"));isNaN(r)?n.start=e.props.start:n.start=r;var p=parseInt(t.getAttribute("cup-end"));isNaN(p)?n.end=e.props.end:n.end=p;var a=parseInt(t.getAttribute("cup-duration"));isNaN(a)?n.duration=e.props.duration:n.duration=a;var s=t.getAttribute("cup-prepend");null==s?n.prepend=e.props.prepend:n.prepend=s;var i=t.getAttribute("cup-append");null==i?n.append=e.props.append:n.append=i;var o=t.getAttribute("cup-intval");null==o?n.intvalues=e.props.intvalues:n.intvalues=o,n.step=(n.end-n.start)/(n.duration/e.props.interval),n.val=n.start,e.elems.push(n),n={}})}counterUp.prototype.start=function(){"use strict";var t=this;this.intervalID=setInterval(function(){t.updating||t.update()},t.props.interval)},counterUp.prototype.update=function(){"use strict";this.updating=!0;var t=!0;this.elems.forEach(function(e){e.val+=e.step,e.val<e.end?(1==e.intvalues?e.obj.innerHTML=e.prepend+Math.floor(e.val).toString()+e.append:e.obj.innerHTML=e.prepend+(Math.round(100*e.val)/100).toString()+e.append,t=!1):e.obj.innerHTML=e.prepend+e.end.toString()+e.append}),1==t&&clearInterval(this.intervalID),this.updating=!1};
|
||||
1
public/themes/default/assets/js/glightbox.min.js
vendored
Normal file
7
public/themes/default/assets/js/imagesloaded.min.js
vendored
Normal file
104
public/themes/default/assets/js/main.js
Normal file
@ -0,0 +1,104 @@
|
||||
|
||||
(function() {
|
||||
|
||||
/* ====================
|
||||
Preloader
|
||||
======================= */
|
||||
window.onload = function () {
|
||||
window.setTimeout(fadeout, 300);
|
||||
}
|
||||
|
||||
function fadeout() {
|
||||
document.querySelector('.preloader').style.opacity = '0';
|
||||
document.querySelector('.preloader').style.display = 'none';
|
||||
}
|
||||
|
||||
// =========== sticky menu
|
||||
window.onscroll = function () {
|
||||
var header_navbar = document.querySelector(".hero-section-wrapper-5 .header");
|
||||
var sticky = header_navbar.offsetTop;
|
||||
|
||||
if (window.pageYOffset > sticky) {
|
||||
header_navbar.classList.add("sticky");
|
||||
} else {
|
||||
header_navbar.classList.remove("sticky");
|
||||
}
|
||||
|
||||
// show or hide the back-top-top button
|
||||
var backToTo = document.querySelector(".scroll-top");
|
||||
if (document.body.scrollTop > 50 || document.documentElement.scrollTop > 50) {
|
||||
backToTo.style.display = "flex";
|
||||
} else {
|
||||
backToTo.style.display = "none";
|
||||
}
|
||||
};
|
||||
|
||||
// header-6 toggler-icon
|
||||
let navbarToggler6 = document.querySelector(".header-6 .navbar-toggler");
|
||||
var navbarCollapse6 = document.querySelector(".header-6 .navbar-collapse");
|
||||
|
||||
document.querySelectorAll(".header-6 .page-scroll").forEach(e =>
|
||||
e.addEventListener("click", () => {
|
||||
navbarToggler6.classList.remove("active");
|
||||
navbarCollapse6.classList.remove('show')
|
||||
})
|
||||
);
|
||||
navbarToggler6.addEventListener('click', function() {
|
||||
navbarToggler6.classList.toggle("active");
|
||||
})
|
||||
|
||||
|
||||
// section menu active
|
||||
function onScroll(event) {
|
||||
var sections = document.querySelectorAll('.page-scroll');
|
||||
var scrollPos = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop;
|
||||
|
||||
for (var i = 0; i < sections.length; i++) {
|
||||
var currLink = sections[i];
|
||||
var val = currLink.getAttribute('href');
|
||||
var refElement = document.querySelector(val);
|
||||
var scrollTopMinus = scrollPos + 73;
|
||||
if (refElement.offsetTop <= scrollTopMinus && (refElement.offsetTop + refElement.offsetHeight > scrollTopMinus)) {
|
||||
document.querySelector('.page-scroll').classList.remove('active');
|
||||
currLink.classList.add('active');
|
||||
} else {
|
||||
currLink.classList.remove('active');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
window.document.addEventListener('scroll', onScroll);
|
||||
|
||||
|
||||
// ===== pricing-style-4 slider
|
||||
tns({
|
||||
container: '.pricing-active',
|
||||
autoplay: false,
|
||||
mouseDrag: true,
|
||||
gutter: 0,
|
||||
nav: false,
|
||||
controls: true,
|
||||
controlsText: [
|
||||
'<i class="lni lni-chevron-left prev"></i>',
|
||||
'<i class="lni lni-chevron-right prev"></i>',
|
||||
],
|
||||
responsive: {
|
||||
0: {
|
||||
items: 1,
|
||||
},
|
||||
768: {
|
||||
items: 2,
|
||||
},
|
||||
992: {
|
||||
items: 1.2,
|
||||
},
|
||||
1200: {
|
||||
items: 2,
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// WOW active
|
||||
new WOW().init();
|
||||
|
||||
})();
|
||||
2
public/themes/default/assets/js/tiny-slider.js
Normal file
3
public/themes/default/assets/js/wow.min.js
vendored
Normal file
@ -1,13 +0,0 @@
|
||||
{
|
||||
"name": "默认模板",
|
||||
"description": "标准企业官网模板,适用于各类企业展示",
|
||||
"version": "1.0.0",
|
||||
"author": "System",
|
||||
"fields": {
|
||||
"site_name": "网站名称",
|
||||
"banner": "轮播图列表",
|
||||
"news": "新闻列表",
|
||||
"solutions": "解决方案",
|
||||
"partners": "合作伙伴"
|
||||
}
|
||||
}
|
||||
@ -1,82 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title data-field="site_name">企业官网</title>
|
||||
<link rel="stylesheet" href="./styles/main.css">
|
||||
</head>
|
||||
<body>
|
||||
<!-- 头部 -->
|
||||
<header class="header">
|
||||
<div class="container">
|
||||
<h1 data-field="site_name">企业官网</h1>
|
||||
<nav class="nav">
|
||||
<a href="/">首页</a>
|
||||
<a href="/news">新闻资讯</a>
|
||||
<a href="/solutions">解决方案</a>
|
||||
<a href="/contact">联系我们</a>
|
||||
</nav>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<!-- 轮播图 -->
|
||||
<section class="banner">
|
||||
<div class="banner-slides">
|
||||
<div class="slide active" data-field="banner">
|
||||
<img src="./images/banner1.jpg" alt="Banner 1">
|
||||
<div class="banner-content">
|
||||
<h2>欢迎来到我们的网站</h2>
|
||||
<p>专业的企业数字化解决方案提供商</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- 新闻资讯 -->
|
||||
<section class="news section">
|
||||
<div class="container">
|
||||
<h2 class="section-title">新闻资讯</h2>
|
||||
<div class="news-list" data-field="news">
|
||||
<div class="news-item">
|
||||
<h3>公司动态</h3>
|
||||
<p>这里是新闻内容...</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- 解决方案 -->
|
||||
<section class="solutions section">
|
||||
<div class="container">
|
||||
<h2 class="section-title">解决方案</h2>
|
||||
<div class="solutions-grid" data-field="solutions">
|
||||
<div class="solution-card">
|
||||
<h3>解决方案一</h3>
|
||||
<p>详细描述...</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- 合作伙伴 -->
|
||||
<section class="partners section">
|
||||
<div class="container">
|
||||
<h2 class="section-title">合作伙伴</h2>
|
||||
<div class="partners-grid" data-field="partners">
|
||||
<div class="partner-logo">Partner Logo</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- 底部 -->
|
||||
<footer class="footer">
|
||||
<div class="container">
|
||||
<p>© 2024 <span data-field="site_name">企业官网</span>. All rights reserved.</p>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<!-- 数据注入脚本 -->
|
||||
<script src="./js/theme-loader.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
527
public/themes/default/index.php
Normal file
@ -0,0 +1,527 @@
|
||||
<!DOCTYPE html>
|
||||
<html class="no-js" lang="">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta http-equiv="x-ua-compatible" content="ie=edge" />
|
||||
<title>Nova - Bootstrap 5 Template</title>
|
||||
<meta name="description" content="" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<!-- Place favicon.ico in the root directory -->
|
||||
|
||||
<!-- ========================= CSS here ========================= -->
|
||||
<link rel="stylesheet" href="assets/css/bootstrap-5.0.0-beta1.min.css" />
|
||||
<link rel="stylesheet" href="assets/css/LineIcons.2.0.css"/>
|
||||
<link rel="stylesheet" href="assets/css/tiny-slider.css"/>
|
||||
<link rel="stylesheet" href="assets/css/animate.css"/>
|
||||
<link rel="stylesheet" href="assets/css/lindy-uikit.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<!--[if lte IE 9]>
|
||||
<p class="browserupgrade">
|
||||
You are using an <strong>outdated</strong> browser. Please
|
||||
<a href="https://browsehappy.com/">upgrade your browser</a> to improve
|
||||
your experience and security.
|
||||
</p>
|
||||
<![endif]-->
|
||||
|
||||
<!-- ========================= preloader start ========================= -->
|
||||
<div class="preloader">
|
||||
<div class="loader">
|
||||
<div class="spinner">
|
||||
<div class="spinner-container">
|
||||
<div class="spinner-rotator">
|
||||
<div class="spinner-left">
|
||||
<div class="spinner-circle"></div>
|
||||
</div>
|
||||
<div class="spinner-right">
|
||||
<div class="spinner-circle"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- ========================= preloader end ========================= -->
|
||||
|
||||
<!-- ========================= hero-section-wrapper-5 start ========================= -->
|
||||
<section id="home" class="hero-section-wrapper-5">
|
||||
|
||||
<!-- ========================= header-6 start ========================= -->
|
||||
<header class="header header-6">
|
||||
<div class="navbar-area">
|
||||
<div class="container">
|
||||
<div class="row align-items-center">
|
||||
<div class="col-lg-12">
|
||||
<nav class="navbar navbar-expand-lg">
|
||||
<a class="navbar-brand" href="index.html">
|
||||
<img src="assets/img/logo/logo.svg" alt="Logo" />
|
||||
</a>
|
||||
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent6" aria-controls="navbarSupportedContent6" aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span class="toggler-icon"></span>
|
||||
<span class="toggler-icon"></span>
|
||||
<span class="toggler-icon"></span>
|
||||
</button>
|
||||
|
||||
<div class="collapse navbar-collapse sub-menu-bar" id="navbarSupportedContent6">
|
||||
<ul id="nav6" class="navbar-nav ms-auto">
|
||||
<li class="nav-item">
|
||||
<a class="page-scroll active" href="#home">Home</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="page-scroll" href="#feature">Feature</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="page-scroll" href="#about">About</a>
|
||||
</li>
|
||||
|
||||
<li class="nav-item">
|
||||
<a class="page-scroll" href="#pricing">Pricing</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="page-scroll" href="#contact">Contact</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="header-action d-flex">
|
||||
<a href="#0"> <i class="lni lni-cart"></i> </a>
|
||||
<a href="#0"> <i class="lni lni-alarm"></i> </a>
|
||||
</div>
|
||||
<!-- navbar collapse -->
|
||||
</nav>
|
||||
<!-- navbar -->
|
||||
</div>
|
||||
</div>
|
||||
<!-- row -->
|
||||
</div>
|
||||
<!-- container -->
|
||||
</div>
|
||||
<!-- navbar area -->
|
||||
</header>
|
||||
<!-- ========================= header-6 end ========================= -->
|
||||
|
||||
<!-- ========================= hero-5 start ========================= -->
|
||||
<div class="hero-section hero-style-5 img-bg" style="background-image: url('assets/img/hero/hero-5/hero-bg.svg')">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-lg-6">
|
||||
<div class="hero-content-wrapper">
|
||||
<h2 class="mb-30 wow fadeInUp" data-wow-delay=".2s">You're Using Free Lite Version</h2>
|
||||
<p class="mb-30 wow fadeInUp" data-wow-delay=".4s">Please purchase full version of the template to get all sections and permission to use with commercial projects.</p>
|
||||
<a href="#0" class="button button-lg radius-50 wow fadeInUp" data-wow-delay=".6s">Get Started <i class="lni lni-chevron-right"></i> </a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-6 align-self-end">
|
||||
<div class="hero-image wow fadeInUp" data-wow-delay=".5s">
|
||||
<img src="assets/img/hero/hero-5/hero-img.svg" alt="">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- ========================= hero-5 end ========================= -->
|
||||
|
||||
</section>
|
||||
<!-- ========================= hero-section-wrapper-6 end ========================= -->
|
||||
|
||||
<!-- ========================= feature style-5 start ========================= -->
|
||||
<section id="feature" class="feature-section feature-style-5">
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-xxl-5 col-xl-5 col-lg-7 col-md-8">
|
||||
<div class="section-title text-center mb-60">
|
||||
<h3 class="mb-15 wow fadeInUp" data-wow-delay=".2s">Specializing In</h3>
|
||||
<p class="wow fadeInUp" data-wow-delay=".4s">Stop wasting time and money designing and managing a website that doesn’t get results. Happiness guaranteed!</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-lg-4 col-md-6">
|
||||
<div class="single-feature wow fadeInUp" data-wow-delay=".2s">
|
||||
<div class="icon">
|
||||
<i class="lni lni-vector"></i>
|
||||
<svg width="110" height="72" viewBox="0 0 110 72" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M110 54.7589C110 85.0014 85.3757 66.2583 55 66.2583C24.6243 66.2583 0 85.0014 0 54.7589C0 24.5164 24.6243 0 55 0C85.3757 0 110 24.5164 110 54.7589Z" fill="#EBF4FF"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="content">
|
||||
<h5>Graphics Design</h5>
|
||||
<p>Short description for the ones who look for something new.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-4 col-md-6">
|
||||
<div class="single-feature wow fadeInUp" data-wow-delay=".4s">
|
||||
<div class="icon">
|
||||
<i class="lni lni-pallet"></i>
|
||||
<svg width="110" height="72" viewBox="0 0 110 72" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M110 54.7589C110 85.0014 85.3757 66.2583 55 66.2583C24.6243 66.2583 0 85.0014 0 54.7589C0 24.5164 24.6243 0 55 0C85.3757 0 110 24.5164 110 54.7589Z" fill="#EBF4FF"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="content">
|
||||
<h5>Print Design</h5>
|
||||
<p>Short description for the ones who look for something new.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-4 col-md-6">
|
||||
<div class="single-feature wow fadeInUp" data-wow-delay=".6s">
|
||||
<div class="icon">
|
||||
<i class="lni lni-stats-up"></i>
|
||||
<svg width="110" height="72" viewBox="0 0 110 72" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M110 54.7589C110 85.0014 85.3757 66.2583 55 66.2583C24.6243 66.2583 0 85.0014 0 54.7589C0 24.5164 24.6243 0 55 0C85.3757 0 110 24.5164 110 54.7589Z" fill="#EBF4FF"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="content">
|
||||
<h5>Business Analysis</h5>
|
||||
<p>Short description for the ones who look for something new.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-4 col-md-6">
|
||||
<div class="single-feature wow fadeInUp" data-wow-delay=".2s">
|
||||
<div class="icon">
|
||||
<i class="lni lni-code-alt"></i>
|
||||
<svg width="110" height="72" viewBox="0 0 110 72" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M110 54.7589C110 85.0014 85.3757 66.2583 55 66.2583C24.6243 66.2583 0 85.0014 0 54.7589C0 24.5164 24.6243 0 55 0C85.3757 0 110 24.5164 110 54.7589Z" fill="#EBF4FF"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="content">
|
||||
<h5>Web Development</h5>
|
||||
<p>Short description for the ones who look for something new.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-4 col-md-6">
|
||||
<div class="single-feature wow fadeInUp" data-wow-delay=".4s">
|
||||
<div class="icon">
|
||||
<i class="lni lni-lock"></i>
|
||||
<svg width="110" height="72" viewBox="0 0 110 72" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M110 54.7589C110 85.0014 85.3757 66.2583 55 66.2583C24.6243 66.2583 0 85.0014 0 54.7589C0 24.5164 24.6243 0 55 0C85.3757 0 110 24.5164 110 54.7589Z" fill="#EBF4FF"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="content">
|
||||
<h5>Best Security</h5>
|
||||
<p>Short description for the ones who look for something new.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-4 col-md-6">
|
||||
<div class="single-feature wow fadeInUp" data-wow-delay=".6s">
|
||||
<div class="icon">
|
||||
<i class="lni lni-code"></i>
|
||||
<svg width="110" height="72" viewBox="0 0 110 72" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M110 54.7589C110 85.0014 85.3757 66.2583 55 66.2583C24.6243 66.2583 0 85.0014 0 54.7589C0 24.5164 24.6243 0 55 0C85.3757 0 110 24.5164 110 54.7589Z" fill="#EBF4FF"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="content">
|
||||
<h5>Web Design</h5>
|
||||
<p>Short description for the ones who look for something new.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</section>
|
||||
<!-- ========================= feature style-5 end ========================= -->
|
||||
|
||||
<!-- ========================= about style-4 start ========================= -->
|
||||
<section id="about" class="about-section about-style-4">
|
||||
<div class="container">
|
||||
<div class="row align-items-center">
|
||||
<div class="col-xl-5 col-lg-6">
|
||||
<div class="about-content-wrapper">
|
||||
<div class="section-title mb-30">
|
||||
<h3 class="mb-25 wow fadeInUp" data-wow-delay=".2s">The future of designing starts here</h3>
|
||||
<p class="wow fadeInUp" data-wow-delay=".3s">Stop wasting time and money designing and managing a website that doesn’t get results. Happiness guaranteed,</p>
|
||||
</div>
|
||||
<ul>
|
||||
<li class="wow fadeInUp" data-wow-delay=".35s">
|
||||
<i class="lni lni-checkmark-circle"></i>
|
||||
Stop wasting time and money designing and managing a website that doesn’t get results.
|
||||
</li>
|
||||
<li class="wow fadeInUp" data-wow-delay=".4s">
|
||||
<i class="lni lni-checkmark-circle"></i>
|
||||
Stop wasting time and money designing and managing.
|
||||
</li>
|
||||
<li class="wow fadeInUp" data-wow-delay=".45s">
|
||||
<i class="lni lni-checkmark-circle"></i>
|
||||
Stop wasting time and money designing and managing a website that doesn’t get results.
|
||||
</li>
|
||||
</ul>
|
||||
<a href="#0" class="button button-lg radius-10 wow fadeInUp" data-wow-delay=".5s">Learn More</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-xl-7 col-lg-6">
|
||||
<div class="about-image text-lg-right wow fadeInUp" data-wow-delay=".5s">
|
||||
<img src="assets/img/about/about-4/about-img.svg" alt="">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<!-- ========================= about style-4 end ========================= -->
|
||||
|
||||
<!-- ========================= pricing style-4 start ========================= -->
|
||||
<section id="pricing" class="pricing-section pricing-style-4 bg-light">
|
||||
<div class="container">
|
||||
<div class="row align-items-center">
|
||||
<div class="col-xl-5 col-lg-6">
|
||||
<div class="section-title mb-60">
|
||||
<h3 class="mb-15 wow fadeInUp" data-wow-delay=".2s">Pricing Plan</h3>
|
||||
<p class="wow fadeInUp" data-wow-delay=".4s">Stop wasting time and money designing and managing a website that doesn’t get results. Happiness guaranteed!Stop wasting time and money designing and managing a website that doesn’t get results. Happiness guaranteed!</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-xl-7 col-lg-6">
|
||||
<div class="pricing-active-wrapper wow fadeInUp" data-wow-delay=".4s">
|
||||
<div class="pricing-active">
|
||||
<div class="single-pricing-wrapper">
|
||||
<div class="single-pricing">
|
||||
<h6>Basic Design</h6>
|
||||
<h4>Web Design</h4>
|
||||
<h3>$ 29.00</h3>
|
||||
<ul>
|
||||
<li>Carefully crafted components</li>
|
||||
<li>Amazing page examples</li>
|
||||
<li>Super friendly support team</li>
|
||||
<li>Awesome Support</li>
|
||||
</ul>
|
||||
<a href="#0" class="button radius-30">Get Started</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="single-pricing-wrapper">
|
||||
<div class="single-pricing">
|
||||
<h6>Standard Design</h6>
|
||||
<h4>Web Development</h4>
|
||||
<h3>$ 89.00</h3>
|
||||
<ul>
|
||||
<li>Carefully crafted components</li>
|
||||
<li>Amazing page examples</li>
|
||||
<li>Super friendly support team</li>
|
||||
<li>Awesome Support</li>
|
||||
</ul>
|
||||
<a href="#0" class="button radius-30">Get Started</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="single-pricing-wrapper">
|
||||
<div class="single-pricing">
|
||||
<h6>Pro Design</h6>
|
||||
<h4>Design & Develop</h4>
|
||||
<h3>$ 199.00</h3>
|
||||
<ul>
|
||||
<li>Carefully crafted components</li>
|
||||
<li>Amazing page examples</li>
|
||||
<li>Super friendly support team</li>
|
||||
<li>Awesome Support</li>
|
||||
</ul>
|
||||
<a href="#0" class="button radius-30">Get Started</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<!-- ========================= pricing style-4 end ========================= -->
|
||||
|
||||
<!-- ========================= contact-style-3 start ========================= -->
|
||||
<section id="contact" class="contact-section contact-style-3">
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-xxl-5 col-xl-5 col-lg-7 col-md-10">
|
||||
<div class="section-title text-center mb-50">
|
||||
<h3 class="mb-15">Get in touch</h3>
|
||||
<p>Stop wasting time and money designing and managing a website that doesn’t get results. Happiness guaranteed!</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-lg-8">
|
||||
<div class="contact-form-wrapper">
|
||||
<form action="" method="">
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div class="single-input">
|
||||
<input type="text" id="name" name="name" class="form-input" placeholder="Name">
|
||||
<i class="lni lni-user"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div class="single-input">
|
||||
<input type="email" id="email" name="email" class="form-input" placeholder="Email">
|
||||
<i class="lni lni-envelope"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div class="single-input">
|
||||
<input type="text" id="number" name="number" class="form-input" placeholder="Number">
|
||||
<i class="lni lni-phone"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div class="single-input">
|
||||
<input type="text" id="subject" name="subject" class="form-input" placeholder="Subject">
|
||||
<i class="lni lni-text-format"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-12">
|
||||
<div class="single-input">
|
||||
<textarea name="message" id="message" class="form-input" placeholder="Message" rows="6"></textarea>
|
||||
<i class="lni lni-comments-alt"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-12">
|
||||
<div class="form-button">
|
||||
<button type="submit" class="button"> <i class="lni lni-telegram-original"></i> Submit</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="col-lg-4">
|
||||
<div class="left-wrapper">
|
||||
<div class="row">
|
||||
<div class="col-lg-12 col-md-6">
|
||||
<div class="single-item">
|
||||
<div class="icon">
|
||||
<i class="lni lni-phone"></i>
|
||||
</div>
|
||||
<div class="text">
|
||||
<p>0045939863784</p>
|
||||
<p>+004389478327</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-12 col-md-6">
|
||||
<div class="single-item">
|
||||
<div class="icon">
|
||||
<i class="lni lni-envelope"></i>
|
||||
</div>
|
||||
<div class="text">
|
||||
<p>yourmail@gmail.com</p>
|
||||
<p>admin@yourwebsite.com</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-12 col-md-6">
|
||||
<div class="single-item">
|
||||
<div class="icon">
|
||||
<i class="lni lni-map-marker"></i>
|
||||
</div>
|
||||
<div class="text">
|
||||
<p>John's House, 13/5 Road, Sidny United State Of America</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<!-- ========================= contact-style-3 end ========================= -->
|
||||
|
||||
<!-- ========================= clients-logo start ========================= -->
|
||||
<section class="clients-logo-section pt-100 pb-100">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-lg-12">
|
||||
<div class="client-logo wow fadeInUp" data-wow-delay=".2s">
|
||||
<img src="assets/img/clients/brands.svg" alt="" class="w-100">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<!-- ========================= clients-logo end ========================= -->
|
||||
|
||||
<!-- ========================= footer style-4 start ========================= -->
|
||||
<footer class="footer footer-style-4">
|
||||
<div class="container">
|
||||
<div class="widget-wrapper">
|
||||
<div class="row">
|
||||
<div class="col-xl-3 col-lg-4 col-md-6">
|
||||
<div class="footer-widget wow fadeInUp" data-wow-delay=".2s">
|
||||
<div class="logo">
|
||||
<a href="#0"> <img src="assets/img/logo/logo.svg" alt=""> </a>
|
||||
</div>
|
||||
<p class="desc">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Facilisis nulla placerat amet amet congue.</p>
|
||||
<ul class="socials">
|
||||
<li> <a href="#0"> <i class="lni lni-facebook-filled"></i> </a> </li>
|
||||
<li> <a href="#0"> <i class="lni lni-twitter-filled"></i> </a> </li>
|
||||
<li> <a href="#0"> <i class="lni lni-instagram-filled"></i> </a> </li>
|
||||
<li> <a href="#0"> <i class="lni lni-linkedin-original"></i> </a> </li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-xl-2 offset-xl-1 col-lg-2 col-md-6 col-sm-6">
|
||||
<div class="footer-widget wow fadeInUp" data-wow-delay=".3s">
|
||||
<h6>Quick Link</h6>
|
||||
<ul class="links">
|
||||
<li> <a href="#0">Home</a> </li>
|
||||
<li> <a href="#0">About</a> </li>
|
||||
<li> <a href="#0">Service</a> </li>
|
||||
<li> <a href="#0">Testimonial</a> </li>
|
||||
<li> <a href="#0">Contact</a> </li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-xl-3 col-lg-3 col-md-6 col-sm-6">
|
||||
<div class="footer-widget wow fadeInUp" data-wow-delay=".4s">
|
||||
<h6>Services</h6>
|
||||
<ul class="links">
|
||||
<li> <a href="#0">Web Design</a> </li>
|
||||
<li> <a href="#0">Web Development</a> </li>
|
||||
<li> <a href="#0">Seo Optimization</a> </li>
|
||||
<li> <a href="#0">Blog Writing</a> </li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-xl-3 col-lg-3 col-md-6">
|
||||
<div class="footer-widget wow fadeInUp" data-wow-delay=".5s">
|
||||
<h6>Download App</h6>
|
||||
<ul class="download-app">
|
||||
<li>
|
||||
<a href="#0">
|
||||
<span class="icon"><i class="lni lni-apple"></i></span>
|
||||
<span class="text">Download on the <b>App Store</b> </span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#0">
|
||||
<span class="icon"><i class="lni lni-play-store"></i></span>
|
||||
<span class="text">GET IT ON <b>Play Store</b> </span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="copyright-wrapper wow fadeInUp" data-wow-delay=".2s">
|
||||
<p>Design and Developed by <a href="https://uideck.com" rel="nofollow" target="_blank">UIdeck</a> Built-with <a href="https://uideck.com" rel="nofollow" target="_blank">Lindy UI Kit</a>. Distributed by <a href="https://themewagon.com" target="_blank">ThemeWagon</a></p>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
<!-- ========================= footer style-4 end ========================= -->
|
||||
|
||||
<!-- ========================= scroll-top start ========================= -->
|
||||
<a href="#" class="scroll-top"> <i class="lni lni-chevron-up"></i> </a>
|
||||
<!-- ========================= scroll-top end ========================= -->
|
||||
|
||||
|
||||
<!-- ========================= JS here ========================= -->
|
||||
<script src="assets/js/bootstrap-5.0.0-beta1.min.js"></script>
|
||||
<script src="assets/js/tiny-slider.js"></script>
|
||||
<script src="assets/js/wow.min.js"></script>
|
||||
<script src="assets/js/main.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@ -1,213 +0,0 @@
|
||||
/**
|
||||
* 模板数据注入脚本
|
||||
* 功能:监听 postMessage 事件,当收到 SET_SITE_DATA 时,
|
||||
* 自动寻找带有 data-field 属性的 HTML 标签,替换为对应的数据
|
||||
*/
|
||||
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
// 日志开关
|
||||
const DEBUG = false;
|
||||
|
||||
function log(...args) {
|
||||
if (DEBUG) {
|
||||
console.log('[ThemeLoader]', ...args);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 替换元素内容或属性
|
||||
* @param {HTMLElement} element - 目标元素
|
||||
* @param {string} field - 字段名
|
||||
* @param {any} value - 数据值
|
||||
*/
|
||||
function applyDataToElement(element, field, value) {
|
||||
if (value === undefined || value === null) {
|
||||
log(`字段 ${field} 值为空,跳过`);
|
||||
return;
|
||||
}
|
||||
|
||||
// 如果是数组或对象,尝试解析
|
||||
if (typeof value === 'string') {
|
||||
try {
|
||||
const parsed = JSON.parse(value);
|
||||
if (parsed) {
|
||||
value = parsed;
|
||||
}
|
||||
} catch (e) {
|
||||
// 保持原值
|
||||
}
|
||||
}
|
||||
|
||||
// 处理数组类型(用于轮播图、列表等)
|
||||
if (Array.isArray(value)) {
|
||||
handleArrayField(element, field, value);
|
||||
return;
|
||||
}
|
||||
|
||||
// 处理对象类型
|
||||
if (typeof value === 'object') {
|
||||
handleObjectField(element, field, value);
|
||||
return;
|
||||
}
|
||||
|
||||
// 处理基础类型(字符串、数字)
|
||||
// 1. 如果是 input/textarea/select,设置为 value
|
||||
const tagName = element.tagName.toLowerCase();
|
||||
if (tagName === 'input' || tagName === 'textarea' || tagName === 'select') {
|
||||
element.value = value;
|
||||
return;
|
||||
}
|
||||
|
||||
// 2. 如果有 src 属性,设置为 src(图片等)
|
||||
if (element.hasAttribute('src') && !element.hasAttribute('data-keep-src')) {
|
||||
// 检查是否是占位符图片
|
||||
const currentSrc = element.getAttribute('src');
|
||||
if (!currentSrc || currentSrc.indexOf('placeholder') > -1) {
|
||||
element.src = value;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// 3. 否则设置为 innerText
|
||||
element.innerText = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理数组类型的字段(如轮播图、列表)
|
||||
*/
|
||||
function handleArrayField(container, field, dataList) {
|
||||
// 查找模板元素(带有 data-template 属性的元素)
|
||||
const templateElement = container.querySelector('[data-template]');
|
||||
if (!templateElement) {
|
||||
log(`字段 ${field} 未找到模板元素`);
|
||||
return;
|
||||
}
|
||||
|
||||
const template = templateElement.cloneNode(true);
|
||||
template.removeAttribute('data-template');
|
||||
template.style.display = '';
|
||||
|
||||
// 清空容器
|
||||
container.innerHTML = '';
|
||||
|
||||
// 渲染每个数据项
|
||||
dataList.forEach((item, index) => {
|
||||
const itemElement = template.cloneNode(true);
|
||||
applyDataToObject(itemElement, item, index);
|
||||
container.appendChild(itemElement);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理对象类型的字段
|
||||
*/
|
||||
function handleObjectField(element, field, data) {
|
||||
// 递归处理对象属性
|
||||
applyDataToObject(element, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将数据应用到元素及其子元素
|
||||
*/
|
||||
function applyDataToObject(element, data, index = 0) {
|
||||
// 处理 data-field 属性
|
||||
const fieldElements = element.querySelectorAll('[data-field]');
|
||||
fieldElements.forEach(el => {
|
||||
const field = el.getAttribute('data-field');
|
||||
// 支持点号分隔的路径,如 "banner.0.image"
|
||||
const value = getNestedValue(data, field);
|
||||
if (value !== undefined) {
|
||||
applyDataToElement(el, field, value);
|
||||
}
|
||||
});
|
||||
|
||||
// 也处理元素本身的 data-field
|
||||
if (element.hasAttribute('data-field')) {
|
||||
const field = element.getAttribute('data-field');
|
||||
const value = getNestedValue(data, field);
|
||||
if (value !== undefined) {
|
||||
applyDataToElement(element, field, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取嵌套属性值
|
||||
* @param {object} obj - 数据对象
|
||||
* @param {string} path - 属性路径,如 "banner.0.image"
|
||||
* @returns {any}
|
||||
*/
|
||||
function getNestedValue(obj, path) {
|
||||
if (!path) return obj;
|
||||
|
||||
const keys = path.split('.');
|
||||
let value = obj;
|
||||
|
||||
for (const key of keys) {
|
||||
if (value === null || value === undefined) {
|
||||
return undefined;
|
||||
}
|
||||
value = value[key];
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化数据注入
|
||||
*/
|
||||
function init() {
|
||||
log('ThemeLoader 初始化');
|
||||
|
||||
// 监听来自父窗口的消息
|
||||
window.addEventListener('message', function(event) {
|
||||
log('收到消息:', event.data);
|
||||
|
||||
// 验证消息类型
|
||||
if (!event.data || event.data.type !== 'SET_SITE_DATA') {
|
||||
return;
|
||||
}
|
||||
|
||||
const siteData = event.data.data;
|
||||
if (!siteData) {
|
||||
log('未收到有效数据');
|
||||
return;
|
||||
}
|
||||
|
||||
log('开始注入数据:', siteData);
|
||||
|
||||
// 查找所有带有 data-field 属性的元素
|
||||
const elements = document.querySelectorAll('[data-field]');
|
||||
|
||||
elements.forEach(element => {
|
||||
const field = element.getAttribute('data-field');
|
||||
const value = siteData[field];
|
||||
|
||||
if (value !== undefined) {
|
||||
applyDataToElement(element, field, value);
|
||||
}
|
||||
});
|
||||
|
||||
// 触发自定义事件,通知数据已加载
|
||||
window.dispatchEvent(new CustomEvent('themeDataLoaded', {
|
||||
detail: siteData
|
||||
}));
|
||||
|
||||
log('数据注入完成');
|
||||
});
|
||||
|
||||
// 发送就绪消息给父窗口
|
||||
window.parent.postMessage({
|
||||
type: 'THEME_READY'
|
||||
}, '*');
|
||||
}
|
||||
|
||||
// DOM 加载完成后初始化
|
||||
if (document.readyState === 'loading') {
|
||||
document.addEventListener('DOMContentLoaded', init);
|
||||
} else {
|
||||
init();
|
||||
}
|
||||
})();
|
||||
BIN
public/themes/default/preview.png
Normal file
|
After Width: | Height: | Size: 105 KiB |
@ -1,153 +0,0 @@
|
||||
/* 基础样式 */
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
|
||||
line-height: 1.6;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.container {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
padding: 0 20px;
|
||||
}
|
||||
|
||||
.section {
|
||||
padding: 60px 0;
|
||||
}
|
||||
|
||||
.section-title {
|
||||
text-align: center;
|
||||
font-size: 32px;
|
||||
margin-bottom: 40px;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
/* 头部 */
|
||||
.header {
|
||||
background: #fff;
|
||||
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
.header .container {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
height: 70px;
|
||||
}
|
||||
|
||||
.header h1 {
|
||||
font-size: 24px;
|
||||
color: #1890ff;
|
||||
}
|
||||
|
||||
.nav a {
|
||||
margin-left: 30px;
|
||||
text-decoration: none;
|
||||
color: #333;
|
||||
transition: color 0.3s;
|
||||
}
|
||||
|
||||
.nav a:hover {
|
||||
color: #1890ff;
|
||||
}
|
||||
|
||||
/* 轮播图 */
|
||||
.banner {
|
||||
margin-top: 70px;
|
||||
height: 500px;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.banner-slides .slide {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.banner-slides .slide.active {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.banner-slides .slide img {
|
||||
width: 100%;
|
||||
height: 500px;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.banner-content {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
text-align: center;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.banner-content h2 {
|
||||
font-size: 48px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.banner-content p {
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
/* 新闻 */
|
||||
.news-list {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
gap: 30px;
|
||||
}
|
||||
|
||||
.news-item {
|
||||
background: #f5f5f5;
|
||||
padding: 20px;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
/* 解决方案 */
|
||||
.solutions-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
.solution-card {
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
padding: 40px 20px;
|
||||
border-radius: 8px;
|
||||
text-align: center;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
/* 合作伙伴 */
|
||||
.partners-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(5, 1fr);
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
.partner-logo {
|
||||
background: #f5f5f5;
|
||||
padding: 30px;
|
||||
text-align: center;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
/* 底部 */
|
||||
.footer {
|
||||
background: #333;
|
||||
color: #fff;
|
||||
padding: 30px 0;
|
||||
text-align: center;
|
||||
}
|
||||
398
public/themes/template1/about.html
Normal file
@ -0,0 +1,398 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<title>Zay Shop - About Page</title>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
<link rel="apple-touch-icon" href="assets/img/apple-icon.png">
|
||||
<link rel="shortcut icon" type="image/x-icon" href="assets/img/favicon.ico">
|
||||
|
||||
<link rel="stylesheet" href="assets/css/bootstrap.min.css">
|
||||
<link rel="stylesheet" href="assets/css/templatemo.css">
|
||||
<link rel="stylesheet" href="assets/css/custom.css">
|
||||
|
||||
<!-- Load fonts style after rendering the layout styles -->
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Roboto:wght@100;200;300;400;500;700;900&display=swap">
|
||||
<link rel="stylesheet" href="assets/css/fontawesome.min.css">
|
||||
<!--
|
||||
|
||||
TemplateMo 559 Zay Shop
|
||||
|
||||
https://templatemo.com/tm-559-zay-shop
|
||||
|
||||
-->
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<!-- Start Top Nav -->
|
||||
<nav class="navbar navbar-expand-lg bg-dark navbar-light d-none d-lg-block" id="templatemo_nav_top">
|
||||
<div class="container text-light">
|
||||
<div class="w-100 d-flex justify-content-between">
|
||||
<div>
|
||||
<i class="fa fa-envelope mx-2"></i>
|
||||
<a class="navbar-sm-brand text-light text-decoration-none" href="mailto:info@company.com">info@company.com</a>
|
||||
<i class="fa fa-phone mx-2"></i>
|
||||
<a class="navbar-sm-brand text-light text-decoration-none" href="tel:010-020-0340">010-020-0340</a>
|
||||
</div>
|
||||
<div>
|
||||
<a class="text-light" href="https://fb.com/templatemo" target="_blank" rel="sponsored"><i class="fab fa-facebook-f fa-sm fa-fw me-2"></i></a>
|
||||
<a class="text-light" href="https://www.instagram.com/" target="_blank"><i class="fab fa-instagram fa-sm fa-fw me-2"></i></a>
|
||||
<a class="text-light" href="https://twitter.com/" target="_blank"><i class="fab fa-twitter fa-sm fa-fw me-2"></i></a>
|
||||
<a class="text-light" href="https://www.linkedin.com/" target="_blank"><i class="fab fa-linkedin fa-sm fa-fw"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
<!-- Close Top Nav -->
|
||||
|
||||
|
||||
<!-- Header -->
|
||||
<nav class="navbar navbar-expand-lg navbar-light shadow">
|
||||
<div class="container d-flex justify-content-between align-items-center">
|
||||
|
||||
<a class="navbar-brand text-success logo h1 align-self-center" href="index.html">
|
||||
Zay
|
||||
</a>
|
||||
|
||||
<button class="navbar-toggler border-0" type="button" data-bs-toggle="collapse" data-bs-target="#templatemo_main_nav" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
|
||||
<div class="align-self-center collapse navbar-collapse flex-fill d-lg-flex justify-content-lg-between" id="templatemo_main_nav">
|
||||
<div class="flex-fill">
|
||||
<ul class="nav navbar-nav d-flex justify-content-between mx-lg-auto">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="index.html">Home</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="about.html">About</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="shop.html">Shop</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="contact.html">Contact</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="navbar align-self-center d-flex">
|
||||
<div class="d-lg-none flex-sm-fill mt-3 mb-4 col-7 col-sm-auto pr-3">
|
||||
<div class="input-group">
|
||||
<input type="text" class="form-control" id="inputMobileSearch" placeholder="Search ...">
|
||||
<div class="input-group-text">
|
||||
<i class="fa fa-fw fa-search"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<a class="nav-icon d-none d-lg-inline" href="#" data-bs-toggle="modal" data-bs-target="#templatemo_search">
|
||||
<i class="fa fa-fw fa-search text-dark mr-2"></i>
|
||||
</a>
|
||||
<a class="nav-icon position-relative text-decoration-none" href="#">
|
||||
<i class="fa fa-fw fa-cart-arrow-down text-dark mr-1"></i>
|
||||
<span class="position-absolute top-0 left-100 translate-middle badge rounded-pill bg-light text-dark">7</span>
|
||||
</a>
|
||||
<a class="nav-icon position-relative text-decoration-none" href="#">
|
||||
<i class="fa fa-fw fa-user text-dark mr-3"></i>
|
||||
<span class="position-absolute top-0 left-100 translate-middle badge rounded-pill bg-light text-dark">+99</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</nav>
|
||||
<!-- Close Header -->
|
||||
|
||||
<!-- Modal -->
|
||||
<div class="modal fade bg-white" id="templatemo_search" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog modal-lg" role="document">
|
||||
<div class="w-100 pt-1 mb-5 text-right">
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<form action="" method="get" class="modal-content modal-body border-0 p-0">
|
||||
<div class="input-group mb-2">
|
||||
<input type="text" class="form-control" id="inputModalSearch" name="q" placeholder="Search ...">
|
||||
<button type="submit" class="input-group-text bg-success text-light">
|
||||
<i class="fa fa-fw fa-search text-white"></i>
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<section class="bg-success py-5">
|
||||
<div class="container">
|
||||
<div class="row align-items-center py-5">
|
||||
<div class="col-md-8 text-white">
|
||||
<h1>About Us</h1>
|
||||
<p>
|
||||
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
|
||||
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
|
||||
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
|
||||
</p>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<img src="assets/img/about-hero.svg" alt="About Hero">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<!-- Close Banner -->
|
||||
|
||||
<!-- Start Section -->
|
||||
<section class="container py-5">
|
||||
<div class="row text-center pt-5 pb-3">
|
||||
<div class="col-lg-6 m-auto">
|
||||
<h1 class="h1">Our Services</h1>
|
||||
<p>
|
||||
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
|
||||
Lorem ipsum dolor sit amet.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
|
||||
<div class="col-md-6 col-lg-3 pb-5">
|
||||
<div class="h-100 py-5 services-icon-wap shadow">
|
||||
<div class="h1 text-success text-center"><i class="fa fa-truck fa-lg"></i></div>
|
||||
<h2 class="h5 mt-4 text-center">Delivery Services</h2>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6 col-lg-3 pb-5">
|
||||
<div class="h-100 py-5 services-icon-wap shadow">
|
||||
<div class="h1 text-success text-center"><i class="fas fa-exchange-alt"></i></div>
|
||||
<h2 class="h5 mt-4 text-center">Shipping & Return</h2>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6 col-lg-3 pb-5">
|
||||
<div class="h-100 py-5 services-icon-wap shadow">
|
||||
<div class="h1 text-success text-center"><i class="fa fa-percent"></i></div>
|
||||
<h2 class="h5 mt-4 text-center">Promotion</h2>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6 col-lg-3 pb-5">
|
||||
<div class="h-100 py-5 services-icon-wap shadow">
|
||||
<div class="h1 text-success text-center"><i class="fa fa-user"></i></div>
|
||||
<h2 class="h5 mt-4 text-center">24 Hours Service</h2>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<!-- End Section -->
|
||||
|
||||
<!-- Start Brands -->
|
||||
<section class="bg-light py-5">
|
||||
<div class="container my-4">
|
||||
<div class="row text-center py-3">
|
||||
<div class="col-lg-6 m-auto">
|
||||
<h1 class="h1">Our Brands</h1>
|
||||
<p>
|
||||
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
|
||||
Lorem ipsum dolor sit amet.
|
||||
</p>
|
||||
</div>
|
||||
<div class="col-lg-9 m-auto tempaltemo-carousel">
|
||||
<div class="row d-flex flex-row">
|
||||
<!--Controls-->
|
||||
<div class="col-1 align-self-center">
|
||||
<a class="h1" href="#templatemo-slide-brand" role="button" data-bs-slide="prev">
|
||||
<i class="text-light fas fa-chevron-left"></i>
|
||||
</a>
|
||||
</div>
|
||||
<!--End Controls-->
|
||||
|
||||
<!--Carousel Wrapper-->
|
||||
<div class="col">
|
||||
<div class="carousel slide carousel-multi-item pt-2 pt-md-0" id="templatemo-slide-brand" data-bs-ride="carousel">
|
||||
<!--Slides-->
|
||||
<div class="carousel-inner product-links-wap" role="listbox">
|
||||
|
||||
<!--First slide-->
|
||||
<div class="carousel-item active">
|
||||
<div class="row">
|
||||
<div class="col-3 p-md-5">
|
||||
<a href="#"><img class="img-fluid brand-img" src="assets/img/brand_01.png" alt="Brand Logo"></a>
|
||||
</div>
|
||||
<div class="col-3 p-md-5">
|
||||
<a href="#"><img class="img-fluid brand-img" src="assets/img/brand_02.png" alt="Brand Logo"></a>
|
||||
</div>
|
||||
<div class="col-3 p-md-5">
|
||||
<a href="#"><img class="img-fluid brand-img" src="assets/img/brand_03.png" alt="Brand Logo"></a>
|
||||
</div>
|
||||
<div class="col-3 p-md-5">
|
||||
<a href="#"><img class="img-fluid brand-img" src="assets/img/brand_04.png" alt="Brand Logo"></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!--End First slide-->
|
||||
|
||||
<!--Second slide-->
|
||||
<div class="carousel-item">
|
||||
<div class="row">
|
||||
<div class="col-3 p-md-5">
|
||||
<a href="#"><img class="img-fluid brand-img" src="assets/img/brand_01.png" alt="Brand Logo"></a>
|
||||
</div>
|
||||
<div class="col-3 p-md-5">
|
||||
<a href="#"><img class="img-fluid brand-img" src="assets/img/brand_02.png" alt="Brand Logo"></a>
|
||||
</div>
|
||||
<div class="col-3 p-md-5">
|
||||
<a href="#"><img class="img-fluid brand-img" src="assets/img/brand_03.png" alt="Brand Logo"></a>
|
||||
</div>
|
||||
<div class="col-3 p-md-5">
|
||||
<a href="#"><img class="img-fluid brand-img" src="assets/img/brand_04.png" alt="Brand Logo"></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!--End Second slide-->
|
||||
|
||||
<!--Third slide-->
|
||||
<div class="carousel-item">
|
||||
<div class="row">
|
||||
<div class="col-3 p-md-5">
|
||||
<a href="#"><img class="img-fluid brand-img" src="assets/img/brand_01.png" alt="Brand Logo"></a>
|
||||
</div>
|
||||
<div class="col-3 p-md-5">
|
||||
<a href="#"><img class="img-fluid brand-img" src="assets/img/brand_02.png" alt="Brand Logo"></a>
|
||||
</div>
|
||||
<div class="col-3 p-md-5">
|
||||
<a href="#"><img class="img-fluid brand-img" src="assets/img/brand_03.png" alt="Brand Logo"></a>
|
||||
</div>
|
||||
<div class="col-3 p-md-5">
|
||||
<a href="#"><img class="img-fluid brand-img" src="assets/img/brand_04.png" alt="Brand Logo"></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!--End Third slide-->
|
||||
|
||||
</div>
|
||||
<!--End Slides-->
|
||||
</div>
|
||||
</div>
|
||||
<!--End Carousel Wrapper-->
|
||||
|
||||
<!--Controls-->
|
||||
<div class="col-1 align-self-center">
|
||||
<a class="h1" href="#templatemo-slide-brand" role="button" data-bs-slide="next">
|
||||
<i class="text-light fas fa-chevron-right"></i>
|
||||
</a>
|
||||
</div>
|
||||
<!--End Controls-->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<!--End Brands-->
|
||||
|
||||
|
||||
<!-- Start Footer -->
|
||||
<footer class="bg-dark" id="tempaltemo_footer">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
|
||||
<div class="col-md-4 pt-5">
|
||||
<h2 class="h2 text-success border-bottom pb-3 border-light logo">Zay Shop</h2>
|
||||
<ul class="list-unstyled text-light footer-link-list">
|
||||
<li>
|
||||
<i class="fas fa-map-marker-alt fa-fw"></i>
|
||||
123 Consectetur at ligula 10660
|
||||
</li>
|
||||
<li>
|
||||
<i class="fa fa-phone fa-fw"></i>
|
||||
<a class="text-decoration-none" href="tel:010-020-0340">010-020-0340</a>
|
||||
</li>
|
||||
<li>
|
||||
<i class="fa fa-envelope fa-fw"></i>
|
||||
<a class="text-decoration-none" href="mailto:info@company.com">info@company.com</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="col-md-4 pt-5">
|
||||
<h2 class="h2 text-light border-bottom pb-3 border-light">Products</h2>
|
||||
<ul class="list-unstyled text-light footer-link-list">
|
||||
<li><a class="text-decoration-none" href="#">Luxury</a></li>
|
||||
<li><a class="text-decoration-none" href="#">Sport Wear</a></li>
|
||||
<li><a class="text-decoration-none" href="#">Men's Shoes</a></li>
|
||||
<li><a class="text-decoration-none" href="#">Women's Shoes</a></li>
|
||||
<li><a class="text-decoration-none" href="#">Popular Dress</a></li>
|
||||
<li><a class="text-decoration-none" href="#">Gym Accessories</a></li>
|
||||
<li><a class="text-decoration-none" href="#">Sport Shoes</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="col-md-4 pt-5">
|
||||
<h2 class="h2 text-light border-bottom pb-3 border-light">Further Info</h2>
|
||||
<ul class="list-unstyled text-light footer-link-list">
|
||||
<li><a class="text-decoration-none" href="#">Home</a></li>
|
||||
<li><a class="text-decoration-none" href="#">About Us</a></li>
|
||||
<li><a class="text-decoration-none" href="#">Shop Locations</a></li>
|
||||
<li><a class="text-decoration-none" href="#">FAQs</a></li>
|
||||
<li><a class="text-decoration-none" href="#">Contact</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="row text-light mb-4">
|
||||
<div class="col-12 mb-3">
|
||||
<div class="w-100 my-3 border-top border-light"></div>
|
||||
</div>
|
||||
<div class="col-auto me-auto">
|
||||
<ul class="list-inline text-left footer-icons">
|
||||
<li class="list-inline-item border border-light rounded-circle text-center">
|
||||
<a rel="nofollow" class="text-light text-decoration-none" target="_blank" href="http://fb.com/templatemo"><i class="fab fa-facebook-f fa-lg fa-fw"></i></a>
|
||||
</li>
|
||||
<li class="list-inline-item border border-light rounded-circle text-center">
|
||||
<a class="text-light text-decoration-none" target="_blank" href="https://www.instagram.com/"><i class="fab fa-instagram fa-lg fa-fw"></i></a>
|
||||
</li>
|
||||
<li class="list-inline-item border border-light rounded-circle text-center">
|
||||
<a class="text-light text-decoration-none" target="_blank" href="https://twitter.com/"><i class="fab fa-twitter fa-lg fa-fw"></i></a>
|
||||
</li>
|
||||
<li class="list-inline-item border border-light rounded-circle text-center">
|
||||
<a class="text-light text-decoration-none" target="_blank" href="https://www.linkedin.com/"><i class="fab fa-linkedin fa-lg fa-fw"></i></a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<label class="sr-only" for="subscribeEmail">Email address</label>
|
||||
<div class="input-group mb-2">
|
||||
<input type="text" class="form-control bg-dark border-light" id="subscribeEmail" placeholder="Email address">
|
||||
<div class="input-group-text btn-success text-light">Subscribe</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="w-100 bg-black py-3">
|
||||
<div class="container">
|
||||
<div class="row pt-2">
|
||||
<div class="col-12">
|
||||
<p class="text-left text-light">
|
||||
Copyright © 2021 Company Name
|
||||
| Designed by <a rel="sponsored" href="https://templatemo.com/page/1" target="_blank">TemplateMo</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</footer>
|
||||
<!-- End Footer -->
|
||||
|
||||
<!-- Start Script -->
|
||||
<script src="assets/js/jquery-1.11.0.min.js"></script>
|
||||
<script src="assets/js/jquery-migrate-1.2.1.min.js"></script>
|
||||
<script src="assets/js/bootstrap.bundle.min.js"></script>
|
||||
<script src="assets/js/templatemo.js"></script>
|
||||
<script src="assets/js/custom.js"></script>
|
||||
<!-- End Script -->
|
||||
</body>
|
||||
|
||||
</html>
|
||||
7
public/themes/template1/assets/css/bootstrap.min.css
vendored
Normal file
3
public/themes/template1/assets/css/custom.css
Normal file
@ -0,0 +1,3 @@
|
||||
/*
|
||||
Custom Css
|
||||
*/
|
||||
4619
public/themes/template1/assets/css/fontawesome.css
vendored
Normal file
4
public/themes/template1/assets/css/fontawesome.min.css
vendored
Normal file
207
public/themes/template1/assets/css/slick-theme.css
Normal file
@ -0,0 +1,207 @@
|
||||
@charset 'UTF-8';
|
||||
/* Slider */
|
||||
.slick-loading .slick-list
|
||||
{
|
||||
background: #fff url('../img/ajax-loader.gif') center center no-repeat;
|
||||
}
|
||||
|
||||
/* Icons */
|
||||
@font-face
|
||||
{
|
||||
font-family: 'slick';
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
|
||||
src: url('../webfonts/slick.eot');
|
||||
src: url('../webfonts/slick.eot?#iefix') format('embedded-opentype'),
|
||||
url('../webfonts/slick.woff') format('woff'),
|
||||
url('../webfonts/slick.ttf') format('truetype'),
|
||||
url('../webfonts/slick.svg#slick') format('svg');
|
||||
}
|
||||
/* Arrows */
|
||||
.slick-prev,
|
||||
.slick-next
|
||||
{
|
||||
font-size: 0;
|
||||
line-height: 0;
|
||||
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
|
||||
display: block;
|
||||
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
padding: 0;
|
||||
-webkit-transform: translate(0, -50%);
|
||||
-ms-transform: translate(0, -50%);
|
||||
transform: translate(0, -50%);
|
||||
|
||||
cursor: pointer;
|
||||
|
||||
color: transparent;
|
||||
border: none;
|
||||
outline: none;
|
||||
background: transparent;
|
||||
}
|
||||
.slick-prev:hover,
|
||||
.slick-prev:focus,
|
||||
.slick-next:hover,
|
||||
.slick-next:focus
|
||||
{
|
||||
color: transparent;
|
||||
outline: none;
|
||||
background: transparent;
|
||||
}
|
||||
.slick-prev:hover:before,
|
||||
.slick-prev:focus:before,
|
||||
.slick-next:hover:before,
|
||||
.slick-next:focus:before
|
||||
{
|
||||
opacity: 1;
|
||||
}
|
||||
.slick-prev.slick-disabled:before,
|
||||
.slick-next.slick-disabled:before
|
||||
{
|
||||
opacity: .25;
|
||||
}
|
||||
|
||||
.slick-prev:before,
|
||||
.slick-next:before
|
||||
{
|
||||
font-family: 'slick';
|
||||
font-size: 20px;
|
||||
line-height: 1;
|
||||
|
||||
opacity: .75;
|
||||
color: white;
|
||||
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
.slick-prev
|
||||
{
|
||||
left: -25px;
|
||||
}
|
||||
[dir='rtl'] .slick-prev
|
||||
{
|
||||
right: -25px;
|
||||
left: auto;
|
||||
}
|
||||
.slick-prev:before
|
||||
{
|
||||
content: '←';
|
||||
}
|
||||
[dir='rtl'] .slick-prev:before
|
||||
{
|
||||
content: '→';
|
||||
}
|
||||
|
||||
.slick-next
|
||||
{
|
||||
right: -25px;
|
||||
}
|
||||
[dir='rtl'] .slick-next
|
||||
{
|
||||
right: auto;
|
||||
left: -25px;
|
||||
}
|
||||
.slick-next:before
|
||||
{
|
||||
content: '→';
|
||||
}
|
||||
[dir='rtl'] .slick-next:before
|
||||
{
|
||||
content: '←';
|
||||
}
|
||||
|
||||
/* Dots */
|
||||
.slick-dotted.slick-slider
|
||||
{
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
.slick-dots
|
||||
{
|
||||
position: absolute;
|
||||
bottom: -25px;
|
||||
|
||||
display: block;
|
||||
|
||||
width: 100%;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
|
||||
list-style: none;
|
||||
|
||||
text-align: center;
|
||||
}
|
||||
.slick-dots li
|
||||
{
|
||||
position: relative;
|
||||
|
||||
display: inline-block;
|
||||
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
margin: 0 5px;
|
||||
padding: 0;
|
||||
|
||||
cursor: pointer;
|
||||
}
|
||||
.slick-dots li button
|
||||
{
|
||||
font-size: 0;
|
||||
line-height: 0;
|
||||
|
||||
display: block;
|
||||
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
padding: 5px;
|
||||
|
||||
cursor: pointer;
|
||||
|
||||
color: transparent;
|
||||
border: 0;
|
||||
outline: none;
|
||||
background: transparent;
|
||||
}
|
||||
.slick-dots li button:hover,
|
||||
.slick-dots li button:focus
|
||||
{
|
||||
outline: none;
|
||||
}
|
||||
.slick-dots li button:hover:before,
|
||||
.slick-dots li button:focus:before
|
||||
{
|
||||
opacity: 1;
|
||||
}
|
||||
.slick-dots li button:before
|
||||
{
|
||||
font-family: 'slick';
|
||||
font-size: 6px;
|
||||
line-height: 20px;
|
||||
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
|
||||
content: '•';
|
||||
text-align: center;
|
||||
|
||||
opacity: .25;
|
||||
color: black;
|
||||
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
.slick-dots li.slick-active button:before
|
||||
{
|
||||
opacity: .75;
|
||||
color: black;
|
||||
}
|
||||
1
public/themes/template1/assets/css/slick-theme.min.css
vendored
Normal file
@ -0,0 +1 @@
|
||||
@charset 'UTF-8';.slick-dots,.slick-next,.slick-prev{position:absolute;display:block;padding:0}.slick-dots li button:before,.slick-next:before,.slick-prev:before{font-family:slick;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.slick-loading .slick-list{background:url(../img/ajax-loader.gif) center center no-repeat #fff}@font-face{font-family:slick;font-weight:400;font-style:normal;src:url(../webfonts/slick.eot);src:url(../webfonts/slick.eot?#iefix) format('embedded-opentype'),url(../webfonts/slick.woff) format('woff'),url(../webfonts/slick.ttf) format('truetype'),url(../webfonts/slick.svg#slick) format('svg')}.slick-next,.slick-prev{font-size:0;line-height:0;top:50%;width:20px;height:20px;-webkit-transform:translate(0,-50%);-ms-transform:translate(0,-50%);transform:translate(0,-50%);cursor:pointer;color:transparent;border:none;outline:0;background:0 0}.slick-next:focus,.slick-next:hover,.slick-prev:focus,.slick-prev:hover{color:transparent;outline:0;background:0 0}.slick-next:focus:before,.slick-next:hover:before,.slick-prev:focus:before,.slick-prev:hover:before{opacity:1}.slick-next.slick-disabled:before,.slick-prev.slick-disabled:before{opacity:.25}.slick-next:before,.slick-prev:before{font-size:20px;line-height:1;opacity:.75;color:#fff}.slick-prev{left:-25px}[dir=rtl] .slick-prev{right:-25px;left:auto}.slick-prev:before{content:'←'}.slick-next:before,[dir=rtl] .slick-prev:before{content:'→'}.slick-next{right:-25px}[dir=rtl] .slick-next{right:auto;left:-25px}[dir=rtl] .slick-next:before{content:'←'}.slick-dotted.slick-slider{margin-bottom:30px}.slick-dots{bottom:-25px;width:100%;margin:0;list-style:none;text-align:center}.slick-dots li{position:relative;display:inline-block;width:20px;height:20px;margin:0 5px;padding:0;cursor:pointer}.slick-dots li button{font-size:0;line-height:0;display:block;width:20px;height:20px;padding:5px;cursor:pointer;color:transparent;border:0;outline:0;background:0 0}.slick-dots li button:focus,.slick-dots li button:hover{outline:0}.slick-dots li button:focus:before,.slick-dots li button:hover:before{opacity:1}.slick-dots li button:before{font-size:6px;line-height:20px;position:absolute;top:0;left:0;width:20px;height:20px;content:'•';text-align:center;opacity:.25;color:#000}.slick-dots li.slick-active button:before{opacity:.75;color:#000}
|
||||
2
public/themes/template1/assets/css/slick.min.css
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
.slick-slider{position:relative;display:block;box-sizing:border-box;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-touch-callout:none;-khtml-user-select:none;-ms-touch-action:pan-y;touch-action:pan-y;-webkit-tap-highlight-color:transparent}.slick-list{position:relative;display:block;overflow:hidden;margin:0;padding:0}.slick-list:focus{outline:0}.slick-list.dragging{cursor:pointer;cursor:hand}.slick-slider .slick-list,.slick-slider .slick-track{-webkit-transform:translate3d(0,0,0);-moz-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);-o-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}.slick-track{position:relative;top:0;left:0;display:block;margin-left:auto;margin-right:auto}.slick-track:after,.slick-track:before{display:table;content:''}.slick-track:after{clear:both}.slick-loading .slick-track{visibility:hidden}.slick-slide{display:none;float:left;height:100%;min-height:1px}[dir=rtl] .slick-slide{float:right}.slick-slide img{display:block}.slick-slide.slick-loading img{display:none}.slick-slide.dragging img{pointer-events:none}.slick-initialized .slick-slide{display:block}.slick-loading .slick-slide{visibility:hidden}.slick-vertical .slick-slide{display:block;height:auto;border:1px solid transparent}.slick-arrow.slick-hidden{display:none}
|
||||
/*# sourceMappingURL=slick.min.css.map */
|
||||
191
public/themes/template1/assets/css/templatemo.css
Normal file
@ -0,0 +1,191 @@
|
||||
/*
|
||||
|
||||
TemplateMo 559 Zay Shop
|
||||
|
||||
https://templatemo.com/tm-559-zay-shop
|
||||
|
||||
---------------------------------------------
|
||||
Table of contents
|
||||
------------------------------------------------
|
||||
1. Typography
|
||||
2. General
|
||||
3. Nav
|
||||
4. Hero Carousel
|
||||
5. Accordion
|
||||
6. Shop
|
||||
7. Product
|
||||
8. Carousel Hero
|
||||
9. Carousel Brand
|
||||
10. Services
|
||||
11. Contact map
|
||||
12. Footer
|
||||
13. Small devices (landscape phones, 576px and up)
|
||||
14. Medium devices (tablets, 768px and up)
|
||||
15. Large devices (desktops, 992px and up)
|
||||
16. Extra large devices (large desktops, 1200px and up)
|
||||
--------------------------------------------- */
|
||||
|
||||
|
||||
|
||||
|
||||
/* Typography */
|
||||
body, ul, li, p, a, label, input, div {
|
||||
font-family: 'Roboto', sans-serif;
|
||||
font-size: 18px !important;
|
||||
font-weight: 300 !important;
|
||||
}
|
||||
.h1 {
|
||||
font-family: 'Roboto', sans-serif;
|
||||
font-size: 48px !important;
|
||||
font-weight: 200 !important;
|
||||
}
|
||||
.h2 {
|
||||
font-family: 'Roboto', sans-serif;
|
||||
font-size: 30px !important;
|
||||
font-weight: 300;
|
||||
}
|
||||
.h3 {
|
||||
font-family: 'Roboto', sans-serif;
|
||||
font-size: 22px !important;
|
||||
}
|
||||
/* General */
|
||||
.logo { font-weight: 500 !important;}
|
||||
.text-warning { color: #ede861 !important;}
|
||||
.text-muted { color: #bcbcbc !important;}
|
||||
.text-success { color: #59ab6e !important;}
|
||||
.text-light { color: #cfd6e1 !important;}
|
||||
.bg-dark { background-color: #212934 !important;}
|
||||
.bg-light { background-color: #e9eef5 !important;}
|
||||
.bg-black { background-color: #1d242d !important;}
|
||||
.bg-success { background-color: #59ab6e !important;}
|
||||
.btn-success {
|
||||
background-color: #59ab6e !important;
|
||||
border-color: #56ae6c !important;
|
||||
}
|
||||
.pagination .page-link:hover {color: #000;}
|
||||
.pagination .page-link:hover, .pagination .page-link.active {
|
||||
background-color: #69bb7e;
|
||||
color: #fff;
|
||||
}
|
||||
/* Nav */
|
||||
#templatemo_nav_top { min-height: 40px;}
|
||||
#templatemo_nav_top * { font-size: .9em !important;}
|
||||
#templatemo_main_nav a { color: #212934;}
|
||||
#templatemo_main_nav a:hover { color: #69bb7e;}
|
||||
#templatemo_main_nav .navbar .nav-icon { margin-right: 20px;}
|
||||
|
||||
/* Hero Carousel */
|
||||
#template-mo-zay-hero-carousel { background: #efefef !important;}
|
||||
/* Accordion */
|
||||
.templatemo-accordion a { color: #000;}
|
||||
.templatemo-accordion a:hover { color: #333d4a;}
|
||||
/* Shop */
|
||||
.shop-top-menu a:hover { color: #69bb7e !important;}
|
||||
/* Product */
|
||||
.product-wap { box-shadow: 0px 5px 10px 0px rgba(0, 0, 0, 0.10);}
|
||||
.product-wap .product-color-dot.color-dot-red { background:#f71515;}
|
||||
.product-wap .product-color-dot.color-dot-blue { background:#6db4fe;}
|
||||
.product-wap .product-color-dot.color-dot-black { background:#000000;}
|
||||
.product-wap .product-color-dot.color-dot-light { background:#e0e0e0;}
|
||||
.product-wap .product-color-dot.color-dot-green { background:#0bff7e;}
|
||||
.card.product-wap .card .product-overlay {
|
||||
background: rgba(0,0,0,.2);
|
||||
visibility: hidden;
|
||||
opacity: 0;
|
||||
transition: .3s;
|
||||
}
|
||||
.card.product-wap:hover .card .product-overlay {
|
||||
visibility: visible;
|
||||
opacity: 1;
|
||||
}
|
||||
.card.product-wap a { color: #000;}
|
||||
#carousel-related-product .slick-slide:focus { outline: none !important;}
|
||||
#carousel-related-product .slick-dots li button:before {
|
||||
font-size: 15px;
|
||||
margin-top: 20px;
|
||||
}
|
||||
/* Brand */
|
||||
.brand-img {
|
||||
filter: grayscale(100%);
|
||||
opacity: 0.5;
|
||||
transition: .5s;
|
||||
}
|
||||
.brand-img:hover {
|
||||
filter: grayscale(0%);
|
||||
opacity: 1;
|
||||
}
|
||||
/* Carousel Hero */
|
||||
#template-mo-zay-hero-carousel .carousel-indicators li {
|
||||
margin-top: -50px;
|
||||
background-color: #59ab6e;
|
||||
}
|
||||
#template-mo-zay-hero-carousel .carousel-control-next i,
|
||||
#template-mo-zay-hero-carousel .carousel-control-prev i {
|
||||
color: #59ab6e !important;
|
||||
font-size: 2.8em !important;
|
||||
}
|
||||
/* Carousel Brand */
|
||||
.tempaltemo-carousel .h1 {
|
||||
font-size: .5em !important;
|
||||
color: #000 !important;
|
||||
}
|
||||
/* Services */
|
||||
.services-icon-wap {transition: .3s;}
|
||||
.services-icon-wap:hover, .services-icon-wap:hover i {color: #fff;}
|
||||
.services-icon-wap:hover {background: #69bb7e;}
|
||||
/* Contact map */
|
||||
.leaflet-control a, .leaflet-control { font-size: 10px !important;}
|
||||
.form-control { border: 1px solid #e8e8e8;}
|
||||
/* Footer */
|
||||
#tempaltemo_footer a { color: #dcdde1;}
|
||||
#tempaltemo_footer a:hover { color: #68bb7d;}
|
||||
#tempaltemo_footer ul.footer-link-list li { padding-top: 10px;}
|
||||
#tempaltemo_footer ul.footer-icons li {
|
||||
width: 2.6em;
|
||||
height: 2.6em;
|
||||
line-height: 2.6em;
|
||||
}
|
||||
#tempaltemo_footer ul.footer-icons li:hover {
|
||||
background-color: #cfd6e1;
|
||||
transition: .5s;
|
||||
}
|
||||
#tempaltemo_footer ul.footer-icons li:hover i {
|
||||
color: #212934;
|
||||
transition: .5s;
|
||||
}
|
||||
#tempaltemo_footer .border-light { border-color: #2d343f !important;}
|
||||
/*
|
||||
// Extra small devices (portrait phones, less than 576px)
|
||||
// No media query since this is the default in Bootstrap
|
||||
*/
|
||||
/* Small devices (landscape phones, 576px and up)*/
|
||||
.product-wap .h3, .product-wap li, .product-wap i, .product-wap p {
|
||||
font-size: 12px !important;
|
||||
}
|
||||
.product-wap .product-color-dot {
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
}
|
||||
|
||||
@media (min-width: 576px) {
|
||||
.tempaltemo-carousel .h1 { font-size: 1em !important;}
|
||||
}
|
||||
|
||||
/*// Medium devices (tablets, 768px and up)*/
|
||||
@media (min-width: 768px) {
|
||||
#templatemo_main_nav .navbar-nav {max-width: 450px;}
|
||||
}
|
||||
|
||||
/* Large devices (desktops, 992px and up)*/
|
||||
@media (min-width: 992px) {
|
||||
#templatemo_main_nav .navbar-nav {max-width: 550px;}
|
||||
#template-mo-zay-hero-carousel .carousel-item {min-height: 30rem !important;}
|
||||
.product-wap .h3, .product-wap li, .product-wap i, .product-wap p {font-size: 18px !important;}
|
||||
.product-wap .product-color-dot {
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
/* Extra large devices (large desktops, 1200px and up)*/
|
||||
@media (min-width: 1200px) {}
|
||||
1
public/themes/template1/assets/css/templatemo.min.css
vendored
Normal file
@ -0,0 +1 @@
|
||||
.h1,.h2,.h3,a,body,div,input,label,li,p,ul{font-family:Roboto,sans-serif}a,body,div,input,label,li,p,ul{font-size:18px!important;font-weight:300!important}.h1{font-size:48px!important;font-weight:200!important}.h2{font-size:30px!important;font-weight:300}.h3{font-size:22px!important}.logo{font-weight:500!important}.text-warning{color:#ede861!important}.text-muted{color:#bcbcbc!important}.text-success{color:#59ab6e!important}.text-light{color:#cfd6e1!important}.bg-dark{background-color:#212934!important}.bg-light{background-color:#e9eef5!important}.bg-black{background-color:#1d242d!important}.bg-success,.btn-success{background-color:#59ab6e!important}.btn-success{border-color:#56ae6c!important}.pagination .page-link.active,.pagination .page-link:hover{background-color:#69bb7e;color:#fff}#templatemo_nav_top{min-height:40px}#templatemo_nav_top *{font-size:.9em!important}#templatemo_main_nav a{color:#212934}#templatemo_main_nav a:hover{color:#69bb7e}#templatemo_main_nav .navbar .nav-icon{margin-right:20px}#template-mo-zay-hero-carousel{background:#efefef!important}.templatemo-accordion a{color:#000}.templatemo-accordion a:hover{color:#333d4a}.shop-top-menu a:hover{color:#69bb7e!important}.product-wap{box-shadow:0 5px 10px 0 rgba(0,0,0,.1)}.product-wap .product-color-dot.color-dot-red{background:#f71515}.product-wap .product-color-dot.color-dot-blue{background:#6db4fe}.product-wap .product-color-dot.color-dot-black{background:#000}.product-wap .product-color-dot.color-dot-light{background:#e0e0e0}.product-wap .product-color-dot.color-dot-green{background:#0bff7e}.card.product-wap .card .product-overlay{background:rgba(0,0,0,.2);visibility:hidden;opacity:0;transition:.3s}.card.product-wap:hover .card .product-overlay{visibility:visible;opacity:1}.card.product-wap a{color:#000}#carousel-related-product .slick-slide:focus{outline:0!important}#carousel-related-product .slick-dots li button:before{font-size:15px;margin-top:20px}.brand-img{filter:grayscale(100%);opacity:.5;transition:.5s}.brand-img:hover{filter:grayscale(0);opacity:1}#template-mo-zay-hero-carousel .carousel-indicators li{margin-top:-50px;background-color:#59ab6e}#template-mo-zay-hero-carousel .carousel-control-next i,#template-mo-zay-hero-carousel .carousel-control-prev i{color:#59ab6e!important;font-size:2.8em!important}.tempaltemo-carousel .h1{font-size:.5em!important;color:#000!important}.services-icon-wap{transition:.3s}.services-icon-wap:hover,.services-icon-wap:hover i{color:#fff}.services-icon-wap:hover{background:#69bb7e}.leaflet-control,.leaflet-control a{font-size:10px!important}.form-control{border:1px solid #e8e8e8}#tempaltemo_footer a{color:#dcdde1}#tempaltemo_footer a:hover{color:#68bb7d}#tempaltemo_footer ul.footer-link-list li{padding-top:10px}#tempaltemo_footer ul.footer-icons li{width:2.6em;height:2.6em;line-height:2.6em}#tempaltemo_footer ul.footer-icons li:hover{background-color:#cfd6e1;transition:.5s}#tempaltemo_footer ul.footer-icons li:hover i{color:#212934;transition:.5s}#tempaltemo_footer .border-light{border-color:#2d343f!important}.product-wap .h3,.product-wap i,.product-wap li,.product-wap p{font-size:12px!important}.product-wap .product-color-dot{width:6px;height:6px}@media (min-width:576px){.tempaltemo-carousel .h1{font-size:1em!important}}@media (min-width:768px){#templatemo_main_nav .navbar-nav{max-width:450px}}@media (min-width:992px){#templatemo_main_nav .navbar-nav{max-width:550px}#template-mo-zay-hero-carousel .carousel-item{min-height:30rem!important}.product-wap .h3,.product-wap i,.product-wap li,.product-wap p{font-size:18px!important}.product-wap .product-color-dot{width:12px;height:12px}}
|
||||
1
public/themes/template1/assets/img/about-hero.svg
Normal file
|
After Width: | Height: | Size: 45 KiB |
BIN
public/themes/template1/assets/img/ajax-loader.gif
Normal file
|
After Width: | Height: | Size: 4.0 KiB |
BIN
public/themes/template1/assets/img/apple-icon.png
Normal file
|
After Width: | Height: | Size: 3.9 KiB |
BIN
public/themes/template1/assets/img/banner_img_01.jpg
Normal file
|
After Width: | Height: | Size: 69 KiB |
BIN
public/themes/template1/assets/img/banner_img_02.jpg
Normal file
|
After Width: | Height: | Size: 43 KiB |
BIN
public/themes/template1/assets/img/banner_img_03.jpg
Normal file
|
After Width: | Height: | Size: 82 KiB |
BIN
public/themes/template1/assets/img/brand_01.png
Normal file
|
After Width: | Height: | Size: 47 KiB |
BIN
public/themes/template1/assets/img/brand_02.png
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
public/themes/template1/assets/img/brand_03.png
Normal file
|
After Width: | Height: | Size: 77 KiB |
BIN
public/themes/template1/assets/img/brand_04.png
Normal file
|
After Width: | Height: | Size: 93 KiB |
BIN
public/themes/template1/assets/img/category_img_01.jpg
Normal file
|
After Width: | Height: | Size: 40 KiB |
BIN
public/themes/template1/assets/img/category_img_02.jpg
Normal file
|
After Width: | Height: | Size: 66 KiB |
BIN
public/themes/template1/assets/img/category_img_03.jpg
Normal file
|
After Width: | Height: | Size: 151 KiB |
BIN
public/themes/template1/assets/img/favicon.ico
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
public/themes/template1/assets/img/feature_prod_01.jpg
Normal file
|
After Width: | Height: | Size: 18 KiB |
BIN
public/themes/template1/assets/img/feature_prod_02.jpg
Normal file
|
After Width: | Height: | Size: 40 KiB |
BIN
public/themes/template1/assets/img/feature_prod_03.jpg
Normal file
|
After Width: | Height: | Size: 23 KiB |
BIN
public/themes/template1/assets/img/product_single_01.jpg
Normal file
|
After Width: | Height: | Size: 72 KiB |
BIN
public/themes/template1/assets/img/product_single_02.jpg
Normal file
|
After Width: | Height: | Size: 80 KiB |
BIN
public/themes/template1/assets/img/product_single_03.jpg
Normal file
|
After Width: | Height: | Size: 59 KiB |
BIN
public/themes/template1/assets/img/product_single_04.jpg
Normal file
|
After Width: | Height: | Size: 66 KiB |
BIN
public/themes/template1/assets/img/product_single_05.jpg
Normal file
|
After Width: | Height: | Size: 57 KiB |
BIN
public/themes/template1/assets/img/product_single_06.jpg
Normal file
|
After Width: | Height: | Size: 63 KiB |
BIN
public/themes/template1/assets/img/product_single_07.jpg
Normal file
|
After Width: | Height: | Size: 79 KiB |
BIN
public/themes/template1/assets/img/product_single_08.jpg
Normal file
|
After Width: | Height: | Size: 70 KiB |
BIN
public/themes/template1/assets/img/product_single_09.jpg
Normal file
|
After Width: | Height: | Size: 78 KiB |
BIN
public/themes/template1/assets/img/product_single_10.jpg
Normal file
|
After Width: | Height: | Size: 50 KiB |
BIN
public/themes/template1/assets/img/shop_01.jpg
Normal file
|
After Width: | Height: | Size: 128 KiB |
BIN
public/themes/template1/assets/img/shop_02.jpg
Normal file
|
After Width: | Height: | Size: 180 KiB |
BIN
public/themes/template1/assets/img/shop_03.jpg
Normal file
|
After Width: | Height: | Size: 123 KiB |
BIN
public/themes/template1/assets/img/shop_04.jpg
Normal file
|
After Width: | Height: | Size: 156 KiB |
BIN
public/themes/template1/assets/img/shop_05.jpg
Normal file
|
After Width: | Height: | Size: 91 KiB |
BIN
public/themes/template1/assets/img/shop_06.jpg
Normal file
|
After Width: | Height: | Size: 115 KiB |
BIN
public/themes/template1/assets/img/shop_07.jpg
Normal file
|
After Width: | Height: | Size: 234 KiB |
BIN
public/themes/template1/assets/img/shop_08.jpg
Normal file
|
After Width: | Height: | Size: 134 KiB |
BIN
public/themes/template1/assets/img/shop_09.jpg
Normal file
|
After Width: | Height: | Size: 162 KiB |
BIN
public/themes/template1/assets/img/shop_10.jpg
Normal file
|
After Width: | Height: | Size: 156 KiB |
BIN
public/themes/template1/assets/img/shop_11.jpg
Normal file
|
After Width: | Height: | Size: 139 KiB |
7
public/themes/template1/assets/js/bootstrap.bundle.min.js
vendored
Normal file
0
public/themes/template1/assets/js/custom.js
Normal file
4
public/themes/template1/assets/js/jquery-1.11.0.min.js
vendored
Normal file
2
public/themes/template1/assets/js/jquery-migrate-1.2.1.min.js
vendored
Normal file
1
public/themes/template1/assets/js/slick.min.js
vendored
Normal file
57
public/themes/template1/assets/js/templatemo.js
Normal file
@ -0,0 +1,57 @@
|
||||
/*
|
||||
|
||||
TemplateMo 559 Zay Shop
|
||||
|
||||
https://templatemo.com/tm-559-zay-shop
|
||||
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
$(document).ready(function() {
|
||||
|
||||
// Accordion
|
||||
var all_panels = $('.templatemo-accordion > li > ul').hide();
|
||||
|
||||
$('.templatemo-accordion > li > a').click(function() {
|
||||
console.log('Hello world!');
|
||||
var target = $(this).next();
|
||||
if(!target.hasClass('active')){
|
||||
all_panels.removeClass('active').slideUp();
|
||||
target.addClass('active').slideDown();
|
||||
}
|
||||
return false;
|
||||
});
|
||||
// End accordion
|
||||
|
||||
// Product detail
|
||||
$('.product-links-wap a').click(function(){
|
||||
var this_src = $(this).children('img').attr('src');
|
||||
$('#product-detail').attr('src',this_src);
|
||||
return false;
|
||||
});
|
||||
$('#btn-minus').click(function(){
|
||||
var val = $("#var-value").html();
|
||||
val = (val=='1')?val:val-1;
|
||||
$("#var-value").html(val);
|
||||
$("#product-quanity").val(val);
|
||||
return false;
|
||||
});
|
||||
$('#btn-plus').click(function(){
|
||||
var val = $("#var-value").html();
|
||||
val++;
|
||||
$("#var-value").html(val);
|
||||
$("#product-quanity").val(val);
|
||||
return false;
|
||||
});
|
||||
$('.btn-size').click(function(){
|
||||
var this_val = $(this).html();
|
||||
$("#product-size").val(this_val);
|
||||
$(".btn-size").removeClass('btn-secondary');
|
||||
$(".btn-size").addClass('btn-success');
|
||||
$(this).removeClass('btn-success');
|
||||
$(this).addClass('btn-secondary');
|
||||
return false;
|
||||
});
|
||||
// End roduct detail
|
||||
|
||||
});
|
||||
1
public/themes/template1/assets/js/templatemo.min.js
vendored
Normal file
@ -0,0 +1 @@
|
||||
"use strict";$(document).ready(function(){var t=$(".templatemo-accordion > li > ul").hide();$(".templatemo-accordion > li > a").click(function(){var a=$(this).next();return a.hasClass("active")||(t.removeClass("active").slideUp(),a.addClass("active").slideDown()),!1}),$(".product-links-wap a").click(function(){var t=$(this).children("img").attr("src");return $("#product-detail").attr("src",t),!1}),$("#btn-minus").click(function(){var t=$("#var-value").html();return t="1"==t?t:t-1,$("#var-value").html(t),$("#product-quanity").val(t),!1}),$("#btn-plus").click(function(){var t=$("#var-value").html();return t++,$("#var-value").html(t),$("#product-quanity").val(t),!1}),$(".btn-size").click(function(){var t=$(this).html();return $("#product-size").val(t),$(".btn-size").removeClass("btn-secondary"),$(".btn-size").addClass("btn-success"),$(this).removeClass("btn-success"),$(this).addClass("btn-secondary"),!1})});
|
||||