From 713024ccb5056e76bcfc9389664981da68a5139f Mon Sep 17 00:00:00 2001
From: curtis <curtis@i-mps.com>
Date: 星期一, 30 三月 2026 14:08:01 +0800
Subject: [PATCH] feat: dfm to web
---
doc/curtis/prompt/dfm_to_web/dfm_to_web_prompt_CB_IMGPSScanImp.md | 8
uiOutput/OldCaseInfo/OldCaseInfo.vue | 122 +++++
uiOutput/assets/ErrList.png | 0
uiOutput/OldCaseInfo/OldCaseInfo.ts | 116 +++++
doc/curtis/prompt/dfm_to_web/dfm_to_web_prompt_DocList.md | 37 +
doc/curtis/prompt/dfm_to_web/dfm_to_web_prompt_OldCaseInfo.md | 37 +
uiOutput/DocPrt/DocPrt.ts | 80 +++
uiOutput/index.html | 21
doc/curtis/screenShot/DocPrt.png | 0
uiOutput/DocList/DocList.ts | 123 +++++
uiOutput/ErrList/ErrList.vue | 245 +++-------
doc/curtis/prompt/dfm_to_web/dfm_to_web_requirement.json | 28 +
/dev/null | 0
doc/curtis/prompt/dfm_to_web/dfm_to_web_prompt_DocPrt.md | 37 +
doc/curtis/screenShot/ErrList.png | 0
uiOutput/assets/DocPrt.png | 0
doc/curtis/prompt/dfm_to_web/dfm_to_web_prompt_ErrList.md | 20
uiOutput/ErrList/ErrList.ts | 338 +++-----------
uiOutput/DocList/DocList.vue | 87 +++
uiOutput/assets/OldCaseInfo.png | 0
doc/curtis/screenShot/DocList.png | 0
doc/curtis/screenShot/OldCaseInfo.png | 0
uiOutput/DocPrt/DocPrt.vue | 80 +++
uiOutput/assets/DocList.png | 0
24 files changed, 944 insertions(+), 435 deletions(-)
diff --git a/doc/curtis/prompt/dfm_to_web/dfm_to_web_prompt_CB_IMGPSScanImp.md b/doc/curtis/prompt/dfm_to_web/dfm_to_web_prompt_CB_IMGPSScanImp.md
index 673335c..9999a4a 100644
--- a/doc/curtis/prompt/dfm_to_web/dfm_to_web_prompt_CB_IMGPSScanImp.md
+++ b/doc/curtis/prompt/dfm_to_web/dfm_to_web_prompt_CB_IMGPSScanImp.md
@@ -1,7 +1,7 @@
### 2.1 DFM 轉換需求: .dfm Delphi 轉換為 vue 實作
-@/CB_IMGPSScanImp.dfm 為 Delphi 的 ui 介面定義, 請幫我轉換為相對應的 /uiOutput/ErrList/CB_IMGPSScanImp.vue
-@/CB_IMGPSScanImp.pas 為 Delphi 的 ui 介面定義實作, 也請幫我轉換為相應的 /uiOutput/ErrList/CB_IMGPSScanImp.ts
-@/doc/curtis/screenShot/CB_IMGPSScanImp.png 則是 @/CB_IMGPSScanImp.dfm 介面的截圖, 轉換後的 /uiOutput/ErrList/CB_IMGPSScanImp.vue 必須與 @/doc/curtis/screenShot/CB_IMGPSScanImp.png 一致
+@/CB_IMGPSScanImp.dfm 為 Delphi 的 ui 介面定義, 請幫我轉換為相對應的 /uiOutput/CB_IMGPSScanImp/CB_IMGPSScanImp.vue
+@/CB_IMGPSScanImp.pas 為 Delphi 的 ui 介面定義實作, 也請幫我轉換為相應的 /uiOutput/CB_IMGPSScanImp/CB_IMGPSScanImp.ts
+@/doc/curtis/screenShot/CB_IMGPSScanImp.png 則是 @/CB_IMGPSScanImp.dfm 介面的截圖, 轉換後的 /uiOutput/CB_IMGPSScanImp/CB_IMGPSScanImp.vue 必須與 @/doc/curtis/screenShot/CB_IMGPSScanImp.png 一致
#### 2.2 轉換原則
##### 2.2.1 CB_IMGPSScanImp.vue 轉換原則
@@ -29,7 +29,7 @@
- 2.2.1 於實作 CB_IMGPSScanImp.vue 時能引用 CB_IMGPSScanImp.ts 用相關方法
#### 2.3 生成後輸出
-- 生成後的檔案請輸出至對應的 /uiOutput/ErrList/CB_IMGPSScanImp.vue 和 /uiOutput/ErrList/CB_IMGPSScanImp.ts 路徑
+- 生成後的檔案請輸出至對應的 /uiOutput/CB_IMGPSScanImp/CB_IMGPSScanImp.vue 和 /uiOutput/CB_IMGPSScanImp/CB_IMGPSScanImp.ts 路徑
#### 2.4 更新 preview 入口
- 2.4.1 preview 入口功能定義:
diff --git a/doc/curtis/prompt/dfm_to_web/dfm_to_web_prompt_DocList.md b/doc/curtis/prompt/dfm_to_web/dfm_to_web_prompt_DocList.md
new file mode 100644
index 0000000..705e0be
--- /dev/null
+++ b/doc/curtis/prompt/dfm_to_web/dfm_to_web_prompt_DocList.md
@@ -0,0 +1,37 @@
+### 2.1 DFM 轉換需求: .dfm Delphi 轉換為 vue 實作
+@/DocList.dfm 為 Delphi 的 ui 介面定義, 請幫我轉換為相對應的 /uiOutput/DocList/DocList.vue
+@/DocList.pas 為 Delphi 的 ui 介面定義實作, 也請幫我轉換為相應的 /uiOutput/DocList/DocList.ts
+@/doc/curtis/screenShot/DocList.png 則是 @/DocList.dfm 介面的截圖, 轉換後的 /uiOutput/DocList/DocList.vue 必須與 @/doc/curtis/screenShot/DocList.png 一致
+
+#### 2.2 轉換原則
+##### 2.2.1 DocList.vue 轉換原則
+- ui layout 及風格請完全參照 DocList.png, 因為這是使用者要的設計, 大小定義請完全參照 DocList.dfm
+- Delphi DFM 結構轉換為使用 Tailwind CSS, 請參考其 Left, Top, Width, Height 屬性來推斷相對位置
+- dfm 檔案內所指向的物件進行轉換時請生成相對應的 vue 元件, 如下 TPanel 在轉換成 vue 時請生成對應的 TPanel元件
+```dfm
+object ErrlistForm: TErrlistForm
+ Left = 0
+ Top = 0
+ ...
+ object Panel2: TPanel
+ Left = 0
+ Top = 0
+ Width = 841
+ Height = 636
+ Align = alClient
+ Caption = 'Panel2'
+```
+- DocList.dfm 參照 DocList.png 的截圖回推 vue 的實作方式,並 以 vuejs 實作 DocList.vue,
+
+##### 2.2.2 DocList.ts 轉換原則
+- 將 DocList.pas 的實作轉換為 ts 實作, 並完全保留其介面及大小寫, 將其 transpile 為 DocList.ts
+- 若 DocList.pas 找不到相依方法的實作方式則於 ts 應完全保留該方法及界面,讓使用者另行實作
+- 2.2.1 於實作 DocList.vue 時能引用 DocList.ts 用相關方法
+
+#### 2.3 生成後輸出
+- 生成後的檔案請輸出至對應的 /uiOutput/DocList/DocList.vue 和 /uiOutput/DocList/DocList.ts 路徑
+
+#### 2.4 更新 preview 入口
+- 2.4.1 preview 入口功能定義:
+ - 2.4.1.1 確保 @/uiOutput/index.html 中的 `availableComponents` 陣列包含此新轉換的元件
+ - 2.4.1.2 此新元件的設定應包含 id, name, vuePath, jsPath (指向 ts 檔案) 和 windowTitle
diff --git a/doc/curtis/prompt/dfm_to_web/dfm_to_web_prompt_DocPrt.md b/doc/curtis/prompt/dfm_to_web/dfm_to_web_prompt_DocPrt.md
new file mode 100644
index 0000000..0a51d45
--- /dev/null
+++ b/doc/curtis/prompt/dfm_to_web/dfm_to_web_prompt_DocPrt.md
@@ -0,0 +1,37 @@
+### 2.1 DFM 轉換需求: .dfm Delphi 轉換為 vue 實作
+@/DocPrt.dfm 為 Delphi 的 ui 介面定義, 請幫我轉換為相對應的 /uiOutput/DocPrt/DocPrt.vue
+@/DocPrt.pas 為 Delphi 的 ui 介面定義實作, 也請幫我轉換為相應的 /uiOutput/DocPrt/DocPrt.ts
+@/doc/curtis/screenShot/DocPrt.png 則是 @/DocPrt.dfm 介面的截圖, 轉換後的 /uiOutput/DocPrt/DocPrt.vue 必須與 @/doc/curtis/screenShot/DocPrt.png 一致
+
+#### 2.2 轉換原則
+##### 2.2.1 DocPrt.vue 轉換原則
+- ui layout 及風格請完全參照 DocPrt.png, 因為這是使用者要的設計, 大小定義請完全參照 DocPrt.dfm
+- Delphi DFM 結構轉換為使用 Tailwind CSS, 請參考其 Left, Top, Width, Height 屬性來推斷相對位置
+- dfm 檔案內所指向的物件進行轉換時請生成相對應的 vue 元件, 如下 TPanel 在轉換成 vue 時請生成對應的 TPanel元件
+```dfm
+object ErrlistForm: TErrlistForm
+ Left = 0
+ Top = 0
+ ...
+ object Panel2: TPanel
+ Left = 0
+ Top = 0
+ Width = 841
+ Height = 636
+ Align = alClient
+ Caption = 'Panel2'
+```
+- DocPrt.dfm 參照 DocPrt.png 的截圖回推 vue 的實作方式,並 以 vuejs 實作 DocPrt.vue,
+
+##### 2.2.2 DocPrt.ts 轉換原則
+- 將 DocPrt.pas 的實作轉換為 ts 實作, 並完全保留其介面及大小寫, 將其 transpile 為 DocPrt.ts
+- 若 DocPrt.pas 找不到相依方法的實作方式則於 ts 應完全保留該方法及界面,讓使用者另行實作
+- 2.2.1 於實作 DocPrt.vue 時能引用 DocPrt.ts 用相關方法
+
+#### 2.3 生成後輸出
+- 生成後的檔案請輸出至對應的 /uiOutput/DocPrt/DocPrt.vue 和 /uiOutput/DocPrt/DocPrt.ts 路徑
+
+#### 2.4 更新 preview 入口
+- 2.4.1 preview 入口功能定義:
+ - 2.4.1.1 確保 @/uiOutput/index.html 中的 `availableComponents` 陣列包含此新轉換的元件
+ - 2.4.1.2 此新元件的設定應包含 id, name, vuePath, jsPath (指向 ts 檔案) 和 windowTitle
diff --git a/doc/curtis/prompt/dfm_to_web/dfm_to_web_prompt_ErrList.md b/doc/curtis/prompt/dfm_to_web/dfm_to_web_prompt_ErrList.md
index 4b48d09..e35309b 100644
--- a/doc/curtis/prompt/dfm_to_web/dfm_to_web_prompt_ErrList.md
+++ b/doc/curtis/prompt/dfm_to_web/dfm_to_web_prompt_ErrList.md
@@ -1,8 +1,7 @@
-
### 2.1 DFM 轉換需求: .dfm Delphi 轉換為 vue 實作
-@ErrList.dfm 為 Delphi 的 ui 介面定義, 請幫我轉換為相對應的 ErrList.vue
-@ErrList.pas 為 Delphi 的 ui 介面定義實, 也請幫我轉換為相應的 ErrList.ts
-@CB_ErrList.png 則是 @ErrList.dfm 介面的截圖, 轉換後的 ErrList.vue 必須與 @CB_ErrList.png 一致
+@/ErrList.dfm 為 Delphi 的 ui 介面定義, 請幫我轉換為相對應的 /uiOutput/ErrList/ErrList.vue
+@/ErrList.pas 為 Delphi 的 ui 介面定義實作, 也請幫我轉換為相應的 /uiOutput/ErrList/ErrList.ts
+@/doc/curtis/screenShot/ErrList.png 則是 @/ErrList.dfm 介面的截圖, 轉換後的 /uiOutput/ErrList/ErrList.vue 必須與 @/doc/curtis/screenShot/ErrList.png 一致
#### 2.2 轉換原則
##### 2.2.1 ErrList.vue 轉換原則
@@ -22,18 +21,17 @@
Align = alClient
Caption = 'Panel2'
```
-- ErrList.dfm 參照 CB_ErrList.png 的截圖回推 vue 的實作方式,並 以 vuejs 實作 ErrList.vue,
--
+- ErrList.dfm 參照 ErrList.png 的截圖回推 vue 的實作方式,並 以 vuejs 實作 ErrList.vue,
+
##### 2.2.2 ErrList.ts 轉換原則
- 將 ErrList.pas 的實作轉換為 ts 實作, 並完全保留其介面及大小寫, 將其 transpile 為 ErrList.ts
- 若 ErrList.pas 找不到相依方法的實作方式則於 ts 應完全保留該方法及界面,讓使用者另行實作
- 2.2.1 於實作 ErrList.vue 時能引用 ErrList.ts 用相關方法
#### 2.3 生成後輸出
-- 生成後的檔案請輸出至 uiOutput/ErrList
+- 生成後的檔案請輸出至對應的 /uiOutput/ErrList/ErrList.vue 和 /uiOutput/ErrList/ErrList.ts 路徑
-#### 2.4 生成 preview 入口
+#### 2.4 更新 preview 入口
- 2.4.1 preview 入口功能定義:
- - 2.4.1.1 preview 入口上方為 list button 區塊, 該區塊用來放致所有於 2.3 轉換生成的 vue 連結
- - 2.4.1.2 preview 入口下方為 preview viewer, 當點擊 2.4.1.1 的 vue 連結時, viewer 能載入相應的 vue 元件內容
-- 2.4.2 prview 入口請輪出至 uiOutput/index.html
+ - 2.4.1.1 確保 @/uiOutput/index.html 中的 `availableComponents` 陣列包含此新轉換的元件
+ - 2.4.1.2 此新元件的設定應包含 id, name, vuePath, jsPath (指向 ts 檔案) 和 windowTitle
diff --git a/doc/curtis/prompt/dfm_to_web/dfm_to_web_prompt_OldCaseInfo.md b/doc/curtis/prompt/dfm_to_web/dfm_to_web_prompt_OldCaseInfo.md
new file mode 100644
index 0000000..48974b5
--- /dev/null
+++ b/doc/curtis/prompt/dfm_to_web/dfm_to_web_prompt_OldCaseInfo.md
@@ -0,0 +1,37 @@
+### 2.1 DFM 轉換需求: .dfm Delphi 轉換為 vue 實作
+@/OldCaseInfo.dfm 為 Delphi 的 ui 介面定義, 請幫我轉換為相對應的 /uiOutput/OldCaseInfo/OldCaseInfo.vue
+@/OldCaseInfo.pas 為 Delphi 的 ui 介面定義實作, 也請幫我轉換為相應的 /uiOutput/OldCaseInfo/OldCaseInfo.ts
+@/doc/curtis/screenShot/OldCaseInfo.png 則是 @/OldCaseInfo.dfm 介面的截圖, 轉換後的 /uiOutput/OldCaseInfo/OldCaseInfo.vue 必須與 @/doc/curtis/screenShot/OldCaseInfo.png 一致
+
+#### 2.2 轉換原則
+##### 2.2.1 OldCaseInfo.vue 轉換原則
+- ui layout 及風格請完全參照 OldCaseInfo.png, 因為這是使用者要的設計, 大小定義請完全參照 OldCaseInfo.dfm
+- Delphi DFM 結構轉換為使用 Tailwind CSS, 請參考其 Left, Top, Width, Height 屬性來推斷相對位置
+- dfm 檔案內所指向的物件進行轉換時請生成相對應的 vue 元件, 如下 TPanel 在轉換成 vue 時請生成對應的 TPanel元件
+```dfm
+object ErrlistForm: TErrlistForm
+ Left = 0
+ Top = 0
+ ...
+ object Panel2: TPanel
+ Left = 0
+ Top = 0
+ Width = 841
+ Height = 636
+ Align = alClient
+ Caption = 'Panel2'
+```
+- OldCaseInfo.dfm 參照 OldCaseInfo.png 的截圖回推 vue 的實作方式,並 以 vuejs 實作 OldCaseInfo.vue,
+
+##### 2.2.2 OldCaseInfo.ts 轉換原則
+- 將 OldCaseInfo.pas 的實作轉換為 ts 實作, 並完全保留其介面及大小寫, 將其 transpile 為 OldCaseInfo.ts
+- 若 OldCaseInfo.pas 找不到相依方法的實作方式則於 ts 應完全保留該方法及界面,讓使用者另行實作
+- 2.2.1 於實作 OldCaseInfo.vue 時能引用 OldCaseInfo.ts 用相關方法
+
+#### 2.3 生成後輸出
+- 生成後的檔案請輸出至對應的 /uiOutput/OldCaseInfo/OldCaseInfo.vue 和 /uiOutput/OldCaseInfo/OldCaseInfo.ts 路徑
+
+#### 2.4 更新 preview 入口
+- 2.4.1 preview 入口功能定義:
+ - 2.4.1.1 確保 @/uiOutput/index.html 中的 `availableComponents` 陣列包含此新轉換的元件
+ - 2.4.1.2 此新元件的設定應包含 id, name, vuePath, jsPath (指向 ts 檔案) 和 windowTitle
diff --git a/doc/curtis/prompt/dfm_to_web/dfm_to_web_requirement.json b/doc/curtis/prompt/dfm_to_web/dfm_to_web_requirement.json
index f4fb16b..0d35fe9 100644
--- a/doc/curtis/prompt/dfm_to_web/dfm_to_web_requirement.json
+++ b/doc/curtis/prompt/dfm_to_web/dfm_to_web_requirement.json
@@ -12,5 +12,33 @@
"png": "/doc/curtis/screenShot/CB_IMGPSScanImp.png",
"vue": "/uiOutput/CB_IMGPSScanImp/CB_IMGPSScanImp.vue",
"ts": "/uiOutput/CB_IMGPSScanImp/CB_IMGPSScanImp.ts"
+ },
+ {
+ "dfm": "/DocList.dfm",
+ "pas": "/DocList.pas",
+ "png": "/doc/curtis/screenShot/DocList.png",
+ "vue": "/uiOutput/DocList/DocList.vue",
+ "ts": "/uiOutput/DocList/DocList.ts"
+ },
+ {
+ "dfm": "/ErrList.dfm",
+ "pas": "/ErrList.pas",
+ "png": "/doc/curtis/screenShot/ErrList.png",
+ "vue": "/uiOutput/ErrList/ErrList.vue",
+ "ts": "/uiOutput/ErrList/ErrList.ts"
+ },
+ {
+ "dfm": "/DocPrt.dfm",
+ "pas": "/DocPrt.pas",
+ "png": "/doc/curtis/screenShot/DocPrt.png",
+ "vue": "/uiOutput/DocPrt/DocPrt.vue",
+ "ts": "/uiOutput/DocPrt/DocPrt.ts"
+ },
+ {
+ "dfm": "/OldCaseInfo.dfm",
+ "pas": "/OldCaseInfo.pas",
+ "png": "/doc/curtis/screenShot/OldCaseInfo.png",
+ "vue": "/uiOutput/OldCaseInfo/OldCaseInfo.vue",
+ "ts": "/uiOutput/OldCaseInfo/OldCaseInfo.ts"
}
]
diff --git a/doc/curtis/screenShot/CB_DocList.png b/doc/curtis/screenShot/CB_DocList.png
deleted file mode 100644
index 2e0d1f7..0000000
--- a/doc/curtis/screenShot/CB_DocList.png
+++ /dev/null
Binary files differ
diff --git a/doc/curtis/screenShot/CB_DocPrt.png b/doc/curtis/screenShot/CB_DocPrt.png
deleted file mode 100644
index 19d26cf..0000000
--- a/doc/curtis/screenShot/CB_DocPrt.png
+++ /dev/null
Binary files differ
diff --git a/doc/curtis/screenShot/CB_ErrList.png b/doc/curtis/screenShot/CB_ErrList.png
deleted file mode 100644
index 9678b2a..0000000
--- a/doc/curtis/screenShot/CB_ErrList.png
+++ /dev/null
Binary files differ
diff --git a/doc/curtis/screenShot/CB_OldCaseInfo.png b/doc/curtis/screenShot/CB_OldCaseInfo.png
deleted file mode 100644
index ff950fd..0000000
--- a/doc/curtis/screenShot/CB_OldCaseInfo.png
+++ /dev/null
Binary files differ
diff --git a/doc/curtis/screenShot/DocList.png b/doc/curtis/screenShot/DocList.png
new file mode 100644
index 0000000..f777c76
--- /dev/null
+++ b/doc/curtis/screenShot/DocList.png
Binary files differ
diff --git a/doc/curtis/screenShot/DocPrt.png b/doc/curtis/screenShot/DocPrt.png
new file mode 100644
index 0000000..cdfa586
--- /dev/null
+++ b/doc/curtis/screenShot/DocPrt.png
Binary files differ
diff --git a/doc/curtis/screenShot/ErrList.png b/doc/curtis/screenShot/ErrList.png
new file mode 100644
index 0000000..7b128b6
--- /dev/null
+++ b/doc/curtis/screenShot/ErrList.png
Binary files differ
diff --git a/doc/curtis/screenShot/OldCaseInfo.png b/doc/curtis/screenShot/OldCaseInfo.png
new file mode 100644
index 0000000..2d58277
--- /dev/null
+++ b/doc/curtis/screenShot/OldCaseInfo.png
Binary files differ
diff --git a/uiOutput/DocList/DocList.ts b/uiOutput/DocList/DocList.ts
new file mode 100644
index 0000000..4aacad7
--- /dev/null
+++ b/uiOutput/DocList/DocList.ts
@@ -0,0 +1,123 @@
+import { ref, computed, onMounted } from 'vue';
+
+interface DocListItem {
+ formId: string;
+ docName: string;
+}
+
+export function useDocListLogic() {
+ // --- State Mapped from Delphi UI Components ---
+
+ const searchText = ref<string>('');
+ const isCustomDoc = ref<boolean>(false);
+ const selectedIndex = ref<number>(-1);
+ const sortColumn = ref<number>(0);
+ const sortOrder = ref<'asc' | 'desc'>('asc');
+
+ // FormIDList: TStringList equivalent
+ // Sample data format from Pascal: 'FormID#@#DocName'
+ const formIDList = ref<string[]>([]);
+
+ // --- Computed ---
+
+ const filteredItems = computed(() => {
+ const items: DocListItem[] = formIDList.value
+ .filter(line => !searchText.value || line.toUpperCase().includes(searchText.value.toUpperCase()))
+ .map(line => {
+ const parts = line.split('#@#');
+ return {
+ formId: parts[0] || '',
+ docName: parts[1] || ''
+ };
+ });
+
+ // Sort items
+ items.sort((a, b) => {
+ let valA = sortColumn.value === 0 ? a.formId : a.docName;
+ let valB = sortColumn.value === 0 ? b.formId : b.docName;
+
+ const comparison = valA.localeCompare(valB);
+ return sortOrder.value === 'asc' ? comparison : -comparison;
+ });
+
+ return items;
+ });
+
+ // --- Methods ---
+
+ const FormCreate = () => {
+ // PostMessage(Handle,WM_ACTIVATE,WA_CLICKACTIVE,0);
+ console.log('DocListForm created');
+
+ // Mock initialization for demo
+ formIDList.value = [
+ 'F001#@#測試文件一',
+ 'F002#@#測試文件二',
+ 'A003#@#合約書',
+ 'B004#@#申請書'
+ ];
+ };
+
+ const OkBtClick = () => {
+ if (selectedIndex.value === -1 && !isCustomDoc.value) {
+ // Showmessage(_Msg('請選擇一個種類'));
+ alert('請選擇一個種類');
+ return;
+ }
+ console.log('Form confirmed:', selectedIndex.value !== -1 ? filteredItems.value[selectedIndex.value] : 'Custom');
+ closeForm('ok');
+ };
+
+ const CancelBtClick = () => {
+ closeForm('cancel');
+ };
+
+ const Edit1Change = () => {
+ // Logic handled by computed filteredItems
+ selectedIndex.value = -1;
+ };
+
+ const DocLVColumnClick = (index: number) => {
+ if (sortColumn.value === index) {
+ sortOrder.value = sortOrder.value === 'asc' ? 'desc' : 'asc';
+ } else {
+ sortColumn.value = index;
+ sortOrder.value = 'asc';
+ }
+ };
+
+ const DocLVDblClick = (index: number) => {
+ selectedIndex.value = index;
+ OkBtClick();
+ };
+
+ const selectItem = (index: number) => {
+ selectedIndex.value = index;
+ };
+
+ const closeForm = (result: string) => {
+ console.log(`DocListForm closing with result: ${result}`);
+ };
+
+ onMounted(() => {
+ FormCreate();
+ });
+
+ return {
+ // State
+ searchText,
+ isCustomDoc,
+ selectedIndex,
+ filteredItems,
+ sortColumn,
+ sortOrder,
+
+ // Actions
+ OkBtClick,
+ CancelBtClick,
+ Edit1Change,
+ DocLVColumnClick,
+ DocLVDblClick,
+ selectItem
+ };
+}
diff --git a/uiOutput/DocList/DocList.vue b/uiOutput/DocList/DocList.vue
new file mode 100644
index 0000000..aa2428d
--- /dev/null
+++ b/uiOutput/DocList/DocList.vue
@@ -0,0 +1,87 @@
+<template>
+ <div class="doc-list-form flex flex-col bg-gray-100 font-sans w-[594px] h-[486px] border border-gray-400 relative overflow-hidden">
+
+ <!-- Main Content Panel (Panel 2) -->
+ <div class="flex-1 flex flex-col border-b border-gray-300 overflow-hidden">
+ <!-- Search Panel (Panel 3) -->
+ <div class="h-[41px] border-b border-gray-300 flex items-center px-4 space-x-4 bg-gray-50 flex-none">
+ <label class="text-base">索引</label>
+ <input type="text"
+ class="w-[306px] h-[24px] border border-gray-400 px-1 uppercase"
+ v-model="searchText"
+ @input="Edit1Change" />
+
+ <label class="flex items-center space-x-1 cursor-pointer">
+ <input type="checkbox" v-model="isCustomDoc" />
+ <span class="text-sm">分類為自訂文件</span>
+ </label>
+ </div>
+
+ <!-- List View (DocLV) -->
+ <div class="flex-1 overflow-auto bg-white">
+ <table class="w-full border-collapse">
+ <thead class="sticky top-0 bg-gray-200 shadow-sm">
+ <tr class="text-left text-sm font-medium border-b border-gray-300">
+ <th class="p-2 border-r border-gray-300 w-[140px] cursor-pointer hover:bg-gray-300" @click="DocLVColumnClick(0)">
+ FormID
+ <span v-if="sortColumn === 0">{{ sortOrder === 'asc' ? '▲' : '▼' }}</span>
+ </th>
+ <th class="p-2 cursor-pointer hover:bg-gray-300" @click="DocLVColumnClick(1)">
+ 文件名稱
+ <span v-if="sortColumn === 1">{{ sortOrder === 'asc' ? '▲' : '▼' }}</span>
+ </th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr v-for="(item, index) in filteredItems"
+ :key="index"
+ :class="['text-sm hover:bg-blue-50 cursor-pointer', selectedIndex === index ? 'bg-blue-600 text-white hover:bg-blue-700' : '']"
+ @click="selectItem(index)"
+ @dblclick="DocLVDblClick(index)">
+ <td class="p-2 border-r border-gray-200">{{ item.formId }}</td>
+ <td class="p-2">{{ item.docName }}</td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+ </div>
+
+ <!-- Bottom Action Panel (Panel 1) -->
+ <div class="h-[41px] flex items-center justify-center space-x-6 bg-gray-50 flex-none border-t border-gray-300">
+ <button class="w-[75px] h-[25px] border border-gray-400 bg-gray-200 hover:bg-gray-300 flex items-center justify-center shadow-sm" @click="OkBtClick">
+ 確定
+ </button>
+ <button class="w-[75px] h-[25px] border border-gray-400 bg-gray-200 hover:bg-gray-300 flex items-center justify-center shadow-sm" @click="CancelBtClick">
+ 取消
+ </button>
+ </div>
+
+ <!-- Visual Reference Overlay -->
+ <div class="doc-list-layout opacity-20 pointer-events-none absolute left-0 top-0">
+ <img src="assets/DocList.png" class="w-[594px] h-[486px]" />
+ </div>
+ </div>
+</template>
+
+<script lang="ts">
+import { defineComponent } from 'vue';
+import { useDocListLogic } from './DocList.ts';
+
+export default defineComponent({
+ name: 'DocListForm',
+ setup() {
+ const logic = useDocListLogic();
+ return { ...logic };
+ }
+});
+</script>
+
+<style scoped>
+/* Ensure standard Delphi font appearance where appropriate */
+.doc-list-form {
+ user-select: none;
+}
+.doc-list-layout {
+ z-index: 1000;
+}
+</style>
diff --git a/uiOutput/DocPrt/DocPrt.ts b/uiOutput/DocPrt/DocPrt.ts
new file mode 100644
index 0000000..64cca3c
--- /dev/null
+++ b/uiOutput/DocPrt/DocPrt.ts
@@ -0,0 +1,80 @@
+import { ref, onMounted } from 'vue';
+
+interface PrintItem {
+ id: string;
+ text: string;
+ checked: boolean;
+}
+
+export function useDocPrtLogic() {
+ // --- State Mapped from Delphi UI Components ---
+
+ const items = ref<PrintItem[]>([]);
+ const selectedIndex = ref<number>(-1);
+
+ // --- Methods ---
+
+ const FormCreate = () => {
+ // PostMessage(Handle,WM_ACTIVATE,WA_CLICKACTIVE,0);
+ console.log('PrintForm created');
+
+ // Mock data
+ items.value = Array.from({ length: 20 }, (_, i) => ({
+ id: (i + 1).toString(),
+ text: `影像檔 ${i + 1}.jpg`,
+ checked: false
+ }));
+ };
+
+ const SelecAllBtClick = () => {
+ items.value.forEach(item => item.checked = true);
+ };
+
+ const EraseBtClick = () => {
+ items.value.forEach(item => item.checked = false);
+ };
+
+ const ExitBtClick = () => {
+ closeForm('cancel');
+ };
+
+ const PrtBtClick = () => {
+ const selected = items.value.filter(i => i.checked);
+ if (selected.length === 0) {
+ alert('請至少選擇一張影像進行列印');
+ return;
+ }
+ console.log('Printing items:', selected);
+ closeForm('ok');
+ };
+
+ const CheckListBox1Click = (index: number) => {
+ selectedIndex.value = index;
+ };
+
+ const ListBox1Click = (index: number) => {
+ selectedIndex.value = index;
+ };
+
+ const closeForm = (result: string) => {
+ console.log(`PrintForm closing with result: ${result}`);
+ };
+
+ onMounted(() => {
+ FormCreate();
+ });
+
+ return {
+ // State
+ items,
+ selectedIndex,
+
+ // Actions
+ SelecAllBtClick,
+ EraseBtClick,
+ ExitBtClick,
+ PrtBtClick,
+ CheckListBox1Click,
+ ListBox1Click
+ };
+}
diff --git a/uiOutput/DocPrt/DocPrt.vue b/uiOutput/DocPrt/DocPrt.vue
new file mode 100644
index 0000000..85d378f
--- /dev/null
+++ b/uiOutput/DocPrt/DocPrt.vue
@@ -0,0 +1,80 @@
+<template>
+ <div class="print-form flex flex-col bg-gray-100 font-sans w-[368px] h-[484px] border border-gray-400 relative overflow-hidden">
+
+ <!-- Document Image GroupBox (DocGB) -->
+ <fieldset class="flex-1 flex flex-col border border-gray-400 m-1 p-0 overflow-hidden">
+ <legend class="text-sm px-1 ml-2">文件影像</legend>
+
+ <div class="flex-1 flex overflow-hidden">
+ <!-- Index List (ListBox1) -->
+ <div class="w-[37px] bg-white border-r border-gray-300 overflow-y-auto">
+ <div v-for="(item, index) in items"
+ :key="'lb'+index"
+ :class="['h-[20px] text-xs flex items-center justify-center cursor-pointer border-b border-gray-100', selectedIndex === index ? 'bg-blue-600 text-white' : '']"
+ @click="ListBox1Click(index)">
+ {{ index + 1 }}
+ </div>
+ </div>
+
+ <!-- Check List (CheckListBox1) -->
+ <div class="flex-1 bg-white overflow-y-auto">
+ <div v-for="(item, index) in items"
+ :key="'clb'+index"
+ :class="['h-[20px] text-sm flex items-center px-2 space-x-2 cursor-pointer border-b border-gray-100', selectedIndex === index ? 'bg-blue-600 text-white' : '']"
+ @click="CheckListBox1Click(index)">
+ <input type="checkbox" v-model="item.checked" class="cursor-pointer" @click.stop />
+ <span class="truncate">{{ item.text }}</span>
+ </div>
+ </div>
+ </div>
+ </fieldset>
+
+ <!-- Bottom Action Panel (Panel 1) -->
+ <div class="h-[51px] flex items-center px-2 space-x-2 bg-gray-50 flex-none border-t border-gray-300">
+ <button class="w-[50px] h-[35px] border border-gray-400 bg-gray-200 hover:bg-gray-300 flex flex-col items-center justify-center text-[10px]" @click="SelecAllBtClick" title="全選">
+ <span class="text-lg">✓</span>
+ 全選
+ </button>
+ <button class="w-[50px] h-[35px] border border-gray-400 bg-gray-200 hover:bg-gray-300 flex flex-col items-center justify-center text-[10px]" @click="EraseBtClick" title="清除">
+ <span class="text-lg">✗</span>
+ 清除
+ </button>
+ <button class="w-[50px] h-[35px] border border-gray-400 bg-gray-200 hover:bg-gray-300 flex flex-col items-center justify-center text-[10px]" @click="PrtBtClick" title="列印">
+ <span class="text-lg">🖨️</span>
+ 列印
+ </button>
+ <div class="flex-1"></div>
+ <button class="w-[50px] h-[35px] border border-gray-400 bg-gray-200 hover:bg-gray-300 flex flex-col items-center justify-center text-[10px]" @click="ExitBtClick" title="離開">
+ <span class="text-lg">🚪</span>
+ 離開
+ </button>
+ </div>
+
+ <!-- Visual Reference Overlay -->
+ <div class="print-layout opacity-20 pointer-events-none absolute left-0 top-0">
+ <img src="assets/DocPrt.png" class="w-[368px] h-[484px]" />
+ </div>
+ </div>
+</template>
+
+<script lang="ts">
+import { defineComponent } from 'vue';
+import { useDocPrtLogic } from './DocPrt.ts';
+
+export default defineComponent({
+ name: 'PrintForm',
+ setup() {
+ const logic = useDocPrtLogic();
+ return { ...logic };
+ }
+});
+</script>
+
+<style scoped>
+.print-form {
+ user-select: none;
+}
+.print-layout {
+ z-index: 1000;
+}
+</style>
diff --git a/uiOutput/ErrList/ErrList.ts b/uiOutput/ErrList/ErrList.ts
index 1a2614e..ffe68ac 100644
--- a/uiOutput/ErrList/ErrList.ts
+++ b/uiOutput/ErrList/ErrList.ts
@@ -1,189 +1,89 @@
-import { ref, onMounted, onUnmounted } from 'vue';
+import { ref, onMounted, computed } from 'vue';
-// Interfaces mapping from Delphi structures
-interface TPoint {
- X: number;
- Y: number;
-}
-
-interface TErrListItem {
- content: string;
+interface ErrItem {
+ reason: string;
index: string;
}
export function useErrListLogic() {
- // State from Delphi variables
- const errListItems = ref<TErrListItem[]>([
- // Mock data for display
- { content: '測試錯誤原因1', index: 'Item_1' },
- { content: '測試錯誤原因2', index: 'Item_2' }
- ]);
- const selectedItemIndex = ref<number>(-1);
+ // --- State Mapped from Delphi UI Components ---
+
+ const errorItems = ref<ErrItem[]>([]);
+ const selectedIndex = ref<number>(-1);
+
+ const primaryImage = ref<string>('');
+ const relatedImage = ref<string>('');
+
+ const siteIdx = ref<number>(1);
+ const siteCount = ref<number>(0);
+ const relaSiteIdx = ref<number>(1);
+ const relaSiteCount = ref<number>(0);
+
const isDeleteEnabled = ref<boolean>(false);
-
- const siteIndex = ref<number>(0);
- const siteTotal = ref<number>(0);
- const isSitePreEnabled = ref<boolean>(false);
- const isSiteNextEnabled = ref<boolean>(false);
- const SiteList = ref<string[]>([]); // TStringlist
-
- const relaSiteIndex = ref<number>(0);
- const relaSiteTotal = ref<number>(0);
- const isRelaPreEnabled = ref<boolean>(false);
- const isRelaNextEnabled = ref<boolean>(false);
- const RelaSiteList = ref<string[]>([]); // TStringlist
-
- const showPanel6 = ref<boolean>(true); // Splitter visibility for related images
- const showNoteBtn = ref<boolean>(false);
- const showRejectBtn = ref<boolean>(false);
-
- const Ingnore = ref<boolean>(false);
- const NowIndex = ref<string>('');
-
- const iniPath = ref<string>(''); // Should be injected or configured
- const MyHotkeyid1 = ref<number>(0);
-
- // Point structures
- const UpLPoint = ref<TPoint>({ X: 0, Y: 0 });
- const UpRPoint = ref<TPoint>({ X: 0, Y: 0 });
- const DownLPoint = ref<TPoint>({ X: 0, Y: 0 });
- const DownRPoint = ref<TPoint>({ X: 0, Y: 0 });
+ const isImmediateEnabled = ref<boolean>(false);
- const UpLPoint_Rela = ref<TPoint>({ X: 0, Y: 0 });
- const UpRPoint_Rela = ref<TPoint>({ X: 0, Y: 0 });
- const DownLPoint_Rela = ref<TPoint>({ X: 0, Y: 0 });
- const DownRPoint_Rela = ref<TPoint>({ X: 0, Y: 0 });
+ // --- Methods ---
- // Hotkey simulation mapped from WMHotKey
- const WMHotKey = (e: KeyboardEvent) => {
- if (e.ctrlKey && e.key.toLowerCase() === 'd' && isDeleteEnabled.value) {
- e.preventDefault();
- DeleteBtClick();
+ const FormCreate = () => {
+ console.log('ErrlistForm created');
+ // Mock initialization
+ errorItems.value = [
+ { reason: 'OMR 檢查失敗: 區域 1 未填寫', index: 'ERR001' },
+ { reason: 'OMR 檢查失敗: 區域 5 重複填寫', index: 'ERR005' },
+ { reason: '條碼讀取失敗', index: 'BAR002' }
+ ];
+
+ if (errorItems.value.length > 0) {
+ selectedIndex.value = 0;
+ loadErrorDetails(errorItems.value[0].index);
}
};
- onMounted(() => {
- window.addEventListener('keydown', WMHotKey);
- InitialData();
- });
-
- onUnmounted(() => {
- window.removeEventListener('keydown', WMHotKey);
- });
-
- const selectItem = (index: number) => {
- selectedItemIndex.value = index;
- ErrListLVClick();
+ const loadErrorDetails = (id: string) => {
+ console.log('Loading error details for:', id);
+ // Mock loading from INI
+ primaryImage.value = 'assets/CB_IMGPSScanImp.png'; // Mock URL
+ relatedImage.value = 'assets/DocList.png'; // Mock URL
+
+ siteCount.value = 3;
+ relaSiteCount.value = 2;
+ siteIdx.value = 1;
+ relaSiteIdx.value = 1;
+
+ isDeleteEnabled.value = true;
+ isImmediateEnabled.value = errorItems.value.length === 0;
};
- // Delphi Methods
- const InitialData = () => {
- isSitePreEnabled.value = false;
- isSiteNextEnabled.value = false;
- isRelaPreEnabled.value = false;
- isRelaNextEnabled.value = false;
-
- SiteList.value = [];
- RelaSiteList.value = [];
-
- siteIndex.value = 1;
- siteTotal.value = 0;
- relaSiteIndex.value = 1;
- relaSiteTotal.value = 0;
-
- isDeleteEnabled.value = false;
- };
-
- const GetOMRErrini = (Index: string) => {
- console.log(`Getting OMR Err INI for index: ${Index}`);
-
- // Mock data population based on index
- SiteList.value = ['Site1', 'Site2'];
- RelaSiteList.value = ['Rela1'];
- Ingnore.value = true;
-
- siteTotal.value = SiteList.value.length;
- relaSiteTotal.value = RelaSiteList.value.length;
-
- if (RelaSiteList.value.length > 0) {
- showPanel6.value = true;
- } else {
- showPanel6.value = false;
- }
-
- if (SiteList.value.length > 1) isSiteNextEnabled.value = true;
- if (RelaSiteList.value.length > 1) isRelaNextEnabled.value = true;
-
- isDeleteEnabled.value = Ingnore.value;
-
- // Mock showing first errors
- if (SiteList.value.length > 0) ShowOMRErr(siteIndex.value);
- if (RelaSiteList.value.length > 0) ShowRelaOMRErr(relaSiteIndex.value);
- };
-
- const ErrListLVClick = () => {
- InitialData();
- if (selectedItemIndex.value === -1 || !errListItems.value[selectedItemIndex.value]) return;
-
- NowIndex.value = errListItems.value[selectedItemIndex.value].index;
- GetOMRErrini(NowIndex.value);
- };
-
- const ErrListLVKeyUp = (e: KeyboardEvent) => {
- if (e.key === 'ArrowUp' || e.key === 'ArrowDown') {
- ErrListLVClick();
- }
- };
-
- const ErrListLVMouseDown = (e: MouseEvent) => {
- // Right click
- if (e.button === 2) {
- ErrListLVClick();
- }
+ const ErrListLVClick = (index: number) => {
+ selectedIndex.value = index;
+ loadErrorDetails(errorItems.value[index].index);
};
const DeleteBtClick = () => {
- InitialData();
- if (Ingnore.value) {
- console.log(`Writing Del=True to INI for ${NowIndex.value}`);
-
- const idx = selectedItemIndex.value;
- if (idx !== -1) {
- errListItems.value.splice(idx, 1);
-
- if (errListItems.value.length === 0) {
- console.log('All errors deleted, enabling Immediate button and writing OMRCheckOk.dat');
- } else {
- selectedItemIndex.value = Math.min(idx, errListItems.value.length - 1);
- ErrListLVClick();
- }
- }
+ if (selectedIndex.value === -1) return;
+
+ errorItems.value.splice(selectedIndex.value, 1);
+ if (errorItems.value.length === 0) {
+ isImmediateEnabled.value = true;
+ selectedIndex.value = -1;
} else {
- alert('此項目不可刪除或已無可刪除項目');
+ if (selectedIndex.value >= errorItems.value.length) {
+ selectedIndex.value = errorItems.value.length - 1;
+ }
+ loadErrorDetails(errorItems.value[selectedIndex.value].index);
}
};
const EnforceBtClick = () => {
- InitialData();
- let deletedAny = false;
-
- for (let i = errListItems.value.length - 1; i >= 0; i--) {
- const itemIgnorable = true;
-
- if (itemIgnorable) {
- console.log(`Writing Del=True for ${errListItems.value[i].index}`);
- errListItems.value.splice(i, 1);
- deletedAny = true;
- }
- }
-
- if (errListItems.value.length === 0 && deletedAny) {
- console.log('All errors enforced, enabling Immediate button and writing OMRCheckOk.dat');
+ if (confirm('是否確定強制送件?')) {
+ errorItems.value = [];
+ isImmediateEnabled.value = true;
+ selectedIndex.value = -1;
}
};
const ImmediateBtClick = () => {
- console.log('ImmediateBtClick: ' + logTimeString() + ' 立即傳送');
+ console.log('Immediate send triggered');
closeForm('ok');
};
@@ -191,113 +91,45 @@
closeForm('cancel');
};
- const NoteBtClick = () => {
- console.log('Ch_WriteNote = True');
- closeForm('note');
- };
-
- const RejectBtClick = () => {
- if (confirm('是否確定退件??')) {
- console.log('RejectCase = True');
- closeForm('reject');
- }
- };
-
- const Button1Click = () => {
- alert(`UpLPoint=${UpLPoint.value.X},${UpLPoint.value.Y}\n` +
- `UpRPoint=${UpRPoint.value.X},${UpRPoint.value.Y}\n` +
- `DownLPoint=${DownLPoint.value.X},${DownLPoint.value.Y}\n` +
- `DownRPoint=${DownRPoint.value.X},${DownRPoint.value.Y}`);
+ const SitePreBtClick = () => {
+ if (siteIdx.value > 1) siteIdx.value--;
};
const SiteNextBtClick = () => {
- siteIndex.value++;
- ShowOMRErr(siteIndex.value);
-
- isSitePreEnabled.value = false;
- isSiteNextEnabled.value = false;
- if (siteIndex.value > 1) isSitePreEnabled.value = true;
- if (siteIndex.value < siteTotal.value) isSiteNextEnabled.value = true;
- };
-
- const SitePreBtClick = () => {
- siteIndex.value--;
- ShowOMRErr(siteIndex.value);
-
- isSitePreEnabled.value = false;
- isSiteNextEnabled.value = false;
- if (siteIndex.value > 1) isSitePreEnabled.value = true;
- if (siteIndex.value < siteTotal.value) isSiteNextEnabled.value = true;
- };
-
- const RelaNextBtClick = () => {
- relaSiteIndex.value++;
- ShowRelaOMRErr(relaSiteIndex.value);
-
- isRelaPreEnabled.value = false;
- isRelaNextEnabled.value = false;
- if (relaSiteIndex.value > 1) isRelaPreEnabled.value = true;
- if (relaSiteIndex.value < relaSiteTotal.value) isRelaNextEnabled.value = true;
+ if (siteIdx.value < siteCount.value) siteIdx.value++;
};
const RelaPreBtClick = () => {
- relaSiteIndex.value--;
- ShowRelaOMRErr(relaSiteIndex.value);
-
- isRelaPreEnabled.value = false;
- isRelaNextEnabled.value = false;
- if (relaSiteIndex.value > 1) isRelaPreEnabled.value = true;
- if (relaSiteIndex.value < relaSiteTotal.value) isRelaNextEnabled.value = true;
+ if (relaSiteIdx.value > 1) relaSiteIdx.value--;
};
- const ShowOMRErr = (Idx: number) => {
- if (Idx > SiteList.value.length) return;
- console.log(`Showing OMR Error shape for index ${Idx}`);
- };
-
- const ShowRelaOMRErr = (RelaIdx: number) => {
- if (RelaIdx > RelaSiteList.value.length) return;
- console.log(`Showing Related OMR Error shape for index ${RelaIdx}`);
- };
-
- // Missing or external methods mapped
- const logTimeString = (): string => {
- const now = new Date();
- const pad = (n: number) => (n < 10 ? '0' + n : n);
- return `${now.getFullYear()}${pad(now.getMonth()+1)}${pad(now.getDate())} ${pad(now.getHours())}:${pad(now.getMinutes())}:${pad(now.getSeconds())} `;
+ const RelaNextBtClick = () => {
+ if (relaSiteIdx.value < relaSiteCount.value) relaSiteIdx.value++;
};
const closeForm = (result: string) => {
- console.log(`Form closing with result: ${result}`);
+ console.log(`ErrlistForm closing with result: ${result}`);
};
- const startResize = (e: MouseEvent) => {
- console.log('Splitter moving started');
- };
+ onMounted(() => {
+ FormCreate();
+ });
return {
- errListItems,
- selectedItemIndex,
+ // State
+ errorItems,
+ selectedIndex,
+ primaryImage,
+ relatedImage,
+ siteIdx,
+ siteCount,
+ relaSiteIdx,
+ relaSiteCount,
isDeleteEnabled,
+ isImmediateEnabled,
- siteIndex,
- siteTotal,
- isSitePreEnabled,
- isSiteNextEnabled,
-
- relaSiteIndex,
- relaSiteTotal,
- isRelaPreEnabled,
- isRelaNextEnabled,
-
- showPanel6,
- showNoteBtn,
- showRejectBtn,
-
- selectItem,
+ // Actions
ErrListLVClick,
- ErrListLVKeyUp,
- ErrListLVMouseDown,
DeleteBtClick,
EnforceBtClick,
ImmediateBtClick,
@@ -305,10 +137,6 @@
SitePreBtClick,
SiteNextBtClick,
RelaPreBtClick,
- RelaNextBtClick,
- NoteBtClick,
- RejectBtClick,
- Button1Click,
- startResize
+ RelaNextBtClick
};
}
diff --git a/uiOutput/ErrList/ErrList.vue b/uiOutput/ErrList/ErrList.vue
index 5793140..e6073c7 100644
--- a/uiOutput/ErrList/ErrList.vue
+++ b/uiOutput/ErrList/ErrList.vue
@@ -1,103 +1,93 @@
<template>
- <div class="err-list-form flex flex-col bg-gray-100 font-sans" style="width: 841px; height: 636px;">
- <!-- Top Panel: Error Reason & Details -->
- <div class="panel-3 border border-gray-300 flex-none" style="height: 212px;">
- <fieldset class="err-reason-gb m-2 border border-gray-400 p-2 h-[calc(100%-16px)]">
- <legend class="text-black text-base px-1">錯誤原因</legend>
- <div class="relative h-full">
- <!-- ListView for Error Items -->
- <div class="err-list-lv bg-white border border-gray-300 w-full h-[calc(100%-20px)] overflow-auto cursor-pointer"
- @click="errListLVClick" @keyup="errListLVKeyUp" @mousedown="errListLVMouseDown">
- <table class="w-full text-left text-base border-collapse">
- <thead>
- <tr class="bg-gray-200">
- <th class="p-1 border border-gray-300 font-normal" style="width: 550px;">內容</th>
- <th class="p-1 border border-gray-300 font-normal" style="width: 80px;">index</th>
- </tr>
- </thead>
- <tbody>
- <tr v-for="(item, index) in errListItems" :key="index"
- @click="selectItem(index)"
- :class="{'bg-blue-600 text-white': selectedItemIndex === index, 'hover:bg-gray-100': selectedItemIndex !== index}">
- <td class="p-1 border border-gray-300">{{ item.content }}</td>
- <td class="p-1 border border-gray-300">{{ item.index }}</td>
- </tr>
- </tbody>
- </table>
+ <div class="err-list-form flex flex-col bg-gray-100 font-sans w-[841px] h-[636px] border border-gray-400 relative overflow-hidden text-sm">
+
+ <!-- Top Error Reason Panel (Panel 3) -->
+ <div class="h-[212px] flex-none border-b border-gray-300 p-1">
+ <fieldset class="w-full h-full border border-gray-400 p-0 flex flex-col">
+ <legend class="px-1 ml-2 text-base text-black">錯誤原因</legend>
+
+ <div class="flex-1 overflow-auto bg-white m-1 border border-gray-300">
+ <table class="w-full border-collapse">
+ <thead class="sticky top-0 bg-gray-100">
+ <tr class="text-left border-b border-gray-300">
+ <th class="p-1 border-r border-gray-200">內容</th>
+ <th class="p-1 w-[80px]">index</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr v-for="(item, index) in errorItems"
+ :key="index"
+ :class="['hover:bg-blue-50 cursor-pointer', selectedIndex === index ? 'bg-blue-600 text-white hover:bg-blue-700' : '']"
+ @click="ErrListLVClick(index)">
+ <td class="p-1 border-r border-gray-200">{{ item.reason }}</td>
+ <td class="p-1">{{ item.index }}</td>
+ </tr>
+ </tbody>
+ </table>
+ <div v-if="errorItems.length === 0" class="flex items-center justify-center h-full text-red-600 font-bold text-lg">
+ 檢核失敗原因已全部清除
</div>
-
- <!-- Hidden ImageScrollBox3 -->
- <div v-show="false" class="image-scroll-box-3 absolute top-[94px] left-[720px] w-[100px] h-[100px] border"></div>
</div>
</fieldset>
</div>
- <!-- Splitter 3 -->
- <div class="splitter-3 h-[5px] w-full bg-gray-300 cursor-row-resize flex-none"></div>
-
- <!-- Action Buttons Panel -->
- <div class="panel-1 border border-gray-300 bg-gray-100 flex items-center px-4 space-x-2 flex-none" style="height: 41px;">
- <button class="delete-bt px-4 py-1.5 border border-gray-400 bg-gray-200 hover:bg-gray-300 text-sm disabled:opacity-50"
- :disabled="!isDeleteEnabled" @click="DeleteBtClick">忽略</button>
- <button class="enforce-bt px-4 py-1.5 border border-gray-400 bg-gray-200 hover:bg-gray-300 text-sm"
- @click="EnforceBtClick">強制傳送</button>
- <button class="immediate-bt px-4 py-1.5 border border-gray-400 bg-gray-200 hover:bg-gray-300 text-sm"
- @click="ImmediateBtClick">立即傳送</button>
-
- <!-- Hidden buttons -->
- <button v-show="showNoteBtn" class="note-bt px-4 py-1.5 border border-gray-400 bg-gray-200" @click="NoteBtClick">備註</button>
- <button v-show="showRejectBtn" class="reject-bt px-4 py-1.5 border border-gray-400 bg-gray-200" @click="RejectBtClick">退件</button>
- <button v-show="false" class="button-1 px-4 py-1.5 border border-gray-400 bg-gray-200" @click="Button1Click">Button1</button>
-
- <div class="flex-grow"></div> <!-- Spacer -->
- <button class="exit-bt px-4 py-1.5 border border-gray-400 bg-gray-200 hover:bg-gray-300 text-sm"
- @click="ExitBtClick">離開</button>
+ <!-- Action Buttons Panel (Panel 1) -->
+ <div class="h-[41px] flex-none border-b border-gray-300 flex items-center px-4 space-x-2 bg-gray-50">
+ <button class="w-[84px] h-[34px] border border-gray-400 bg-gray-200 hover:bg-gray-300 disabled:opacity-50"
+ :disabled="!isDeleteEnabled" @click="DeleteBtClick">
+ 忽略
+ </button>
+ <button class="w-[79px] h-[34px] border border-gray-400 bg-gray-200 hover:bg-gray-300" @click="EnforceBtClick">
+ 強制送件
+ </button>
+ <div class="flex-1"></div>
+ <button class="w-[89px] h-[34px] border border-gray-400 bg-gray-200 hover:bg-gray-300 disabled:opacity-50"
+ :disabled="!isImmediateEnabled" @click="ImmediateBtClick">
+ 立即傳送
+ </button>
+ <button class="w-[84px] h-[34px] border border-gray-400 bg-gray-200 hover:bg-gray-300" @click="ExitBtClick">
+ 離開
+ </button>
</div>
- <!-- Bottom Panel: Image Viewers -->
- <div class="panel-4 flex flex-1 overflow-hidden border border-gray-300">
-
- <!-- Left Image Viewer Panel -->
- <div class="panel-5 flex flex-col h-full w-[407px]">
- <div class="panel-8 flex items-center bg-gray-200 border-b border-gray-300 px-2 h-[28px] flex-none">
- <button class="site-pre-bt p-0.5 border border-gray-400 bg-gray-100 disabled:opacity-50 mr-1"
- :disabled="!isSitePreEnabled" @click="SitePreBtClick">
- <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 19l-7-7 7-7"></path></svg>
- </button>
- <span class="label-3 text-sm ml-2">{{ siteIndex }}/{{ siteTotal }}</span>
- <button class="site-next-bt p-0.5 border border-gray-400 bg-gray-100 disabled:opacity-50 ml-1"
- :disabled="!isSiteNextEnabled" @click="SiteNextBtClick">
- <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"></path></svg>
- </button>
+ <!-- Image Viewing Area (Panel 4) -->
+ <div class="flex-1 flex overflow-hidden">
+ <!-- Primary Image View (Panel 5) -->
+ <div class="flex-1 flex flex-col border-r border-gray-400 overflow-hidden">
+ <div class="h-[28px] bg-gray-200 border-b border-gray-300 flex items-center px-2 space-x-4">
+ <button class="w-[29px] h-[23px] border border-gray-400 bg-gray-100 flex items-center justify-center text-xs"
+ :disabled="siteIdx <= 1" @click="SitePreBtClick">◀</button>
+ <span class="text-xs font-mono">{{ siteIdx }}/{{ siteCount }}</span>
+ <button class="w-[29px] h-[23px] border border-gray-400 bg-gray-100 flex items-center justify-center text-xs"
+ :disabled="siteIdx >= siteCount" @click="SiteNextBtClick">▶</button>
</div>
- <div class="image-scroll-box-1 flex-1 bg-white border border-gray-300 overflow-auto relative">
- <!-- Placeholder for Main Image -->
- <div class="text-gray-400 absolute inset-0 flex items-center justify-center">Image 1</div>
+ <div class="flex-1 bg-gray-800 overflow-auto relative p-2 flex items-center justify-center">
+ <img :src="primaryImage" class="max-w-none shadow-xl border border-gray-400" />
+ <!-- Mock OMR Error Overlay -->
+ <div v-if="siteIdx > 0" class="absolute left-1/2 top-1/4 w-[100px] h-[40px] border-2 border-yellow-400 bg-yellow-200 opacity-40 animate-pulse pointer-events-none"></div>
</div>
</div>
- <!-- Splitter 1 -->
- <div class="splitter-1 w-[5px] h-full bg-gray-300 cursor-col-resize flex-none hover:bg-gray-400" @mousedown="startResize"></div>
-
- <!-- Right Image Viewer Panel (Conditional Visibility in original code based on RelaSite) -->
- <div class="panel-6 flex flex-col h-full flex-1" v-show="showPanel6">
- <div class="panel-9 flex items-center bg-gray-200 border-b border-gray-300 px-2 h-[28px] flex-none">
- <button class="rela-pre-bt p-0.5 border border-gray-400 bg-gray-100 disabled:opacity-50 mr-1"
- :disabled="!isRelaPreEnabled" @click="RelaPreBtClick">
- <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 19l-7-7 7-7"></path></svg>
- </button>
- <span class="label-4 text-sm ml-2">{{ relaSiteIndex }}/{{ relaSiteTotal }}</span>
- <button class="rela-next-bt p-0.5 border border-gray-400 bg-gray-100 disabled:opacity-50 ml-1"
- :disabled="!isRelaNextEnabled" @click="RelaNextBtClick">
- <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"></path></svg>
- </button>
+ <!-- Related Image View (Panel 6) -->
+ <div class="w-[427px] flex-none flex flex-col overflow-hidden">
+ <div class="h-[28px] bg-gray-200 border-b border-gray-300 flex items-center px-2 space-x-4">
+ <button class="w-[31px] h-[23px] border border-gray-400 bg-gray-100 flex items-center justify-center text-xs"
+ :disabled="relaSiteIdx <= 1" @click="RelaPreBtClick">◀</button>
+ <span class="text-xs font-mono">{{ relaSiteIdx }}/{{ relaSiteCount }}</span>
+ <button class="w-[31px] h-[23px] border border-gray-400 bg-gray-100 flex items-center justify-center text-xs"
+ :disabled="relaSiteIdx >= relaSiteCount" @click="RelaNextBtClick">▶</button>
</div>
- <div class="image-scroll-box-2 flex-1 bg-white border border-gray-300 overflow-auto relative">
- <!-- Placeholder for Related Image -->
- <div class="text-gray-400 absolute inset-0 flex items-center justify-center">Image 2 (Related)</div>
+ <div class="flex-1 bg-gray-800 overflow-auto relative p-2 flex items-center justify-center">
+ <img :src="relatedImage" class="max-w-none shadow-xl border border-gray-400" />
+ <!-- Mock Related Error Overlay -->
+ <div v-if="relaSiteIdx > 0" class="absolute left-1/3 top-1/3 w-[80px] h-[30px] border-2 border-red-400 bg-red-200 opacity-40 pointer-events-none"></div>
</div>
</div>
+ </div>
+ <!-- Visual Reference Overlay -->
+ <div class="err-list-layout opacity-20 pointer-events-none absolute left-0 top-0">
+ <img src="assets/ErrList.png" class="w-[841px] h-[636px]" />
</div>
</div>
</template>
@@ -109,92 +99,17 @@
export default defineComponent({
name: 'ErrlistForm',
setup() {
- const {
- // State
- errListItems,
- selectedItemIndex,
- isDeleteEnabled,
- siteIndex,
- siteTotal,
- isSitePreEnabled,
- isSiteNextEnabled,
- relaSiteIndex,
- relaSiteTotal,
- isRelaPreEnabled,
- isRelaNextEnabled,
- showPanel6,
- showNoteBtn,
- showRejectBtn,
-
- // Actions
- selectItem,
- ErrListLVClick,
- ErrListLVKeyUp,
- ErrListLVMouseDown,
- DeleteBtClick,
- EnforceBtClick,
- ImmediateBtClick,
- ExitBtClick,
- SitePreBtClick,
- SiteNextBtClick,
- RelaPreBtClick,
- RelaNextBtClick,
- NoteBtClick,
- RejectBtClick,
- Button1Click,
- startResize
- } = useErrListLogic();
-
- return {
- errListItems,
- selectedItemIndex,
- isDeleteEnabled,
- siteIndex,
- siteTotal,
- isSitePreEnabled,
- isSiteNextEnabled,
- relaSiteIndex,
- relaSiteTotal,
- isRelaPreEnabled,
- isRelaNextEnabled,
- showPanel6,
- showNoteBtn,
- showRejectBtn,
-
- selectItem,
- ErrListLVClick,
- ErrListLVKeyUp,
- ErrListLVMouseDown,
- DeleteBtClick,
- EnforceBtClick,
- ImmediateBtClick,
- ExitBtClick,
- SitePreBtClick,
- SiteNextBtClick,
- RelaPreBtClick,
- RelaNextBtClick,
- NoteBtClick,
- RejectBtClick,
- Button1Click,
- startResize
- };
+ const logic = useErrListLogic();
+ return { ...logic };
}
});
</script>
<style scoped>
-/* Optional: Add custom scrollbar styling to match Delphi look if desired */
-.err-list-lv::-webkit-scrollbar {
- width: 16px;
+.err-list-form {
+ user-select: none;
}
-.err-list-lv::-webkit-scrollbar-track {
- background: #f1f1f1;
-}
-.err-list-lv::-webkit-scrollbar-thumb {
- background: #c1c1c1;
- border: 1px solid #f1f1f1;
-}
-.err-list-lv::-webkit-scrollbar-thumb:hover {
- background: #a8a8a8;
+.err-list-layout {
+ z-index: 1000;
}
</style>
diff --git a/uiOutput/OldCaseInfo/OldCaseInfo.ts b/uiOutput/OldCaseInfo/OldCaseInfo.ts
new file mode 100644
index 0000000..42ae667
--- /dev/null
+++ b/uiOutput/OldCaseInfo/OldCaseInfo.ts
@@ -0,0 +1,116 @@
+import { ref, onMounted } from 'vue';
+
+interface OldCase {
+ id: string;
+ year: string;
+ type: string;
+ isOld: string;
+}
+
+interface DocGroup {
+ text: string;
+ checked: boolean;
+ pages: string[];
+}
+
+export function useOldCaseInfoLogic() {
+ // --- State Mapped from Delphi UI Components ---
+
+ const currentPage = ref<'CaseInfo' | 'View'>('CaseInfo');
+ const oldCases = ref<OldCase[]>([]);
+ const selectedCaseIndex = ref<number>(-1);
+
+ const docGroups = ref<DocGroup[]>([]);
+ const selectedGroupIndex = ref<number>(-1);
+
+ const previewImage = ref<string>('');
+
+ // --- Methods ---
+
+ const FormCreate = () => {
+ console.log('OldCaseInfoForm created');
+ // Mock data for OldCaseLV
+ oldCases.value = [
+ { id: 'CASE2023001', year: '2023', type: 'HLN', isOld: 'Y' },
+ { id: 'CASE2022045', year: '2022', type: 'HLN', isOld: 'Y' },
+ { id: 'CASE2024012', year: '2024', type: 'NORMAL', isOld: 'N' }
+ ];
+ };
+
+ const LoadBtClick = () => {
+ if (selectedCaseIndex.value === -1) {
+ alert('請先選擇一個案件編號');
+ return;
+ }
+
+ console.log('Loading case:', oldCases.value[selectedCaseIndex.value].id);
+ currentPage.value = 'View';
+
+ // Mock doc groups loading
+ docGroups.value = [
+ { text: '身份證{正本}-1', checked: false, pages: ['assets/DocList.png'] },
+ { text: '申請書{複本}-2', checked: false, pages: ['assets/CB_IMGPSScanImp.png', 'assets/DocPrt.png'] },
+ { text: '財力證明{附件}-1', checked: false, pages: ['assets/ErrList.png'] }
+ ];
+ };
+
+ const ImportBtClick = () => {
+ const selected = docGroups.value.filter(g => g.checked);
+ if (selected.length === 0) {
+ alert('請至少選擇一個要引用之文件');
+ return;
+ }
+ console.log('Importing groups:', selected);
+ closeForm('ok');
+ };
+
+ const ExitBtClick = () => {
+ currentPage.value = 'CaseInfo';
+ };
+
+ const OldExitBtClick = () => {
+ closeForm('cancel');
+ };
+
+ const CheckListBox1Click = (index: number) => {
+ selectedGroupIndex.value = index;
+ if (docGroups.value[index].pages.length > 0) {
+ previewImage.value = docGroups.value[index].pages[0];
+ }
+ };
+
+ const selectCase = (index: number) => {
+ selectedCaseIndex.value = index;
+ };
+
+ const setThumbnailAsPreview = (url: string) => {
+ previewImage.value = url;
+ };
+
+ const closeForm = (result: string) => {
+ console.log(`OldCaseInfoForm closing with result: ${result}`);
+ };
+
+ onMounted(() => {
+ FormCreate();
+ });
+
+ return {
+ // State
+ currentPage,
+ oldCases,
+ selectedCaseIndex,
+ docGroups,
+ selectedGroupIndex,
+ previewImage,
+
+ // Actions
+ LoadBtClick,
+ ImportBtClick,
+ ExitBtClick,
+ OldExitBtClick,
+ CheckListBox1Click,
+ selectCase,
+ setThumbnailAsPreview
+ };
+}
diff --git a/uiOutput/OldCaseInfo/OldCaseInfo.vue b/uiOutput/OldCaseInfo/OldCaseInfo.vue
new file mode 100644
index 0000000..ed531db
--- /dev/null
+++ b/uiOutput/OldCaseInfo/OldCaseInfo.vue
@@ -0,0 +1,122 @@
+<template>
+ <div class="old-case-info-form flex flex-col bg-gray-100 font-sans w-[740px] h-[554px] border border-gray-400 relative overflow-hidden text-sm">
+
+ <!-- Page 1: CaseInfo -->
+ <div v-if="currentPage === 'CaseInfo'" class="flex-1 flex flex-col overflow-hidden">
+ <!-- Toolbar (Panel 1) -->
+ <div class="h-[41px] flex items-center px-4 space-x-4 bg-gray-50 border-b border-gray-300">
+ <button class="w-[75px] h-[25px] border border-gray-400 bg-gray-200 hover:bg-gray-300" @click="LoadBtClick">
+ 載入影像
+ </button>
+ <button class="w-[75px] h-[25px] border border-gray-400 bg-gray-200 hover:bg-gray-300" @click="OldExitBtClick">
+ 離開
+ </button>
+ </div>
+
+ <!-- Case List (OldCaseLV) -->
+ <div class="flex-1 bg-white overflow-auto">
+ <table class="w-full border-collapse">
+ <thead class="sticky top-0 bg-gray-100">
+ <tr class="text-left border-b border-gray-300">
+ <th class="p-2 border-r border-gray-200 w-[200px]">掛報書編號</th>
+ <th class="p-2 border-r border-gray-200 w-[120px]">年度</th>
+ <th class="p-2 border-r border-gray-200 w-[120px]">業務別</th>
+ <th class="p-2">是否舊案</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr v-for="(item, index) in oldCases"
+ :key="index"
+ :class="['hover:bg-blue-50 cursor-pointer border-b border-gray-100', selectedCaseIndex === index ? 'bg-blue-600 text-white hover:bg-blue-700' : '']"
+ @click="selectCase(index)"
+ @dblclick="LoadBtClick">
+ <td class="p-2 border-r border-gray-200">{{ item.id }}</td>
+ <td class="p-2 border-r border-gray-200">{{ item.year }}</td>
+ <td class="p-2 border-r border-gray-200">{{ item.type }}</td>
+ <td class="p-2">{{ item.isOld }}</td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+ </div>
+
+ <!-- Page 2: View -->
+ <div v-else class="flex-1 flex flex-col overflow-hidden">
+ <!-- Toolbar (Panel 3) -->
+ <div class="h-[49px] flex items-center px-4 space-x-4 bg-gray-50 border-b border-gray-300">
+ <button class="w-[75px] h-[25px] border border-gray-400 bg-gray-200 hover:bg-gray-300" @click="ImportBtClick">
+ 引用
+ </button>
+ <button class="w-[75px] h-[25px] border border-gray-400 bg-gray-200 hover:bg-gray-300" @click="ExitBtClick">
+ 離開
+ </button>
+ <div class="flex-1"></div>
+ <span class="text-xs text-gray-500">案件編號: {{ oldCases[selectedCaseIndex].id }}</span>
+ </div>
+
+ <div class="flex-1 flex overflow-hidden">
+ <!-- Left Sidebar: Document Groups (Panel 4) -->
+ <div class="w-[249px] flex-none border-r border-gray-400 p-1 flex flex-col bg-gray-50">
+ <fieldset class="flex-1 border border-gray-400 p-0 flex flex-col">
+ <legend class="px-1 ml-2 text-sm">案件編號</legend>
+ <div class="flex-1 overflow-y-auto bg-white m-1 border border-gray-300">
+ <div v-for="(group, index) in docGroups"
+ :key="index"
+ :class="['flex items-center px-2 py-1 space-x-2 cursor-pointer hover:bg-blue-50', selectedGroupIndex === index ? 'bg-blue-100' : '']"
+ @click="CheckListBox1Click(index)">
+ <input type="checkbox" v-model="group.checked" @click.stop />
+ <span class="text-sm truncate">{{ group.text }}</span>
+ </div>
+ </div>
+ </fieldset>
+ </div>
+
+ <!-- Main Preview Area (Panel 5) -->
+ <div class="flex-1 flex overflow-hidden">
+ <!-- Thumbnails (Panel 6) -->
+ <div class="w-[183px] flex-none border-r border-gray-400 overflow-y-auto bg-gray-300 p-1 space-y-2">
+ <div v-for="(page, pIdx) in (selectedGroupIndex !== -1 ? docGroups[selectedGroupIndex].pages : [])"
+ :key="pIdx"
+ class="w-[150px] mx-auto border-2 border-transparent hover:border-blue-500 cursor-pointer bg-white shadow-sm"
+ @click="setThumbnailAsPreview(page)">
+ <img :src="page" class="w-full" />
+ <div class="text-[10px] text-center bg-gray-100 py-1">第 {{ pIdx + 1 }} 頁</div>
+ </div>
+ </div>
+ <!-- Large Preview (Panel 7) -->
+ <div class="flex-1 bg-gray-800 flex items-center justify-center p-2 overflow-auto">
+ <img v-if="previewImage" :src="previewImage" class="max-w-none shadow-2xl border-4 border-white" />
+ <div v-else class="text-white text-lg opacity-30">請選擇影像進行預覽</div>
+ </div>
+ </div>
+ </div>
+ </div>
+
+ <!-- Visual Reference Overlay -->
+ <div class="old-case-layout opacity-20 pointer-events-none absolute left-0 top-0">
+ <img src="assets/OldCaseInfo.png" class="w-[740px] h-[554px]" />
+ </div>
+ </div>
+</template>
+
+<script lang="ts">
+import { defineComponent } from 'vue';
+import { useOldCaseInfoLogic } from './OldCaseInfo.ts';
+
+export default defineComponent({
+ name: 'OldCaseInfoForm',
+ setup() {
+ const logic = useOldCaseInfoLogic();
+ return { ...logic };
+ }
+});
+</script>
+
+<style scoped>
+.old-case-info-form {
+ user-select: none;
+}
+.old-case-layout {
+ z-index: 1000;
+}
+</style>
diff --git a/uiOutput/assets/DocList.png b/uiOutput/assets/DocList.png
new file mode 100644
index 0000000..f777c76
--- /dev/null
+++ b/uiOutput/assets/DocList.png
Binary files differ
diff --git a/uiOutput/assets/DocPrt.png b/uiOutput/assets/DocPrt.png
new file mode 100644
index 0000000..cdfa586
--- /dev/null
+++ b/uiOutput/assets/DocPrt.png
Binary files differ
diff --git a/uiOutput/assets/ErrList.png b/uiOutput/assets/ErrList.png
new file mode 100644
index 0000000..7b128b6
--- /dev/null
+++ b/uiOutput/assets/ErrList.png
Binary files differ
diff --git a/uiOutput/assets/OldCaseInfo.png b/uiOutput/assets/OldCaseInfo.png
new file mode 100644
index 0000000..2d58277
--- /dev/null
+++ b/uiOutput/assets/OldCaseInfo.png
Binary files differ
diff --git a/uiOutput/index.html b/uiOutput/index.html
index d9b112d..0c61824 100644
--- a/uiOutput/index.html
+++ b/uiOutput/index.html
@@ -278,6 +278,20 @@
return {
availableComponents: [
{
+ id: 'DocList',
+ name: 'DocList.vue',
+ vuePath: './DocList/DocList.vue',
+ jsPath: './DocList/DocList.ts',
+ windowTitle: '歷史類畫面'
+ },
+ {
+ id: 'DocPrt',
+ name: 'DocPrt.vue',
+ vuePath: './DocPrt/DocPrt.vue',
+ jsPath: './DocPrt/DocPrt.ts',
+ windowTitle: '列印畫面'
+ },
+ {
id: 'ErrList',
name: 'ErrList.vue',
vuePath: './ErrList/ErrList.vue',
@@ -285,6 +299,13 @@
windowTitle: '檢核失敗原因畫面'
},
{
+ id: 'OldCaseInfo',
+ name: 'OldCaseInfo.vue',
+ vuePath: './OldCaseInfo/OldCaseInfo.vue',
+ jsPath: './OldCaseInfo/OldCaseInfo.ts',
+ windowTitle: '舊案引用畫面'
+ },
+ {
id: 'PatchFom',
name: 'PatchFom.vue',
vuePath: './PatchFom/PatchFom.vue',
--
Gitblit v1.8.0