Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
F
factory_front
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
qinjianhui
factory_front
Commits
1e825855
Commit
1e825855
authored
May 08, 2026
by
qinjianhui
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fix: 修复 Lodop 打印 PDF 到虚拟打印机时输出空白的问题
parent
51a1fdda
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
258 additions
and
184 deletions
+258
-184
src/components/print.ts
+131
-9
src/utils/lodopPrinter.ts
+0
-166
src/views/order/factoryOrderNew/index.vue
+127
-9
No files found.
src/components/print.ts
View file @
1e825855
import
useLodop
from
'@/utils/hooks/useLodop.t
s'
import
{
ElMessage
}
from
'element-plu
s'
import
{
printWithLodop
}
from
'@/utils/lodopPrinter
'
import
useLodop
,
{
LODOPObject
}
from
'@/utils/hooks/useLodop.ts
'
const
{
getCLodop
}
=
useLodop
()
const
{
getCLodop
}
=
useLodop
()
const
lodopCall
=
async
(
fn
:
(
lodop
:
LODOPObject
)
=>
string
)
=>
{
if
(
!
window
.
_lodop
)
{
window
.
_lodop
=
getCLodop
(
null
,
null
)
if
(
window
.
_lodop
)
{
window
.
_lodop
.
On_Return_Remain
=
true
window
.
_lodop
.
SET_PRINT_MODE
(
'CATCH_PRINT_STATUS'
,
true
)
window
.
_lodopCallback
=
{}
window
.
_lodop
.
On_Return
=
function
(
id
,
value
)
{
const
cb
=
window
.
_lodopCallback
[
id
]
if
(
!
cb
)
return
delete
window
.
_lodopCallback
[
id
]
cb
(
value
)
}
}
}
export
const
print
=
async
(
url
:
string
,
printDevice
:
string
)
=>
{
return
new
Promise
((
resolve
)
=>
{
await
printWithLodop
({
let
id
getCLodop
:
()
=>
getCLodop
(
null
,
null
),
if
(
window
.
_lodop
)
{
printer
:
printDevice
,
id
=
fn
(
window
.
_lodop
)
data
:
{
filePath
:
url
},
}
callback
:
(
_status
:
boolean
)
=>
{},
window
.
_lodopCallback
[
id
||
0
]
=
resolve
baseUrl
:
''
,
})
})
}
}
function
downloadPDF
(
url
:
string
)
{
if
(
!
/^https
?
:/i
.
test
(
url
))
return
url
let
xhr
,
arrybuffer
=
false
,
dataArray
=
null
if
(
window
.
XMLHttpRequest
)
{
xhr
=
new
XMLHttpRequest
()
}
else
{
xhr
=
new
window
.
ActiveXObject
(
'MSXML2.XMLHTTP'
)
}
xhr
.
open
(
'GET'
,
url
,
false
)
//同步方式
if
(
xhr
.
overrideMimeType
)
try
{
xhr
.
responseType
=
'arraybuffer'
arrybuffer
=
true
}
catch
(
err
)
{
xhr
.
overrideMimeType
(
'text/plain; charset=x-user-defined'
)
}
xhr
.
send
(
null
)
const
data
=
xhr
.
response
||
xhr
.
responseBody
if
(
typeof
Uint8Array
!==
'undefined'
)
{
if
(
arrybuffer
)
{
dataArray
=
new
Uint8Array
(
data
)
}
else
{
dataArray
=
new
Uint8Array
(
data
.
length
)
for
(
let
i
=
0
;
i
<
dataArray
.
length
;
i
++
)
{
dataArray
[
i
]
=
data
.
charCodeAt
(
i
)
}
}
}
else
{
dataArray
=
window
.
VBS_BinaryToArray
(
data
).
toArray
()
//兼容IE低版本
}
const
digits
=
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='
let
strData
=
''
for
(
let
i
=
0
,
ii
=
dataArray
.
length
;
i
<
ii
;
i
+=
3
)
{
if
(
isNaN
(
dataArray
[
i
]))
break
const
b1
=
dataArray
[
i
]
&
0xff
,
b2
=
dataArray
[
i
+
1
]
&
0xff
,
b3
=
dataArray
[
i
+
2
]
&
0xff
const
d1
=
b1
>>
2
,
d2
=
((
b1
&
3
)
<<
4
)
|
(
b2
>>
4
)
const
d3
=
i
+
1
<
ii
?
((
b2
&
0xf
)
<<
2
)
|
(
b3
>>
6
)
:
64
const
d4
=
i
+
2
<
ii
?
b3
&
0x3f
:
64
strData
+=
digits
.
substring
(
d1
,
d1
+
1
)
+
digits
.
substring
(
d2
,
d2
+
1
)
+
digits
.
substring
(
d3
,
d3
+
1
)
+
digits
.
substring
(
d4
,
d4
+
1
)
}
return
strData
}
export
const
print
=
async
(
url
:
string
,
printDevice
:
string
)
=>
{
const
lodop
=
getCLodop
(
null
,
null
)
//调用getLodop获取LODOP对象
if
(
!
lodop
)
return
lodop
.
PRINT_INIT
(
'打印内容'
)
// SET_PRINTER_INDEX 指定打印设备
const
setPrintRes
=
lodop
.
SET_PRINTER_INDEX
(
printDevice
)
if
(
!
setPrintRes
)
{
ElMessage
.
warning
(
'设置面单打印机出错'
)
return
}
lodop
.
ADD_PRINT_PDF
(
0
,
0
,
'100%'
,
'100%'
,
downloadPDF
(
url
))
console
.
log
(
lodop
)
if
(
lodop
.
CVERSION
)
{
const
startTime
=
Date
.
now
()
const
jobCode
=
await
lodopCall
((
lodop
:
LODOPObject
)
=>
{
lodop
.
SET_PRINT_MODE
(
'CATCH_PRINT_STATUS'
,
true
)
return
lodop
.
PRINT
()
})
console
.
log
(
'[LODOP] job '
+
jobCode
)
// eslint-disable-next-line no-constant-condition
while
(
true
)
{
const
ok
=
await
lodopCall
((
lodop
:
LODOPObject
)
=>
lodop
.
GET_VALUE
(
'PRINT_STATUS_OK'
,
jobCode
),
)
if
(
ok
==
1
)
{
// 打印状态:成功
return
}
// 如果打印状态表示未成功或者返回了空,继续获取任务是否存在
const
exist
=
await
lodopCall
((
lodop
:
LODOPObject
)
=>
lodop
.
GET_VALUE
(
'PRINT_STATUS_EXIST'
,
jobCode
),
)
console
.
log
(
'[LODOP] PRINT_STATUS OK,EXIST'
,
jobCode
,
ok
,
exist
,
`(
${
Date
.
now
()
-
startTime
}
ms)`
,
)
if
(
exist
==
0
)
{
// 任务不存在了
return
}
await
new
Promise
((
r
)
=>
setTimeout
(
r
,
500
))
if
(
Date
.
now
()
-
startTime
>=
30000
)
{
ElMessage
.
error
(
'打印超时(30秒)'
)
return
}
}
}
else
{
lodop
.
PRINT
()
}
}
src/utils/lodopPrinter.ts
deleted
100644 → 0
View file @
51a1fdda
import
{
ElMessage
}
from
'element-plus'
import
type
{
LODOPObject
}
from
'@/utils/hooks/useLodop'
type
LodopGetter
=
()
=>
LODOPObject
|
null
export
function
downloadPDF
(
url
:
string
):
string
{
if
(
!
/^https
?
:/i
.
test
(
url
))
return
url
const
xhr
=
new
XMLHttpRequest
()
let
arrayBuffer
=
false
xhr
.
open
(
'GET'
,
url
,
false
)
if
(
xhr
.
overrideMimeType
)
{
try
{
xhr
.
responseType
=
'arraybuffer'
arrayBuffer
=
true
}
catch
{
xhr
.
overrideMimeType
(
'text/plain; charset=x-user-defined'
)
}
}
xhr
.
send
(
null
)
const
data
=
(
xhr
.
response
||
(
xhr
as
unknown
as
{
responseBody
?:
unknown
}).
responseBody
)
as
|
ArrayBuffer
|
string
let
dataArray
:
Uint8Array
if
(
arrayBuffer
)
{
dataArray
=
new
Uint8Array
(
data
as
ArrayBuffer
)
}
else
{
const
text
=
data
as
string
dataArray
=
new
Uint8Array
(
text
.
length
)
for
(
let
i
=
0
;
i
<
dataArray
.
length
;
i
++
)
dataArray
[
i
]
=
text
.
charCodeAt
(
i
)
}
const
digits
=
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='
let
strData
=
''
for
(
let
i
=
0
,
ii
=
dataArray
.
length
;
i
<
ii
;
i
+=
3
)
{
const
b1
=
dataArray
[
i
]
&
0xff
const
b2
=
dataArray
[
i
+
1
]
&
0xff
const
b3
=
dataArray
[
i
+
2
]
&
0xff
const
d1
=
b1
>>
2
const
d2
=
((
b1
&
3
)
<<
4
)
|
(
b2
>>
4
)
const
d3
=
i
+
1
<
ii
?
((
b2
&
0xf
)
<<
2
)
|
(
b3
>>
6
)
:
64
const
d4
=
i
+
2
<
ii
?
b3
&
0x3f
:
64
strData
+=
digits
.
charAt
(
d1
)
+
digits
.
charAt
(
d2
)
+
digits
.
charAt
(
d3
)
+
digits
.
charAt
(
d4
)
}
return
'data:application/pdf;base64,'
+
strData
}
export
function
createLodopCaller
(
getCLodop
:
LodopGetter
)
{
let
lodop
:
LODOPObject
|
null
=
null
let
lodopCallback
:
{
[
key
:
string
]:
(
value
:
string
)
=>
void
}
=
{}
return
(
fn
:
(
lodop
:
LODOPObject
)
=>
string
)
=>
{
if
(
!
lodop
)
{
lodop
=
getCLodop
()
if
(
!
lodop
)
return
Promise
.
resolve
(
''
)
lodop
.
On_Return_Remain
=
true
lodop
.
SET_PRINT_MODE
(
'CATCH_PRINT_STATUS'
,
true
)
lodopCallback
=
{}
lodop
.
On_Return
=
(
id
,
value
)
=>
{
const
cb
=
lodopCallback
[
id
]
if
(
!
cb
)
return
delete
lodopCallback
[
id
]
cb
(
value
)
}
}
return
new
Promise
<
string
>
((
resolve
)
=>
{
if
(
!
lodop
)
{
resolve
(
''
)
return
}
const
id
=
fn
(
lodop
)
lodopCallback
[
id
]
=
resolve
})
}
}
interface
PrintData
{
filePath
?:
string
fileData
?:
string
}
interface
PrintWithLodopOptions
{
getCLodop
:
LodopGetter
printer
:
string
data
:
PrintData
callback
?:
(
success
:
boolean
)
=>
void
timeout
?:
number
baseUrl
?:
string
}
export
async
function
printWithLodop
(
options
:
PrintWithLodopOptions
)
{
const
{
getCLodop
,
printer
,
data
,
callback
,
timeout
=
30000
,
baseUrl
=
''
,
}
=
options
const
lodop
=
getCLodop
()
if
(
!
lodop
)
return
const
lodopCall
=
createLodopCaller
(
getCLodop
)
lodop
.
PRINT_INIT
(
'打印内容'
)
const
printerIndex
=
lodop
.
SET_PRINTER_INDEX
(
printer
)
if
(
!
printerIndex
)
{
ElMessage
.
error
(
'打印机设置失败'
)
callback
?.(
false
)
return
}
if
(
data
.
filePath
)
{
const
strURL
=
/^https
?
:/i
.
test
(
data
.
filePath
)
?
data
.
filePath
:
baseUrl
+
data
.
filePath
lodop
.
ADD_PRINT_PDF
(
0
,
0
,
'100%'
,
'100%'
,
/^https
?
:/i
.
test
(
strURL
)
?
downloadPDF
(
strURL
)
:
strURL
,
)
}
else
{
lodop
.
SEND_PRINT_RAWDATA
(
data
.
fileData
||
''
)
}
if
(
lodop
.
CVERSION
)
{
const
startTime
=
Date
.
now
()
const
jobCode
=
await
lodopCall
((
instance
)
=>
{
instance
.
SET_PRINT_MODE
(
'CATCH_PRINT_STATUS'
,
true
)
return
instance
.
PRINT
()
})
let
pending
=
true
while
(
pending
)
{
const
ok
=
await
lodopCall
((
instance
)
=>
instance
.
GET_VALUE
(
'PRINT_STATUS_OK'
,
jobCode
),
)
if
(
ok
==
'1'
||
ok
==
'1.0'
)
{
callback
?.(
true
)
return
}
const
exist
=
await
lodopCall
((
instance
)
=>
instance
.
GET_VALUE
(
'PRINT_STATUS_EXIST'
,
jobCode
),
)
if
(
exist
==
'0'
||
exist
==
'0.0'
)
{
callback
?.(
true
)
return
}
await
new
Promise
((
r
)
=>
setTimeout
(
r
,
500
))
if
(
Date
.
now
()
-
startTime
>=
timeout
)
{
ElMessage
.
error
(
`打印超时(
${
Math
.
floor
(
timeout
/
1000
)}
秒)`
)
callback
?.(
false
)
pending
=
false
}
}
return
}
lodop
.
PRINT
()
callback
?.(
false
)
}
src/views/order/factoryOrderNew/index.vue
View file @
1e825855
...
@@ -977,8 +977,7 @@ import {
...
@@ -977,8 +977,7 @@ import {
import
BigNumber
from
'bignumber.js'
import
BigNumber
from
'bignumber.js'
import
{
filePath
}
from
'@/api/axios'
import
{
filePath
}
from
'@/api/axios'
import
{
OrderData
}
from
'@/types/api/podMakeOrder'
import
{
OrderData
}
from
'@/types/api/podMakeOrder'
import
useLodop
from
'@/utils/hooks/useLodop'
import
useLodop
,
{
LODOPObject
}
from
'@/utils/hooks/useLodop'
import
{
printWithLodop
}
from
'@/utils/lodopPrinter'
import
LogisticsWaySelect
from
'@/views/logistics/components/LogisticsWaySelect'
import
LogisticsWaySelect
from
'@/views/logistics/components/LogisticsWaySelect'
import
ProductTypeFilter
from
'./component/ProductTypeFilter.vue'
import
ProductTypeFilter
from
'./component/ProductTypeFilter.vue'
import
ConfirmOrderDialog
from
'./component/ConfirmOrderDialog.vue'
import
ConfirmOrderDialog
from
'./component/ConfirmOrderDialog.vue'
...
@@ -1470,7 +1469,9 @@ const baseProductColumns = computed(() => [
...
@@ -1470,7 +1469,9 @@ const baseProductColumns = computed(() => [
render
:
(
row
:
ProductListData
)
=>
{
render
:
(
row
:
ProductListData
)
=>
{
return
(
return
(
<
span
>
<
span
>
{
new
BigNumber
(
row
.
templatePrice
??
0
).
plus
(
row
.
craftPrice
??
0
).
toString
()
}
{
new
BigNumber
(
row
.
templatePrice
??
0
)
.
plus
(
row
.
craftPrice
??
0
)
.
toString
()
}
<
/span
>
<
/span
>
)
)
}
,
}
,
...
@@ -1976,14 +1977,131 @@ const printOrder = async (
...
@@ -1976,14 +1977,131 @@ const printOrder = async (
data
:
OrderData
,
data
:
OrderData
,
callback
:
(
status
:
boolean
)
=>
void
,
callback
:
(
status
:
boolean
)
=>
void
,
)
=>
{
)
=>
{
await
printWithLodop
({
const
lodop
=
getCLodop
(
null
,
null
)
getCLodop
:
()
=>
getCLodop
(
null
,
null
),
if
(
!
lodop
)
return
printer
:
sheetPrinter
.
value
,
lodop
.
PRINT_INIT
(
'打印内容'
)
data
,
const
printerIndex
=
lodop
.
SET_PRINTER_INDEX
(
sheetPrinter
.
value
)
callback
,
console
.
log
(
baseUrl
:
filePath
,
'printerIndex'
,
printerIndex
,
`sheetPrinter.value:${sheetPrinter.value
}
`
,
)
if
(
!
printerIndex
)
{
ElMessage
.
error
(
'打印机设置失败'
)
callback
&&
callback
(
false
)
return
}
if
(
data
.
filePath
)
{
const
strURL
=
/^https
?
:/i
.
test
(
data
.
filePath
)
?
data
.
filePath
:
filePath
+
data
.
filePath
const
pdfData
=
/^https
?
:/i
.
test
(
strURL
)
?
await
downloadPDF
(
strURL
)
:
strURL
lodop
.
ADD_PRINT_PDF
(
0
,
0
,
'100%'
,
'100%'
,
pdfData
)
}
else
{
lodop
.
SEND_PRINT_RAWDATA
(
data
.
fileData
||
''
)
}
console
.
log
(
'lodop.CVERSION'
,
lodop
.
CVERSION
)
if
(
lodop
.
CVERSION
)
{
const
startTime
=
Date
.
now
()
const
jobCode
=
await
lodopCall
((
lodop
)
=>
{
lodop
.
SET_PRINT_MODE
(
'CATCH_PRINT_STATUS'
,
true
)
return
lodop
.
PRINT
()
}
)
console
.
log
(
'jobCode'
,
jobCode
)
// eslint-disable-next-line no-constant-condition
while
(
true
)
{
const
ok
=
await
lodopCall
((
lodop
)
=>
lodop
.
GET_VALUE
(
'PRINT_STATUS_OK'
,
jobCode
),
)
console
.
log
(
'PRINT_STATUS_OK:'
,
jobCode
,
`ok: ${ok
}
`
)
if
(
ok
==
1
)
{
console
.
log
(
'打印成功'
)
// 打印状态:成功
callback
&&
callback
(
true
)
return
}
// 如果打印状态表示未成功或者返回了空,继续获取任务是否存在
const
exist
=
await
lodopCall
((
lodop
)
=>
lodop
.
GET_VALUE
(
'PRINT_STATUS_EXIST'
,
jobCode
),
)
console
.
log
(
'[LODOP] PRINT_STATUS OK,EXIST'
,
jobCode
,
`ok:${ok
}
`
,
`exist:${exist
}
`
,
`jobCode:${jobCode
}
`
,
`(${Date.now() - startTime
}
ms)`
,
)
if
(
exist
==
0
)
{
console
.
log
(
'任务不存在了'
,
`exist:${exist
}
`
)
// 任务不存在了
callback
&&
callback
(
true
)
return
}
await
new
Promise
((
r
)
=>
setTimeout
(
r
,
500
))
if
(
Date
.
now
()
-
startTime
>=
30000
)
{
console
.
log
(
'打印超时(30秒)'
)
ElMessage
.
error
(
'打印超时(30秒)'
)
callback
&&
callback
(
false
)
return
}
}
}
else
{
lodop
.
PRINT
()
callback
&&
callback
(
false
)
}
}
let
_lodop
:
LODOPObject
|
null
=
null
let
_lodopCallback
:
{
[
key
:
string
]:
(
value
:
string
)
=>
void
}
=
{
}
const
lodopCall
=
(
fn
:
(
lodop
:
LODOPObject
)
=>
string
)
=>
{
if
(
!
_lodop
)
{
_lodop
=
getCLodop
(
null
,
null
)
if
(
!
_lodop
)
return
_lodop
.
On_Return_Remain
=
true
_lodop
.
SET_PRINT_MODE
(
'CATCH_PRINT_STATUS'
,
true
)
_lodopCallback
=
{
}
_lodop
.
On_Return
=
(
id
,
value
)
=>
{
console
.
log
(
'lodopCall return'
,
id
,
JSON
.
stringify
(
value
))
const
cb
=
_lodopCallback
[
id
]
if
(
!
cb
)
return
delete
_lodopCallback
[
id
]
cb
(
value
)
}
}
return
new
Promise
((
resolve
)
=>
{
if
(
!
_lodop
)
return
const
id
=
fn
(
_lodop
)
console
.
log
(
'lodopCall'
,
id
)
_lodopCallback
[
id
]
=
resolve
}
)
}
)
}
}
const
downloadPDF
=
async
(
url
:
string
):
Promise
<
string
>
=>
{
if
(
!
/^https
?
:/i
.
test
(
url
))
return
url
const
headers
:
Record
<
string
,
string
>
=
{
}
const
token
=
localStorage
.
getItem
(
'token'
)
if
(
token
)
headers
[
'jwt-token'
]
=
token
const
response
=
await
fetch
(
url
,
{
headers
}
)
if
(
!
response
.
ok
)
{
console
.
error
(
`PDF download failed: ${response.status
}
${response.statusText
}
`
,
)
return
''
}
const
arrayBuffer
=
await
response
.
arrayBuffer
()
const
bytes
=
new
Uint8Array
(
arrayBuffer
)
let
binary
=
''
for
(
let
i
=
0
;
i
<
bytes
.
byteLength
;
i
++
)
{
binary
+=
String
.
fromCharCode
(
bytes
[
i
])
}
return
'data:application/pdf;base64,'
+
btoa
(
binary
)
}
const
handleDownloadMaterial
=
async
()
=>
{
const
handleDownloadMaterial
=
async
()
=>
{
if
(
!
ensureSelection
())
return
if
(
!
ensureSelection
())
return
const
usePodOrderDownloadStatuses
=
[
'PENDING_DELIVERY'
,
'SUSPEND'
]
const
usePodOrderDownloadStatuses
=
[
'PENDING_DELIVERY'
,
'SUSPEND'
]
...
...
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