CJ

營運總部

OPERATIONS

今天要處理

{{ pageSub }}
{{ homeSecTitle }} {{ homeSecSub }} {{ homeSecNotify }} {{ homeSecWhen }}
{{ c.label }}

{{ c.n }}{{ c.u }} {{ c.badge.t }}

{{ c.f1 }}
{{ c.f2 }}

待辦

今天要處理{{ todayCounts.all }} 家 · {{ todayCounts.allAmt.toLocaleString() }}/月

這幾家店有事情等著 —— 已經過期還開著的、快到期的、看起來沒在用的

正在看今天有什麼事…

{{ todayTab === 'all' ? '今天沒有待辦。' : '這一類現在沒有。' }} {{ todayTab === 'all' ? '沒有過期的、沒有快到期的、也沒有看起來沒在用的 —— 24 家店都正常。' : '換上面的分頁籤看別類。' }}

租戶名冊

篩出 {{ filteredTenants.length }} / {{ tenants.length }} 共 {{ tenants.length }} 間 依建立時間
租戶 方案 服務到期 授權模組 操作
!

讀不到租戶名冊

{{ tenants.length ? '這一次沒拿到最新的名冊,所以暫時不顯示(不是客戶不見了)。' : '這不是「沒有客戶」—— 是這一次沒拿到。' }}
{{ loadErr.tenants }}

正在讀租戶名冊…

還沒有開通任何租戶。
右上角的「開通新租戶」會建立一間新的店 —— 子網域、資料庫、預設帳號一次做完。
這個條件篩不到任何租戶(名冊裡一共有 {{ tenants.length }} 間)。

本月續約漏斗

讀取中… {{ renewFunnel.total }} 家到期 · {{ renewFunnel.amount.toLocaleString() }} 這個月 0 家到期

收入結構

讀取中… 月 {{ revenueMix.total.toLocaleString() }} 月 0
還沒有任何一家綁定方案 —— 這張圖是照「哪家店買了哪個方案、那一級月費多少」畫的, 綁定之前算不出收入。
去「方案與報價」把方案與級距設給客戶,這裡就會長出環圈圖與每條線的佔比。

客戶健康分布

用量 × 月費
{{ Math.round(healthScatter.feeTop/1000) }}K {{ Math.round(healthScatter.yMid/1000) }}K 0 用量 0% 100% 付了錢但沒在用 健康且高價值 {{ p.name }} 月費 {{ p.fee.toLocaleString() }} 學生 {{ p.stu }} / {{ p.cap === -1 ? '無上限' : p.cap }}(用量 {{ p.use }}%) {{ p.name }}

還沒有店可以放上這張圖 —— 要先替客戶設方案(才有月費與容量),點數才畫得出來。

左半邊那 {{ healthScatter.riskN }} 家 付了錢但幾乎沒在用
那是下個月最可能退租的,合計月費 {{ healthScatter.riskFee.toLocaleString() }}

另有 {{ healthScatter.skipped.length }} 家沒畫進來(還沒設方案,算不出月費與容量):{{ healthScatter.skipped.slice(0,3).join('、') }}

全部都是{{ healthMix[0].label }}({{ healthMix[0].n }} 家)

系統維運

讀取中… 讀不到 {{ opsCard.bad }} 支掛了 全部正常 一支都沒登記

讀不到排程的心跳 —— 這不等於「排程都正常」,是這一頁問不到它們的狀態。
{{ loadErr.cron }}

一支排程都沒有登記 —— 主機上的排程設定可能整個沒掛上去。
去「系統 → 排程健康」看一次;那一頁會告訴你是沒登記、還是心跳檔不見了。

{{ r.n }}{{ r.why }} {{ r.v }}{{ r.u }}
近 30 次成功率 {{ opsCard.rate }}% · {{ opsCard.ok }} / {{ opsCard.tot }}

成功率算不出來:掛掉的 {{ opsCard.badNoHist }} 支完全沒有執行紀錄, 把它們算成「沒失敗」會得到一個騙人的 100%。

平台分析

全平台 · 近半年活躍學生

{{ spark(platformTrend.map(m => m.v), 600, 150, 8).last }}人

{{ platformTrend[i].ym }} {{ platformTrend[i].v }} 人
{{ m.ym.slice(5) }}

今日操作分布

{{ todayOps.total }} 筆· 長度跟最多的那一項比 今天還沒有人動過
{{ r.label }} {{ r.n }}筆

方案分布

全部都是{{ tierMix[0].label }}({{ tierMix[0].n }} 家)

還沒有店設方案

{{ m.label }} {{ m.n }}

模組採用率

{{ m.label }} {{ m.n }}/ {{ tenants.length }} 家
{{ rankStudents[0].n }} {{ rankStudents[0].v }} 在籍 {{ (rankClasses[0] || {}).v || 0 }} 堂 / 月 {{ (rankOrders[0] || {}).v || 0 }} 筆 / 月 目前只有一家店,排名要兩家以上才有意義
學生數前段班
{{ i + 1 }} {{ r.n }} {{ r.v }}在籍
本月排課前段班
{{ i + 1 }} {{ r.n }} {{ r.v }}堂
本月交易前段班
{{ i + 1 }} {{ r.n }} {{ r.v }}筆
全平台營運總覽
!

讀不到營運總覽

租戶名冊照舊可以用 —— 只有這一塊這次沒拿到。
{{ loadErr.insights }}

全平台營運總覽

正在讀全平台數字…

全平台營運總覽
總在籍學生{{ platformStats.students }}人
本月總堂數{{ platformStats.classes }}堂
本月總交易{{ platformStats.orders }}筆
近 7 天活躍店{{ platformStats.activeStores }}/{{ tenants.length }} 間
租戶健康

{{ loadErr.insights ? '這一塊也沒拿到(原因同上)。' : '正在讀租戶健康…' }}

租戶健康
{{ h.tenant_name }} {{ h.label }}
{{ m }}
{{ h.loginText }}
{{ h.onboardText }}
{{ h.frozenText }}
看全部 {{ healthCards.length }} 家
租戶健康

目前沒有需要注意的租戶。
(這是算出來的結果,不是沒拿到資料。)

{{ centerMeta.grp }}

{{ centerMeta.title }}

{{ centerMeta.sub }}

正式客戶 {{ healthSummary.customers }} 家 · 需要注意 {{ healthSummary.need_attn }} 家 · 另有 {{ healthSummary.non_customer }} 筆非客戶(自用/測試/範本,不列入客戶數與警示) 私密區監看:{{ { pass: '安全', leak: '外洩', unverifiable: '無法驗證' }[healthGuard.verdict] || healthGuard.verdict }} ({{ healthGuard.checked_at }})
!

讀不到租戶健康

這不是「沒有資料」—— 是這一次沒拿到。
{{ loadErr.health }}

正在讀租戶健康…

還沒有任何租戶。

{{ r.state_label }} {{ r.tenant_name }} {{ r.subdomain }}
服務至 {{ r.expires_at }}({{ daysLeftText(r.days_left) }}) 服務期限:未設定 · 最後登入 {{ r.idle_days === 0 ? '今天' : r.idle_days + ' 天前' }} 從來沒有人登入過 · 資料 {{ r.data.total }} 筆 (學生 {{ r.data.students }}/課堂 {{ r.data.classes }}/銷售 {{ r.data.orders }}/商品 {{ r.data.products }})
{{ f }} {{ f }}
近半年活躍學生
{{ m.ym.slice(5) }}
級距依據(第 2 高){{ r.trend.second_highest }} {{ r.trend.note }}
{{ g.line }} {{ g.plans.length }} 版{{ lineRange(g.plans) }} ✓ 每個方案都開得出報價單 草稿 {{ planRows.filter(p => p.status === 'draft').length }} · 已停售 {{ planRows.filter(p => p.status === 'retired').length }}
真正在擋功能的那兩道閘(LINE 與 ERP)還沒接上來,那要改到另外兩個模組,等你決定。
所以現在客戶實際能用什麼,仍然照「單獨加買」那一份(租戶編輯面板裡的加值功能)。
!

讀不到方案目錄

這不是「沒有資料」—— 是這一次沒拿到。
{{ loadErr.plans }}

正在讀方案目錄…

還沒有任何方案 —— 所以現在開不出任何一張報價單。
按右上角「帶入建議方案」可以一次建好兩條產品線的版本與級距,再逐項改成你談定的價格;
或按「新增方案」自己開。建議先開草稿,內容排好再改成「正式開放」(草稿不會發出任何功能)。

{{ g.line }} 線 {{ g.modules }} {{ g.plans.length }} 個版本 月費 {{ lineRange(g.plans) }} {{ lineTenants(g.plans) ? lineTenants(g.plans) + ' 家在用' : '還沒有人買' }} 由上到下排,下面那一版包含上面的全部
{{ p._tier + 1 }} {{ p.plan_name }} {{ { draft: '草稿', retired: '已停售' }[p.status] || p.status }} {{ p.plan_code }} {{ p.tenants }} 家在用

內部{{ p.notes }}

月費 · 看{{ p.product_line === 'CLASS' ? '在學學生數' : '商品品項數' }}

還沒開級距,所以這個方案開不出報價單 —— 按「編輯」加一級並填月費。

{{ p.features.length }} 項功能基礎+{{ p._added.length }} {{ planMetrics[l.metric] || l.metric }} {{ l.limit_value < 0 ? '無上限' : l.limit_value }} (緩衝 {{ l.buffer_pct }}%)

這一版少掉上一版有的 {{ p._removed.length }} 項: {{ featLabel(c) }}
高階版通常要包含低階版的全部 —— 請按「編輯」確認是不是漏勾了。

這一版有 {{ featLabel(c) }}
創始客戶優惠 {{ rateText(founding.discount_rate) }} 還沒設 已收 {{ setupOpened }} 家客戶 只打第一年·跟年繳 9 折相疊

算進那 {{ setupOpened }} 家的是:

· {{ c.tenant_name }} ({{ c.kind_label }}) ← 這一家要是你自己的店,到「租戶管理」把種類改成「自用」就不會算進名額

目前一個正式客戶都沒有 —— 名額從第 1 家開始算

{{ founding.state.why }}

最便宜那一級 原價 {{ Number(founding.sample_monthly).toLocaleString() }}/月 → 第一年 {{ Number(founding.state.monthly).toLocaleString() }}/月 (每月省 {{ Number(founding.state.saved_monthly).toLocaleString() }})· 第二年起回原價

建置費菜單 {{ setupItems.filter(i => i.status === 'active').length }} 個項目 已開通 {{ setupOpened }} 家 促銷:日期沒過而且名額沒滿才算數
{{ it.item_name }}({{ it.line_label }}) 套餐 看情況報價 {{ it.product_line === 'BOTH' ? '兩條線都有' : it.product_line + ' 線' }}

{{ it.item_desc }}

做到這裡算完成{{ it.done_when }}

這一列要做的工變了

定價當時按 {{ it.priced_for_accounts }} 個 LINE 官方帳號,而這條線現在要建 {{ it.accounts_now }} 個

你當初寫的是:「{{ it.price_reason }}」寫了 {{ it.reason_age_days }} 天

這一列沒有寫定價理由 三年後沒有人答得出為什麼收這個價

或在底下改價格/改理由,按儲存
{{ it.promo ? it.promo.why : '' }}
{{ it.promo ? it.promo.why : '' }}
你在 {{ String(it.price_reason_at).slice(0, 10) }} 寫的 還沒寫過
共 {{ termRows.length }} 條 · 要印的 {{ termRows.filter(t => t.is_enabled).length }} · 被機器擋住 {{ termRows.filter(t => t.check.state === 'blocked').length }}

系統自己檢查過的承諾({{ termPromises.filter(p => p.ok).length }} 條成立、{{ termPromises.filter(p => !p.ok).length }} 條還不成立)

{{ pr.ok ? '可以承諾' : '還不能承諾' }} {{ pr.label }}
判準:{{ pr.evidence }}
{{ pr.why }}
!

讀不到服務說明

這不是「沒有資料」—— 是這一次沒拿到。
{{ loadErr.terms }}

正在讀服務說明條文…

還沒有任何條文。按「帶入建議條文」會照 2026-09-27 定案的六節寫進去,
之後你逐條改字;其中三條會被機器擋住印不出來(那三個功能還沒做)。

{{ label }}

{{ { verified: '機器驗過', blocked: '印不出來', unchecked: '沒有機器在看' }[t.check.state] }} {{ t.title }} (關著,不印)
{{ t.body }}
這一條印不出來:{{ t.check.evidence }}
{{ t.check.evidence }}

可以印出去的那一份 ({{ termPrint.generated_at }} 產生)

這 {{ termPrint.blocked.length }} 條沒有印進去(那件事還沒做完 —— 現在寫上去就是承諾一個不存在的東西)

· {{ b.title }} —— {{ b.check.evidence }}

共 {{ quoteRows.length }} 張 · 成交 {{ quoteRows.filter(q => q.status === 'accepted').length }} · 已送出 {{ quoteRows.filter(q => q.status === 'sent').length }}
開一張新的報價單

已經選了店,名字就跟著那家店走,不用再填。

這幾級是方案目錄裡真的有的。級距越大代表學生數/品項數越多,月費越高。

印在單子上的「這個價格何時失效」。留白=不印期限。

要賣哪幾個方案

還沒有任何「正式開放」的方案 —— 先到方案目錄把它從草稿改成正式開放。

要收哪幾項建置費 (一項都不勾=這張單不收建置費)

建置費菜單是空的 —— 先到上面的「建置費菜單」加項目。

這幾項沒有重複收:

{{ quoteDraft.founding.label }}({{ rateText(quoteDraft.founding.rate) }}) 還剩 {{ quoteDraft.founding.left_quota }} 家

· 第一年 每月 {{ quoteDraft.founding.y1_monthly.toLocaleString() }} (月繳一年 {{ quoteDraft.founding.y1_monthly_total.toLocaleString() }}/年繳 {{ quoteDraft.founding.y1_annual.toLocaleString() }}) 省 {{ quoteDraft.founding.saved_y1.toLocaleString() }}

· 第二年起 每月 {{ quoteDraft.founding.later_monthly.toLocaleString() }} (年繳 {{ quoteDraft.founding.later_annual.toLocaleString() }})—— 回原價

年繳 9 折是疊在這個折扣上算的(月費先打折並進位,那個整數才算年繳)

創始客戶優惠沒有套用:{{ quoteDraft.founding.why }}

這張單有 {{ quoteDraft.setup_mismatch.length }} 件事對不上(不擋你,但先看一眼)

· {{ m.item_name }}:{{ m.note }}

這一句會原樣印在單子上給客人看,不影響上面算出來的金額。

月費合計 {{ quoteDraft.total_monthly.toLocaleString() }}
一次性費用 {{ quoteDraft.total_setup.toLocaleString() }}
下次續約日 {{ quoteDraft.renewal_date }}

這幾個方案還沒定價,存不了:{{ quoteDraft.price_missing.join('、') }}
先到「方案目錄」把那一級的月費填好 —— 0 元的單發出去,對方會當成免費。

!

讀不到報價單

這不是「沒有資料」—— 是這一次沒拿到。
{{ loadErr.quotes }}

正在讀報價單…

還沒有開過報價單。 報價單會記下「這家店買哪條線哪個版本、月費多少、下次什麼時候續約」。
{{ { draft: '草稿', sent: '已送出', accepted: '成交', lost: '沒成' }[q.status] || q.status }} {{ q.who }} {{ q.quote_no }} 月 {{ Number(q.total_monthly).toLocaleString() }} +一次性 {{ Number(q.total_setup).toLocaleString() }}
報價日 {{ q.quoted_at }} · 有效到 {{ q.valid_until }} · 下次續約 {{ q.renewal_date }} · {{ q.discount_note }}

{{ quotePrint.quote.quote_no }} · {{ quotePrint.quote.who }} (這是當時定格的內容,不是現在重算的)

月費合計 {{ Number(quotePrint.quote.total_monthly).toLocaleString() }} · 一次性 {{ Number(quotePrint.quote.total_setup).toLocaleString() }}

{{ quotePrint.quote.discount_note }}

~ 清除日期
總部稽核簿完整 · 未偵測到任何竄改(已驗 {{ masterVerifyResult.result ? masterVerifyResult.result.checked : 0 }} 筆) 但整本有 {{ masterVerifyResult.result.total }} 筆 —— 另外 {{ masterUnsealedCount }} 筆是防篡改封條上線之前的舊紀錄,不在保護範圍(那幾筆被改過也驗不出來)。 這本簿子從頭到尾沒有任何一筆有封條 —— 上面那句「未偵測到任何竄改」只代表「沒有證據」,不代表有被保護。 偵測到異常 —— 有紀錄被改過或被刪/插入 關閉
{{ masterVerifyResult.result.reason }} · 斷點在第 {{ masterVerifyResult.result.broken_at }} 號紀錄
!

讀不到操作紀錄

這不是「沒有資料」—— 是這一次沒拿到。
{{ loadErr.audit }}

正在讀總部操作紀錄…

符合條件共 {{ auditTotal }} 筆
~
全店稽核簿完整 · 未偵測到任何竄改 偵測到異常 —— 有店家的紀錄被動過手腳 關閉
{{ r.table }} · 店 {{ r.tenant_id }}:✓ 完整(驗過 {{ r.checked }} 筆)✗ 第 {{ r.broken_at }} 筆之後被動過 — {{ r.reason }}
!

讀不到跨店稽核

這不是「沒有資料」—— 是這一次沒拿到。
{{ loadErr.storeaudit }}

正在讀分店操作紀錄…

現在是篩過的: 只看真人 單一租戶 操作人「{{ storeAuditFilter.operator }}」 關鍵字「{{ storeAuditFilter.keyword }}」

符合條件共 {{ storeAuditTotal }} 筆 · 第 {{ storeAuditFilter.page }} 頁
~ 清除日期
協助通行證有效 30 分鐘; 紅色=現在還有人在裡面
!

讀不到化身紀錄

這不是「沒有資料」—— 是這一次沒拿到。
{{ loadErr.imp }}

正在讀化身通行證紀錄…

符合條件共 {{ impTotal }} 筆
!

讀不到總部的 LINE 設定

{{ loadErr.platformline }}

正在讀設定…

!

讀不到通知設定

這不是「沒有設定」—— 是這一次沒拿到。
{{ secSetErr || '原因不明' }}

{{ secHealth.ok ? '守門情報運作中' : '沒有在記錄 —— 底下的數字不可信' }} {{ secHealth.reason }}
外人 · 沒有有效身分

{{ secNum(secCards.outsider.hits) }}次 {{ secCards.outsider.hits ? '要你看一眼' : '乾淨' }}

自己人 · 權限沒勾好

{{ secNum(secCards.insider.hits) }}次 {{ secCards.insider.hits ? '行政待辦' : '乾淨' }}

!

讀不到守門情報

這不是「沒有人被擋」—— 是這一次沒拿到。
{{ loadErr.secintel }}

正在讀守門情報…

{{ cronSummary.bad }} 支掛了 {{ cronSummary.warn }} 支太久沒跑 全部正常 共 {{ cronSummary.total }} 支排程
!

讀不到排程健康

這不是「沒有資料」—— 是這一次沒拿到。
{{ loadErr.cron }}

正在讀排程健康…

還沒有任何排程心跳紀錄。
(登記在系統裡的排程都會列出來,包含從來沒跑過的)

{{ { ok: '正常', bad: '失敗', mid: '太久沒跑', off: '無紀錄', dry: '演練模式', never: '從來沒跑過' }[c.level] }} {{ c.label || c.key }} {{ c.module }} {{ c.ago }} · {{ c.msText }}
這支排程從來沒有跑過(系統裡登記了它,但一次紀錄都沒有)。 通常代表主機上的排程設定漏了這一條,或路徑寫錯了。
這支排程不在系統的排程清單裡,但它真的有在跑。 (所以它不會被「太久沒跑」盯著 —— 要盯就得把它登記進去。)
最近 {{ c.band.length }} 次 · 失敗 {{ c.failCount }} 次
{{ c.summaryText }}
{{ c.atText }}
每次送檔成功後自動留一筆(2026-09-23 起) ·「2026-07-22 以前」那幾筆是當初建表時人工補登的;中間到 2026-09-23 那段沒有紀錄
!

讀不到部署歷史

這不是「沒有資料」—— 是這一次沒拿到。
{{ loadErr.deploy }}

正在讀部署紀錄…

還沒有部署紀錄。
(下一次送檔成功之後,這裡就會出現一筆)

共 {{ deployTotal }} 筆
這幾個數字只要不是 0 就要看一下 —— 那是重灌之後對不上的殘留資料
!

讀不到移轉健檢

這不是「沒有資料」—— 是這一次沒拿到。
{{ loadErr.mig }}

正在讀搬家健康…

沒有資料。
(需要 customers/cl_attendance 等表存在)

{{ m.issues > 0 ? '有 ' + m.issues + ' 筆待清' : '乾淨' }} {{ m.tenant_name }} 移轉 {{ m.migrated }} / 在籍 {{ m.total }}
孤兒出席 {{ m.orphan_attendance }} 孤兒點數 {{ m.orphan_credits }} LINE 斷線 {{ m.broken_line }}

還差 {{ 8 - newUser.password.length }} 個字。

客服可以:{{ supportCan.join('、') || '(讀不到分權表)' }}。
客服不能:{{ supportCannot.join('、') || '(讀不到分權表)' }}。

!

讀不到總部人員

這不是「沒有資料」—— 是這一次沒拿到。
{{ loadErr.users }}

正在讀總部人員…

{{ u.enable === 1 ? '啟用中' : '已停用' }} {{ u.username }} {{ u.name }} {{ roleLabel(u.role) }} 這是你 系統排程 {{ lockedText(u) }}
最後登入:{{ u.last_login_at || '從未登入' }} · 來源 {{ u.last_login_ip }} · 連續失敗 {{ u.failed_attempts }} 次 · 舊通行證作廢過 {{ (Number(u.token_version) || 1) - 1 }} 次
{{ u.enable === 1 ? '停用' : '啟用' }} 重設密碼 改角色({{ u.role === 'super_admin' ? '降為客服' : '升為總管理員' }})
你不能停用自己 —— 那會把你關在門外。要改密碼請用上面的「改我的密碼」。
排程留稽核用的系統主體,永遠不可登入,也不可停用或改密碼。
1
這裡放的是反悔藥

每次按「清理」或「刪除」之前,系統會自動把那家店的資料存成一個檔放在這裡。

2
保留 30 天

超過 30 天的會被每天凌晨那支排程自動清掉,所以要救要趁早。

3
按還原=把那一天的資料整批倒回去

倒回去之前,系統會先把「現在的樣子」另外存一份。

還原會覆蓋那家店現在的資料。它不是「把舊資料加回去」,是整批換成那一天的樣子 —— 那天之後新增的東西會不見。
現在有人在客戶系統裡
{{ impActiveCount }} 張通行證還活著 進行中
每一張最多 30 分鐘,到期自動失效
看是誰、還剩幾分鐘、立刻收回 →
全平台營運總覽
總在籍學生{{ platformStats.students }}
本月總堂數{{ platformStats.classes }}
本月總交易{{ platformStats.orders }}
近 7 天活躍店{{ platformStats.activeStores }}/ {{ tenants.length }}
租戶健康
{{ h.tenant_name }} {{ h.label }}
{{ m }}
{{ h.loginText }}
看全部 {{ healthCards.length }} 家

租戶設定

ID: {{ editForm.tenant_id }} | {{ editForm.subdomain }}.cj33.tw

{{ editForm.status === 'suspended' ? '停權封鎖' : '正常營運' }} 只有總管理員改得動

設為停權,這家店的 ERP 與收銀台會立刻全部登不進去。

LOGO

本店採購窗口

這家店的供應商在 LINE 上看得到(採購單頁面的聯絡窗口卡)。填的是那家店自己的窗口,不是我們的人。

總部內部窗口

只有總部看得到。客戶停權或到期時,你要打給誰。

這家店買了哪些系統 勾好之後,對方的功能表會立刻跟著變。
加值功能 這裡開的是要另外買的功能。關掉之後,對方畫面上那一項會立刻被擋住。
讀取中…
目前沒有任何加值功能可以開通。

續約會把到期日往後推(未過期接在後面、已過期從今天起算)。設好按下方「儲存方案」才生效。
留空 = 永久,永不到期。

方案只有系統管理員能改。客服帳號按下去會被擋,並留下紀錄。

方案等級目前只是一個標記,不會擋任何功能。真正決定客戶用得到什麼的是「訂閱模組」與「加值功能」兩個頁籤。

救援:強制換掉客戶管理員的密碼 直接覆蓋這家店『初始管理帳號』的密碼。只有在客戶自己進不去的時候才用。