在准备环境前提交次全部更改。

This commit is contained in:
Neo
2026-02-19 08:35:13 +08:00
parent ded6dfb9d8
commit 4eac07da47
1387 changed files with 6107191 additions and 33002 deletions

View File

@@ -0,0 +1,292 @@
"""
board-coach.html: 将单一助教列表替换为按筛选分类的多个 dim-container
并添加 JS 切换逻辑。同时修复 board-customer.html 各维度指数标签。
"""
import re
# ============================================================
# 1. board-coach.html — 多维度切换
# ============================================================
filepath = "docs/h5_ui/pages/board-coach.html"
with open(filepath, "r", encoding="utf-8") as f:
content = f.read()
# 定位旧的助教列表 + 隐藏样式区域
old_start = ' <!-- 助教列表'
old_end = ' <!-- 悬浮助手按钮 -->'
start_idx = content.index(old_start)
end_idx = content.index(old_end)
# 6 位助教的基础信息(复用)
coaches = [
("", "小燕", "from-blue-400 to-indigo-500", "星级", "bg-gradient-to-r from-amber-400 to-orange-400 text-white", "中🎱", "bg-primary/10 text-primary", ""),
("", "泡芙", "from-green-400 to-emerald-500", "高级", "bg-gradient-to-r from-purple-400 to-violet-400 text-white", "斯诺克", "bg-success/10 text-success", ""),
("A", "Amy", "from-pink-400 to-rose-500", "星级", "bg-gradient-to-r from-amber-400 to-orange-400 text-white", "中🎱", "bg-primary/10 text-primary", '<span class="px-1.5 py-0.5 bg-success/10 text-success text-xs rounded flex-shrink-0">斯诺克</span>'),
("M", "Mia", "from-amber-400 to-orange-500", "中级", "bg-gradient-to-r from-blue-400 to-indigo-400 text-white", "麻将", "bg-warning/10 text-warning", ""),
("", "糖糖", "from-purple-400 to-violet-500", "初级", "bg-gradient-to-r from-gray-400 to-gray-500 text-white", "中🎱", "bg-primary/10 text-primary", ""),
("", "露露", "from-cyan-400 to-teal-500", "中级", "bg-gradient-to-r from-blue-400 to-indigo-400 text-white", "团建", "bg-error/10 text-error", ""),
]
clients = [
("💖 王先生", "💖 李女士", "💛 赵总"),
("💖 陈先生", "💛 刘女士", "💛 黄总"),
("💖 张先生", "💛 周女士", "💛 吴总"),
("💛 赵先生", "💛 吴女士", "💛 孙总"),
("💛 钱先生", "💛 孙女士", "💛 周总"),
("💛 郑先生", "💛 冯女士", "💛 陈总"),
]
def coach_header(i):
"""生成助教卡片的头像+昵称+标签行(通用)"""
ch, name, grad, level, lvl_cls, skill, sk_cls, extra = coaches[i]
return f''' <div class="w-11 h-11 rounded-full bg-gradient-to-br {grad} flex items-center justify-center flex-shrink-0">
<span class="text-white font-semibold text-base">{ch}</span>
</div>
<div class="flex-1 min-w-0">
<div class="flex items-center gap-1.5 flex-wrap">
<span class="text-base font-semibold text-gray-13">{name}</span>
<span class="px-1.5 py-0.5 {lvl_cls} text-xs rounded flex-shrink-0">{level}</span>
<span class="px-1.5 py-0.5 {sk_cls} text-xs rounded flex-shrink-0">{skill}</span>
{extra}
</div>'''
def coach_row2(i, right_html):
"""生成第二行:客户 + 右侧数据"""
c1, c2, c3 = clients[i]
return f''' <div class="flex items-center justify-between text-xs pt-2 border-t border-gray-100">
<div class="flex items-center gap-2 text-gray-6 truncate">
<span>{c1}</span><span>{c2}</span><span>{c3}</span>
</div>
{right_html}
</div>'''
# 定档业绩数据
perf_data = [
("86.2", "13.8", "92.0"),
("72.5", "7.5", "78.0"),
("68.0", "32.0", "72.5"),
("55.0", "5.0", ""),
("42.0", "达标", "45.0"),
("38.0", "22.0", ""),
]
perf_levels = [
("星级", "王牌"),
("高级", "星级"),
("星级", "王牌"),
("中级", "高级"),
("初级", "中级"),
("中级", "高级"),
]
def make_perf_card(i):
"""定档业绩最高/最低 卡片"""
h, need, pre = perf_data[i]
cur, nxt = perf_levels[i]
if need == "达标":
data_line = f''' <div class="mt-1 flex items-center gap-2 text-xs">
<span class="font-bold text-success text-sm">{h}h</span>
<span class="text-success font-medium">✅ 已达标</span>
</div>'''
else:
data_line = f''' <div class="mt-1 flex items-center gap-2 text-xs">
<span class="font-bold text-primary text-sm">{h}h</span>
<span class="text-gray-7">下一档还需 <span class="text-warning font-medium">{need}h</span></span>
</div>'''
pre_html = f'<span class="text-gray-5">|</span>\n <span>折前 <b class="text-gray-10">{pre}h</b></span>' if pre else ''
right = f'''<div class="flex items-center gap-2 text-gray-7 flex-shrink-0">
<span>定档 <b class="text-gray-10">{h}h</b></span>
{pre_html}
</div>'''
return f''' <a href="coach-detail.html" class="block bg-white rounded-2xl p-4 shadow-sm coach-card">
<div class="flex items-start gap-3 mb-2.5">
{coach_header(i)}
{data_line}
</div>
</div>
{coach_row2(i, right)}
</a>'''
# 工资数据
salary_data = ["¥12,680", "¥10,200", "¥9,800", "¥7,500", "¥6,200", "¥5,100"]
def make_salary_card(i):
"""工资最高/最低 卡片"""
sal = salary_data[i]
h = perf_data[i][0]
pre = perf_data[i][2]
pre_html = f'<span class="text-gray-5">|</span>\n <span>折前 <b class="text-gray-10">{pre}h</b></span>' if pre else ''
right = f'''<div class="flex items-center gap-2 text-gray-7 flex-shrink-0">
<span>定档 <b class="text-gray-10">{h}h</b></span>
{pre_html}
</div>'''
return f''' <a href="coach-detail.html" class="block bg-white rounded-2xl p-4 shadow-sm coach-card">
<div class="flex items-start gap-3 mb-2.5">
{coach_header(i)}
<div class="mt-1 flex items-center gap-2">
<span class="text-lg font-semibold text-gray-13">{sal}</span>
<span class="px-1.5 py-0.5 bg-warning/10 text-warning text-xs rounded">预估</span>
</div>
</div>
</div>
{coach_row2(i, right)}
</a>'''
# 客源储值数据
sv_balance = ["¥45,200", "¥38,600", "¥32,100", "¥28,500", "¥22,000", "¥18,300"]
sv_consume = ["¥8,600", "¥6,200", "¥5,800", "¥4,100", "¥3,500", "¥2,800"]
def make_sv_card(i):
"""客源储值最高 卡片"""
right = f'''<div class="flex items-center gap-2 text-gray-7 flex-shrink-0">
<span>周期消耗 <b class="text-gray-10">{sv_consume[i]}</b></span>
</div>'''
return f''' <a href="coach-detail.html" class="block bg-white rounded-2xl p-4 shadow-sm coach-card">
<div class="flex items-start gap-3 mb-2.5">
{coach_header(i)}
<div class="mt-1">
<span class="text-lg font-semibold text-gray-13">{sv_balance[i]}</span>
<span class="text-xs text-gray-6 ml-1">客户储值余额</span>
</div>
</div>
</div>
{coach_row2(i, right)}
</a>'''
# 任务完成数据
task_counts = [(32, 18), (28, 15), (25, 14), (20, 12), (18, 10), (15, 9)]
def make_task_card(i):
"""任务完成最多 卡片"""
tc, cc = task_counts[i]
h = perf_data[i][0]
pre = perf_data[i][2]
pre_html = f'<span class="text-gray-5">|</span>\n <span>折前 <b class="text-gray-10">{pre}h</b></span>' if pre else ''
right = f'''<div class="flex items-center gap-2 text-gray-7 flex-shrink-0">
<span>定档 <b class="text-gray-10">{h}h</b></span>
{pre_html}
</div>'''
return f''' <a href="coach-detail.html" class="block bg-white rounded-2xl p-4 shadow-sm coach-card">
<div class="flex items-start gap-3 mb-2.5">
{coach_header(i)}
<div class="mt-1 flex items-center gap-3">
<div><span class="text-lg font-semibold text-primary">{tc}</span><span class="text-xs text-gray-6 ml-0.5">个任务</span></div>
<div class="w-px h-4 bg-gray-3"></div>
<div><span class="text-lg font-semibold text-gray-13">{cc}</span><span class="text-xs text-gray-6 ml-0.5">位客户</span></div>
</div>
</div>
</div>
{coach_row2(i, right)}
</a>'''
# 生成各维度容器
dims = []
# 定档业绩最高
cards = "\n\n".join(make_perf_card(i) for i in range(6))
dims.append(f''' <!-- ====== 定档业绩最高/最低 ====== -->
<div id="dim-perf" class="dim-container active p-4 space-y-3">
{cards}
</div>''')
# 工资最高
cards = "\n\n".join(make_salary_card(i) for i in range(6))
dims.append(f''' <!-- ====== 工资最高/最低 ====== -->
<div id="dim-salary" class="dim-container p-4 space-y-3">
{cards}
</div>''')
# 客源储值最高
cards = "\n\n".join(make_sv_card(i) for i in range(6))
dims.append(f''' <!-- ====== 客源储值最高 ====== -->
<div id="dim-sv" class="dim-container p-4 space-y-3">
{cards}
</div>''')
# 任务完成最多
cards = "\n\n".join(make_task_card(i) for i in range(6))
dims.append(f''' <!-- ====== 任务完成最多 ====== -->
<div id="dim-task" class="dim-container p-4 space-y-3">
{cards}
</div>''')
new_section = "\n\n".join(dims) + "\n\n"
content = content[:start_idx] + new_section + content[end_idx:]
# 添加 dim-container CSS如果不存在
if '.dim-container' not in content:
content = content.replace(
'.coach-card:active {',
'.dim-container { display: none; }\n .dim-container.active { display: block; }\n .coach-card:active {'
)
# 替换 selectSort JS 函数,添加维度切换逻辑
old_select_sort = ''' function selectSort(value) {
document.getElementById('sortLabel').textContent = value;
closeAllFilters();
}'''
new_select_sort = ''' function selectSort(value) {
document.getElementById('sortLabel').textContent = value;
closeAllFilters();
// 切换维度容器
var dimMap = {
'定档业绩最高': 'dim-perf',
'定档业绩最低': 'dim-perf',
'工资最高': 'dim-salary',
'工资最低': 'dim-salary',
'客源储值最高': 'dim-sv',
'任务完成最多': 'dim-task'
};
document.querySelectorAll('.dim-container').forEach(function(el) { el.classList.remove('active'); });
var id = dimMap[value];
if (id) document.getElementById(id).classList.add('active');
}'''
content = content.replace(old_select_sort, new_select_sort)
with open(filepath, "w", encoding="utf-8") as f:
f.write(content)
print("OK — board-coach.html: 4 dim-containers + JS 切换")
# ============================================================
# 2. board-customer.html — 修正各维度的指数标签
# ============================================================
filepath2 = "docs/h5_ui/pages/board-customer.html"
with open(filepath2, "r", encoding="utf-8") as f:
c2 = f.read()
# 最高余额维度:指数标签应该是"余额排名"而不是"消费潜力指数"
# 最频繁维度:应该是"到店频率"
# 最近到店:应该是"到店新鲜度"
# 最专一:应该是"专一指数"
# 最高消费近60天应该是"消费力指数"
replacements = [
# dim-balance 区域
('id="dim-balance"', '消费潜力指数', '余额排名'),
# dim-freq60 区域
('id="dim-freq60"', '消费潜力指数', '到店频率'),
# dim-recent 区域
('id="dim-recent"', '消费潜力指数', '到店新鲜度'),
# dim-loyal 区域
('id="dim-loyal"', '消费潜力指数', '专一指数'),
# dim-spend60 区域
('id="dim-spend60"', '消费潜力指数', '消费力指数'),
]
for dim_id, old_label, new_label in replacements:
# 找到该维度区域的起始位置
dim_start = c2.index(dim_id)
# 找到下一个维度或文件末尾
next_dim = c2.find('dim-container', dim_start + 50)
if next_dim == -1:
next_dim = len(c2)
# 在该区域内替换标签
section = c2[dim_start:next_dim]
section = section.replace(old_label, new_label)
c2 = c2[:dim_start] + section + c2[next_dim:]
with open(filepath2, "w", encoding="utf-8") as f:
f.write(c2)
print("OK — board-customer.html: 各维度指数标签已修正")