dm-design/平台端web/菜市场管理/菜市场列表.html

1695 lines
60 KiB
HTML
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>菜市场管理</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
background-color: #f5f7fa;
padding: 20px;
}
.container {
max-width: 1600px;
margin: 0 auto;
background: white;
padding: 20px;
border-radius: 8px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}
/* 搜索栏样式 */
.search-bar {
display: flex;
gap: 15px;
margin-bottom: 20px;
align-items: center;
flex-wrap: wrap;
}
.search-bar input,
.search-bar select {
padding: 8px 12px;
border: 1px solid #dcdfe6;
border-radius: 4px;
font-size: 14px;
outline: none;
min-width: 180px;
}
.search-bar input:focus,
.search-bar select:focus {
border-color: #409eff;
}
.search-bar input::placeholder {
color: #c0c4cc;
}
.btn {
padding: 8px 20px;
border: none;
border-radius: 4px;
font-size: 14px;
cursor: pointer;
transition: all 0.3s;
}
.btn-primary {
background-color: #409eff;
color: white;
}
.btn-primary:hover {
background-color: #66b1ff;
}
.btn-success {
background-color: #67c23a;
color: white;
}
.btn-success:hover {
background-color: #85ce61;
}
.btn-small {
padding: 5px 12px;
font-size: 12px;
max-width: 90px;
white-space: normal;
word-break: break-all;
line-height: 1.4;
}
.btn-danger {
background-color: #f56c6c;
color: white;
}
.btn-danger:hover {
background-color: #f78989;
}
/* 新增按钮 */
.add-section {
margin-bottom: 15px;
}
/* 表格样式 */
.table-wrapper {
overflow-x: auto;
}
table {
width: 100%;
border-collapse: collapse;
font-size: 14px;
}
thead {
background-color: #f5f7fa;
}
th {
padding: 12px 8px;
text-align: center;
font-weight: 500;
color: #606266;
border-bottom: 1px solid #ebeef5;
white-space: nowrap;
}
td {
padding: 12px 8px;
text-align: center;
border-bottom: 1px solid #ebeef5;
color: #606266;
}
tbody tr:hover {
background-color: #f5f7fa;
}
/* 操作按钮组 */
.action-buttons {
display: flex;
flex-direction: column;
gap: 8px;
align-items: center;
}
.action-row {
display: flex;
gap: 5px;
justify-content: center;
flex-wrap: wrap;
}
/* 状态标签 */
.status-normal {
color: #67c23a;
}
.status-disabled {
color: #909399;
}
.business-status {
color: #606266;
}
/* 模态框样式 */
.modal {
display: none;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.5);
z-index: 1000;
}
.modal.active {
display: flex;
align-items: center;
justify-content: center;
}
.modal-content {
background: white;
width: 90%;
max-width: 650px;
max-height: 90vh;
border-radius: 8px;
overflow: hidden;
display: flex;
flex-direction: column;
}
.modal-header {
padding: 20px;
border-bottom: 1px solid #ebeef5;
display: flex;
justify-content: space-between;
align-items: center;
}
.modal-header h3 {
font-size: 18px;
color: #303133;
margin: 0;
}
.modal-close {
font-size: 24px;
color: #909399;
cursor: pointer;
border: none;
background: none;
padding: 0;
width: 24px;
height: 24px;
line-height: 1;
}
.modal-close:hover {
color: #606266;
}
.modal-body {
padding: 20px;
overflow-y: auto;
flex: 1;
}
.modal-footer {
padding: 15px 20px;
border-top: 1px solid #ebeef5;
display: flex;
justify-content: flex-end;
gap: 10px;
}
/* 表单样式 */
.form-section {
margin-bottom: 25px;
}
.form-section-title {
font-size: 16px;
color: #303133;
font-weight: 500;
margin-bottom: 15px;
padding-bottom: 10px;
border-bottom: 1px solid #ebeef5;
}
.form-group {
margin-bottom: 18px;
display: flex;
align-items: flex-start;
}
.form-label {
width: 120px;
padding-top: 8px;
color: #606266;
font-size: 14px;
text-align: right;
padding-right: 12px;
flex-shrink: 0;
}
.form-label.required::before {
content: "*";
color: #f56c6c;
margin-right: 4px;
}
.form-input-wrapper {
flex: 1;
}
.form-input,
.form-select,
.form-textarea {
width: 100%;
padding: 8px 12px;
border: 1px solid #dcdfe6;
border-radius: 4px;
font-size: 14px;
outline: none;
transition: border-color 0.3s;
}
.form-input:focus,
.form-select:focus,
.form-textarea:focus {
border-color: #409eff;
}
.form-input::placeholder,
.form-textarea::placeholder {
color: #c0c4cc;
}
.form-textarea {
resize: vertical;
min-height: 80px;
}
/* 图片上传样式 */
.upload-box {
width: 140px;
height: 140px;
border: 1px dashed #dcdfe6;
border-radius: 4px;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
background-color: #fafafa;
transition: border-color 0.3s;
}
.upload-box:hover {
border-color: #409eff;
}
.upload-box-text {
color: #909399;
font-size: 14px;
}
/* 开关样式 */
.switch-group {
display: flex;
align-items: center;
gap: 15px;
}
.switch {
position: relative;
display: inline-block;
width: 44px;
height: 22px;
}
.switch input {
opacity: 0;
width: 0;
height: 0;
}
.switch-slider {
position: absolute;
cursor: pointer;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: #dcdfe6;
transition: 0.3s;
border-radius: 22px;
}
.switch-slider:before {
position: absolute;
content: "";
height: 18px;
width: 18px;
left: 2px;
bottom: 2px;
background-color: white;
transition: 0.3s;
border-radius: 50%;
}
.switch input:checked + .switch-slider {
background-color: #409eff;
}
.switch input:checked + .switch-slider:before {
transform: translateX(22px);
}
.switch-label {
color: #606266;
font-size: 14px;
}
.switch-label.active {
color: #409eff;
}
/* 单选框组样式 */
.radio-group {
display: flex;
gap: 15px;
align-items: center;
}
.radio-option {
display: flex;
align-items: center;
gap: 5px;
}
.radio-option input[type="radio"] {
margin: 0;
}
.radio-option label {
color: #606266;
font-size: 14px;
cursor: pointer;
}
/* 复选框组样式 */
.checkbox-group {
display: flex;
gap: 15px;
align-items: center;
}
.checkbox-option {
display: flex;
align-items: center;
gap: 5px;
}
.checkbox-option input[type="checkbox"] {
margin: 0;
}
.checkbox-option label {
color: #606266;
font-size: 14px;
cursor: pointer;
}
/* 时间输入样式 */
.time-group {
display: flex;
gap: 10px;
align-items: center;
}
.time-input {
width: 180px;
}
/* 说明文字样式 */
.form-hint {
color: #909399;
font-size: 12px;
margin-top: 5px;
line-height: 1.5;
}
/* 地图位置选择 */
.location-input {
position: relative;
}
.location-icon {
position: absolute;
right: 10px;
top: 50%;
transform: translateY(-50%);
color: #409eff;
cursor: pointer;
}
.btn-cancel {
background-color: white;
color: #606266;
border: 1px solid #dcdfe6;
}
.btn-cancel:hover {
background-color: #f5f7fa;
border-color: #c0c4cc;
}
/* 隐藏元素 */
.hidden {
display: none !important;
}
/* 权限配置样式 */
.permissions-container {
max-height: 400px;
overflow-y: auto;
}
.permission-tree {
list-style: none;
padding: 0;
margin: 0;
}
.permission-item {
margin-bottom: 8px;
}
.permission-node {
display: flex;
align-items: center;
padding: 10px 12px;
border-radius: 4px;
transition: all 0.3s;
cursor: pointer;
background-color: #fafafa;
border: 1px solid #ebeef5;
}
.permission-node:hover {
background-color: #f0f7ff;
border-color: #409eff;
}
.permission-node.selected {
background-color: #e6f4ff;
border-color: #409eff;
}
.permission-checkbox {
margin-right: 10px;
width: 16px;
height: 16px;
cursor: pointer;
}
.expand-btn {
background: none;
border: none;
cursor: pointer;
padding: 2px;
margin-right: 8px;
color: #409eff;
font-size: 12px;
transition: all 0.3s;
min-width: 20px;
border-radius: 3px;
}
.expand-btn:hover {
background: #e6f4ff;
}
.expand-btn.collapsed {
transform: rotate(-90deg);
}
.permission-label {
font-size: 14px;
color: #606266;
user-select: none;
flex: 1;
}
.permission-children {
margin-left: 32px;
margin-top: 8px;
border-left: 2px solid #e6f4ff;
padding-left: 12px;
display: none;
}
.permission-children.expanded {
display: block;
}
.permission-item.parent > .permission-node {
background-color: #f5f7fa;
font-weight: 500;
}
/* 权限容器滚动条样式 */
.permissions-container::-webkit-scrollbar {
width: 6px;
}
.permissions-container::-webkit-scrollbar-track {
background: #f5f7fa;
border-radius: 3px;
}
.permissions-container::-webkit-scrollbar-thumb {
background: #dcdfe6;
border-radius: 3px;
}
.permissions-container::-webkit-scrollbar-thumb:hover {
background: #c0c4cc;
}
</style>
</head>
<body>
<div class="container">
<!-- 搜索栏 -->
<div class="search-bar">
<input type="text" placeholder="市场名称">
<select>
<option value="">地区</option>
<option value="shanghai">上海市</option>
<option value="beijing">北京市</option>
<option value="fujian">福建省</option>
</select>
<select>
<option value="">状态</option>
<option value="normal">正常</option>
<option value="disabled">禁用</option>
</select>
<button class="btn btn-primary">搜索</button>
</div>
<!-- 新增按钮 -->
<div class="add-section">
<button class="btn btn-success">新增</button>
<button class="btn btn-primary" onclick="goToPendingMarkets()">待审核菜市场</button>
</div>
<!-- 表格 -->
<div class="table-wrapper">
<table>
<thead>
<tr>
<th>市场名</th>
<th>商品类目类型</th>
<th>地址</th>
<th>经营者姓名</th>
<th>经营者账号</th>
<th>第三方配送</th>
<th>状态</th>
<th>摊位数</th>
<th>营业状态</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<tr data-category-type="offline">
<td>权限测试市场</td>
<td>线下菜市场</td>
<td>上海市市辖区闵行区</td>
<td>权限测试</td>
<td>13800001500</td>
<td></td>
<td class="status-normal">正常</td>
<td>2</td>
<td class="business-status">营业</td>
<td>
<div class="action-buttons">
<div class="action-row">
<button class="btn btn-primary btn-small">设置结算比例</button>
<button class="btn btn-primary btn-small">分销推广</button>
<button class="btn btn-primary btn-small">摊位详情</button>
</div>
<div class="action-row">
<button class="btn btn-primary btn-small">详情</button>
<button class="btn btn-primary btn-small">编辑</button>
<button class="btn btn-danger btn-small">删除</button>
</div>
</div>
</td>
</tr>
<tr data-category-type="cloud">
<td>测试菜市场-葡萄</td>
<td>云店</td>
<td>北京市市辖区东城区</td>
<td>林xx</td>
<td>17750208698</td>
<td></td>
<td class="status-normal">正常</td>
<td>0</td>
<td class="business-status">营业</td>
<td>
<div class="action-buttons">
<div class="action-row">
<button class="btn btn-primary btn-small">设置结算比例</button>
<button class="btn btn-primary btn-small">分销推广</button>
<button class="btn btn-primary btn-small">摊位详情</button>
</div>
<div class="action-row">
<button class="btn btn-primary btn-small">详情</button>
<button class="btn btn-primary btn-small">编辑</button>
<button class="btn btn-danger btn-small">删除</button>
</div>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<!-- 摊位详情模态框 -->
<div class="modal" id="boothDetailModal">
<div class="modal-content" style="max-width: 1200px;">
<div class="modal-header">
<h3>摊铺详情</h3>
<button class="modal-close" onclick="closeBoothDetailModal()">&times;</button>
</div>
<div class="modal-body">
<!-- 标签页导航 -->
<div style="border-bottom: 2px solid #ebeef5; margin-bottom: 20px;">
<div style="display: inline-block; padding: 10px 20px; border-bottom: 2px solid #409eff; color: #409eff; font-weight: 500; cursor: pointer;">
摊位列表
</div>
</div>
<!-- 摊位列表表格 -->
<div class="table-wrapper">
<table>
<thead>
<tr>
<th>摊位ID</th>
<th>摊位名称</th>
<th>收益人名称</th>
<th>收益人手机号</th>
<th>加入时间</th>
</tr>
</thead>
<tbody id="boothListTableBody">
<!-- 动态填充摊位数据 -->
</tbody>
</table>
</div>
</div>
<div class="modal-footer">
<button class="btn btn-cancel" onclick="closeBoothDetailModal()">关闭</button>
</div>
</div>
</div>
<!-- 设置结算比例模态框 -->
<div class="modal" id="settlementRatioModal">
<div class="modal-content" style="max-width: 500px;">
<div class="modal-header">
<h3>设置结算比例</h3>
<button class="modal-close" onclick="closeSettlementModal()">&times;</button>
</div>
<div class="modal-body">
<form id="settlementRatioForm">
<div class="form-group">
<div class="form-label required">结算比例</div>
<div class="form-input-wrapper">
<input type="number" class="form-input" id="settlementRatio" value="0.000" step="0.001" min="0" max="1" placeholder="请输入结算比例">
</div>
</div>
</form>
</div>
<div class="modal-footer">
<button class="btn btn-cancel" onclick="closeSettlementModal()">关闭</button>
<button class="btn btn-primary" onclick="submitSettlementRatio()">确定</button>
</div>
</div>
</div>
<!-- 详情模态框 -->
<div class="modal" id="detailMarketModal">
<div class="modal-content">
<div class="modal-header">
<h3>菜市场详情</h3>
<button class="modal-close" onclick="closeDetailModal()">&times;</button>
</div>
<div class="modal-body">
<form id="detailMarketForm">
<!-- 基础配置 -->
<div class="form-section">
<div class="form-section-title">基础信息</div>
<div class="form-group">
<div class="form-label">菜市场名称</div>
<div class="form-input-wrapper">
<input type="text" class="form-input" id="detailMarketName" readonly>
</div>
</div>
<div class="form-group">
<div class="form-label">详细地址</div>
<div class="form-input-wrapper">
<input type="text" class="form-input" id="detailDetailAddress" readonly>
</div>
</div>
<div class="form-group">
<div class="form-label">定位信息</div>
<div class="form-input-wrapper">
<div style="width: 100%; height: 300px; border: 1px solid #dcdfe6; border-radius: 4px; background-color: #f5f7fa; display: flex; align-items: center; justify-content: center; color: #909399; font-size: 14px;">
<div style="text-align: center;">
<div style="font-size: 48px; margin-bottom: 10px;">📍</div>
<div>地图定位显示区域</div>
<div style="font-size: 12px; margin-top: 5px;" id="detailLocationCoords"></div>
</div>
</div>
</div>
</div>
</div>
</form>
</div>
<div class="modal-footer">
<button class="btn btn-cancel" onclick="closeDetailModal()">关闭</button>
</div>
</div>
</div>
<!-- 新增菜市场模态框 -->
<div class="modal" id="addMarketModal">
<div class="modal-content">
<div class="modal-header">
<h3>新增菜市场</h3>
<button class="modal-close" onclick="closeModal()">&times;</button>
</div>
<div class="modal-body">
<form id="addMarketForm">
<!-- 经营者信息 -->
<div class="form-section">
<div class="form-section-title">经营者信息</div>
<div class="form-group">
<div class="form-label required">经营者账号</div>
<div class="form-input-wrapper">
<input type="text" class="form-input" id="operatorAccount" placeholder="请输入手机号码" maxlength="11">
<div class="form-hint">请输入经营者的手机号码</div>
</div>
</div>
<div class="form-group">
<div class="form-label required">验证码</div>
<div class="form-input-wrapper">
<div style="display: flex; gap: 10px;">
<input type="text" class="form-input" id="verifyCode" placeholder="请输入验证码" maxlength="6" style="flex: 1;">
<button type="button" class="btn btn-primary" id="sendCodeBtn" onclick="sendVerifyCode()">发送验证码</button>
</div>
<div class="form-hint">验证码将发送至经营者手机</div>
</div>
</div>
</div>
<!-- 权限配置 -->
<div class="form-section">
<div class="form-section-title">权限配置</div>
<div class="form-group" style="display: block;">
<div class="permissions-container" style="max-height: 400px; overflow-y: auto; border: 1px solid #ebeef5; border-radius: 4px; padding: 15px;">
<ul id="permissionTree" class="permission-tree">
<!-- 权限树将通过JavaScript动态生成 -->
</ul>
</div>
</div>
</div>
<!-- 基础配置 -->
<div class="form-section">
<div class="form-section-title">基础配置</div>
<div class="form-group">
<div class="form-label required">菜市场名称</div>
<div class="form-input-wrapper">
<input type="text" class="form-input" id="marketName" placeholder="请输入菜市场名称25字符内" maxlength="25">
</div>
</div>
<div class="form-group">
<div class="form-label required">商品类目类型</div>
<div class="form-input-wrapper">
<select class="form-select" id="categoryType">
<option value="">请选择商品类目类型</option>
<option value="offline">线下菜市场</option>
<option value="cloud">云店</option>
</select>
</div>
</div>
<div class="form-group">
<div class="form-label required">菜市场背景图</div>
<div class="form-input-wrapper">
<div class="upload-box">
<span class="upload-box-text">选择图片</span>
</div>
</div>
</div>
<div class="form-group">
<div class="form-label required">菜市场营业执照</div>
<div class="form-input-wrapper">
<div class="upload-box">
<span class="upload-box-text">选择图片</span>
</div>
</div>
</div>
<div class="form-group">
<div class="form-label required">菜市场实拍图</div>
<div class="form-input-wrapper">
<div class="upload-box">
<span class="upload-box-text">选择图片</span>
</div>
</div>
</div>
<div class="form-group">
<div class="form-label required">菜市场营业执照</div>
<div class="form-input-wrapper">
<div class="upload-box">
<span class="upload-box-text">选择图片</span>
</div>
</div>
</div>
<div class="form-group">
<div class="form-label required">菜市场实拍图</div>
<div class="form-input-wrapper">
<div class="upload-box">
<span class="upload-box-text">选择图片</span>
</div>
</div>
</div>
<div class="form-group">
<div class="form-label required">菜市场地址</div>
<div class="form-input-wrapper">
<select class="form-select">
<option value="">请选择省市区</option>
<option value="shanghai">上海市</option>
<option value="beijing">北京市</option>
<option value="fujian">福建省</option>
</select>
</div>
</div>
<div class="form-group">
<div class="form-label required">详细地址</div>
<div class="form-input-wrapper">
<input type="text" class="form-input" placeholder="请输入具体地址">
</div>
</div>
<div class="form-group">
<div class="form-label required">菜市场定位</div>
<div class="form-input-wrapper">
<div style="width: 100%; height: 300px; border: 1px solid #dcdfe6; border-radius: 4px; background-color: #f5f7fa; display: flex; align-items: center; justify-content: center; color: #909399; font-size: 14px; cursor: pointer;" onclick="selectLocation()">
<div style="text-align: center;">
<div style="font-size: 48px; margin-bottom: 10px;">📍</div>
<div>点击选择地图定位</div>
<div style="font-size: 12px; margin-top: 5px; color: #f56c6c;" id="selectedLocationText">请选择定位</div>
</div>
</div>
<input type="hidden" id="locationLat" value="">
<input type="hidden" id="locationLng" value="">
</div>
</div>
<div class="form-group">
<div class="form-label required">菜市场营业时间</div>
<div class="form-input-wrapper">
<div class="switch-group">
<span class="switch-label">手动营业</span>
<label class="switch">
<input type="checkbox" id="autoBusinessTime" checked onchange="toggleBusinessTimeOptions()">
<span class="switch-slider"></span>
</label>
<span class="switch-label active">自动营业</span>
</div>
<div class="checkbox-group" id="businessDayOptions" style="margin-top: 10px;">
<div class="checkbox-option">
<input type="checkbox" id="everyday">
<label for="everyday">每天</label>
</div>
<div class="checkbox-option">
<input type="checkbox" id="workday">
<label for="workday">工作日</label>
</div>
<div class="checkbox-option">
<input type="checkbox" id="custom">
<label for="custom">自定义</label>
</div>
</div>
<div class="time-group" id="businessTimeRange" style="margin-top: 10px;">
<input type="time" class="form-input time-input" placeholder="开始营业时间">
<input type="time" class="form-input time-input" placeholder="结束营业时间">
</div>
</div>
</div>
<div class="form-group">
<div class="form-label required">菜市场状态</div>
<div class="form-input-wrapper">
<div class="switch-group">
<span class="switch-label">禁用</span>
<label class="switch">
<input type="checkbox" id="marketStatus" checked>
<span class="switch-slider"></span>
</label>
<span class="switch-label active">启用</span>
</div>
<div class="form-hint">禁用后,用户端不展示该菜市场</div>
</div>
</div>
</div>
<!-- 配送设置 -->
<div class="form-section">
<div class="form-section-title">配送设置</div>
<div class="form-group">
<div class="form-label"></div>
<div class="form-input-wrapper">
<div class="form-hint"> 开启后,将允许该菜市场经营者/摊主(无经营者)自由配置是否呼叫第三方骑手进行配送;</div>
<div class="form-hint">第三方配送费用因距离、天气、时段等因素会产生不同程度的浮动;将根据实际配送费用进行扣除。</div>
</div>
</div>
<div class="form-group">
<div class="form-label">是否允许第三方骑手配送</div>
<div class="form-input-wrapper">
<div class="switch-group">
<span class="switch-label">禁用</span>
<label class="switch">
<input type="checkbox" id="thirdPartyDelivery" checked>
<span class="switch-slider"></span>
</label>
<span class="switch-label active">启用</span>
</div>
</div>
</div>
</div>
</form>
</div>
<div class="modal-footer">
<button class="btn btn-cancel" onclick="closeModal()">取消</button>
<button class="btn btn-primary" onclick="submitForm()">确认</button>
</div>
</div>
</div>
<script>
// 权限数据
const permissions = [
{
id: 1,
code: 'MARKET_MANAGE',
name: '菜市场管理',
description: '菜市场管理模块',
parentCode: '',
type: 'menu'
},
{
id: 2,
code: 'MARKET_BOOTH',
name: '摊位管理',
description: '摊位管理功能',
parentCode: 'MARKET_MANAGE',
type: 'menu'
},
{
id: 3,
code: 'MARKET_BOOTH_ADD',
name: '添加摊位',
description: '添加新摊位按钮',
parentCode: 'MARKET_BOOTH',
type: 'button'
},
{
id: 4,
code: 'MARKET_BOOTH_EDIT',
name: '编辑摊位',
description: '编辑摊位信息按钮',
parentCode: 'MARKET_BOOTH',
type: 'button'
},
{
id: 5,
code: 'MARKET_BOOTH_DELETE',
name: '删除摊位',
description: '删除摊位按钮',
parentCode: 'MARKET_BOOTH',
type: 'button'
},
{
id: 6,
code: 'MARKET_GOODS',
name: '商品管理',
description: '商品管理功能',
parentCode: 'MARKET_MANAGE',
type: 'menu'
},
{
id: 7,
code: 'MARKET_GOODS_ADD',
name: '添加商品',
description: '添加新商品按钮',
parentCode: 'MARKET_GOODS',
type: 'button'
},
{
id: 8,
code: 'MARKET_GOODS_EDIT',
name: '编辑商品',
description: '编辑商品信息按钮',
parentCode: 'MARKET_GOODS',
type: 'button'
},
{
id: 9,
code: 'ORDER_MANAGE',
name: '订单管理',
description: '订单管理模块',
parentCode: '',
type: 'menu'
},
{
id: 10,
code: 'ORDER_VIEW',
name: '查看订单',
description: '查看订单功能',
parentCode: 'ORDER_MANAGE',
type: 'menu'
},
{
id: 11,
code: 'ORDER_PROCESS',
name: '处理订单',
description: '处理订单按钮',
parentCode: 'ORDER_MANAGE',
type: 'button'
},
{
id: 12,
code: 'FINANCE_MANAGE',
name: '财务管理',
description: '财务管理模块',
parentCode: '',
type: 'menu'
},
{
id: 13,
code: 'FINANCE_VIEW',
name: '查看财务',
description: '查看财务数据',
parentCode: 'FINANCE_MANAGE',
type: 'menu'
}
];
let selectedPermissions = new Set();
// 验证码倒计时
let countdown = 0;
let countdownTimer = null;
// 切换营业时间选项的显示/隐藏
function toggleBusinessTimeOptions() {
const autoBusinessTime = document.getElementById('autoBusinessTime');
const businessDayOptions = document.getElementById('businessDayOptions');
const businessTimeRange = document.getElementById('businessTimeRange');
if (autoBusinessTime.checked) {
// 自动营业,显示时间范围和日期选项
businessDayOptions.classList.remove('hidden');
businessTimeRange.classList.remove('hidden');
} else {
// 手动营业,隐藏时间范围和日期选项
businessDayOptions.classList.add('hidden');
businessTimeRange.classList.add('hidden');
}
}
// 选择地图定位
function selectLocation() {
// 这里应该打开地图选择器实际应调用地图API
// 模拟选择定位
alert('此处应打开地图选择器实际开发时需要集成地图API如高德地图、百度地图等');
// 模拟选择了一个位置
const mockLat = 31.230416;
const mockLng = 121.473701;
document.getElementById('locationLat').value = mockLat;
document.getElementById('locationLng').value = mockLng;
document.getElementById('selectedLocationText').textContent = '已选择: ' + mockLat + ', ' + mockLng;
document.getElementById('selectedLocationText').style.color = '#67c23a';
}
// 发送验证码
function sendVerifyCode() {
const account = document.getElementById('operatorAccount').value;
const btn = document.getElementById('sendCodeBtn');
// 验证手机号格式
if (!account || !/^1[3-9]\d{9}$/.test(account)) {
alert('请输入正确的手机号码');
return;
}
// 如果正在倒计时,不允许再次发送
if (countdown > 0) {
return;
}
// 这里应该调用后端API发送验证码
// 模拟发送成功
alert('验证码已发送至 ' + account);
// 开始倒计时
countdown = 60;
btn.disabled = true;
btn.textContent = countdown + '秒后重发';
countdownTimer = setInterval(function() {
countdown--;
if (countdown > 0) {
btn.textContent = countdown + '秒后重发';
} else {
clearInterval(countdownTimer);
btn.disabled = false;
btn.textContent = '发送验证码';
}
}, 1000);
}
// 搜索功能
document.querySelector('.search-bar .btn-primary').addEventListener('click', function() {
alert('搜索功能待实现');
});
// 新增功能 - 打开模态框
document.querySelector('.btn-success').addEventListener('click', function() {
openModal();
});
// 打开模态框
function openModal() {
document.getElementById('addMarketModal').classList.add('active');
// 重置倒计时
if (countdownTimer) {
clearInterval(countdownTimer);
countdown = 0;
document.getElementById('sendCodeBtn').disabled = false;
document.getElementById('sendCodeBtn').textContent = '发送验证码';
}
// 初始化权限树
initPermissionTree();
}
// 初始化权限树
function initPermissionTree() {
const tree = buildPermissionTree(permissions);
const treeContainer = document.getElementById('permissionTree');
treeContainer.innerHTML = '';
tree.forEach(item => {
treeContainer.appendChild(createPermissionNode(item));
});
}
// 构建权限树
function buildPermissionTree(data) {
const map = {};
const roots = [];
// 创建映射
data.forEach(item => {
map[item.code] = { ...item, children: [] };
});
// 构建树结构
data.forEach(item => {
if (item.parentCode && map[item.parentCode]) {
map[item.parentCode].children.push(map[item.code]);
} else {
roots.push(map[item.code]);
}
});
return roots;
}
// 创建权限节点
function createPermissionNode(item) {
const li = document.createElement('li');
li.className = 'permission-item ' + (item.children.length > 0 ? 'parent' : 'child');
const nodeDiv = document.createElement('div');
nodeDiv.className = 'permission-node';
// 展开/收起按钮
if (item.children.length > 0) {
const expandBtn = document.createElement('button');
expandBtn.className = 'expand-btn';
expandBtn.type = 'button'; // 防止触发表单提交
expandBtn.textContent = '▼';
expandBtn.onclick = (e) => {
e.preventDefault();
e.stopPropagation();
togglePermissionChildren(expandBtn, li);
};
nodeDiv.appendChild(expandBtn);
} else {
// 占位符保持对齐
const placeholder = document.createElement('span');
placeholder.style.width = '20px';
placeholder.style.display = 'inline-block';
nodeDiv.appendChild(placeholder);
}
// 复选框
const checkbox = document.createElement('input');
checkbox.type = 'checkbox';
checkbox.className = 'permission-checkbox';
checkbox.dataset.permissionCode = item.code;
checkbox.onchange = (e) => handlePermissionChange(e, item);
nodeDiv.appendChild(checkbox);
// 权限标签
const label = document.createElement('span');
label.className = 'permission-label';
label.textContent = `${item.name} (${item.description || item.code})`;
label.onclick = () => checkbox.click();
nodeDiv.appendChild(label);
li.appendChild(nodeDiv);
// 子权限
if (item.children.length > 0) {
const childrenContainer = document.createElement('ul');
childrenContainer.className = 'permission-children';
item.children.forEach(child => {
childrenContainer.appendChild(createPermissionNode(child));
});
li.appendChild(childrenContainer);
}
return li;
}
// 切换权限子节点显示
function togglePermissionChildren(btn, li) {
const children = li.querySelector('.permission-children');
if (!children) return;
const isExpanded = children.classList.contains('expanded');
children.classList.toggle('expanded');
btn.textContent = isExpanded ? '▶' : '▼';
btn.classList.toggle('collapsed', isExpanded);
}
// 处理权限选择变化
function handlePermissionChange(event, permission) {
const checkbox = event.target;
const isChecked = checkbox.checked;
const permissionCode = permission.code;
const node = checkbox.closest('.permission-node');
// 更新节点选中样式
if (node) {
node.classList.toggle('selected', isChecked);
}
if (isChecked) {
selectedPermissions.add(permissionCode);
// 选中子级权限时,自动选中所有父级权限
selectParentPermissions(permission);
// 如果是父权限,自动选中所有子权限
if (permission.children && permission.children.length > 0) {
selectChildrenPermissions(permission, true);
}
} else {
selectedPermissions.delete(permissionCode);
// 如果是父权限,自动取消所有子权限
if (permission.children && permission.children.length > 0) {
selectChildrenPermissions(permission, false);
}
// 如果是子权限,检查是否需要取消父权限
uncheckParentIfNeeded(permission);
}
console.log('已选择权限:', Array.from(selectedPermissions));
}
// 选择所有父级权限
function selectParentPermissions(permission) {
if (!permission.parentCode) return;
// 查找父权限
const parent = permissions.find(p => p.code === permission.parentCode);
if (!parent) return;
// 选中父权限
const parentCheckbox = document.querySelector(`[data-permission-code="${parent.code}"]`);
if (parentCheckbox && !parentCheckbox.checked) {
parentCheckbox.checked = true;
selectedPermissions.add(parent.code);
const parentNode = parentCheckbox.closest('.permission-node');
if (parentNode) parentNode.classList.add('selected');
}
// 递归选中上级父权限
selectParentPermissions(parent);
}
// 选择/取消子权限
function selectChildrenPermissions(parent, select) {
if (!parent.children) return;
parent.children.forEach(child => {
const childCheckbox = document.querySelector(`[data-permission-code="${child.code}"]`);
if (childCheckbox) {
childCheckbox.checked = select;
const childNode = childCheckbox.closest('.permission-node');
if (childNode) childNode.classList.toggle('selected', select);
if (select) {
selectedPermissions.add(child.code);
} else {
selectedPermissions.delete(child.code);
}
// 递归处理子权限
selectChildrenPermissions(child, select);
}
});
}
// 检查是否需要取消父权限选择
function uncheckParentIfNeeded(permission) {
if (!permission.parentCode) return;
// 查找父权限
const parent = permissions.find(p => p.code === permission.parentCode);
if (!parent) return;
// 检查父权限的所有子权限是否都未选中
const siblings = permissions.filter(p => p.parentCode === parent.code);
const hasSelectedSibling = siblings.some(sibling => selectedPermissions.has(sibling.code));
if (!hasSelectedSibling) {
const parentCheckbox = document.querySelector(`[data-permission-code="${parent.code}"]`);
if (parentCheckbox) {
parentCheckbox.checked = false;
selectedPermissions.delete(parent.code);
const parentNode = parentCheckbox.closest('.permission-node');
if (parentNode) parentNode.classList.remove('selected');
// 递归检查上级父权限
uncheckParentIfNeeded(parent);
}
}
}
// 关闭模态框
function closeModal() {
document.getElementById('addMarketModal').classList.remove('active');
// 清理倒计时
if (countdownTimer) {
clearInterval(countdownTimer);
countdown = 0;
}
// 重置表单
document.getElementById('addMarketForm').reset();
// 重置定位信息
document.getElementById('locationLat').value = '';
document.getElementById('locationLng').value = '';
document.getElementById('selectedLocationText').textContent = '请选择定位';
document.getElementById('selectedLocationText').style.color = '#f56c6c';
// 重置权限选择
selectedPermissions.clear();
document.querySelectorAll('.permission-checkbox').forEach(checkbox => {
checkbox.checked = false;
});
document.querySelectorAll('.permission-node').forEach(node => {
node.classList.remove('selected');
});
}
// 提交表单
function submitForm() {
const account = document.getElementById('operatorAccount').value;
const verifyCode = document.getElementById('verifyCode').value;
const marketName = document.getElementById('marketName').value;
const categoryType = document.getElementById('categoryType').value;
// 验证必填项
if (!account || !/^1[3-9]\d{9}$/.test(account)) {
alert('请输入正确的手机号码');
return;
}
if (!verifyCode || verifyCode.length !== 6) {
alert('请输入6位验证码');
return;
}
if (!marketName || marketName.trim() === '') {
alert('请输入菜市场名称');
return;
}
if (!categoryType || categoryType === '') {
alert('请选择商品类目类型');
return;
}
// 验证权限选择(可选,根据需求决定是否必选)
if (selectedPermissions.size === 0) {
if (!confirm('您还未选择任何权限,确定要继续吗?')) {
return;
}
}
// 构建提交数据,包含权限信息
const formData = {
operatorAccount: account,
verifyCode: verifyCode,
marketName: marketName,
categoryType: categoryType,
permissions: Array.from(selectedPermissions)
};
console.log('提交数据:', formData);
// 这里应该调用后端API验证验证码并提交表单
alert('表单提交功能待实现\n已选择权限: ' + formData.permissions.join(', '));
closeModal();
}
// 点击模态框背景关闭
document.getElementById('addMarketModal').addEventListener('click', function(e) {
if (e.target === this) {
closeModal();
}
});
// 打开摊位详情模态框
function openBoothDetailModal(marketName) {
// 模拟摊位数据实际应该从后端API获取
const mockBoothData = [
{
id: 4,
name: '猪肉铺',
beneficiaryName: '张三',
beneficiaryPhone: '13800000000',
joinTime: '2025-10-20 12:06:56'
},
{
id: 5,
name: '测试摊位',
beneficiaryName: '李四(和经营者相同)',
beneficiaryPhone: '13800000001和经营者相同',
joinTime: '2025-10-20 12:06:56'
}
];
// 填充表格数据
const tbody = document.getElementById('boothListTableBody');
tbody.innerHTML = '';
if (mockBoothData.length === 0) {
tbody.innerHTML = '<tr><td colspan="5" style="text-align: center; color: #909399;">暂无摊位数据</td></tr>';
} else {
mockBoothData.forEach(booth => {
const row = document.createElement('tr');
row.innerHTML = `
<td>${booth.id}</td>
<td>${booth.name}</td>
<td>${booth.beneficiaryName || ''}</td>
<td>${booth.beneficiaryPhone || ''}</td>
<td>${booth.joinTime}</td>
`;
tbody.appendChild(row);
});
}
// 显示模态框
document.getElementById('boothDetailModal').classList.add('active');
}
// 关闭摊位详情模态框
function closeBoothDetailModal() {
document.getElementById('boothDetailModal').classList.remove('active');
}
// 点击摊位详情模态框背景关闭
document.getElementById('boothDetailModal').addEventListener('click', function(e) {
if (e.target === this) {
closeBoothDetailModal();
}
});
// 打开设置结算比例模态框
function openSettlementModal() {
document.getElementById('settlementRatioModal').classList.add('active');
}
// 关闭设置结算比例模态框
function closeSettlementModal() {
document.getElementById('settlementRatioModal').classList.remove('active');
}
// 提交结算比例
function submitSettlementRatio() {
const ratio = document.getElementById('settlementRatio').value;
if (ratio === '' || ratio < 0 || ratio > 1) {
alert('请输入有效的结算比例(0-1之间)');
return;
}
alert('结算比例已设置为: ' + ratio);
closeSettlementModal();
}
// 点击结算比例模态框背景关闭
document.getElementById('settlementRatioModal').addEventListener('click', function(e) {
if (e.target === this) {
closeSettlementModal();
}
});
// 打开详情模态框
function openDetailModal(rowData) {
// 填充详情数据
document.getElementById('detailMarketName').value = rowData.marketName || '';
document.getElementById('detailDetailAddress').value = rowData.address || '';
// 显示定位坐标信息(模拟数据,实际应从后端获取)
const coordsElement = document.getElementById('detailLocationCoords');
if (rowData.location) {
coordsElement.textContent = '经纬度: ' + rowData.location;
} else {
coordsElement.textContent = '暂无定位信息';
}
// 显示模态框
document.getElementById('detailMarketModal').classList.add('active');
}
// 关闭详情模态框
function closeDetailModal() {
document.getElementById('detailMarketModal').classList.remove('active');
}
// 点击详情模态框背景关闭
document.getElementById('detailMarketModal').addEventListener('click', function(e) {
if (e.target === this) {
closeDetailModal();
}
});
// 从表格行获取数据
function getRowData(button) {
const row = button.closest('tr');
const cells = row.querySelectorAll('td');
return {
marketName: cells[0].textContent.trim(),
categoryType: row.getAttribute('data-category-type') || '',
address: cells[2].textContent.trim(),
operatorName: cells[3].textContent.trim(),
operatorAccount: cells[4].textContent.trim(),
thirdPartyDelivery: cells[5].textContent.trim() === '是',
marketStatus: cells[7].textContent.trim() === '正常',
boothCount: cells[8].textContent.trim(),
businessStatus: cells[9].textContent.trim(),
detailAddress: '',
location: '',
autoBusinessTime: true
};
}
// 为所有操作按钮添加事件监听
document.querySelectorAll('.action-buttons button').forEach(button => {
button.addEventListener('click', function(e) {
e.stopPropagation();
const buttonText = this.textContent;
// 如果是设置结算比例按钮,打开对应的模态框
if (buttonText === '设置结算比例') {
openSettlementModal();
} else if (buttonText === '详情') {
// 获取当前行数据并打开详情模态框
const rowData = getRowData(this);
openDetailModal(rowData);
} else if (buttonText === '摊位详情') {
// 获取市场名称并打开摊位详情模态框
const rowData = getRowData(this);
openBoothDetailModal(rowData.marketName);
} else {
alert(buttonText + ' 功能待实现');
}
});
});
// 跳转到待审核菜市场页面
function goToPendingMarkets() {
window.location.href = '待审核菜市场.html';
}
</script>
</body>
</html>