599 行
30 KiB
HTML
599 行
30 KiB
HTML
<style>
|
|
.srv-modal-wrap { padding: 4px 8px; color: #1e293b; }
|
|
|
|
/* 顶部商品摘要横幅 */
|
|
.srv-hero-banner {
|
|
background: linear-gradient(135deg, #fff7ed 0%, #ffedd5 100%);
|
|
border: 1px solid #fed7aa;
|
|
border-radius: 10px;
|
|
padding: 12px 18px;
|
|
margin-bottom: 14px;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
}
|
|
.srv-hero-left { display: flex; align-items: center; gap: 12px; }
|
|
.srv-hero-thumb {
|
|
width: 46px;
|
|
height: 46px;
|
|
border-radius: 8px;
|
|
object-fit: cover;
|
|
border: 1px solid #fdba74;
|
|
background: #fff;
|
|
}
|
|
.srv-hero-title { font-size: 16px; font-weight: 700; color: #9a3412; display: flex; align-items: center; gap: 8px; }
|
|
.srv-hero-cat {
|
|
font-size: 11.5px;
|
|
padding: 2px 8px;
|
|
border-radius: 12px;
|
|
background: #ea580c;
|
|
color: #fff;
|
|
font-weight: 600;
|
|
}
|
|
.srv-hero-sub { font-size: 12px; color: #c2410c; margin-top: 3px; }
|
|
.srv-hero-badges { display: flex; gap: 10px; }
|
|
.srv-hero-stat {
|
|
background: rgba(255, 255, 255, 0.85);
|
|
border: 1px solid #fed7aa;
|
|
border-radius: 8px;
|
|
padding: 6px 12px;
|
|
text-align: center;
|
|
min-width: 86px;
|
|
}
|
|
.srv-hero-stat .s-num { font-size: 16px; font-weight: 800; color: #ea580c; line-height: 1.1; }
|
|
.srv-hero-stat .s-lbl { font-size: 11px; color: #78350f; margin-top: 2px; }
|
|
|
|
/* 顶部现代化分段 Tab */
|
|
.srv-nav-tabs {
|
|
border-bottom: 2px solid #e2e8f0;
|
|
margin-bottom: 16px;
|
|
display: flex;
|
|
gap: 8px;
|
|
}
|
|
.srv-nav-tabs > li > a {
|
|
border: none !important;
|
|
border-radius: 8px 8px 0 0 !important;
|
|
padding: 10px 20px !important;
|
|
font-size: 13.5px;
|
|
font-weight: 600;
|
|
color: #64748b !important;
|
|
background: #f8fafc !important;
|
|
margin-right: 0 !important;
|
|
transition: all 0.2s;
|
|
}
|
|
.srv-nav-tabs > li.active > a,
|
|
.srv-nav-tabs > li.active > a:hover,
|
|
.srv-nav-tabs > li.active > a:focus {
|
|
color: #ea580c !important;
|
|
background: #fff7ed !important;
|
|
border-bottom: 2px solid #ea580c !important;
|
|
}
|
|
|
|
/* 分区卡片 */
|
|
.srv-section-card {
|
|
background: #ffffff;
|
|
border: 1px solid #e2e8f0;
|
|
border-radius: 10px;
|
|
padding: 16px 18px;
|
|
margin-bottom: 16px;
|
|
box-shadow: 0 1px 3px rgba(15, 23, 42, 0.02);
|
|
}
|
|
.srv-section-header {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
padding-bottom: 12px;
|
|
margin-bottom: 14px;
|
|
border-bottom: 1px solid #f1f5f9;
|
|
}
|
|
.srv-section-title {
|
|
font-size: 14px;
|
|
font-weight: 700;
|
|
color: #0f172a;
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
}
|
|
.srv-section-title i { color: #ea580c; }
|
|
|
|
/* 服务矩阵顶部过滤工具条 */
|
|
.srv-matrix-toolbar {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
background: #f8fafc;
|
|
border: 1px solid #e2e8f0;
|
|
border-radius: 8px;
|
|
padding: 8px 12px;
|
|
margin-bottom: 12px;
|
|
}
|
|
.srv-filter-btn-group { display: flex; gap: 6px; }
|
|
.srv-filter-btn {
|
|
border: 1px solid #cbd5e1;
|
|
background: #fff;
|
|
color: #475569;
|
|
padding: 4px 12px;
|
|
border-radius: 6px;
|
|
font-size: 12px;
|
|
font-weight: 600;
|
|
cursor: pointer;
|
|
transition: all 0.15s;
|
|
}
|
|
.srv-filter-btn.active {
|
|
background: #0f172a;
|
|
color: #fff;
|
|
border-color: #0f172a;
|
|
}
|
|
|
|
/* 服务定价矩阵表格美化 */
|
|
.srv-matrix-table {
|
|
width: 100%;
|
|
border-collapse: separate;
|
|
border-spacing: 0;
|
|
border: 1px solid #e2e8f0;
|
|
border-radius: 8px;
|
|
overflow: hidden;
|
|
}
|
|
.srv-matrix-table thead th {
|
|
padding: 10px 12px;
|
|
font-size: 12.5px;
|
|
font-weight: 700;
|
|
color: #334155;
|
|
border-bottom: 1px solid #e2e8f0;
|
|
background: #f8fafc;
|
|
}
|
|
.srv-matrix-table thead th.col-main-hd { background: #eff6ff; color: #1e40af; border-left: 1px solid #dbeafe; }
|
|
.srv-matrix-table thead th.col-addon-hd { background: #fff7ed; color: #9a3412; border-left: 1px solid #fed7aa; }
|
|
|
|
.srv-matrix-table tbody tr {
|
|
border-bottom: 1px solid #f1f5f9;
|
|
transition: background 0.15s;
|
|
}
|
|
.srv-matrix-table tbody tr:last-child td { border-bottom: none; }
|
|
.srv-matrix-table tbody td {
|
|
padding: 10px 12px;
|
|
vertical-align: middle;
|
|
border-bottom: 1px solid #f1f5f9;
|
|
}
|
|
.srv-matrix-table tbody tr.is-row-enabled { background: #ffffff; }
|
|
.srv-matrix-table tbody tr.is-row-disabled { background: #f8fafc; opacity: 0.75; }
|
|
.srv-matrix-table tbody tr.is-row-disabled:hover { opacity: 1; }
|
|
|
|
.srv-name-box { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
|
|
.srv-name-text { font-size: 13.5px; font-weight: 700; color: #0f172a; white-space: nowrap; }
|
|
.srv-code-badge {
|
|
font-size: 11px;
|
|
padding: 1px 6px;
|
|
border-radius: 4px;
|
|
background: #f1f5f9;
|
|
color: #64748b;
|
|
font-family: Consolas, monospace;
|
|
}
|
|
|
|
/* 现代化 Switch 开关 */
|
|
.srv-switch {
|
|
position: relative;
|
|
display: inline-flex;
|
|
align-items: center;
|
|
cursor: pointer;
|
|
margin: 0;
|
|
user-select: none;
|
|
}
|
|
.srv-switch input { display: none; }
|
|
.srv-switch .slider {
|
|
width: 38px;
|
|
height: 20px;
|
|
background-color: #cbd5e1;
|
|
border-radius: 20px;
|
|
position: relative;
|
|
transition: 0.2s;
|
|
}
|
|
.srv-switch .slider::before {
|
|
content: "";
|
|
position: absolute;
|
|
width: 16px;
|
|
height: 16px;
|
|
left: 2px;
|
|
bottom: 2px;
|
|
background-color: white;
|
|
border-radius: 50%;
|
|
transition: 0.2s;
|
|
box-shadow: 0 1px 2px rgba(0,0,0,0.2);
|
|
}
|
|
.srv-switch.switch-blue input:checked + .slider { background-color: #2563eb; }
|
|
.srv-switch.switch-orange input:checked + .slider { background-color: #ea580c; }
|
|
.srv-switch input:checked + .slider::before { transform: translateX(18px); }
|
|
|
|
/* 主服务与增项服务内联配置区 */
|
|
.srv-config-cell-main { border-left: 1px solid #f1f5f9; background: #fafcff; }
|
|
.srv-config-cell-addon { border-left: 1px solid #f1f5f9; background: #fffdf9; }
|
|
.srv-inline-controls {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 10px;
|
|
flex-wrap: nowrap;
|
|
}
|
|
.srv-off-hint {
|
|
font-size: 12px;
|
|
color: #94a3b8;
|
|
margin-left: 8px;
|
|
}
|
|
.srv-quote-badge {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: 4px;
|
|
padding: 4px 10px;
|
|
border-radius: 6px;
|
|
background: #f1f5f9;
|
|
color: #475569;
|
|
font-size: 12px;
|
|
font-weight: 500;
|
|
border: 1px dashed #cbd5e1;
|
|
}
|
|
.srv-default-label {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: 4px;
|
|
font-size: 12px;
|
|
color: #475569;
|
|
cursor: pointer;
|
|
margin: 0;
|
|
padding: 3px 8px;
|
|
border-radius: 6px;
|
|
border: 1px solid transparent;
|
|
}
|
|
.srv-default-label.is-def-active {
|
|
background: #dbeafe;
|
|
color: #1d4ed8;
|
|
border-color: #93c5fd;
|
|
font-weight: 600;
|
|
}
|
|
</style>
|
|
|
|
<?php
|
|
$activeTab = input('get.tab', '') === 'services' ? 'services' : 'basic';
|
|
|
|
$savedMainMap = [];
|
|
foreach ($serviceTypes as $st) {
|
|
if (isset($st['code'])) {
|
|
$savedMainMap[$st['code']] = $st;
|
|
}
|
|
}
|
|
$savedAddonMap = [];
|
|
foreach ($assignedAddons as $ad) {
|
|
if (isset($ad['code']) && $ad['code'] !== '') {
|
|
$savedAddonMap[$ad['code']] = $ad;
|
|
} elseif (isset($ad['name'])) {
|
|
$savedAddonMap[$ad['name']] = $ad;
|
|
}
|
|
}
|
|
|
|
// 整理服务列表:将当前商品已启用的服务排在最前面,方便一眼查看和改价
|
|
$sortedPool = [];
|
|
$disabledPool = [];
|
|
foreach ($typesPool as $tp) {
|
|
$c = $tp['code'];
|
|
$n = $tp['name'];
|
|
$mainOn = !empty($savedMainMap) ? isset($savedMainMap[$c]) : ($tp['can_be_main'] == 1 && in_array($c, ['install','repair','remove']));
|
|
$addonOn = !empty($savedAddonMap) ? (isset($savedAddonMap[$c]) || isset($savedAddonMap[$n])) : ($c === 'remove');
|
|
if ($mainOn || $addonOn) {
|
|
$sortedPool[] = $tp;
|
|
} else {
|
|
$disabledPool[] = $tp;
|
|
}
|
|
}
|
|
$finalTypesPool = array_merge($sortedPool, $disabledPool);
|
|
?>
|
|
|
|
<form id="edit-form" class="form-horizontal srv-modal-wrap" role="form" data-toggle="validator" method="POST" action="">
|
|
|
|
<!-- 顶部商品摘要横幅 -->
|
|
<?php $srvThumbUrl = empty($row['image']) ? '/assets/img/qrcode.png' : (strpos($row['image'], '/assets/') === 0 || strpos($row['image'], '/icon/') === 0 ? $row['image'] : cdnurl($row['image'], true)); ?>
|
|
<div class="srv-hero-banner">
|
|
<div class="srv-hero-left">
|
|
<img class="srv-hero-thumb" src="{$srvThumbUrl|htmlentities}" onerror="this.src='/assets/img/qrcode.png'">
|
|
<div>
|
|
<div class="srv-hero-title">
|
|
{$row.name|htmlentities}
|
|
<span class="srv-hero-cat">{$catName|htmlentities}</span>
|
|
</div>
|
|
<div class="srv-hero-sub">计价单位:{$row.unit|htmlentities} · 商品本身无固定价格,价格按下方关联的「主服务」与「增项服务」独立生效</div>
|
|
</div>
|
|
</div>
|
|
<div class="srv-hero-badges">
|
|
<div class="srv-hero-stat">
|
|
<div class="s-num" id="stat-main-cnt">{:count($savedMainMap)}</div>
|
|
<div class="s-lbl">已启用主服务</div>
|
|
</div>
|
|
<div class="srv-hero-stat">
|
|
<div class="s-num" id="stat-addon-cnt">{:count($savedAddonMap)}</div>
|
|
<div class="s-lbl">已启用增项</div>
|
|
</div>
|
|
<div class="srv-hero-stat">
|
|
<div class="s-num" id="stat-spec-cnt">{:count($specs)}</div>
|
|
<div class="s-lbl">细分型号规格</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 导航选项卡 -->
|
|
<ul class="nav nav-tabs srv-nav-tabs">
|
|
<li class="{if $activeTab=='basic'}active{/if}">
|
|
<a href="#tab-basic" data-toggle="tab"><i class="fa fa-cube"></i> 1. 商品基础属性与细分规格</a>
|
|
</li>
|
|
<li class="{if $activeTab=='services'}active{/if}">
|
|
<a href="#tab-services" data-toggle="tab"><i class="fa fa-sliders"></i> 2. 关联服务与独立定价(主服务 / 增项服务)</a>
|
|
</li>
|
|
</ul>
|
|
|
|
<div class="tab-content">
|
|
<!-- ==================== Tab 1: 商品与规格信息 ==================== -->
|
|
<div class="tab-pane {if $activeTab=='basic'}active{/if}" id="tab-basic">
|
|
<div class="srv-section-card">
|
|
<div class="srv-section-header">
|
|
<div class="srv-section-title"><i class="fa fa-info-circle"></i> 商品标的物基础信息</div>
|
|
</div>
|
|
<div class="row">
|
|
<div class="col-xs-12 col-sm-6">
|
|
<div class="form-group">
|
|
<label class="control-label col-xs-12 col-sm-4">所属服务类目:</label>
|
|
<div class="col-xs-12 col-sm-8">
|
|
<input id="c-cat_id" data-rule="required" min="0" data-source="service/cat/index" class="form-control selectpage" name="row[cat_id]" type="text" value="{$row.cat_id|htmlentities}" placeholder="请选择所属类目">
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-xs-12 col-sm-6">
|
|
<div class="form-group">
|
|
<label class="control-label col-xs-12 col-sm-4">商品名称:</label>
|
|
<div class="col-xs-12 col-sm-8">
|
|
<input id="c-name" data-rule="required" class="form-control" name="row[name]" type="text" value="{$row.name|htmlentities}" placeholder="如:坐便器、浴室柜、沙发">
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row">
|
|
<div class="col-xs-12 col-sm-6">
|
|
<div class="form-group">
|
|
<label class="control-label col-xs-12 col-sm-4">数量单位:</label>
|
|
<div class="col-xs-12 col-sm-8">
|
|
<input id="c-unit" data-rule="required" class="form-control" name="row[unit]" type="text" value="{$row.unit|htmlentities}" placeholder="如:台、套、张、个、扇">
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-xs-12 col-sm-6">
|
|
<div class="form-group">
|
|
<label class="control-label col-xs-12 col-sm-4">步梯搬运楼层费:</label>
|
|
<div class="col-xs-12 col-sm-8">
|
|
<div class="row">
|
|
<div class="col-xs-6">
|
|
<div class="input-group">
|
|
<span class="input-group-addon">¥</span>
|
|
<input id="c-floor_fee" data-rule="required" class="form-control" step="0.01" name="row[floor_fee]" type="number" value="{$row.floor_fee|htmlentities}">
|
|
<span class="input-group-addon">/层</span>
|
|
</div>
|
|
</div>
|
|
<div class="col-xs-6">
|
|
<div class="input-group">
|
|
<span class="input-group-addon">免</span>
|
|
<input id="c-free_floor" data-rule="required" class="form-control" name="row[free_floor]" type="number" value="{$row.free_floor|htmlentities}">
|
|
<span class="input-group-addon">层</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label class="control-label col-xs-12 col-sm-2">商品缩略图:</label>
|
|
<div class="col-xs-12 col-sm-10">
|
|
<div class="input-group">
|
|
<input id="c-image" class="form-control" size="50" name="row[image]" type="text" value="{$row.image|htmlentities}">
|
|
<div class="input-group-addon no-border no-padding">
|
|
<span><button type="button" id="faupload-image" class="btn btn-danger faupload plupload" data-category="service" data-input-id="c-image" data-mimetype="image/gif,image/jpeg,image/png,image/jpg,image/bmp,image/webp" data-multiple="false" data-preview-id="p-image"><i class="fa fa-upload"></i> 上传图片</button></span>
|
|
<span><button type="button" id="fachoose-image" class="btn btn-primary fachoose" data-input-id="c-image" data-mimetype="image/*" data-multiple="false"><i class="fa fa-list"></i> 图库选择</button></span>
|
|
</div>
|
|
<span class="msg-box n-right" for="c-image"></span>
|
|
</div>
|
|
<p class="help-block" style="margin:6px 0 0;font-size:12px;color:#64748b;">上传后同时作为小程序「系统图库」该商品的默认参考图;如需配置多款参考图,可在下方细分规格上传或前往「系统图库」管理。</p>
|
|
<ul class="row list-inline faupload-preview plupload-preview" id="p-image"></ul>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row">
|
|
<div class="col-xs-12 col-sm-6">
|
|
<div class="form-group" style="margin-bottom:0;">
|
|
<label class="control-label col-xs-12 col-sm-4">排序权重:</label>
|
|
<div class="col-xs-12 col-sm-8">
|
|
<input id="c-weigh" data-rule="required" class="form-control" name="row[weigh]" type="number" value="{$row.weigh|htmlentities}">
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-xs-12 col-sm-6">
|
|
<div class="form-group" style="margin-bottom:0;">
|
|
<label class="control-label col-xs-12 col-sm-4">上架状态:</label>
|
|
<div class="col-xs-12 col-sm-8">
|
|
<div class="radio">
|
|
{foreach name="statusList" item="vo"}
|
|
<label for="row[status]-{$key}"><input id="row[status]-{$key}" name="row[status]" type="radio" value="{$key}" {in name="key" value="$row.status"}checked{/in} /> {$vo}</label>
|
|
{/foreach}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 细分型号规格管理卡片 -->
|
|
<div class="srv-section-card">
|
|
<div class="srv-section-header">
|
|
<div class="srv-section-title">
|
|
<i class="fa fa-tags"></i> 商品细分型号与款式规格
|
|
<small class="text-muted" style="font-weight:400;font-size:12px;">(常规规格留空价格即可,自动沿用商品默认服务价;仅施工难度特殊的规格需填专属一口价)</small>
|
|
</div>
|
|
<button type="button" class="btn btn-xs btn-success" id="btn-add-spec"><i class="fa fa-plus"></i> 新增细分规格</button>
|
|
</div>
|
|
|
|
<table class="table table-bordered table-hover" id="specs-table" style="margin-bottom: 0;">
|
|
<thead>
|
|
<tr class="active">
|
|
<th style="width: 50px; text-align: center;">序号</th>
|
|
<th style="width: 220px;">细分规格/款式名称</th>
|
|
<th style="width: 155px; text-align: center;">规格参考图(选填)</th>
|
|
<th style="width: 195px;">特殊规格一口价(选填)</th>
|
|
<th>规格说明或施工提示(选填)</th>
|
|
<th style="width: 65px; text-align: center;">操作</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody id="specs-tbody">
|
|
{foreach name="specs" item="sp" key="idx"}
|
|
<?php $spImgRaw = isset($sp['image']) ? trim((string)$sp['image']) : ''; $spImgFull = $spImgRaw !== '' ? (strpos($spImgRaw, 'http') === 0 ? $spImgRaw : cdnurl($spImgRaw, true)) : ''; ?>
|
|
<tr data-id="{$sp.id}">
|
|
<td style="text-align: center; vertical-align: middle; color: #64748b; font-weight: 600;">{$idx+1}</td>
|
|
<td>
|
|
<input type="hidden" name="specs[{$idx}][id]" value="{$sp.id}">
|
|
<input type="text" name="specs[{$idx}][name]" class="form-control input-sm" value="{$sp.name|htmlentities}" placeholder="如:普通坐便器(马桶) / 智能马桶">
|
|
</td>
|
|
<td style="text-align: center; vertical-align: middle;">
|
|
<div class="spec-img-cell" style="display:inline-flex;align-items:center;gap:6px;">
|
|
<input type="hidden" name="specs[{$idx}][image]" class="spec-img-input" value="{$spImgRaw|htmlentities}">
|
|
<img class="spec-img-preview" src="{$spImgFull|htmlentities}" style="width:34px;height:34px;border-radius:4px;object-fit:cover;border:1px solid #cbd5e1;{if !$spImgFull}display:none;{/if}" onclick="window.open(this.src)" title="点击查看大图">
|
|
<button type="button" class="btn btn-xs btn-default btn-upload-spec-img"><i class="fa fa-upload"></i> {if $spImgFull}更换{else/}上传{/if}</button>
|
|
<button type="button" class="btn btn-xs btn-link text-danger btn-clear-spec-img" style="padding:0 2px;{if !$spImgFull}display:none;{/if}" title="移除图片"><i class="fa fa-times"></i></button>
|
|
<input type="file" class="spec-img-file" accept="image/*" style="display:none;">
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<div class="input-group input-group-sm">
|
|
<span class="input-group-addon">¥</span>
|
|
<input type="number" step="0.01" name="specs[{$idx}][base_price]" class="form-control input-sm" value="{if $sp.base_price > 0}{$sp.base_price|htmlentities}{/if}" placeholder="留空则沿用商品默认价">
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<input type="text" name="specs[{$idx}][description]" class="form-control input-sm" value="{$sp.description|htmlentities}" placeholder="选填说明">
|
|
</td>
|
|
<td style="text-align: center; vertical-align: middle;">
|
|
<button type="button" class="btn btn-xs btn-danger btn-del-spec"><i class="fa fa-trash-o"></i></button>
|
|
</td>
|
|
</tr>
|
|
{/foreach}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- ==================== Tab 2: 关联服务与定价配置 ==================== -->
|
|
<div class="tab-pane {if $activeTab=='services'}active{/if}" id="tab-services">
|
|
<div class="srv-matrix-toolbar">
|
|
<div class="srv-filter-btn-group">
|
|
<button type="button" class="srv-filter-btn active" data-filter="all">全部服务字典 ({:count($finalTypesPool)})</button>
|
|
<button type="button" class="srv-filter-btn" data-filter="enabled">仅看已启用服务</button>
|
|
</div>
|
|
<div style="display:flex;align-items:center;gap:10px;">
|
|
<input type="text" id="srv-matrix-search" class="form-control input-sm" style="width:210px;border-radius:6px;" placeholder="搜索服务名称或标识...">
|
|
</div>
|
|
</div>
|
|
|
|
<table class="srv-matrix-table" id="service-matrix-table">
|
|
<thead>
|
|
<tr>
|
|
<th style="width: 230px;">全局服务项</th>
|
|
<th class="col-main-hd" style="width: 430px;">作为【主服务项目】配置(用户单独呼叫该服务时的价格)</th>
|
|
<th class="col-addon-hd">作为【增项服务】配置(顺带加选时的加价)</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{foreach name="finalTypesPool" item="tp"}
|
|
<?php
|
|
$code = $tp['code'];
|
|
$name = $tp['name'];
|
|
$unit = $tp['unit'] ?: ($row['unit'] ?: '份');
|
|
|
|
$isMainChecked = !empty($savedMainMap) ? isset($savedMainMap[$code]) : ($tp['can_be_main'] == 1 && in_array($code, ['install','repair','remove']));
|
|
$mainSupportFixed = (int)$tp['support_fixed'];
|
|
$mainPrice = isset($savedMainMap[$code]['price']) && (float)$savedMainMap[$code]['price'] > 0 ? (float)$savedMainMap[$code]['price'] : (float)$tp['default_price'];
|
|
$isMainDefault = ($mainSupportFixed === 1 && isset($savedMainMap[$code]['is_default'])) ? (int)$savedMainMap[$code]['is_default'] : ($mainSupportFixed === 1 ? (int)$tp['is_default'] : 0);
|
|
|
|
$matchedAddon = isset($savedAddonMap[$code]) ? $savedAddonMap[$code] : (isset($savedAddonMap[$name]) ? $savedAddonMap[$name] : null);
|
|
$isAddonChecked = !empty($savedAddonMap) ? ($matchedAddon !== null) : ($code === 'remove');
|
|
$addonPrice = $matchedAddon !== null && isset($matchedAddon['price']) ? (float)$matchedAddon['price'] : ((float)$tp['default_addon_price'] > 0 ? (float)$tp['default_addon_price'] : 30.00);
|
|
$addonUnit = $matchedAddon !== null && !empty($matchedAddon['unit']) ? $matchedAddon['unit'] : $unit;
|
|
$rowEnabled = ($isMainChecked || $isAddonChecked);
|
|
?>
|
|
<tr class="srv-matrix-row {if $rowEnabled}is-row-enabled{else/}is-row-disabled{/if}" data-id="{$tp.id}" data-code="{$code}" data-name="{$name}" data-unit="{$addonUnit}" data-support-fixed="{$mainSupportFixed}">
|
|
<!-- 服务名称与标识 -->
|
|
<td>
|
|
<div class="srv-name-box">
|
|
<span class="srv-name-text">{$name}</span>
|
|
<span class="srv-code-badge">{$code}</span>
|
|
</div>
|
|
</td>
|
|
|
|
<!-- 主服务配置列 -->
|
|
<td class="srv-config-cell-main">
|
|
<div class="srv-inline-controls">
|
|
<label class="srv-switch switch-blue" title="开启/关闭主服务">
|
|
<input type="checkbox" class="st-enable" data-code="{$code}" {if $isMainChecked}checked{/if}>
|
|
<span class="slider"></span>
|
|
</label>
|
|
|
|
<div class="st-active-panel" style="display: {if $isMainChecked}inline-flex{else/}none{/if}; align-items: center; gap: 10px;">
|
|
{if $mainSupportFixed == 1}
|
|
<div class="input-group input-group-sm st-price-wrap" style="width: 170px;">
|
|
<span class="input-group-addon" style="background:#eff6ff;color:#1d4ed8;font-weight:700;">¥</span>
|
|
<input type="number" step="0.01" class="form-control st-price" data-code="{$code}" value="{$mainPrice}" style="font-weight:700;color:#0f172a;">
|
|
<span class="input-group-addon">/{$addonUnit}</span>
|
|
</div>
|
|
|
|
<label class="srv-default-label {if $isMainDefault==1}is-def-active{/if}">
|
|
<input type="radio" name="st_default_radio" class="st-default" data-code="{$code}" {if $isMainDefault==1}checked{/if}> 默认首选
|
|
</label>
|
|
{else/}
|
|
<span class="srv-quote-badge">不支持一口价(下单时自动转师傅报价)</span>
|
|
{/if}
|
|
</div>
|
|
|
|
<span class="srv-off-hint st-off-hint" style="display: {if $isMainChecked}none{else/}inline{/if};">未启用主服务</span>
|
|
</div>
|
|
</td>
|
|
|
|
<!-- 增项服务配置列 -->
|
|
<td class="srv-config-cell-addon">
|
|
<div class="srv-inline-controls">
|
|
<label class="srv-switch switch-orange" title="开启/关闭增项服务">
|
|
<input type="checkbox" class="ad-bind" data-code="{$code}" {if $isAddonChecked}checked{/if}>
|
|
<span class="slider"></span>
|
|
</label>
|
|
|
|
<div class="ad-active-panel" style="display: {if $isAddonChecked}inline-flex{else/}none{/if}; align-items: center; gap: 8px;">
|
|
<div class="input-group input-group-sm" style="width: 175px;">
|
|
<span class="input-group-addon" style="background:#fff7ed;color:#ea580c;font-weight:700;">+¥</span>
|
|
<input type="number" step="0.01" class="form-control ad-price" data-code="{$code}" value="{$addonPrice}" style="font-weight:700;color:#ea580c;">
|
|
<span class="input-group-addon">/{$addonUnit}</span>
|
|
</div>
|
|
</div>
|
|
|
|
<span class="srv-off-hint ad-off-hint" style="display: {if $isAddonChecked}none{else/}inline{/if};">未作为增项启用</span>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
{/foreach}
|
|
</tbody>
|
|
</table>
|
|
|
|
<input type="hidden" name="row[service_types_raw]" id="service_types_raw" value="">
|
|
<input type="hidden" name="row[addons_raw]" id="addons_raw" value="">
|
|
</div>
|
|
</div>
|
|
|
|
<div class="form-group layer-footer">
|
|
<label class="control-label col-xs-12 col-sm-2"></label>
|
|
<div class="col-xs-12 col-sm-8">
|
|
<button type="submit" class="btn btn-primary btn-embossed disabled" id="btn-submit-service"><i class="fa fa-check"></i> 保存商品与服务定价</button>
|
|
<button type="reset" class="btn btn-default btn-embossed">{:__('Reset')}</button>
|
|
</div>
|
|
</div>
|
|
</form>
|