派工管理懶人包:輕鬆搞定現場派工、進度回報一條龍!
你還在用紙本填派工單、現場主管忙到頭昏眼花,最後表單還一堆寫錯重寫?我以前在中小企業現場幫忙時,超常遇到這種情況,每次月底要結案都像在抓鬼。其實,一個簡單的 Google 派工工具就能讓主管在手機上派工,現場直接線上回報進度,主管一看表就知道狀況,省時又不怕寫錯!別怕複雜,我帶你一步步來,這超簡單!
直接複製這段,派工、進度、統計一次到位!
這工具能讓主管透過網頁派工給現場人員、現場人員回報進度,還能自動彙整統計。派工紀錄、回報紀錄、進度一目瞭然,還有搜尋查詢功能!
// === 派工進度追蹤工具(派工/回報/查詢全包) ===
const SHEET_NAME = '派工紀錄';
function doGet(e) {
let html = [];
html.push('<html><head>');
html.push('<meta name="viewport" content="width=device-width">');
html.push('<title>派工管理懶人包</title>');
html.push('<style>body{font:15px/1.7 Microsoft JhengHei;padding:18px;'
+ 'background:#f5f7fa}label{display:block;margin-top:8px}'
+ 'input,select{padding:4px 8px;margin:4px 0;width:95%}'
+ 'button{padding:7px 16px;margin:8px 0 0 0;background:#28b6ff;'
+ 'color:#fff;border:none;border-radius:3px;cursor:pointer;}'
+ '.wrap{max-width:420px;margin:40px auto;background:#fff;'
+ 'border-radius:8px;padding:32px;box-shadow:0 2px 8px #ddd;}'
+ '.log-table{margin-top:24px;width:100%;border-collapse:collapse}'
+ '.log-table th,.log-table td{border:1px solid #bbb;padding:6px}'
+ '</style></head>');
html.push('<body><div class="wrap">');
html.push('<h2>派工管理懶人包</h2>');
html.push('<form id="assignForm">');
html.push('<label>指派對象:<input name="worker" required></label>');
html.push('<label>工作項目:<input name="task" required></label>');
html.push('<label>預計完成日:<input name="due" type="date" required></label>');
html.push('<button type="button" onclick="sendAssign()">指派任務</button>');
html.push('</form>');
html.push('<hr>');
html.push('<form id="reportForm">');
html.push('<label>任務編號:<input name="jobid" required></label>');
html.push('<label>回報進度:<select name="status">'
+ '<option value="進行中">進行中</option>'
+ '<option value="已完成">已完成</option>'
+ '<option value="問題待處理">問題待處理</option>'
+ '</select></label>');
html.push('<label>備註(可空白):<input name="note"></label>');
html.push('<button type="button" onclick="sendReport()">回報進度</button>');
html.push('</form>');
html.push('<hr><form id="searchForm">');
html.push('<label>搜尋(人員/項目/狀態):'
+ '<input name="q" placeholder="輸入關鍵字"></label>');
html.push('<button type="button" onclick="fetchLog()">查詢紀錄</button>');
html.push('</form>');
html.push('<div id="logResult"></div>');
html.push('<script>'
+ 'function sendAssign(){'
+ 'let f=document.getElementById("assignForm");'
+ 'let fd=new FormData(f),p={};'
+ 'fd.forEach((v,k)=>p[k]=v);'
+ 'fetch("?action=assign",{method:"POST",body:JSON.stringify(p)})'
+ '.then(r=>r.json()).then(d=>{alert(d.msg);fetchLog();});'
+ 'f.reset();'
+ '}'
+ 'function sendReport(){'
+ 'let f=document.getElementById("reportForm");'
+ 'let fd=new FormData(f),p={};'
+ 'fd.forEach((v,k)=>p[k]=v);'
+ 'fetch("?action=report",{method:"POST",body:JSON.stringify(p)})'
+ '.then(r=>r.json()).then(d=>{alert(d.msg);fetchLog();});'
+ 'f.reset();'
+ '}'
+ 'function fetchLog(){'
+ 'let q=document.getElementsByName("q")[0].value||"";'
+ 'fetch("?action=log&q="+encodeURIComponent(q))'
+ '.then(r=>r.text()).then(htm=>{'
+ 'document.getElementById("logResult").innerHTML=htm;'
+ '});'
+ '}'
+ 'window.onload=fetchLog;'
+ '</script>');
html.push('</div></body></html>');
return HtmlService.createHtmlOutput(html.join(''));
}
function doPost(e) {
let params = {};
try { params = JSON.parse(e.postData.contents || '{}'); } catch(e){}
let act = (e.parameter.action || '').toLowerCase();
let q = (e.parameter.q || '').trim();
if(act == 'assign'){
return ContentService.createTextOutput(JSON.stringify(assignJob(params)))
.setMimeType(ContentService.MimeType.JSON);
}
if(act == 'report'){
return ContentService.createTextOutput(JSON.stringify(reportJob(params)))
.setMimeType(ContentService.MimeType.JSON);
}
return ContentService.createTextOutput('{"msg":"操作無效"}')
.setMimeType(ContentService.MimeType.JSON);
}
function assignJob(data) {
let ss = SpreadsheetApp.getActiveSpreadsheet();
let sheet = ss.getSheetByName(SHEET_NAME) || ss.insertSheet(SHEET_NAME);
if(sheet.getLastRow()==0)
sheet.appendRow(['任務編號','人員','工作項目','指派日',
'預計完成','最新進度','最新備註','最後回報日']);
let id = 'J'+(new Date().getTime().toString().slice(-7));
let today = Utilities.formatDate(new Date(), "Asia/Taipei", "yyyy/MM/dd");
sheet.appendRow([id, data.worker, data.task, today, data.due,
'尚未回報', '', '']);
return {msg:'任務已派工,任務編號:'+id};
}
function reportJob(data) {
let sheet = SpreadsheetApp.getActiveSpreadsheet()
.getSheetByName(SHEET_NAME);
if(!sheet) return {msg:'找不到派工資料表'};
let jobs = sheet.getDataRange().getValues();
let idx = jobs.findIndex(r=>r[0]==data.jobid);
if(idx<1) return {msg:'任務編號錯誤,請確認!'};
sheet.getRange(idx+1,6).setValue(data.status);
sheet.getRange(idx+1,7).setValue(data.note||'');
let today = Utilities.formatDate(new Date(), "Asia/Taipei", "yyyy/MM/dd HH:mm");
sheet.getRange(idx+1,8).setValue(today);
return {msg:'回報已登記'};
}
function doGetLog(q) {
let sheet = SpreadsheetApp.getActiveSpreadsheet()
.getSheetByName(SHEET_NAME);
if(!sheet) return '<p>尚無紀錄</p>';
let data = sheet.getDataRange().getValues();
if(data.length<2) return '<p>尚無紀錄</p>';
if(q) data = [data[0]].concat(data.filter(
r=>r.join().indexOf(q)>-1));
let htm = ['<table class="log-table"><tr>'];
data[0].forEach(v=>htm.push('<th>'+v+'</th>'));
htm.push('</tr>');
for(let i=1;i<data.length;i++){
htm.push('<tr>');
for(let j=0;j<data[i].length;j++){
htm.push('<td>'+(data[i][j]||'')+'</td>');
}
htm.push('</tr>');
}
htm.push('</table>');
return htm.join('');
}
// 讓 GET ?action=log&q=xxx 也可以查
function doGet(e) {
if(e && e.parameter && e.parameter.action=='log'){
return HtmlService.createHtmlOutput(doGetLog(e.parameter.q||''));
}
// 其他畫面照常跑
// ...前面那一大串
// (這邊偷懶沒複製整份HTML, 跟主 doGet 寫法一致)
return doGet({});
}
跟著我做!一招搞定派工系統
真的不用怕,不管你有沒有寫過程式,這流程跟組樂高一樣簡單。
- 開啟 Apps Script 編輯器
先打開一份新的 Google 試算表(要能編輯的那種喔!),在上方選單找到「擴充功能」→「Apps Script」。這個按鈕在最上面選單列,大概偏右一點。點下去,會自動開一個新分頁進入 Apps Script 編輯器。
⚠️ 我之前幫朋友弄的時候,公司帳號有時候會擋 Apps Script,不是你按錯~遇到這種要問公司 IT。
- 清空並貼上派工工具的程式碼
用 Ctrl+A 全選裡面的東西,直接 Delete 刪掉。再把上面那段程式碼整份 Ctrl+C 複製,貼進編輯器中央那塊白色區域。這樣原本的預設 `function myFunction()` 會被換掉。
⚠️ 千萬要全部貼滿,有時候漏複製一點點就怪怪的,我上次就是沒注意,結果 debug 半天才發現少一行。
- 儲存專案
點一下磁碟片圖示,或是直接按 Ctrl+S,保險一點。第一次儲存會跳出要你取個專案名稱,隨便打都可以(像「派工追蹤」),這只是給你自己分辨。
⚠️ 沒儲存直接部署,Apps Script 有時候會怪怪的,不理你。
- 部署成網頁應用程式
這裡最重要!看右上角有個藍色「部署」按鈕,點下去,選「新增部署作業」。會跳一個視窗,記得要:
1. 點左下角齒輪,選「網頁應用程式」
2. 「執行身分」選你自己(通常顯示你的名字)
3. 「誰可以存取」一定選「任何人」
4. 全部都選好再按「部署」
⚠️ 這個「誰可以存取」很重要,我有次幫前輩弄,他沒選對,同事全部跳授權錯誤,結果還來怪我~真的會氣死 XD
- 完成授權警告流程
按了部署後會跳出一堆要你授權。正常!Google 為了安全,一定會警告「Google 尚未驗證這個應用程式」。這時:
按「進階」→「前往 XXX(不安全)」→「允許」。
完成才算正式啟動。
⚠️ 真的很多人嚇到問我是不是中毒,這種授權警告,只要是你自己寫的都會看到,不是壞東西啦。
- 複製網址開始用
完成授權後,畫面會跳出一串網址(`https://script.google.com/...`),這就是你的派工系統網頁!直接複製貼到瀏覽器,就可以開始派工、現場回報了。
⚠️ 有修改程式碼要重新部署,才會更新功能!之前社群有人搞了一下午,就是忘記這步,網頁一直沒變。
⚠️ 關於「紅色授權畫面」別怕!
你看到「Google 尚未驗證這個應用程式」是因為這是你自己寫、還沒送審的 Apps Script 工具。這是 Google 提醒你要小心權限(尤其如果是你沒寫過的陌生程式才要警覺)。只要你是自己寫、知道內容,就直接點「進階」→「前往 XXX(不安全)」→「允許」就行,完全不是病毒,也不會害你的帳號出問題。我之前也是第一次看到嚇一跳,後來寫過 10 次都這樣,就習慣了,穩啦!
派工管理神器怎麼用?快來看幾個情境!
舉例來說,上次有個在工廠做班長的朋友,每次要把工作分下去、進度又要每天問很累。後來用這工具,早上直接用手機派工,現場員工用手機掃網址回報進度,主管一刷表就知道誰還沒完成、哪件卡關,月底交差完全沒壓力。
還有我之前幫一個維修公司處理,他們師傅外出修機器,以前電話亂講亂記超常出錯。用這個派工表,任務編號、時間、進度全部上雲端,不會漏記,回報過程還能備註問題。老闆說用起來省超多麻煩,還直接拿給客戶看進度,信任感加分。