处理后台管理系统、修复BUG、处理权限
This commit is contained in:
@@ -314,6 +314,10 @@
|
||||
display: flex;
|
||||
}
|
||||
|
||||
#shopManageGroupModal {
|
||||
z-index: 1010;
|
||||
}
|
||||
|
||||
.modal {
|
||||
background: #fff;
|
||||
border-radius: 8px;
|
||||
@@ -948,17 +952,24 @@
|
||||
<h3>分组管理</h3>
|
||||
<div class="form-row">
|
||||
<input type="hidden" id="shopManageGroupEditId">
|
||||
<input type="hidden" id="shopManageGroupLeaderUserId">
|
||||
<div class="form-group" style="min-width:220px;">
|
||||
<label>关联用户</label>
|
||||
<select id="shopManageGroupUserSelect">
|
||||
<option value="">请选择用户</option>
|
||||
</select>
|
||||
<label>组长</label>
|
||||
<input type="text" id="shopManageGroupLeaderName" placeholder="当前登录用户" readonly
|
||||
style="background:#f5f5f5;">
|
||||
</div>
|
||||
<div class="form-group" style="min-width:260px;">
|
||||
<label>分组名称</label>
|
||||
<input type="text" id="shopManageGroupInput" placeholder="选择用户后自动带出" readonly
|
||||
style="background:#f5f5f5;">
|
||||
<input type="text" id="shopManageGroupInput" placeholder="请输入分组名称">
|
||||
</div>
|
||||
<div class="form-group" style="min-width:280px;flex:1;">
|
||||
<label>组员</label>
|
||||
<select id="shopManageGroupMemberSelect" multiple size="6" style="min-height:140px;">
|
||||
</select>
|
||||
<div style="color:#888;font-size:12px;margin-top:6px;">可添加当前组长创建的普通员工账号,按住 Ctrl 或 Command 可多选。</div>
|
||||
</div>
|
||||
</div>
|
||||
<div style="display:flex;gap:8px;justify-content:flex-end;margin-bottom:12px;">
|
||||
<button class="btn" id="btnSaveShopManageGroup" type="button">保存分组</button>
|
||||
<button class="btn btn-secondary" id="btnCancelShopManageGroupEdit" type="button">取消编辑</button>
|
||||
</div>
|
||||
@@ -968,7 +979,9 @@
|
||||
<tr>
|
||||
<th>序号</th>
|
||||
<th>分组名称</th>
|
||||
<th>关联用户</th>
|
||||
<th>组长</th>
|
||||
<th>组员数量</th>
|
||||
<th>组员</th>
|
||||
<th>创建时间</th>
|
||||
<th>修改时间</th>
|
||||
<th>操作</th>
|
||||
@@ -1658,43 +1671,61 @@
|
||||
sel.value = cur || '';
|
||||
});
|
||||
}
|
||||
var shopManageGroupUsers = [];
|
||||
function refreshShopManageGroupUserSelect(selectedUserId) {
|
||||
var sel = document.getElementById('shopManageGroupUserSelect');
|
||||
if (!sel) return;
|
||||
var opts = ['<option value="">请选择用户</option>'];
|
||||
shopManageGroupUsers.forEach(function (u) {
|
||||
opts.push('<option value="' + u.id + '">' + (u.username || '') + '</option>');
|
||||
var shopManageAllUsers = [];
|
||||
function getEligibleShopManageGroupUsers(leaderUserId) {
|
||||
var canViewAllMembers = currentUserRole === 'super_admin';
|
||||
return shopManageAllUsers.filter(function (u) {
|
||||
if (String(u.id || '') === String(leaderUserId || '')) return false;
|
||||
if (canViewAllMembers) return true;
|
||||
return String(u.role || '') === 'normal' &&
|
||||
String(u.created_by_id || '') === String(leaderUserId || '');
|
||||
});
|
||||
sel.innerHTML = opts.join('');
|
||||
if (selectedUserId != null && selectedUserId !== '') {
|
||||
sel.value = String(selectedUserId);
|
||||
}
|
||||
syncShopManageGroupNameWithUser();
|
||||
}
|
||||
function syncShopManageGroupNameWithUser() {
|
||||
var sel = document.getElementById('shopManageGroupUserSelect');
|
||||
var input = document.getElementById('shopManageGroupInput');
|
||||
if (!sel || !input) return;
|
||||
var selectedUser = null;
|
||||
shopManageGroupUsers.some(function (u) {
|
||||
if (String(u.id) === String(sel.value || '')) {
|
||||
selectedUser = u;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
function refreshShopManageGroupMemberSelect(leaderUserId, selectedUserIds) {
|
||||
var sel = document.getElementById('shopManageGroupMemberSelect');
|
||||
if (!sel) return;
|
||||
var selectedMap = {};
|
||||
(selectedUserIds || []).forEach(function (id) {
|
||||
selectedMap[String(id)] = true;
|
||||
});
|
||||
input.value = selectedUser ? (selectedUser.username || '') : '';
|
||||
var options = getEligibleShopManageGroupUsers(leaderUserId).map(function (u) {
|
||||
return '<option value="' + u.id + '"' + (selectedMap[String(u.id)] ? ' selected' : '') + '>' + (u.username || '') + '</option>';
|
||||
});
|
||||
sel.innerHTML = options.join('');
|
||||
}
|
||||
function setShopManageGroupLeader(leaderUserId, leaderUsername, selectedUserIds) {
|
||||
var leaderIdEl = document.getElementById('shopManageGroupLeaderUserId');
|
||||
var leaderNameEl = document.getElementById('shopManageGroupLeaderName');
|
||||
if (leaderIdEl) leaderIdEl.value = leaderUserId ? String(leaderUserId) : '';
|
||||
if (leaderNameEl) leaderNameEl.value = leaderUsername || '';
|
||||
refreshShopManageGroupMemberSelect(leaderUserId, selectedUserIds || []);
|
||||
}
|
||||
function getSelectedShopManageGroupMemberIds() {
|
||||
var sel = document.getElementById('shopManageGroupMemberSelect');
|
||||
if (!sel) return [];
|
||||
return Array.prototype.slice.call(sel.options || [])
|
||||
.filter(function (opt) { return !!opt.selected; })
|
||||
.map(function (opt) { return Number(opt.value); })
|
||||
.filter(function (id) { return !!id; });
|
||||
}
|
||||
function loadUserOptions() {
|
||||
return fetch('/api/admin/users?page=1&page_size=999')
|
||||
.then(function (r) { return r.json(); })
|
||||
.then(function (res) {
|
||||
var items = res.items || [];
|
||||
shopManageGroupUsers = items.map(function (u) {
|
||||
return { id: u.id, username: u.username || '', role: u.role || 'normal' };
|
||||
shopManageAllUsers = items.map(function (u) {
|
||||
return {
|
||||
id: u.id,
|
||||
username: u.username || '',
|
||||
role: u.role || 'normal',
|
||||
created_by_id: u.created_by_id || null
|
||||
};
|
||||
});
|
||||
refreshShopManageGroupUserSelect(document.getElementById('shopManageGroupUserSelect') ? document.getElementById('shopManageGroupUserSelect').value : '');
|
||||
setShopManageGroupLeader(
|
||||
document.getElementById('shopManageGroupLeaderUserId') ? document.getElementById('shopManageGroupLeaderUserId').value : '',
|
||||
document.getElementById('shopManageGroupLeaderName') ? document.getElementById('shopManageGroupLeaderName').value : '',
|
||||
getSelectedShopManageGroupMemberIds()
|
||||
);
|
||||
var sel = document.getElementById('filterUser');
|
||||
var cur = sel.value;
|
||||
sel.innerHTML = '<option value="">全部用户</option>';
|
||||
@@ -2163,107 +2194,6 @@
|
||||
return query;
|
||||
}
|
||||
|
||||
function refreshShopGroupSelects(selectedCreateId, selectedEditId) {
|
||||
var createSel = document.getElementById('shopManageGroupSelect');
|
||||
var editSel = document.getElementById('editShopManageGroupSelect');
|
||||
var filterSel = document.getElementById('shopManageFilterGroupId');
|
||||
var skipCreateSel = document.getElementById('skipPriceAsinGroupSelect');
|
||||
var skipFilterSel = document.getElementById('skipPriceAsinFilterGroupId');
|
||||
var chooseSkipShopSel = document.getElementById('chooseSkipPriceAsinShopGroupId');
|
||||
var selectedFilterId = filterSel ? filterSel.value : '';
|
||||
var selectedSkipCreateId = skipCreateSel ? skipCreateSel.value : '';
|
||||
var selectedSkipFilterId = skipFilterSel ? skipFilterSel.value : '';
|
||||
var selectedChooseSkipShopId = chooseSkipShopSel ? chooseSkipShopSel.value : '';
|
||||
var createOpts = ['<option value="">请选择分组</option>'];
|
||||
var filterOpts = ['<option value="">全部分组</option>'];
|
||||
shopManageGroups.forEach(function (g) {
|
||||
var option = '<option value="' + g.id + '">' + (g.group_name || '') + '</option>';
|
||||
createOpts.push(option);
|
||||
filterOpts.push(option);
|
||||
});
|
||||
createSel.innerHTML = createOpts.join('');
|
||||
editSel.innerHTML = createOpts.join('');
|
||||
if (skipCreateSel) skipCreateSel.innerHTML = createOpts.join('');
|
||||
if (filterSel) filterSel.innerHTML = filterOpts.join('');
|
||||
if (skipFilterSel) skipFilterSel.innerHTML = filterOpts.join('');
|
||||
if (chooseSkipShopSel) chooseSkipShopSel.innerHTML = filterOpts.join('');
|
||||
if (selectedCreateId != null) createSel.value = String(selectedCreateId);
|
||||
if (selectedEditId != null) editSel.value = String(selectedEditId);
|
||||
if (filterSel && selectedFilterId) filterSel.value = selectedFilterId;
|
||||
if (skipCreateSel && selectedSkipCreateId) skipCreateSel.value = selectedSkipCreateId;
|
||||
if (skipFilterSel && selectedSkipFilterId) skipFilterSel.value = selectedSkipFilterId;
|
||||
if (chooseSkipShopSel && selectedChooseSkipShopId) chooseSkipShopSel.value = selectedChooseSkipShopId;
|
||||
}
|
||||
|
||||
function loadShopManageGroups(selectedCreateId, selectedEditId) {
|
||||
return fetch('/api/admin/shop-manage-groups')
|
||||
.then(function (r) { return r.json(); })
|
||||
.then(function (res) {
|
||||
if (!res.success) throw new Error(res.error || '加载分组失败');
|
||||
shopManageGroups = res.items || [];
|
||||
refreshShopGroupSelects(selectedCreateId, selectedEditId);
|
||||
return shopManageGroups;
|
||||
})
|
||||
.catch(function () {
|
||||
shopManageGroups = [];
|
||||
refreshShopGroupSelects();
|
||||
return [];
|
||||
});
|
||||
}
|
||||
|
||||
function openShopManageGroupModal() {
|
||||
document.getElementById('shopManageGroupEditId').value = '';
|
||||
document.getElementById('shopManageGroupInput').value = '';
|
||||
document.getElementById('msgShopManageGroup').textContent = '';
|
||||
document.getElementById('msgShopManageGroup').className = 'msg';
|
||||
loadShopManageGroups().then(function () {
|
||||
renderShopManageGroupRows();
|
||||
document.getElementById('shopManageGroupModal').classList.add('show');
|
||||
});
|
||||
}
|
||||
|
||||
function renderShopManageGroupRows() {
|
||||
var tbody = document.getElementById('shopManageGroupListBody');
|
||||
if (!shopManageGroups.length) {
|
||||
tbody.innerHTML = '<tr><td colspan="5" class="empty-tip">暂无分组</td></tr>';
|
||||
return;
|
||||
}
|
||||
tbody.innerHTML = shopManageGroups.map(function (item, index) {
|
||||
return '<tr><td>' + (index + 1) + '</td><td>' + (item.group_name || '') + '</td><td>' + (item.created_at || '') + '</td><td>' + (item.updated_at || '') + '</td><td>' +
|
||||
'<button class="btn btn-sm" data-shop-group-edit="' + item.id + '" data-shop-group-name="' + (item.group_name || '').replace(/"/g, '"') + '">编辑</button> ' +
|
||||
'<button class="btn btn-sm btn-danger" data-shop-group-delete="' + item.id + '" data-shop-group-name="' + (item.group_name || '').replace(/"/g, '"') + '">删除</button>' +
|
||||
'</td></tr>';
|
||||
}).join('');
|
||||
|
||||
document.querySelectorAll('[data-shop-group-edit]').forEach(function (btn) {
|
||||
btn.onclick = function () {
|
||||
document.getElementById('shopManageGroupEditId').value = btn.dataset.shopGroupEdit;
|
||||
document.getElementById('shopManageGroupInput').value = (btn.dataset.shopGroupName || '').replace(/"/g, '"');
|
||||
};
|
||||
});
|
||||
|
||||
document.querySelectorAll('[data-shop-group-delete]').forEach(function (btn) {
|
||||
btn.onclick = function () {
|
||||
var gid = btn.dataset.shopGroupDelete;
|
||||
var gname = (btn.dataset.shopGroupName || '').replace(/"/g, '"');
|
||||
if (!confirm('确定删除分组“' + gname + '”吗?')) return;
|
||||
fetch('/api/admin/shop-manage-group/' + gid, { method: 'DELETE' })
|
||||
.then(function (r) { return r.json(); })
|
||||
.then(function (res) {
|
||||
if (!res.success) {
|
||||
alert(res.error || '删除失败');
|
||||
return;
|
||||
}
|
||||
loadShopManageGroups().then(function () {
|
||||
renderShopManageGroupRows();
|
||||
loadShopManage(shopManagePage);
|
||||
loadSkipPriceAsin(skipPriceAsinPage);
|
||||
});
|
||||
});
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
function loadShopManage(page) {
|
||||
shopManagePage = page || 1;
|
||||
fetch('/api/admin/shop-manages?' + buildShopManageQuery(shopManagePage))
|
||||
@@ -2325,65 +2255,6 @@
|
||||
});
|
||||
}
|
||||
|
||||
document.getElementById('btnManageShopGroups').onclick = openShopManageGroupModal;
|
||||
document.getElementById('btnManageShopGroupsFromEdit').onclick = openShopManageGroupModal;
|
||||
document.getElementById('btnSearchShopManage').onclick = function () {
|
||||
loadShopManage(1);
|
||||
};
|
||||
document.getElementById('shopManageFilterShopName').addEventListener('keydown', function (e) {
|
||||
if (e.key === 'Enter') {
|
||||
e.preventDefault();
|
||||
loadShopManage(1);
|
||||
}
|
||||
});
|
||||
document.getElementById('btnCloseShopManageGroupModal').onclick = function () {
|
||||
document.getElementById('shopManageGroupModal').classList.remove('show');
|
||||
};
|
||||
document.getElementById('btnCancelShopManageGroupEdit').onclick = function () {
|
||||
document.getElementById('shopManageGroupEditId').value = '';
|
||||
document.getElementById('shopManageGroupInput').value = '';
|
||||
};
|
||||
document.getElementById('btnSaveShopManageGroup').onclick = function () {
|
||||
var editId = (document.getElementById('shopManageGroupEditId').value || '').trim();
|
||||
var groupName = (document.getElementById('shopManageGroupInput').value || '').trim();
|
||||
var msgEl = document.getElementById('msgShopManageGroup');
|
||||
msgEl.textContent = '';
|
||||
msgEl.className = 'msg';
|
||||
if (!groupName) {
|
||||
msgEl.textContent = '请输入分组名称';
|
||||
msgEl.className = 'msg err';
|
||||
return;
|
||||
}
|
||||
var method = editId ? 'PUT' : 'POST';
|
||||
var url = editId ? ('/api/admin/shop-manage-group/' + editId) : '/api/admin/shop-manage-group';
|
||||
fetch(url, {
|
||||
method: method,
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ group_name: groupName })
|
||||
})
|
||||
.then(function (r) { return r.json(); })
|
||||
.then(function (res) {
|
||||
if (!res.success) {
|
||||
msgEl.textContent = res.error || '保存失败';
|
||||
msgEl.className = 'msg err';
|
||||
return;
|
||||
}
|
||||
document.getElementById('shopManageGroupEditId').value = '';
|
||||
document.getElementById('shopManageGroupInput').value = '';
|
||||
msgEl.textContent = res.msg || '保存成功';
|
||||
msgEl.className = 'msg ok';
|
||||
loadShopManageGroups().then(function () {
|
||||
renderShopManageGroupRows();
|
||||
loadShopManage(shopManagePage);
|
||||
loadSkipPriceAsin(skipPriceAsinPage);
|
||||
});
|
||||
})
|
||||
.catch(function () {
|
||||
msgEl.textContent = '请求失败';
|
||||
msgEl.className = 'msg err';
|
||||
});
|
||||
};
|
||||
|
||||
function refreshShopGroupSelects(selectedCreateId, selectedEditId) {
|
||||
var createSel = document.getElementById('shopManageGroupSelect');
|
||||
var editSel = document.getElementById('editShopManageGroupSelect');
|
||||
@@ -2434,10 +2305,12 @@
|
||||
|
||||
function resetShopManageGroupForm() {
|
||||
document.getElementById('shopManageGroupEditId').value = '';
|
||||
document.getElementById('shopManageGroupLeaderUserId').value = currentUserId || '';
|
||||
document.getElementById('shopManageGroupLeaderName').value = currentUserUsername || '';
|
||||
document.getElementById('shopManageGroupInput').value = '';
|
||||
document.getElementById('msgShopManageGroup').textContent = '';
|
||||
document.getElementById('msgShopManageGroup').className = 'msg';
|
||||
refreshShopManageGroupUserSelect('');
|
||||
refreshShopManageGroupMemberSelect(currentUserId, []);
|
||||
}
|
||||
|
||||
function openShopManageGroupModal() {
|
||||
@@ -2453,20 +2326,33 @@
|
||||
function renderShopManageGroupRows() {
|
||||
var tbody = document.getElementById('shopManageGroupListBody');
|
||||
if (!shopManageGroups.length) {
|
||||
tbody.innerHTML = '<tr><td colspan="6" class="empty-tip">暂无分组</td></tr>';
|
||||
tbody.innerHTML = '<tr><td colspan="8" class="empty-tip">暂无分组</td></tr>';
|
||||
return;
|
||||
}
|
||||
tbody.innerHTML = shopManageGroups.map(function (item, index) {
|
||||
return '<tr><td>' + (index + 1) + '</td><td>' + (item.group_name || '') + '</td><td>' + (item.username || '') + '</td><td>' + (item.created_at || '') + '</td><td>' + (item.updated_at || '') + '</td><td>' +
|
||||
'<button class="btn btn-sm" data-shop-group-edit="' + item.id + '" data-shop-group-user-id="' + (item.user_id || '') + '">编辑</button> ' +
|
||||
var memberNames = Array.isArray(item.member_usernames) ? item.member_usernames.join('、') : '';
|
||||
return '<tr><td>' + (index + 1) + '</td><td>' + (item.group_name || '') + '</td><td>' + (item.leader_username || '') + '</td><td>' + (item.member_count || 0) + '</td><td>' + (memberNames || '-') + '</td><td>' + (item.created_at || '') + '</td><td>' + (item.updated_at || '') + '</td><td>' +
|
||||
'<button class="btn btn-sm" data-shop-group-edit="' + item.id + '">编辑</button> ' +
|
||||
'<button class="btn btn-sm btn-danger" data-shop-group-delete="' + item.id + '" data-shop-group-name="' + (item.group_name || '').replace(/"/g, '"') + '">删除</button>' +
|
||||
'</td></tr>';
|
||||
}).join('');
|
||||
|
||||
document.querySelectorAll('[data-shop-group-edit]').forEach(function (btn) {
|
||||
btn.onclick = function () {
|
||||
document.getElementById('shopManageGroupEditId').value = btn.dataset.shopGroupEdit;
|
||||
refreshShopManageGroupUserSelect(btn.dataset.shopGroupUserId || '');
|
||||
var item = null;
|
||||
shopManageGroups.some(function (group) {
|
||||
if (String(group.id || '') === String(btn.dataset.shopGroupEdit || '')) {
|
||||
item = group;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
if (!item) return;
|
||||
document.getElementById('shopManageGroupEditId').value = item.id || '';
|
||||
document.getElementById('shopManageGroupInput').value = item.group_name || '';
|
||||
setShopManageGroupLeader(item.leader_user_id || '', item.leader_username || '', item.member_user_ids || []);
|
||||
document.getElementById('msgShopManageGroup').textContent = '';
|
||||
document.getElementById('msgShopManageGroup').className = 'msg';
|
||||
};
|
||||
});
|
||||
|
||||
@@ -2492,10 +2378,18 @@
|
||||
});
|
||||
}
|
||||
|
||||
document.getElementById('shopManageGroupUserSelect').onchange = syncShopManageGroupNameWithUser;
|
||||
document.getElementById('btnManageShopGroups').onclick = openShopManageGroupModal;
|
||||
document.getElementById('btnManageShopGroupsFromEdit').onclick = openShopManageGroupModal;
|
||||
document.getElementById('btnManageSkipPriceAsinGroups').onclick = openShopManageGroupModal;
|
||||
document.getElementById('btnSearchShopManage').onclick = function () {
|
||||
loadShopManage(1);
|
||||
};
|
||||
document.getElementById('shopManageFilterShopName').addEventListener('keydown', function (e) {
|
||||
if (e.key === 'Enter') {
|
||||
e.preventDefault();
|
||||
loadShopManage(1);
|
||||
}
|
||||
});
|
||||
document.getElementById('btnCloseShopManageGroupModal').onclick = function () {
|
||||
document.getElementById('shopManageGroupModal').classList.remove('show');
|
||||
};
|
||||
@@ -2503,12 +2397,12 @@
|
||||
document.getElementById('btnSaveShopManageGroup').onclick = function () {
|
||||
var editId = (document.getElementById('shopManageGroupEditId').value || '').trim();
|
||||
var groupName = (document.getElementById('shopManageGroupInput').value || '').trim();
|
||||
var userId = (document.getElementById('shopManageGroupUserSelect').value || '').trim();
|
||||
var memberUserIds = getSelectedShopManageGroupMemberIds();
|
||||
var msgEl = document.getElementById('msgShopManageGroup');
|
||||
msgEl.textContent = '';
|
||||
msgEl.className = 'msg';
|
||||
if (!userId || !groupName) {
|
||||
msgEl.textContent = '请选择关联用户';
|
||||
if (!groupName) {
|
||||
msgEl.textContent = '请输入分组名称';
|
||||
msgEl.className = 'msg err';
|
||||
return;
|
||||
}
|
||||
@@ -2517,7 +2411,7 @@
|
||||
fetch(url, {
|
||||
method: method,
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ group_name: groupName, user_id: Number(userId) })
|
||||
body: JSON.stringify({ group_name: groupName, member_user_ids: memberUserIds })
|
||||
})
|
||||
.then(function (r) { return r.json(); })
|
||||
.then(function (res) {
|
||||
|
||||
Reference in New Issue
Block a user