542 lines
24 KiB
JavaScript
542 lines
24 KiB
JavaScript
document.addEventListener('DOMContentLoaded', () => {
|
||
const addBtn = document.getElementById('add-btn');
|
||
const addForm = document.getElementById('add-form');
|
||
const cancelBtn = document.getElementById('cancel-btn');
|
||
const saveBtn = document.getElementById('save-btn');
|
||
|
||
const envSelect = document.getElementById('env-select');
|
||
const clientInput = document.getElementById('client-input');
|
||
const usernameInput = document.getElementById('username-input');
|
||
const passwordInput = document.getElementById('password-input');
|
||
const rulesList = document.getElementById('rules-list');
|
||
const rulesContainer = document.querySelector('.rules-container');
|
||
const formTitle = document.getElementById('form-title');
|
||
const editingIdInput = document.getElementById('editing-id');
|
||
|
||
const loginView = document.getElementById('login-view');
|
||
const registerView = document.getElementById('register-view');
|
||
const appView = document.getElementById('app-view');
|
||
const authLoginBtn = document.getElementById('auth-login-btn');
|
||
const authRegBtn = document.getElementById('auth-reg-btn');
|
||
const goToRegister = document.getElementById('go-to-register');
|
||
const goToLogin = document.getElementById('go-to-login');
|
||
const logoutBtn = document.getElementById('logout-btn');
|
||
const archiveToggle = document.getElementById('archive-toggle');
|
||
const backToMain = document.getElementById('back-to-main');
|
||
const mainViewContent = document.getElementById('main-view-content');
|
||
const archiveViewContent = document.getElementById('archive-view-content');
|
||
const archiveList = document.getElementById('archive-list');
|
||
|
||
if (logoutBtn) {
|
||
logoutBtn.addEventListener('click', (e) => {
|
||
e.preventDefault();
|
||
if (confirm('确定要退出当前同步账号吗?')) {
|
||
chrome.storage.local.remove(['quickPurgeUser'], () => {
|
||
currentUser = null;
|
||
rules = [];
|
||
renderRules(); // 立即清空界面显示的 rules
|
||
showView('login');
|
||
});
|
||
}
|
||
});
|
||
}
|
||
|
||
const ENV_CONFIG = {
|
||
DD_PP: {
|
||
domain: 'app135148.dingtalkoxm.com',
|
||
url: 'https://app135148.dingtalkoxm.com/user/login'
|
||
},
|
||
DD_ATS: {
|
||
domain: 'app135149.dingtalkoxm.com',
|
||
url: 'https://app135149.dingtalkoxm.com/login'
|
||
},
|
||
STD_PP: {
|
||
domain: 'core.mokahr.com',
|
||
url: 'https://core.mokahr.com'
|
||
},
|
||
STD_ATS: {
|
||
domain: 'app.mokahr.com',
|
||
url: 'https://app.mokahr.com'
|
||
}
|
||
};
|
||
|
||
const API_BASE = 'https://sqd.zhouzishen.cn/api'; // 已更新为您的生产服务器地址
|
||
let currentUser = null;
|
||
let rules = [];
|
||
let dragStartIndex = -1;
|
||
|
||
// --- 工具函数 ---
|
||
function hasChinese(str) {
|
||
return /[\u4E00-\u9FA5]/.test(str);
|
||
}
|
||
|
||
const ICON_SET = [
|
||
'<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"/><circle cx="12" cy="7" r="4"/></svg>', // User
|
||
'<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="4" y="2" width="16" height="20" rx="2" ry="2"/><line x1="9" y1="22" x2="9" y2="22"/><line x1="15" y1="22" x2="15" y2="22"/><line x1="12" y1="18" x2="12" y2="18"/><line x1="9" y1="14" x2="9" y2="14"/><line x1="15" y1="14" x2="15" y2="14"/><line x1="9" y1="10" x2="9" y2="10"/><line x1="15" y1="10" x2="15" y2="10"/><line x1="9" y1="6" x2="9" y2="6"/><line x1="15" y1="6" x2="15" y2="6"/></svg>', // Building
|
||
'<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/></svg>', // Shield
|
||
'<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 2l-2 2m-7.61 7.61a5.5 5.5 0 1 1-7.778 7.778 5.5 5.5 0 0 1 7.777-7.777zm0 0L15.5 7.5m0 0l3 3m-3-3l-2.5-2.5"/></svg>', // Key
|
||
'<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10"/><line x1="2" y1="12" x2="22" y2="12"/><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"/></svg>', // Globe
|
||
'<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="2" y="7" width="20" height="14" rx="2" ry="2"/><path d="M16 21V5a2 2 0 0 0-2-2h-4a2 2 0 0 0-2 2v16"/></svg>', // Briefcase
|
||
'<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2"/></svg>', // Zap
|
||
'<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><ellipse cx="12" cy="5" rx="9" ry="3"/><path d="M21 12c0 1.66-4 3-9 3s-9-1.34-9-3"/><path d="M3 5v14c0 1.66 4 3 9 3s9-1.34 9-3V5"/></svg>' // Database
|
||
];
|
||
|
||
function getRandomIcon(seed) {
|
||
// Use a simple hash of the seed (rule ID) to pick a stable icon
|
||
let hash = 0;
|
||
for (let i = 0; i < seed.length; i++) {
|
||
hash = seed.charCodeAt(i) + ((hash << 5) - hash);
|
||
}
|
||
return ICON_SET[Math.abs(hash) % ICON_SET.length];
|
||
}
|
||
|
||
// --- Auth View Controllers ---
|
||
function showView(viewName) {
|
||
if (loginView) loginView.classList.add('hidden');
|
||
if (registerView) registerView.classList.add('hidden');
|
||
if (appView) appView.classList.add('hidden');
|
||
|
||
if (viewName === 'app') {
|
||
if (appView) appView.classList.remove('hidden');
|
||
} else {
|
||
if (viewName === 'login' && loginView) loginView.classList.remove('hidden');
|
||
else if (viewName === 'register' && registerView) registerView.classList.remove('hidden');
|
||
}
|
||
}
|
||
|
||
|
||
if (goToRegister) goToRegister.addEventListener('click', (e) => { e.preventDefault(); showView('register'); });
|
||
if (goToLogin) goToLogin.addEventListener('click', (e) => { e.preventDefault(); showView('login'); });
|
||
|
||
if (authRegBtn) {
|
||
authRegBtn.addEventListener('click', async () => {
|
||
const username = document.getElementById('auth-reg-username').value.trim();
|
||
const password = document.getElementById('auth-reg-password').value;
|
||
const inviteCode = document.getElementById('auth-reg-invite').value.trim();
|
||
|
||
if (!username || !password || !inviteCode) return alert('请填写完整信息');
|
||
if (hasChinese(username) || hasChinese(password) || hasChinese(inviteCode)) {
|
||
return alert('账号、密码和邀请码不允许包含中文字符');
|
||
}
|
||
authRegBtn.textContent = '注册中...';
|
||
try {
|
||
const res = await fetch(`${API_BASE}/register`, {
|
||
method: 'POST', headers: { 'Content-Type': 'application/json' },
|
||
body: JSON.stringify({ username, password, inviteCode })
|
||
});
|
||
const data = await res.json();
|
||
if (data.code === 0) {
|
||
alert('注册成功,请使用该账号登录');
|
||
document.getElementById('auth-login-username').value = username;
|
||
document.getElementById('auth-login-password').value = password;
|
||
showView('login');
|
||
} else alert(data.msg);
|
||
} catch (e) { alert('请求失败,请确保本地服务器已启动运行。' + e); }
|
||
finally { authRegBtn.textContent = '注册'; }
|
||
});
|
||
}
|
||
|
||
if (authLoginBtn) {
|
||
authLoginBtn.addEventListener('click', async () => {
|
||
const username = document.getElementById('auth-login-username').value.trim();
|
||
const password = document.getElementById('auth-login-password').value;
|
||
|
||
if (!username || !password) return alert('请输入账号和密码');
|
||
if (hasChinese(username) || hasChinese(password)) {
|
||
return alert('账号和密码格式不正确(不能包含中文)');
|
||
}
|
||
authLoginBtn.textContent = '登录中...';
|
||
try {
|
||
const res = await fetch(`${API_BASE}/login`, {
|
||
method: 'POST', headers: { 'Content-Type': 'application/json' },
|
||
body: JSON.stringify({ username, password })
|
||
});
|
||
const data = await res.json();
|
||
if (data.code === 0) {
|
||
currentUser = { username, password };
|
||
rules = processLoadedRules(data.data.rules || []);
|
||
chrome.storage.local.set({ quickPurgeUser: { username, password, rules } }, () => {
|
||
showView('app');
|
||
renderRules();
|
||
});
|
||
} else alert(data.msg);
|
||
} catch (e) { alert('请求失败,请确保本地服务器已启动运行。' + e); }
|
||
finally { authLoginBtn.textContent = '登录'; }
|
||
});
|
||
}
|
||
|
||
|
||
// Load Init from local cache
|
||
function loadAndInitBaseApp() {
|
||
if (typeof chrome !== 'undefined' && chrome.storage) {
|
||
chrome.storage.local.get(['quickPurgeUser'], async (result) => {
|
||
const user = result.quickPurgeUser;
|
||
if (user && user.username && user.password) {
|
||
currentUser = user;
|
||
rules = processLoadedRules(user.rules || []);
|
||
showView('app'); // Proceed to app UI
|
||
renderRules();
|
||
|
||
// 静默发起登录获取云端最新数据
|
||
try {
|
||
const res = await fetch(`${API_BASE}/login`, {
|
||
method: 'POST', headers: { 'Content-Type': 'application/json' },
|
||
body: JSON.stringify({ username: user.username, password: user.password })
|
||
});
|
||
const data = await res.json();
|
||
if (data.code === 0) {
|
||
rules = processLoadedRules(data.data.rules || []);
|
||
chrome.storage.local.set({ quickPurgeUser: { ...currentUser, rules } });
|
||
renderRules();
|
||
}
|
||
} catch (e) {
|
||
console.log("Offline mode, using local storage cache fallback.");
|
||
}
|
||
} else {
|
||
showView('login'); // Not logged in
|
||
}
|
||
});
|
||
} else {
|
||
showView('login');
|
||
}
|
||
}
|
||
|
||
function processLoadedRules(rawRules) {
|
||
return rawRules.map(rule => {
|
||
if (rule.env === 'PP') rule.env = 'DD_PP';
|
||
if (rule.env === 'ATS') rule.env = 'DD_ATS';
|
||
return rule;
|
||
});
|
||
}
|
||
|
||
function saveRules() {
|
||
if (typeof chrome !== 'undefined' && chrome.storage && currentUser) {
|
||
chrome.storage.local.set({ quickPurgeUser: { ...currentUser, rules } }, () => {
|
||
renderRules();
|
||
// 异步防抖提交到自建服务云端
|
||
fetch(`${API_BASE}/sync`, {
|
||
method: 'POST', headers: { 'Content-Type': 'application/json' },
|
||
body: JSON.stringify({ username: currentUser.username, rules })
|
||
}).catch(e => console.error("Sync error:", e));
|
||
});
|
||
} else {
|
||
renderRules();
|
||
}
|
||
}
|
||
|
||
function toggleAddForm(mode = 'add', ruleId = null) {
|
||
if (mode === 'edit') {
|
||
const rule = rules.find(r => r.id === ruleId);
|
||
if (rule) {
|
||
formTitle.textContent = '编辑配置';
|
||
editingIdInput.value = rule.id;
|
||
envSelect.value = rule.env;
|
||
clientInput.value = rule.clientName;
|
||
usernameInput.value = rule.username;
|
||
passwordInput.value = rule.password;
|
||
addForm.classList.remove('hidden');
|
||
rulesContainer.classList.add('hidden');
|
||
addBtn.classList.add('hidden'); // Optional: hide add btn while editing
|
||
}
|
||
} else {
|
||
formTitle.textContent = '添加配置';
|
||
editingIdInput.value = '';
|
||
resetForm();
|
||
addForm.classList.toggle('hidden');
|
||
|
||
if (addForm.classList.contains('hidden')) {
|
||
rulesContainer.classList.remove('hidden');
|
||
addBtn.classList.remove('hidden');
|
||
} else {
|
||
rulesContainer.classList.add('hidden');
|
||
addBtn.classList.add('hidden');
|
||
}
|
||
}
|
||
|
||
if (!addForm.classList.contains('hidden')) {
|
||
clientInput.focus();
|
||
}
|
||
}
|
||
|
||
addBtn.addEventListener('click', () => toggleAddForm('add'));
|
||
|
||
cancelBtn.addEventListener('click', () => {
|
||
addForm.classList.add('hidden');
|
||
rulesContainer.classList.remove('hidden');
|
||
addBtn.classList.remove('hidden');
|
||
resetForm();
|
||
});
|
||
|
||
function resetForm() {
|
||
editingIdInput.value = '';
|
||
envSelect.value = 'DD_PP';
|
||
clientInput.value = '';
|
||
usernameInput.value = '';
|
||
passwordInput.value = '';
|
||
}
|
||
|
||
saveBtn.addEventListener('click', () => {
|
||
const env = envSelect.value;
|
||
const clientName = clientInput.value.trim();
|
||
const username = usernameInput.value.trim();
|
||
const password = passwordInput.value;
|
||
const editingId = editingIdInput.value;
|
||
|
||
if (!clientName || !username || !password) {
|
||
alert('请填写完整的客户名称、账号和密码!');
|
||
return;
|
||
}
|
||
|
||
if (editingId) {
|
||
// Update existing rule
|
||
const index = rules.findIndex(r => r.id === editingId);
|
||
if (index !== -1) {
|
||
rules[index] = {
|
||
...rules[index],
|
||
env: env,
|
||
clientName: clientName,
|
||
username: username,
|
||
password: password
|
||
};
|
||
}
|
||
} else {
|
||
// Add new rule
|
||
rules.push({
|
||
id: Date.now().toString(),
|
||
env: env,
|
||
clientName: clientName,
|
||
username: username,
|
||
password: password
|
||
});
|
||
}
|
||
|
||
saveRules();
|
||
addForm.classList.add('hidden');
|
||
rulesContainer.classList.remove('hidden');
|
||
addBtn.classList.remove('hidden');
|
||
resetForm();
|
||
});
|
||
|
||
function renderRules() {
|
||
rulesList.innerHTML = '';
|
||
const activeRules = rules.filter(r => !r.archived);
|
||
|
||
if (activeRules.length === 0) {
|
||
rulesList.innerHTML = `
|
||
<div class="empty-state">
|
||
<svg width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
|
||
<rect x="3" y="3" width="18" height="18" rx="2" ry="2"></rect>
|
||
<line x1="9" y1="9" x2="15" y2="15"></line>
|
||
<line x1="15" y1="9" x2="9" y2="15"></line>
|
||
</svg>
|
||
<span>暂无账号配置,点击上方 "+" 添加</span>
|
||
</div>`;
|
||
return;
|
||
}
|
||
|
||
activeRules.forEach((rule, index) => {
|
||
const li = document.createElement('li');
|
||
li.className = 'rule-item';
|
||
li.setAttribute('draggable', 'true');
|
||
li.setAttribute('data-index', index.toString());
|
||
|
||
li.innerHTML = `
|
||
<div class="drag-handle" title="拖拽排序">
|
||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M8 9h8M8 15h8" /></svg>
|
||
</div>
|
||
<div class="rule-icon-box">${getRandomIcon(rule.id)}</div>
|
||
<div class="rule-info" data-id="${rule.id}" title="点击执行一键登录">
|
||
<div class="rule-domain">
|
||
${rule.clientName}
|
||
<span class="rule-env env-${rule.env.toLowerCase().replace('_', '-')}">${rule.env.replace('_', ' ')}</span>
|
||
</div>
|
||
</div>
|
||
<div class="rule-actions">
|
||
<button class="icon-btn btn-edit" data-id="${rule.id}" title="编辑此配置">
|
||
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
||
<path stroke-linecap="round" stroke-linejoin="round" d="M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z" />
|
||
</svg>
|
||
</button>
|
||
<button class="icon-btn btn-delete" data-id="${rule.id}" title="归档此配置">
|
||
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
||
<path stroke-linecap="round" stroke-linejoin="round" d="M20 7l-8 8-4-4m12 4v5a2 2 0 01-2 2H6a2 2 0 01-2-2V9a2 2 0 012-2h5" />
|
||
</svg>
|
||
</button>
|
||
</div>
|
||
`;
|
||
|
||
addDragEvents(li);
|
||
rulesList.appendChild(li);
|
||
});
|
||
|
||
attachRuleEvents();
|
||
}
|
||
|
||
function renderArchive() {
|
||
archiveList.innerHTML = '';
|
||
const archivedRules = rules.filter(r => r.archived);
|
||
|
||
if (archivedRules.length === 0) {
|
||
archiveList.innerHTML = '<div class="empty-state" style="padding: 20px 0;"><span>暂无归档内容</span></div>';
|
||
return;
|
||
}
|
||
|
||
archivedRules.forEach(rule => {
|
||
const li = document.createElement('li');
|
||
li.className = 'rule-item';
|
||
li.innerHTML = `
|
||
<div class="rule-icon-box">${getRandomIcon(rule.id)}</div>
|
||
<div class="rule-info">
|
||
<div class="rule-domain">${rule.clientName} <span class="rule-env env-${rule.env.toLowerCase().replace('_', '-')}">${rule.env.replace('_', ' ')}</span></div>
|
||
</div>
|
||
<div class="rule-actions">
|
||
<button class="icon-btn btn-restore" data-id="${rule.id}" title="恢复到主列表">
|
||
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8"/><path d="M3 3v5h5"/></svg>
|
||
</button>
|
||
<button class="icon-btn btn-delete-perm" data-id="${rule.id}" title="彻底删除">
|
||
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"/></svg>
|
||
</button>
|
||
</div>
|
||
`;
|
||
archiveList.appendChild(li);
|
||
});
|
||
|
||
document.querySelectorAll('.btn-restore').forEach(btn => {
|
||
btn.addEventListener('click', (e) => {
|
||
const id = e.currentTarget.getAttribute('data-id');
|
||
const index = rules.findIndex(r => r.id === id);
|
||
if (index !== -1) {
|
||
rules[index].archived = false;
|
||
saveRules();
|
||
renderArchive();
|
||
}
|
||
});
|
||
});
|
||
|
||
document.querySelectorAll('.btn-delete-perm').forEach(btn => {
|
||
btn.addEventListener('click', (e) => {
|
||
const id = e.currentTarget.getAttribute('data-id');
|
||
if (confirm('确定要彻底删除此配置吗?此操作不可撤销。')) {
|
||
rules = rules.filter(r => r.id !== id);
|
||
saveRules();
|
||
renderArchive();
|
||
}
|
||
});
|
||
});
|
||
}
|
||
|
||
function attachRuleEvents() {
|
||
document.querySelectorAll('.rule-info').forEach(infoArea => {
|
||
infoArea.addEventListener('click', (e) => {
|
||
const id = e.currentTarget.getAttribute('data-id');
|
||
const rule = rules.find(r => r.id === id);
|
||
if (rule) executePurgeAndLogin(rule, e.currentTarget);
|
||
});
|
||
});
|
||
|
||
document.querySelectorAll('.btn-edit').forEach(btn => {
|
||
btn.addEventListener('click', (e) => {
|
||
e.stopPropagation();
|
||
toggleAddForm('edit', e.currentTarget.getAttribute('data-id'));
|
||
});
|
||
});
|
||
|
||
document.querySelectorAll('.btn-delete').forEach(btn => {
|
||
btn.addEventListener('click', (e) => {
|
||
e.stopPropagation();
|
||
const id = e.currentTarget.getAttribute('data-id');
|
||
const index = rules.findIndex(r => r.id === id);
|
||
if (index !== -1) {
|
||
rules[index].archived = true;
|
||
saveRules();
|
||
}
|
||
});
|
||
});
|
||
}
|
||
|
||
if (archiveToggle) {
|
||
archiveToggle.addEventListener('click', () => {
|
||
mainViewContent.classList.add('hidden');
|
||
archiveViewContent.classList.remove('hidden');
|
||
renderArchive();
|
||
});
|
||
}
|
||
|
||
if (backToMain) {
|
||
backToMain.addEventListener('click', () => {
|
||
archiveViewContent.classList.add('hidden');
|
||
mainViewContent.classList.remove('hidden');
|
||
renderRules();
|
||
});
|
||
}
|
||
|
||
// --- Drag and Drop functionality ---
|
||
function addDragEvents(item) {
|
||
item.addEventListener('dragstart', (e) => {
|
||
dragStartIndex = parseInt(e.currentTarget.getAttribute('data-index'));
|
||
e.currentTarget.classList.add('dragging');
|
||
// Set empty ghost image
|
||
if (e.dataTransfer) {
|
||
e.dataTransfer.effectAllowed = 'move';
|
||
// Need to set data to allow dragging in Firefox
|
||
e.dataTransfer.setData('text/plain', dragStartIndex);
|
||
}
|
||
});
|
||
|
||
item.addEventListener('dragend', (e) => {
|
||
e.currentTarget.classList.remove('dragging');
|
||
});
|
||
|
||
item.addEventListener('dragover', (e) => {
|
||
e.preventDefault();
|
||
// Allow drop
|
||
return false;
|
||
});
|
||
|
||
item.addEventListener('dragenter', (e) => {
|
||
e.preventDefault();
|
||
});
|
||
|
||
item.addEventListener('drop', (e) => {
|
||
e.stopPropagation();
|
||
const dragEndIndex = parseInt(e.currentTarget.closest('.rule-item').getAttribute('data-index'));
|
||
|
||
if (dragStartIndex !== dragEndIndex) {
|
||
swapItems(dragStartIndex, dragEndIndex);
|
||
}
|
||
return false;
|
||
});
|
||
}
|
||
|
||
function swapItems(fromIndex, toIndex) {
|
||
// Array manipulation for drag sorting
|
||
const itemOne = rules[fromIndex];
|
||
rules.splice(fromIndex, 1);
|
||
rules.splice(toIndex, 0, itemOne);
|
||
saveRules();
|
||
}
|
||
|
||
function executePurgeAndLogin(rule, element) {
|
||
const originalContent = element.innerHTML;
|
||
element.innerHTML = `<div class="loading-state"><svg class="loading" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M12 2v4m0 12v4M4.93 4.93l2.83 2.83m8.48 8.48l2.83 2.83M2 12h4m12 0h4M4.93 19.07l2.83-2.83m8.48-8.48l2.83-2.83"/></svg><span>清理中...</span></div>`;
|
||
|
||
if (typeof chrome !== 'undefined' && chrome.runtime) {
|
||
const config = ENV_CONFIG[rule.env];
|
||
chrome.runtime.sendMessage({
|
||
action: "purgeAndRedirect",
|
||
domain: config.domain,
|
||
targetUrl: config.url,
|
||
username: rule.username,
|
||
password: rule.password
|
||
}, (response) => {
|
||
// 提供短暂的“清理中...”视觉反馈后关闭插件
|
||
setTimeout(() => {
|
||
window.close();
|
||
}, 1500); // 保持 1500ms 反馈后关闭,也可改为更短如 200ms,为保持原逻辑体验暂设 1500ms
|
||
});
|
||
}
|
||
}
|
||
|
||
loadAndInitBaseApp();
|
||
});
|