用AI協力 開發 UOF2 EIP BPM (4):測試成果🥂-寫客製頁面,測試頁面載入 |Codex| ChatGPT | Agent Mode|一等一科技

by | 5 月 26, 2026 | 一等一UOF系統, 程式 | 0 comments

Views: 0

這邊我試著請AI幫我寫客製頁面,速度很快成果很棒,可以自己去找之前學到的東西,寫出正確率非常高的頁面

目標說明

UOF2在啟動時候會非常的久…所以官方有個簡單的Warm-upscript,會呼叫瀏覽器自己開頁面

我將這個檔案放在Codex Workspace 下script資料夾當中,請AI幫我寫成客製頁面

官方的script如下

@ECHO OFF
SET BROWSER=chrome.exe
:: SET BROWSER=chrome.exe
:: SET BROWSER=firefox.exe
SET WAIT_TIME=2
::首頁
START %BROWSER% -new-tab "http://%1/%2/Homepage.aspx"
@ping 127.0.0.1 -n %WAIT_TIME% -w 1000 > nul

::WKF
START %BROWSER% -new-tab "http://%1/%2/WKF/FormUse/PersonalBox/ApplyFormList.aspx"
START %BROWSER% -new-tab "http://%1/%2/WKF/FormManagement/Default.aspx"
START %BROWSER% -new-tab "http://%1/%2/WKF/FormUse/PersonalBox/MyFormList.aspx"
START %BROWSER% -new-tab "http://%1/%2/WKF/Auth/Default.aspx"
START %BROWSER% -new-tab "http://%1/%2/WKF/FormUse/PersonalBox/MyFormList.aspx?item=FormExamined"
::START %BROWSER% -new-tab "http://%1/%2/WKF/Responsible/FormAdministrator.aspx"

::EIP
START %BROWSER% -new-tab "http://%1/%2/EIP/Bulletin/Default.aspx"
START %BROWSER% -new-tab "http://%1/%2/EIP/Plant/Default.aspx"

::舊START %BROWSER% -new-tab "http://%1/%2/EIP/Duty/Punch/PunchIPRange.aspx"

START %BROWSER% -new-tab "http://%1/%2/EIP/Duty/Punch/PunchPositionSetting.aspx"
START %BROWSER% -new-tab "http://%1/%2/EIP/Duty/Punch/PunchAPPSetting.aspx"
START %BROWSER% -new-tab "http://%1/%2/EIP/Duty/Punch/PunchExcludeSetting.aspx"
START %BROWSER% -new-tab "http://%1/%2/EIP/Duty/Punch/ImportPunchData.aspx"
START %BROWSER% -new-tab "http://%1/%2/EIP/Duty/Report/QueryPunchDef.aspx"
START %BROWSER% -new-tab "http://%1/%2/EIP/Duty/Report/QueryDutyPunchSetting.aspx"

START %BROWSER% -new-tab "http://%1/%2/EIP/Duty/Report/QueryDayRecordByManager.aspx"
START %BROWSER% -new-tab "http://%1/%2/EIP/Duty/Leave/Collective/LeaveCollectiveDefault.aspx"

::DMS
START %BROWSER% -new-tab "http://%1/%2/DMS/DocStore/Default.aspx"

::DUTY


::SYSTEM
START %BROWSER% -new-tab "http://%1/%2/System/Authorization/Default.aspx"
START %BROWSER% -new-tab "http://%1/%2/System/OnlineUser/Default.aspx"
START %BROWSER% -new-tab "http://%1/%2/System/Config/Default.aspx"
START %BROWSER% -new-tab "http://%1/%2/System/SetRoleAdmin/Default.aspx"
START %BROWSER% -new-tab "http://%1/%2/System/LogViewer/Default.aspx"
START %BROWSER% -new-tab "http://%1/%2/System/AD/Default.aspx"
START %BROWSER% -new-tab "http://%1/%2/System/Task/Default.aspx"
START %BROWSER% -new-tab "http://%1/%2/System/Organization/Employee/Default.aspx"
START %BROWSER% -new-tab "http://%1/%2/System/Organization/Member/Default.aspx"
START %BROWSER% -new-tab "http://%1/%2/System/Config/UserColumn.aspx"
START %BROWSER% -new-tab "http://%1/%2/System/Organization/Employee/Hierarchical.aspx"

::Other
START %BROWSER% -new-tab "http://%1/%2/System/MNextMenu/Default.aspx"
START %BROWSER% -new-tab "http://%1/%2/Basic/OnlineUser/Default.aspx"
START %BROWSER% -new-tab "http://%1/%2/Basic/Personal/Information/Default.aspx"

pause

開始提示

C:\WEB_AI\EIP\scripts 裡面我放了兩個opensite的 這應該是官方在網站重啟時會強迫WEB 開啟頁面重新編譯

現在目標是在
C:\WEB_AI\EIP\site\UOFTEST\CDS\Tools
加入一個aspx頁面,要符合EIP的格式
參考 BPM_ReturnSite.aspx

要用JS跑相同的功能 
讓瀏覽器在背景進行 
並且可以計時完成時間的頁面

然後各頁面的標題要看site內的檔案  
妳試試能否完成

畫面上有

頁面標題   路徑   載入時間    狀態
---------------------------------------
| 個人設定 | aaa.aspx | 等待中 |  等待中 |

----------------------------------------------
按鈕:下載EXCEL檔  按鈕:重新執行  按鈕:開始讀取
加分項目 :可以將執行結果下載EXCEL檔案

狀態有 尚未開始,載入中,載入完成,錯誤500,錯誤404
路徑要點了可以另開視窗

Image

我使用的是Codex GPT-5.5 中,耗時約5分鐘

第一次測試後發現編譯錯誤,是編碼問題,我回饋給Codex

Image

大約過了30秒修好了,可以看到畫面

Image

接著我請它自己加入判斷使用者是不是系統管理員,測試它能不能自己讀UOF22的程式碼後,寫出我要的功能

提示詞
幫我加入驗證  登入是否為系統管理員 角色
如果不是的話要出現紅色警示

Image

加入後發現頁面又不能動了,應該是using錯誤的問題,我請它修改

Image

測試開始讀取

Image

可以WORK !! cheers🥂🥂🥂

測試下載EXCEL檔案

Image

成品程式碼

UOF_OpenSiteWarmup.aspx

<%@ Page Title="" Language="C#" MasterPageFile="~/Master/DefaultMasterPage.master" AutoEventWireup="true" CodeFile="UOF_OpenSiteWarmup.aspx.cs" Inherits="CDS_Tools_UOF_OpenSiteWarmup" %>

<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" runat="Server">
    <style>
        .warmup-panel {
            padding: 12px;
        }

        .warmup-toolbar {
            margin: 8px 0 12px 0;
        }

        .warmup-toolbar input {
            margin-right: 8px;
        }

        .warmup-summary {
            margin: 8px 0;
            color: #555;
        }

        .warmup-warning {
            margin: 10px 0;
            padding: 10px 12px;
            border: 1px solid #d93025;
            background: #fff4f4;
            color: #b00020;
            font-weight: bold;
        }

        .warmup-table {
            width: 100%;
            border-collapse: collapse;
        }

        .warmup-table th,
        .warmup-table td {
            border: 1px solid #cfcfcf;
            padding: 6px 8px;
            vertical-align: top;
        }

        .warmup-table th {
            background: #f3f3f3;
            white-space: nowrap;
        }

        .warmup-path {
            font-family: Consolas, "Courier New", monospace;
        }

        .status-not-started {
            color: #555;
        }

        .status-loading {
            color: #1f5fbf;
            font-weight: bold;
        }

        .status-done {
            color: #137333;
            font-weight: bold;
        }

        .status-error {
            color: #b00020;
            font-weight: bold;
        }
    </style>

    <div class="warmup-panel">
        <table class="PopTable">
            <tr>
                <td style="width: 160px;">工具名稱</td>
                <td>UOF 站台頁面背景載入 / Warm-up</td>
            </tr>
            <tr>
                <td>說明</td>
                <td>依序背景讀取常用 UOF 頁面,觸發 ASP.NET WebForms 動態編譯與站台載入,並記錄每頁載入時間與 HTTP 狀態。</td>
            </tr>
        </table>

        <asp:Panel runat="server" ID="pnlAdminWarning" CssClass="warmup-warning" Visible="false">
            目前登入者不是系統管理員角色,無法執行站台背景載入。
        </asp:Panel>

        <div class="warmup-toolbar">
            <input type="button" id="btnDownloadExcel" value="下載EXCEL檔" disabled="disabled" />
            <input type="button" id="btnReset" value="重新執行" />
            <input type="button" id="btnStart" value="開始讀取" />
        </div>

        <div class="warmup-summary">
            <span>總狀態:</span><span id="lblSummary">尚未開始</span>
            <span style="margin-left: 16px;">總耗時:</span><span id="lblTotalTime">等待中</span>
        </div>

        <table class="warmup-table" id="tblWarmup">
            <thead>
                <tr>
                    <th>頁面標題</th>
                    <th>路徑</th>
                    <th>載入時間</th>
                    <th>狀態</th>
                </tr>
            </thead>
            <tbody></tbody>
        </table>
    </div>

    <script type="text/javascript">
        (function () {
            var targets = <%= WarmupTargetsJson %>;
            var canExecute = <%= IsSystemAdminUser ? "true" : "false" %>;
            var baseUrl = '<%= ResolveUrl("~/") %>';
            var rows = [];
            var isRunning = false;

            function text(value) {
                return value == null ? '' : String(value);
            }

            function buildUrl(path) {
                return baseUrl + path.replace(/^\/+/, '');
            }

            function setStatus(row, status, cssClass) {
                row.status = status;
                row.statusCell.className = cssClass || '';
                row.statusCell.innerText = status;
            }

            function setDuration(row, durationText) {
                row.duration = durationText;
                row.durationCell.innerText = durationText;
            }

            function renderRows() {
                var tbody = document.querySelector('#tblWarmup tbody');
                tbody.innerHTML = '';
                rows = [];

                for (var i = 0; i < targets.length; i++) {
                    var target = targets[i];
                    var tr = document.createElement('tr');

                    var titleCell = document.createElement('td');
                    titleCell.innerText = target.Title;

                    var pathCell = document.createElement('td');
                    pathCell.className = 'warmup-path';
                    var link = document.createElement('a');
                    link.href = buildUrl(target.Path);
                    link.target = '_blank';
                    link.innerText = target.Path;
                    pathCell.appendChild(link);

                    var durationCell = document.createElement('td');
                    durationCell.innerText = '等待中';

                    var statusCell = document.createElement('td');
                    statusCell.className = 'status-not-started';
                    statusCell.innerText = '尚未開始';

                    tr.appendChild(titleCell);
                    tr.appendChild(pathCell);
                    tr.appendChild(durationCell);
                    tr.appendChild(statusCell);
                    tbody.appendChild(tr);

                    rows.push({
                        title: target.Title,
                        path: target.Path,
                        duration: '等待中',
                        status: '尚未開始',
                        httpStatus: '',
                        durationCell: durationCell,
                        statusCell: statusCell
                    });
                }
            }

            function getStatusText(response) {
                if (response.status === 404) return '錯誤404';
                if (response.status >= 500) return '錯誤500';
                if (!response.ok) return '錯誤' + response.status;
                return '載入完成';
            }

            function getStatusClass(statusText) {
                if (statusText === '載入完成') return 'status-done';
                if (statusText.indexOf('錯誤') === 0) return 'status-error';
                if (statusText === '載入中') return 'status-loading';
                return 'status-not-started';
            }

            async function loadOne(row) {
                setStatus(row, '載入中', 'status-loading');
                setDuration(row, '計時中');

                var startedAt = performance.now();
                try {
                    var response = await fetch(buildUrl(row.path), {
                        method: 'GET',
                        credentials: 'include',
                        cache: 'no-store'
                    });

                    await response.text();

                    var elapsed = Math.round(performance.now() - startedAt);
                    var statusText = getStatusText(response);
                    row.httpStatus = response.status;
                    setDuration(row, elapsed + ' ms');
                    setStatus(row, statusText, getStatusClass(statusText));
                } catch (err) {
                    var errorElapsed = Math.round(performance.now() - startedAt);
                    row.httpStatus = '';
                    setDuration(row, errorElapsed + ' ms');
                    setStatus(row, '錯誤500', 'status-error');
                }
            }

            async function startWarmup() {
                if (!canExecute) return;
                if (isRunning) return;
                isRunning = true;

                document.getElementById('btnStart').disabled = true;
                document.getElementById('btnReset').disabled = true;
                document.getElementById('btnDownloadExcel').disabled = true;
                document.getElementById('lblSummary').innerText = '載入中';
                document.getElementById('lblTotalTime').innerText = '計時中';

                var startedAt = performance.now();
                for (var i = 0; i < rows.length; i++) {
                    await loadOne(rows[i]);
                }

                var totalElapsed = Math.round(performance.now() - startedAt);
                document.getElementById('lblSummary').innerText = '載入完成';
                document.getElementById('lblTotalTime').innerText = totalElapsed + ' ms';
                document.getElementById('btnStart').disabled = false;
                document.getElementById('btnReset').disabled = false;
                document.getElementById('btnDownloadExcel').disabled = false;
                isRunning = false;
            }

            function resetWarmup() {
                if (!canExecute) return;
                if (isRunning) return;
                renderRows();
                document.getElementById('lblSummary').innerText = '尚未開始';
                document.getElementById('lblTotalTime').innerText = '等待中';
                document.getElementById('btnDownloadExcel').disabled = true;
            }

            function htmlEncode(value) {
                return text(value)
                    .replace(/&/g, '&amp;')
                    .replace(/</g, '&lt;')
                    .replace(/>/g, '&gt;')
                    .replace(/"/g, '&quot;');
            }

            function downloadExcel() {
                if (!canExecute) return;
                var html = '<html><head><meta charset="utf-8"></head><body><table border="1">';
                html += '<tr><th>頁面標題</th><th>路徑</th><th>載入時間</th><th>狀態</th><th>HTTP狀態</th></tr>';
                for (var i = 0; i < rows.length; i++) {
                    html += '<tr>';
                    html += '<td>' + htmlEncode(rows[i].title) + '</td>';
                    html += '<td>' + htmlEncode(rows[i].path) + '</td>';
                    html += '<td>' + htmlEncode(rows[i].duration) + '</td>';
                    html += '<td>' + htmlEncode(rows[i].status) + '</td>';
                    html += '<td>' + htmlEncode(rows[i].httpStatus) + '</td>';
                    html += '</tr>';
                }
                html += '</table></body></html>';

                var blob = new Blob([html], { type: 'application/vnd.ms-excel;charset=utf-8' });
                var link = document.createElement('a');
                link.href = URL.createObjectURL(blob);
                link.download = 'UOF_OpenSiteWarmup_' + new Date().toISOString().replace(/[:.]/g, '') + '.xls';
                document.body.appendChild(link);
                link.click();
                document.body.removeChild(link);
                URL.revokeObjectURL(link.href);
            }

            document.getElementById('btnStart').onclick = startWarmup;
            document.getElementById('btnReset').onclick = resetWarmup;
            document.getElementById('btnDownloadExcel').onclick = downloadExcel;

            renderRows();
            if (!canExecute) {
                document.getElementById('btnStart').disabled = true;
                document.getElementById('btnReset').disabled = true;
                document.getElementById('btnDownloadExcel').disabled = true;
                document.getElementById('lblSummary').innerText = '權限不足';
            }
        })();
    </script>
</asp:Content>

UOF_OpenSiteWarmup.aspx.cs

using System;
using System.Collections.Generic;
using System.IO;
using System.Text.RegularExpressions;
using System.Web.Script.Serialization;
using Ede.Uof.EIP.Organization;
using Ede.Uof.EIP.Organization.Util;
using Ede.Uof.EIP.Security;
using Ede.Uof.EIP.SystemInfo;

public partial class CDS_Tools_UOF_OpenSiteWarmup : Ede.Uof.Utility.Page.BasePage
{
    protected string WarmupTargetsJson { get; private set; }
    protected bool IsSystemAdminUser { get; private set; }

    protected void Page_Load(object sender, EventArgs e)
    {
        IsSystemAdminUser = CheckSystemAdmin();
        pnlAdminWarning.Visible = !IsSystemAdminUser;

        if (!IsPostBack)
        {
            AddSiteMapNode("內部連結");
            AddSiteMapNode("客製工具");
            AddSiteMapNode("UOF 站台頁面背景載入", Request.Url.AbsoluteUri);
        }

        WarmupTargetsJson = new JavaScriptSerializer().Serialize(
            IsSystemAdminUser ? BuildWarmupTargets() : new List<WarmupTarget>());
    }

    private bool CheckSystemAdmin()
    {
        if (string.IsNullOrEmpty(Current.UserGUID))
        {
            return false;
        }

        try
        {
            RoleAdminUCO roleUco = new RoleAdminUCO();
            UserSet systemAdmins = new UserSet();
            systemAdmins.SetXML(roleUco.QueryRoleAdmin("SystemAdmin"));
            return systemAdmins.Contains(Current.UserGUID);
        }
        catch
        {
            return false;
        }
    }

    private List<WarmupTarget> BuildWarmupTargets()
    {
        List<WarmupTargetDefinition> definitions = new List<WarmupTargetDefinition>
        {
            new WarmupTargetDefinition("首頁", "Homepage.aspx"),

            new WarmupTargetDefinition("申請表單", "WKF/FormUse/PersonalBox/ApplyFormList.aspx"),
            new WarmupTargetDefinition("表單管理", "WKF/FormManagement/Default.aspx"),
            new WarmupTargetDefinition("我的表單", "WKF/FormUse/PersonalBox/MyFormList.aspx"),
            new WarmupTargetDefinition("電子簽核權限", "WKF/Auth/Default.aspx"),
            new WarmupTargetDefinition("已審核表單", "WKF/FormUse/PersonalBox/MyFormList.aspx?item=FormExamined"),
            new WarmupTargetDefinition("管理者表單查詢", "WKF/Responsible/FormAdministrator.aspx"),

            new WarmupTargetDefinition("公告管理", "EIP/Bulletin/Default.aspx"),
            new WarmupTargetDefinition("廠區設定", "EIP/Plant/Default.aspx"),
            new WarmupTargetDefinition("刷卡位置設定", "EIP/Duty/Punch/PunchPositionSetting.aspx"),
            new WarmupTargetDefinition("APP 打卡設定", "EIP/Duty/Punch/PunchAPPSetting.aspx"),
            new WarmupTargetDefinition("刷卡排除設定", "EIP/Duty/Punch/PunchExcludeSetting.aspx"),
            new WarmupTargetDefinition("匯入刷卡資料", "EIP/Duty/Punch/ImportPunchData.aspx"),
            new WarmupTargetDefinition("刷卡定義查詢", "EIP/Duty/Report/QueryPunchDef.aspx"),
            new WarmupTargetDefinition("出勤刷卡設定查詢", "EIP/Duty/Report/QueryDutyPunchSetting.aspx"),
            new WarmupTargetDefinition("主管查詢每日刷卡", "EIP/Duty/Report/QueryDayRecordByManager.aspx"),
            new WarmupTargetDefinition("集體請假", "EIP/Duty/Leave/Collective/LeaveCollectiveDefault.aspx"),

            new WarmupTargetDefinition("文件庫", "DMS/DocStore/Default.aspx"),

            new WarmupTargetDefinition("系統權限", "System/Authorization/Default.aspx"),
            new WarmupTargetDefinition("線上人員", "System/OnlineUser/Default.aspx"),
            new WarmupTargetDefinition("系統組態", "System/Config/Default.aspx"),
            new WarmupTargetDefinition("角色管理員", "System/SetRoleAdmin/Default.aspx"),
            new WarmupTargetDefinition("系統記錄", "System/LogViewer/Default.aspx"),
            new WarmupTargetDefinition("AD 設定", "System/AD/Default.aspx"),
            new WarmupTargetDefinition("排程管理", "System/Task/Default.aspx"),
            new WarmupTargetDefinition("員工管理", "System/Organization/Employee/Default.aspx"),
            new WarmupTargetDefinition("組織成員", "System/Organization/Member/Default.aspx"),
            new WarmupTargetDefinition("使用者欄位", "System/Config/UserColumn.aspx"),
            new WarmupTargetDefinition("組織階層", "System/Organization/Employee/Hierarchical.aspx"),

            new WarmupTargetDefinition("選單管理", "System/MNextMenu/Default.aspx"),
            new WarmupTargetDefinition("線上人員 Basic", "Basic/OnlineUser/Default.aspx"),
            new WarmupTargetDefinition("個人設定", "Basic/Personal/Information/Default.aspx")
        };

        List<WarmupTarget> targets = new List<WarmupTarget>();
        foreach (WarmupTargetDefinition definition in definitions)
        {
            targets.Add(new WarmupTarget
            {
                Title = ResolvePageTitle(definition.Path, definition.FallbackTitle),
                Path = definition.Path
            });
        }
        return targets;
    }

    private string ResolvePageTitle(string path, string fallbackTitle)
    {
        string pathOnly = path.Split('?')[0].TrimStart('/', '\\');
        string physicalPath = Server.MapPath("~/" + pathOnly);
        if (!File.Exists(physicalPath))
        {
            return fallbackTitle;
        }

        try
        {
            string firstLine;
            using (StreamReader reader = new StreamReader(physicalPath))
            {
                firstLine = reader.ReadLine();
            }

            if (!string.IsNullOrEmpty(firstLine))
            {
                Match match = Regex.Match(firstLine, "Title\\s*=\\s*\"([^\"]*)\"", RegexOptions.IgnoreCase);
                if (match.Success && !string.IsNullOrWhiteSpace(match.Groups[1].Value))
                {
                    return match.Groups[1].Value.Trim();
                }
            }
        }
        catch
        {
            return fallbackTitle;
        }

        return fallbackTitle;
    }

    private class WarmupTargetDefinition
    {
        public WarmupTargetDefinition(string fallbackTitle, string path)
        {
            FallbackTitle = fallbackTitle;
            Path = path;
        }

        public string FallbackTitle { get; private set; }
        public string Path { get; private set; }
    }

    private class WarmupTarget
    {
        public string Title { get; set; }
        public string Path { get; set; }
    }
}

0 Comments

Submit a Comment

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *