Function bodies 132 total
formatItems function · javascript · L3-L6 (4 LOC)miniprogram/pages/info/info.js
function formatItems(items) {
if (!items?.length) return "-";
return items.map(x => `${x.name}×${x.qty}`).join(",");
}formatItems function · javascript · L4-L7 (4 LOC)miniprogram/pages/pay/pay.js
function formatItems(items) {
if (!items?.length) return "-";
return items.map(x => `${x.name}×${x.qty}`).join(",");
}formatItems function · javascript · L3-L6 (4 LOC)miniprogram/pages/success/success.js
function formatItems(items) {
if (!items?.length) return "-";
return items.map(x => `${x.name}×${x.qty}`).join(",");
}requestJson function · javascript · L4-L18 (15 LOC)miniprogram/utils/api.js
function requestJson({ url, method = "GET", data }) {
return new Promise((resolve, reject) => {
wx.request({
url,
method,
data,
header: { "Content-Type": "application/json" },
success: (res) => {
if (res.statusCode >= 200 && res.statusCode < 300) return resolve(res.data);
reject(res.data || { error: `HTTP ${res.statusCode}` });
},
fail: reject
});
});
}createOrder function · javascript · L20-L40 (21 LOC)miniprogram/utils/api.js
export async function createOrder(payload) {
if (USE_MOCK) {
return {
ok: true,
order: {
id: randomId(),
createdAt: new Date().toISOString(),
status: "NEW",
...payload
}
};
}
const base = (API_BASE || "").replace(/\/+$/, "");
if (!base) throw new Error("API_BASE 未配置");
return requestJson({
url: `${base}/api/orders`,
method: "POST",
data: payload
});
}randomId function · javascript · L1-L3 (3 LOC)miniprogram/utils/id.js
export function randomId() {
return Math.random().toString(16).slice(2, 10) + Date.now().toString(16).slice(-6);
}saveCheckout function · javascript · L5-L7 (3 LOC)miniprogram/utils/storage.js
export function saveCheckout(checkout) {
wx.setStorageSync(KEY_CHECKOUT, checkout);
}Repobility · open methodology · https://repobility.com/research/
loadCheckout function · javascript · L9-L11 (3 LOC)miniprogram/utils/storage.js
export function loadCheckout() {
return wx.getStorageSync(KEY_CHECKOUT) || null;
}clearCheckout function · javascript · L13-L15 (3 LOC)miniprogram/utils/storage.js
export function clearCheckout() {
wx.removeStorageSync(KEY_CHECKOUT);
}saveInfo function · javascript · L17-L19 (3 LOC)miniprogram/utils/storage.js
export function saveInfo(info) {
wx.setStorageSync(KEY_INFO, info);
}loadInfo function · javascript · L21-L23 (3 LOC)miniprogram/utils/storage.js
export function loadInfo() {
return wx.getStorageSync(KEY_INFO) || null;
}clearInfo function · javascript · L25-L27 (3 LOC)miniprogram/utils/storage.js
export function clearInfo() {
wx.removeStorageSync(KEY_INFO);
}saveReceipt function · javascript · L29-L31 (3 LOC)miniprogram/utils/storage.js
export function saveReceipt(receipt) {
wx.setStorageSync(KEY_RECEIPT, receipt);
}loadReceipt function · javascript · L33-L35 (3 LOC)miniprogram/utils/storage.js
export function loadReceipt() {
return wx.getStorageSync(KEY_RECEIPT) || null;
}formatAmount function · javascript · L45-L51 (7 LOC)public/admin.js
function formatAmount(order) {
const myr = `RM ${order.total ?? "-"}`;
if (order.paymentCurrency === "CNY" && typeof order.totalCny === "number") {
return `¥${Number(order.totalCny).toFixed(2)}(约 ${myr})`;
}
return myr;
}Repobility (the analyzer behind this table) · https://repobility.com
formatSignedNumber function · javascript · L53-L57 (5 LOC)public/admin.js
function formatSignedNumber(value) {
const n = Number(value) || 0;
if (n > 0) return `+${n}`;
return `${n}`;
}getLocalISODate function · javascript · L59-L64 (6 LOC)public/admin.js
function getLocalISODate(d = new Date()) {
const y = d.getFullYear();
const m = String(d.getMonth() + 1).padStart(2, "0");
const day = String(d.getDate()).padStart(2, "0");
return `${y}-${m}-${day}`;
}parseDateSafe function · javascript · L66-L70 (5 LOC)public/admin.js
function parseDateSafe(dateKey) {
const dt = new Date(`${dateKey}T00:00:00`);
if (Number.isNaN(dt.getTime())) return null;
return dt;
}weekdayLabel function · javascript · L72-L76 (5 LOC)public/admin.js
function weekdayLabel(dateKey) {
const dt = parseDateSafe(dateKey);
if (!dt) return "";
return dt.toLocaleDateString("zh-CN", { weekday: "short" });
}dateShortLabel function · javascript · L78-L84 (7 LOC)public/admin.js
function dateShortLabel(dateKey) {
const dt = parseDateSafe(dateKey);
if (!dt) return escapeHtml(dateKey);
const month = String(dt.getMonth() + 1).padStart(2, "0");
const day = String(dt.getDate()).padStart(2, "0");
return `${month}-${day}`;
}statusCountsFrom function · javascript · L86-L94 (9 LOC)public/admin.js
function statusCountsFrom(data) {
const src = data?.statusCounts || {};
return {
NEW: Number(src.NEW) || 0,
PAID: Number(src.PAID) || 0,
FULFILLED: Number(src.FULFILLED) || 0,
CANCELLED: Number(src.CANCELLED) || 0
};
}getPickupDateFilter function · javascript · L96-L98 (3 LOC)public/admin.js
function getPickupDateFilter() {
return String(filterPickupDateEl?.value || "").trim();
}setPickupDateFilter function · javascript · L100-L104 (5 LOC)public/admin.js
function setPickupDateFilter(value) {
if (!filterPickupDateEl) return;
filterPickupDateEl.value = value;
localStorage.setItem(FILTER_STORAGE_KEY, value);
}Want this analysis on your repo? https://repobility.com/scan/
getSearchQuery function · javascript · L106-L108 (3 LOC)public/admin.js
function getSearchQuery() {
return String(searchInputEl?.value || "").trim().toLowerCase();
}orderSearchText function · javascript · L110-L112 (3 LOC)public/admin.js
function orderSearchText(order) {
return `${order.name || ""} ${order.id || ""} ${order.contact || ""}`.toLowerCase();
}statusBadgeHTML function · javascript · L114-L117 (4 LOC)public/admin.js
function statusBadgeHTML(status) {
const meta = STATUS_META[status] || STATUS_META.NEW;
return `<span class="status-badge ${meta.badgeClass}">${meta.label}</span>`;
}renderStatusBar function · javascript · L119-L146 (28 LOC)public/admin.js
function renderStatusBar(counts, total) {
if (!total) {
return `
<div class="progress-bar"><span class="bar-segment bar-empty" style="width:100%"></span></div>
<div class="status-legend">
<span class="legend-item"><i class="dot dot-empty"></i>暂无订单</span>
</div>
`;
}
const keys = ["NEW", "PAID", "FULFILLED", "CANCELLED"];
const segments = keys
.filter(key => counts[key] > 0)
.map((key) => {
const width = Math.max(4, Math.round((counts[key] / total) * 100));
return `<span class="bar-segment bar-${key.toLowerCase()}" style="width:${width}%"></span>`;
})
.join("");
const legend = keys
.map((key) => `<span class="legend-item"><i class="dot dot-${key.toLowerCase()}"></i>${STATUS_META[key].label} ${counts[key]}</span>`)
.join("");
return `
<div class="progress-bar">${segments}</div>
<div class="status-legend">${legend}</div>
`;
}isStaleNewOrder function · javascript · L148-L153 (6 LOC)public/admin.js
function isStaleNewOrder(order) {
if (String(order?.status || "").toUpperCase() !== "NEW") return false;
const createdAt = Date.parse(order?.createdAt || "");
if (Number.isNaN(createdAt)) return false;
return (Date.now() - createdAt) > (24 * 60 * 60 * 1000);
}normalizeWhatsAppPhone function · javascript · L155-L160 (6 LOC)public/admin.js
function normalizeWhatsAppPhone(raw) {
const cleaned = String(raw || "").replace(/[^\d+]/g, "");
if (!cleaned) return "";
if (cleaned.startsWith("+")) return cleaned.slice(1);
return cleaned;
}renderSummary function · javascript · L162-L204 (43 LOC)public/admin.js
function renderSummary(data) {
const pickupDate = getPickupDateFilter();
const today = getLocalISODate();
const isToday = pickupDate && pickupDate === today;
const filterLabel = pickupDate ? `取货日期:${pickupDate}` : "取货日期:全部";
const counts = statusCountsFrom(data);
const total = Number(data?.total) || 0;
const totalQuantity = Number(data?.totalQuantity) || 0;
const newCount = counts.NEW;
summaryEl.innerHTML = `
<div class="summary-head">
<p class="hint">筛选:${escapeHtml(filterLabel)} ${isToday ? '<span class="today-badge">今天</span>' : ""}</p>
<button id="printPrepBtn" class="ghost print-btn" type="button">打印准备清单</button>
</div>
<div class="summary-grid-4">
<div class="metric-card">
<p class="label">总预订</p>
<p class="value">${total}</p>
</div>
<div class="metric-card">
<p class="label">总份数</p>
<p class="value">${totalQuantity}</p>
</div>
<div class="metric-card ${newCount > 0 ? "metric-renderAlerts function · javascript · L206-L269 (64 LOC)public/admin.js
function renderAlerts(orders, availabilityList) {
if (!alertsContainerEl) return;
const alerts = [];
const staleOrders = (orders || []).filter(isStaleNewOrder);
if (staleOrders.length > 0) {
const names = staleOrders.slice(0, 3).map((o) => escapeHtml(o.name || "-")).join("、");
alerts.push({
className: "alert-warning",
text: `${staleOrders.length} 笔订单超过 24 小时未确认收款${names ? `(${names})` : ""}`
});
}
const today = getLocalISODate();
const todayNewCount = (orders || []).filter((o) => String(o.pickupDate || "") === today && String(o.status || "") === "NEW").length;
if (todayNewCount > 0) {
alerts.push({
className: "alert-urgent",
text: `今天有 ${todayNewCount} 笔待确认订单需要跟进`
});
}
const highUsage = [];
const fullDates = [];
for (const day of (availabilityList || [])) {
const cap = Number(day.effectiveCapacity) || Number(day.capacity) || 0;
const reserved = Number(day.reservedQuantity) || 0;
const remain = Number(daRepobility · code-quality intelligence · https://repobility.com
renderCalendar function · javascript · L271-L304 (34 LOC)public/admin.js
function renderCalendar(list) {
if (!calendarGridEl) return;
const today = getLocalISODate();
const selectedDate = getPickupDateFilter();
if (!Array.isArray(list) || list.length === 0) {
calendarGridEl.innerHTML = "<p class=\"hint\">暂无可用容量数据。</p>";
return;
}
calendarGridEl.innerHTML = list.map((row) => {
const date = String(row.date || "");
const cap = Number(row.effectiveCapacity) || Number(row.capacity) || 0;
const reserved = Number(row.reservedQuantity) || 0;
const remain = Number(row.remainingQuantity) || 0;
const usage = cap > 0 ? Math.min(100, Math.round((reserved / cap) * 100)) : 100;
let levelClass = "cal-low";
if (remain <= 0) levelClass = "cal-full";
else if (usage >= 80) levelClass = "cal-critical";
else if (usage >= 50) levelClass = "cal-medium";
const isTodayClass = date === today ? "cal-today" : "";
const isSelectedClass = date === selectedDate ? "cal-selected" : "";
const weekText = date === today ? "今天setStockValue function · javascript · L306-L309 (4 LOC)public/admin.js
function setStockValue(el, value) {
if (!el) return;
el.textContent = value;
}setStockLoadingState function · javascript · L311-L316 (6 LOC)public/admin.js
function setStockLoadingState(loading) {
const disabled = Boolean(loading);
if (stockRefreshBtn) stockRefreshBtn.disabled = disabled;
if (stockAddBtn) stockAddBtn.disabled = disabled;
if (stockResetBtn) stockResetBtn.disabled = disabled;
}renderStock function · javascript · L318-L327 (10 LOC)public/admin.js
function renderStock(stock) {
setStockValue(stockBaseEl, String(stock.baseCapacity ?? "-"));
setStockValue(stockReservedEl, String(stock.reservedQuantity ?? "-"));
setStockValue(stockAdjustmentEl, formatSignedNumber(stock.manualAdjustment ?? 0));
setStockValue(stockEffectiveEl, String(stock.effectiveCapacity ?? "-"));
setStockValue(stockRemainingEl, String(stock.remainingQuantity ?? "-"));
if (stockDateHintEl) {
stockDateHintEl.textContent = `${stock.date}:剩余 ${stock.remainingQuantity} 份(已占用 ${stock.reservedQuantity} 份)`;
}
}resetStockView function · javascript · L329-L336 (8 LOC)public/admin.js
function resetStockView(message) {
setStockValue(stockBaseEl, "-");
setStockValue(stockReservedEl, "-");
setStockValue(stockAdjustmentEl, "-");
setStockValue(stockEffectiveEl, "-");
setStockValue(stockRemainingEl, "-");
if (stockDateHintEl) stockDateHintEl.textContent = message;
}loadStock function · javascript · L338-L367 (30 LOC)public/admin.js
async function loadStock() {
const pickupDate = getPickupDateFilter();
if (!pickupDate) {
resetStockView("请选择取货日期后可查看库存。");
return;
}
setStockLoadingState(true);
if (stockDateHintEl) stockDateHintEl.textContent = `正在加载 ${pickupDate} 的库存...`;
try {
const qs = new URLSearchParams({
pickupDate,
_t: String(Date.now())
});
const res = await fetch(`/api/admin/stock?${qs.toString()}`, {
cache: "no-store",
headers: {
"Cache-Control": "no-cache"
}
});
const data = await res.json();
if (!res.ok) throw new Error(data?.error || "库存加载失败");
renderStock(data);
} catch (error) {
resetStockView(error?.message || "库存加载失败,请稍后再试。");
} finally {
setStockLoadingState(false);
}
}contextActionsHTML function · javascript · L369-L385 (17 LOC)public/admin.js
function contextActionsHTML(order) {
const id = escapeHtml(order.id || "");
const status = String(order.status || "NEW").toUpperCase();
if (status === "NEW") {
return `
<button class="ghost action-primary" data-action="paid" data-id="${id}">确认收款</button>
<button class="ghost" data-action="cancel" data-id="${id}">取消</button>
`;
}
if (status === "PAID") {
return `<button class="ghost action-primary" data-action="done" data-id="${id}">标记完成</button>`;
}
if (status === "CANCELLED") {
return `<button class="ghost" data-action="reopen" data-id="${id}">恢复为新订单</button>`;
}
return `<span class="meta">已完成</span>`;
}contactHtml function · javascript · L387-L392 (6 LOC)public/admin.js
function contactHtml(contact) {
const safeContact = escapeHtml(contact || "-");
const phone = normalizeWhatsAppPhone(contact);
if (!phone) return safeContact;
return `<a class="inline-link" href="https://wa.me/${escapeHtml(phone)}" target="_blank" rel="noreferrer">${safeContact}</a>`;
}Repobility · open methodology · https://repobility.com/research/
renderOrders function · javascript · L394-L463 (70 LOC)public/admin.js
function renderOrders(rawOrders) {
const orders = Array.isArray(rawOrders) ? rawOrders : [];
const query = getSearchQuery();
const filtered = query ? orders.filter(order => orderSearchText(order).includes(query)) : orders;
lastOrders = orders;
if (!filtered.length) {
if (query) {
listEl.innerHTML = `<p class="hint">没有找到匹配“${escapeHtml(query)}”的订单。</p>`;
} else {
listEl.innerHTML = "<p class=\"hint\">还没有预订记录。</p>";
}
return;
}
listEl.innerHTML = filtered
.map((order) => {
const id = escapeHtml(order.id || "");
const name = escapeHtml(order.name || "");
const status = String(order.status || "NEW").toUpperCase();
const quantity = Number(order.quantity) || 0;
const pickupDate = escapeHtml(order.pickupDate || "-");
const pickupLocation = escapeHtml(order.pickupLocation || "-");
const amount = escapeHtml(formatAmount(order));
const method = escapeHtml(paymentMethodLabel(order.paymentMethod));
setStatus function · javascript · L465-L477 (13 LOC)public/admin.js
async function setStatus(id, status) {
const res = await fetch(`/api/orders/${id}`, {
method: "PATCH",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ status })
});
const data = await res.json();
if (!res.ok) {
alert(data.error || "更新失败");
return;
}
await loadOrders();
}updateBulkUI function · javascript · L479-L496 (18 LOC)public/admin.js
function updateBulkUI() {
const count = selectedIds.size;
if (bulkCountEl) bulkCountEl.textContent = `已选 ${count}`;
if (!selectAllEl) return;
const query = getSearchQuery();
const visibleOrders = query ? lastOrders.filter(order => orderSearchText(order).includes(query)) : lastOrders;
const visibleIds = visibleOrders.map(o => String(o?.id || "")).filter(Boolean);
if (!visibleIds.length) {
selectAllEl.checked = false;
selectAllEl.indeterminate = false;
return;
}
const selectedVisible = visibleIds.filter(id => selectedIds.has(id)).length;
selectAllEl.checked = selectedVisible === visibleIds.length;
selectAllEl.indeterminate = selectedVisible > 0 && selectedVisible < visibleIds.length;
}bulkSetStatus function · javascript · L498-L521 (24 LOC)public/admin.js
async function bulkSetStatus(ids, status) {
const next = String(status || "").toUpperCase();
if (!ids.length) {
alert("请先选择要批量修改的订单。");
return;
}
if (!next) {
alert("请选择要修改到的状态。");
return;
}
if (!confirm(`确定将 ${ids.length} 条订单批量设置为 ${next} 吗?`)) return;
const res = await fetch("/api/orders/bulk", {
method: "PATCH",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ ids, status: next })
});
const data = await res.json();
if (!res.ok) {
alert(data.error || "更新失败");
return;
}
await loadOrders();
}addStock function · javascript · L523-L554 (32 LOC)public/admin.js
async function addStock() {
const pickupDate = getPickupDateFilter();
if (!pickupDate) {
alert("请先选择取货日期,再添加库存。");
return;
}
const delta = Number.parseInt(stockDeltaInputEl?.value, 10);
if (!Number.isFinite(delta) || delta <= 0) {
alert("请输入大于 0 的补货数量。");
return;
}
setStockLoadingState(true);
try {
const res = await fetch("/api/admin/stock/add", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ pickupDate, delta })
});
const data = await res.json();
if (!res.ok) throw new Error(data?.error || "库存添加失败");
if (stockActionHintEl) {
stockActionHintEl.textContent = `已为 ${pickupDate} 增加 ${delta} 份库存。`;
}
await loadOrders();
} catch (error) {
alert(error?.message || "库存添加失败");
} finally {
setStockLoadingState(false);
}
}resetStockAdjustment function · javascript · L556-L582 (27 LOC)public/admin.js
async function resetStockAdjustment() {
const pickupDate = getPickupDateFilter();
if (!pickupDate) {
alert("请先选择取货日期,再重置库存。");
return;
}
if (!confirm(`确定重置 ${pickupDate} 的临时库存调整吗?`)) return;
setStockLoadingState(true);
try {
const res = await fetch("/api/admin/stock/reset", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ pickupDate })
});
const data = await res.json();
if (!res.ok) throw new Error(data?.error || "库存重置失败");
if (stockActionHintEl) {
stockActionHintEl.textContent = `已重置 ${pickupDate} 的临时库存调整。`;
}
await loadOrders();
} catch (error) {
alert(error?.message || "库存重置失败");
} finally {
setStockLoadingState(false);
}
}loadCalendar function · javascript · L584-L609 (26 LOC)public/admin.js
async function loadCalendar() {
if (!calendarGridEl) return;
calendarGridEl.innerHTML = "<p class=\"hint\">加载中...</p>";
try {
const qs = new URLSearchParams({
days: "7",
qty: "1",
_t: String(Date.now())
});
const res = await fetch(`/api/availability?${qs.toString()}`, {
cache: "no-store",
headers: {
"Cache-Control": "no-cache"
}
});
const data = await res.json();
if (!res.ok) throw new Error(data?.error || "加载失败");
lastAvailabilityList = Array.isArray(data?.list) ? data.list : [];
renderCalendar(lastAvailabilityList);
} catch (error) {
calendarGridEl.innerHTML = `<p class="hint">容量加载失败:${escapeHtml(error?.message || "未知错误")}</p>`;
lastAvailabilityList = [];
}
renderAlerts(lastOrders, lastAvailabilityList);
}loadOrders function · javascript · L611-L647 (37 LOC)public/admin.js
async function loadOrders() {
selectedIds = new Set();
if (selectAllEl) {
selectAllEl.checked = false;
selectAllEl.indeterminate = false;
}
if (bulkStatusEl) bulkStatusEl.value = "";
updateBulkUI();
const pickupDate = getPickupDateFilter();
const qs = new URLSearchParams();
if (pickupDate) qs.set("pickupDate", pickupDate);
qs.set("_t", String(Date.now()));
try {
const res = await fetch(`/api/orders?${qs.toString()}`, {
cache: "no-store",
headers: {
"Cache-Control": "no-cache"
}
});
const data = await res.json();
if (!res.ok) throw new Error(data?.error || "加载失败");
renderSummary(data);
renderOrders(data.orders || []);
updateBulkUI();
} catch (error) {
summaryEl.innerHTML = `<p class="hint">订单加载失败:${escapeHtml(error?.message || "未知错误")}</p>`;
listEl.innerHTML = "<p class=\"hint\">请点击刷新重试。</p>";
document.title = BASE_TITLE;
lastOrders = [];
}
await Promise.all([loadStock(), loadCaleRepobility (the analyzer behind this table) · https://repobility.com
clamp function · javascript · L1-L3 (3 LOC)public/app.js
function clamp(n, min, max) {
return Math.max(min, Math.min(max, n));
}formatItems function · javascript · L17-L20 (4 LOC)public/app.js
function formatItems(items) {
if (!items?.length) return "-";
return items.map(x => `${x.name}×${x.qty}`).join(",");
}formatMyr function · javascript · L22-L26 (5 LOC)public/app.js
function formatMyr(amount) {
const n = Number(amount);
if (!Number.isFinite(n)) return "RM -";
return `RM ${Math.round(n)}`;
}page 1 / 3next ›