Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
E
electron-printer
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
1
Merge Requests
1
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
zhuzhequan
electron-printer
Commits
0508c0d0
Commit
0508c0d0
authored
Jul 15, 2026
by
linjinhong
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fix:添加自动排版本地下载标记
parent
530e2bc6
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
115 additions
and
55 deletions
+115
-55
src/background.js
+53
-24
src/config/index.js
+1
-1
src/server/index.js
+2
-2
src/server/utils/store.js
+8
-3
src/utils/download-core.js
+23
-2
src/utils/download-queue.js
+5
-3
src/views/dtf-list/components/head.vue
+5
-4
src/views/dtf-list/index.vue
+17
-11
src/views/dtf-setting/index.vue
+1
-5
No files found.
src/background.js
View file @
0508c0d0
...
@@ -193,27 +193,42 @@ async function createWindow() {
...
@@ -193,27 +193,42 @@ async function createWindow() {
}
}
try
{
try
{
let
configObj
=
JSON
.
parse
(
data
);
let
configObj
=
JSON
.
parse
(
data
);
configObj
.
apiApiHost
=
`https://
${
newDomain
}
/api`
;
const
isTest
=
process
.
env
.
VUE_APP_ENV
===
"test"
;
configObj
.
fileApiUrl
=
`https://
${
newDomain
}
/upload/factory`
;
console
.
log
(
"isTest"
,
isTest
);
configObj
.
configPath
=
configPath
;
console
.
log
(
"configObj"
,
configObj
);
const
newData
=
JSON
.
stringify
(
configObj
);
// 使用2个空格缩进
const
config
=
isTest
?
configObj
.
test
:
configObj
.
prod
;
config
.
apiApiHost
=
isTest
?
`http://
${
newDomain
}
/api`
:
`https://
${
newDomain
}
/api`
;
config
.
fileApiUrl
=
isTest
?
`http://
${
newDomain
}
/upload/factory`
:
`https://
${
newDomain
}
/upload/factory`
;
config
.
configPath
=
configPath
;
// const newData = JSON.stringify(config); // 使用2个空格缩进
// console.log("修改后的数据:", newData);
// console.log("修改后的数据:", newData);
configObj
[
isTest
?
"test"
:
"prod"
]
=
config
;
const
newConfigObj
=
JSON
.
stringify
(
configObj
);
// 4. 写回文件
// 4. 写回文件
fs
.
writeFile
(
configPath
,
newData
,
"utf-8"
,
writeErr
=>
{
fs
.
writeFile
(
if
(
writeErr
)
{
configPath
,
console
.
error
(
"写入配置文件失败:"
,
writeErr
);
newConfigObj
,
this
.
$message
.
error
(
"utf-8"
,
`写入配置文件失败:
${
writeErr
.
message
}
`
writeErr
=>
{
);
if
(
writeErr
)
{
return
;
console
.
error
(
"写入配置文件失败:"
,
writeErr
);
this
.
$message
.
error
(
`写入配置文件失败:
${
writeErr
.
message
}
`
);
return
;
}
console
.
log
(
"配置文件更新成功"
,
config
);
setApi
(
config
);
}
}
);
console
.
log
(
"配置文件更新成功"
,
configObj
);
setApi
(
configObj
);
});
}
catch
(
parseError
)
{
}
catch
(
parseError
)
{
console
.
error
(
"解析 JSON 失败:"
,
parseError
);
console
.
error
(
"解析 JSON 失败:"
,
parseError
);
this
.
$message
.
error
(
this
.
$message
.
error
(
...
@@ -494,19 +509,17 @@ async function createWindow() {
...
@@ -494,19 +509,17 @@ async function createWindow() {
});
});
ipcMain
.
on
(
"get-install-path"
,
event
=>
{
ipcMain
.
on
(
"get-install-path"
,
event
=>
{
// 固定桌面路径,不再区分开发环境
const
desktopPath
=
app
.
getPath
(
"desktop"
);
const
desktopPath
=
app
.
getPath
(
"desktop"
);
const
dtfDir
=
path
.
join
(
desktopPath
,
"JomallProductionAssistant-DTF"
);
const
dtfDir
=
path
.
join
(
desktopPath
,
"JomallProductionAssistant-DTF"
);
let
resPath
=
desktopPath
;
try
{
try
{
// 递归创建文件夹,不存在自动生成,存在不报错
fs
.
mkdirSync
(
dtfDir
,
{
recursive
:
true
});
fs
.
mkdirSync
(
dtfDir
,
{
recursive
:
true
});
event
.
returnValue
=
dtfDir
;
resPath
=
dtfDir
;
}
catch
(
err
)
{
}
catch
(
err
)
{
console
.
error
(
"创建 DTF 桌面文件夹失败:"
,
err
);
console
.
error
(
"创建文件夹失败"
,
err
);
// 兜底返回桌面,防止空值
event
.
returnValue
=
desktopPath
;
}
}
event
.
reply
(
"get-install-path-res"
,
resPath
);
});
});
// ========== 新增3:窗口关闭时停止定时任务 ==========
// ========== 新增3:窗口关闭时停止定时任务 ==========
...
@@ -515,6 +528,22 @@ async function createWindow() {
...
@@ -515,6 +528,22 @@ async function createWindow() {
});
});
}
}
const
gotTheLock
=
app
.
requestSingleInstanceLock
();
if
(
!
gotTheLock
)
{
app
.
quit
();
}
else
{
app
.
on
(
"second-instance"
,
()
=>
{
// 第二次双击时,唤起已有的窗口
const
allWindows
=
BrowserWindow
.
getAllWindows
();
const
mainWin
=
allWindows
[
0
];
if
(
mainWin
)
{
if
(
mainWin
.
isMinimized
())
mainWin
.
restore
();
mainWin
.
show
();
mainWin
.
focus
();
}
});
}
app
.
on
(
"activate"
,
async
()
=>
{
app
.
on
(
"activate"
,
async
()
=>
{
if
(
win
===
null
)
{
if
(
win
===
null
)
{
await
createWindow
();
await
createWindow
();
...
...
src/config/index.js
View file @
0508c0d0
...
@@ -52,7 +52,7 @@ export const pathMap = {
...
@@ -52,7 +52,7 @@ export const pathMap = {
listOperationByBatch
:
"factory/podOrderBatchDownload/listOperationByBatch"
,
listOperationByBatch
:
"factory/podOrderBatchDownload/listOperationByBatch"
,
//排版
//排版
replenishmentComposingDesignImages
:
replenishmentComposingDesignImages
:
"factory/podOrderOperation/replenishmentComposingDesignImages"
,
"factory/podOrderOperation/
softwareProduction-
replenishmentComposingDesignImages"
,
//获取单个批次号信息
//获取单个批次号信息
podOrderBatchDownload
:
"factory/podOrderBatchDownload/get"
,
podOrderBatchDownload
:
"factory/podOrderBatchDownload/get"
,
//操作日志
//操作日志
...
...
src/server/index.js
View file @
0508c0d0
...
@@ -13,7 +13,7 @@ export const createServer = () => {
...
@@ -13,7 +13,7 @@ export const createServer = () => {
webApp
.
use
(
logMiddleWare
());
webApp
.
use
(
logMiddleWare
());
webApp
.
use
(
express
.
json
());
webApp
.
use
(
express
.
json
());
webApp
.
use
(
express
.
urlencoded
({
extended
:
false
}));
webApp
.
use
(
express
.
urlencoded
({
extended
:
false
}));
webApp
.
use
(
"/"
,
router
);
webApp
.
use
(
"/"
,
router
);
// catch 404
// catch 404
webApp
.
use
((
req
,
res
)
=>
{
webApp
.
use
((
req
,
res
)
=>
{
res
.
status
(
404
).
send
(
"Sorry! 404 Error."
);
res
.
status
(
404
).
send
(
"Sorry! 404 Error."
);
...
@@ -29,7 +29,7 @@ export const createServer = () => {
...
@@ -29,7 +29,7 @@ export const createServer = () => {
res
.
status
(
err
.
status
||
500
);
res
.
status
(
err
.
status
||
500
);
res
.
json
({
res
.
json
({
message
:
err
.
message
,
message
:
err
.
message
,
error
:
err
,
error
:
err
});
});
});
});
...
...
src/server/utils/store.js
View file @
0508c0d0
...
@@ -7,7 +7,6 @@ const MAX_LIMIT_RECORD_KEY = "originalIdMaxLimitRecord"; // 永久上限标记
...
@@ -7,7 +7,6 @@ const MAX_LIMIT_RECORD_KEY = "originalIdMaxLimitRecord"; // 永久上限标记
// ===== 2. 核心内存缓存 =====
// ===== 2. 核心内存缓存 =====
let
orderCacheMap
=
new
Map
();
// key格式:前缀-数字(如AAAF...-1),value:原始订单对象
let
orderCacheMap
=
new
Map
();
// key格式:前缀-数字(如AAAF...-1),value:原始订单对象
// ===== 3. 永久上限标记方法(保留你的原有核心逻辑,无改动) =====
// ===== 3. 永久上限标记方法(保留你的原有核心逻辑,无改动) =====
/**
/**
* 获取已达永久上限的原始newId Map
* 获取已达永久上限的原始newId Map
...
@@ -197,6 +196,7 @@ module.exports = {
...
@@ -197,6 +196,7 @@ module.exports = {
store
.
set
(
"desktoBoard"
,
version
);
store
.
set
(
"desktoBoard"
,
version
);
},
},
getBoard
:
()
=>
store
.
get
(
"desktoBoard"
)
||
3
,
getBoard
:
()
=>
store
.
get
(
"desktoBoard"
)
||
3
,
setIsOver
:
value
=>
{
setIsOver
:
value
=>
{
store
.
set
(
"isOver"
,
value
);
store
.
set
(
"isOver"
,
value
);
},
},
...
@@ -213,10 +213,9 @@ module.exports = {
...
@@ -213,10 +213,9 @@ module.exports = {
store
.
set
(
"productType"
,
value
);
store
.
set
(
"productType"
,
value
);
},
},
getProductType
:
()
=>
store
.
get
(
"productType"
)
||
"DTG"
,
getProductType
:
()
=>
store
.
get
(
"productType"
)
||
"DTG"
,
//DTF生产设置
//DTF生产设置
setDTFSetting
:
value
=>
{
setDTFSetting
:
value
=>
{
console
.
log
(
"DTFSetting"
,
value
);
store
.
set
(
"DTFSetting"
,
value
);
store
.
set
(
"DTFSetting"
,
value
);
},
},
getDTFSetting
:
()
=>
getDTFSetting
:
()
=>
...
@@ -232,6 +231,12 @@ module.exports = {
...
@@ -232,6 +231,12 @@ module.exports = {
downloadDir
:
""
downloadDir
:
""
},
},
//本地储存 文件批次号
setBatchNumbers
:
value
=>
{
store
.
set
(
"batchNumbers"
,
value
);
},
getBatchNumbers
:
()
=>
store
.
get
(
"batchNumbers"
)
||
[],
setLocation
:
(
version
,
locationKey
)
=>
{
setLocation
:
(
version
,
locationKey
)
=>
{
if
(
!
locationKey
)
return
;
if
(
!
locationKey
)
return
;
store
.
set
(
locationKey
,
version
);
store
.
set
(
locationKey
,
version
);
...
...
src/utils/download-core.js
View file @
0508c0d0
...
@@ -3,7 +3,7 @@ const fs = require("fs");
...
@@ -3,7 +3,7 @@ const fs = require("fs");
const
http
=
require
(
"http"
);
const
http
=
require
(
"http"
);
const
https
=
require
(
"https"
);
const
https
=
require
(
"https"
);
const
url
=
require
(
"url"
);
const
url
=
require
(
"url"
);
const
{
setBatchNumbers
,
getBatchNumbers
}
=
require
(
"@/server/utils/store"
);
/* ===================== 基础工具函数 ===================== */
/* ===================== 基础工具函数 ===================== */
/**
/**
...
@@ -206,12 +206,28 @@ async function batchDownloadByList(urlList, targetDir, options = {}) {
...
@@ -206,12 +206,28 @@ async function batchDownloadByList(urlList, targetDir, options = {}) {
retryTimes
=
0
,
retryTimes
=
0
,
baseUrl
=
""
,
baseUrl
=
""
,
skipExists
=
true
,
skipExists
=
true
,
fileNameFormatter
=
null
// 新增:自定义文件名回调,
fileNameFormatter
=
null
,
// 新增:自定义文件名回调,
isCheck
=
false
,
batchId
=
""
// 新增:批次唯一标识,isCheck 模式下使用
}
=
options
;
}
=
options
;
const
success
=
[];
const
success
=
[];
const
failed
=
[];
const
failed
=
[];
if
(
isCheck
)
{
// 批次已处理过则直接跳过整个批次,不执行后续任何下载逻辑
const
batchNumbers
=
getBatchNumbers
()
||
[];
if
(
batchNumbers
.
includes
(
batchId
))
{
console
.
log
(
`该批次已执行过,直接跳过 | 批次号:
${
batchId
}
`
);
return
{
success
:
[],
failed
:
[],
skipped
:
true
,
batchId
};
}
}
// 1. 创建目标目录
// 1. 创建目标目录
try
{
try
{
await
ensureDir
(
targetDir
);
await
ensureDir
(
targetDir
);
...
@@ -260,6 +276,11 @@ async function batchDownloadByList(urlList, targetDir, options = {}) {
...
@@ -260,6 +276,11 @@ async function batchDownloadByList(urlList, targetDir, options = {}) {
})
})
);
);
if
(
isCheck
&&
batchId
)
{
setBatchNumbers
([...
getBatchNumbers
(),
batchId
]);
console
.
log
(
`批量下载 批次标记已标记批次为已处理 | 批次号:
${
batchId
}
`
);
}
await
Promise
.
all
(
tasks
);
await
Promise
.
all
(
tasks
);
console
.
log
(
`批量下载完成,成功:
${
success
.
length
}
,失败:
${
failed
.
length
}
`
);
console
.
log
(
`批量下载完成,成功:
${
success
.
length
}
,失败:
${
failed
.
length
}
`
);
return
{
success
,
failed
};
return
{
success
,
failed
};
...
...
src/utils/download-queue.js
View file @
0508c0d0
...
@@ -30,7 +30,7 @@ const { pLimit } = require("./download-core");
...
@@ -30,7 +30,7 @@ const { pLimit } = require("./download-core");
/* ========== 业务逻辑 ========== */
/* ========== 业务逻辑 ========== */
async
function
processBatchItem
(
item
)
{
async
function
processBatchItem
(
item
)
{
const
{
batchArrangeNum
,
u
rl
:
urlStr
}
=
item
;
const
{
batchArrangeNum
,
spU
rl
:
urlStr
}
=
item
;
if
(
!
batchArrangeNum
)
{
if
(
!
batchArrangeNum
)
{
logDownloadError
(
logDownloadError
(
...
@@ -70,7 +70,9 @@ async function processBatchItem(item) {
...
@@ -70,7 +70,9 @@ async function processBatchItem(item) {
await
batchDownloadByStr
(
urlStr
,
saveDir
,
{
await
batchDownloadByStr
(
urlStr
,
saveDir
,
{
concurrency
:
taskState
.
maxImageConcurrency
,
concurrency
:
taskState
.
maxImageConcurrency
,
timeout
:
30000
,
timeout
:
30000
,
baseUrl
:
getHostApi
().
fileApiUrl
baseUrl
:
getHostApi
().
fileApiUrl
,
isCheck
:
true
,
batchId
:
batchArrangeNum
});
});
}
}
...
@@ -105,7 +107,7 @@ async function runTask() {
...
@@ -105,7 +107,7 @@ async function runTask() {
console
.
log
(
"当前页无数据,本轮任务结束"
);
console
.
log
(
"当前页无数据,本轮任务结束"
);
return
;
return
;
}
}
console
.
log
(
layoutRes
);
// 多批次并行下载
// 多批次并行下载
const
batchLimit
=
pLimit
(
taskState
.
maxBatchConcurrency
);
const
batchLimit
=
pLimit
(
taskState
.
maxBatchConcurrency
);
const
batchPromises
=
list
.
map
(
item
=>
const
batchPromises
=
list
.
map
(
item
=>
...
...
src/views/dtf-list/components/head.vue
View file @
0508c0d0
...
@@ -90,12 +90,13 @@ export default {
...
@@ -90,12 +90,13 @@ export default {
<el-option
label=
"部分成功"
:value=
"5"
>
</el-option>
<el-option
label=
"部分成功"
:value=
"5"
>
</el-option>
</el-select>
</el-select>
</el-form-item>
</el-form-item>
<el-form-item
label=
"
创建时间
"
>
<el-form-item
label=
"
时间范围
"
>
<el-date-picker
<el-date-picker
style=
"width: 380px;"
clearable
clearable
v-model=
"searchForm.
startTim
e"
v-model=
"searchForm.
timeRang
e"
type=
"datetime"
type=
"datetime
range
"
placeholder=
"选择
创建
时间"
placeholder=
"选择时间"
format=
"yyyy-MM-dd HH:mm:ss"
format=
"yyyy-MM-dd HH:mm:ss"
value-format=
"yyyy-MM-dd HH:mm:ss"
value-format=
"yyyy-MM-dd HH:mm:ss"
>
>
...
...
src/views/dtf-list/index.vue
View file @
0508c0d0
...
@@ -140,12 +140,12 @@ export default {
...
@@ -140,12 +140,12 @@ export default {
},
},
methods
:
{
methods
:
{
async
loadLocalConfig
()
{
async
loadLocalConfig
()
{
console
.
log
(
getDTFSetting
());
setDTFSetting
({
downloadDir
:
""
});
try
{
try
{
if
(
!
getDTFSetting
().
downloadDir
)
{
if
(
!
getDTFSetting
().
downloadDir
)
{
const
path
=
ipcRenderer
.
sendSync
(
"get-install-path"
);
ipcRenderer
.
send
(
"get-install-path"
);
setDTFSetting
({
downloadDir
:
path
});
ipcRenderer
.
once
(
"get-install-path-res"
,
(
_
,
defaultPath
)
=>
{
setDTFSetting
({
downloadDir
:
defaultPath
});
});
}
}
}
catch
(
error
)
{
}
catch
(
error
)
{
console
.
log
(
error
);
console
.
log
(
error
);
...
@@ -274,7 +274,7 @@ export default {
...
@@ -274,7 +274,7 @@ export default {
);
);
const
res
=
await
submitTypesettingDownload
({
const
res
=
await
submitTypesettingDownload
({
urlStr
:
data
.
data
.
u
rl
,
urlStr
:
data
.
data
.
spU
rl
,
targetPath
:
path
.
join
(
targetPath
:
path
.
join
(
getDTFSetting
().
downloadDir
,
getDTFSetting
().
downloadDir
,
`批次号:
${
this
.
templateBatchArrangeNum
}
`
,
`批次号:
${
this
.
templateBatchArrangeNum
}
`
,
...
@@ -394,6 +394,17 @@ export default {
...
@@ -394,6 +394,17 @@ export default {
}
catch
(
err
)
{
}
catch
(
err
)
{
console
.
error
(
"同步下载状态失败"
,
err
);
console
.
error
(
"同步下载状态失败"
,
err
);
}
}
},
searchFn
(
value
)
{
this
.
searchForm
=
value
;
if
(
value
.
timeRange
?.
length
)
{
this
.
searchForm
.
startTime
=
value
.
timeRange
[
0
];
this
.
searchForm
.
endTime
=
value
.
timeRange
[
1
];
}
else
{
this
.
searchForm
.
startTime
=
""
;
this
.
searchForm
.
endTime
=
""
;
}
this
.
fetchBatchList
(
this
.
searchForm
);
}
}
}
}
};
};
...
@@ -404,12 +415,7 @@ export default {
...
@@ -404,12 +415,7 @@ export default {
<DTFhead
<DTFhead
:user=
"user"
:user=
"user"
:factoryType=
"factoryType"
:factoryType=
"factoryType"
@
search=
"
@
search=
"searchFn"
value =>
{
searchForm = value;
this.fetchBatchList(searchForm);
}
"
></DTFhead>
></DTFhead>
<BaseTable
<BaseTable
v-if=
"tableList.length"
v-if=
"tableList.length"
...
...
src/views/dtf-setting/index.vue
View file @
0508c0d0
...
@@ -120,11 +120,7 @@ export default {
...
@@ -120,11 +120,7 @@ export default {
try
{
try
{
const
{
data
}
=
await
this
.
$api
.
post
(
pathMap
[
"productionConfig"
]);
const
{
data
}
=
await
this
.
$api
.
post
(
pathMap
[
"productionConfig"
]);
this
.
form
=
{
...
getDTFSetting
(),
...
data
};
this
.
form
=
{
...
getDTFSetting
(),
...
data
};
console
.
log
(
94
,
this
.
form
);
// if (!this.form.downloadDir) {
// const path = ipcRenderer.sendSync("get-install-path");
// this.form.downloadDir = path;
// }
setDTFSetting
({
...
this
.
form
});
setDTFSetting
({
...
this
.
form
});
this
.
$nextTick
(()
=>
(
this
.
isInitLoad
=
false
));
this
.
$nextTick
(()
=>
(
this
.
isInitLoad
=
false
));
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment