Browse Source

域控

master
han\hanst 3 months ago
parent
commit
c6a4cb89ff
  1. 3
      src/api/labelSetting/label_setting.js
  2. 410
      src/components/print/PrintService.vue
  3. 9
      src/views/modules/sys/user-add-or-update.vue
  4. 7
      src/views/modules/sys/user.vue

3
src/api/labelSetting/label_setting.js

@ -18,6 +18,9 @@ export const getUserLabelPrinters = data => createAPI('/label/setting/getUserLab
// 打印标签 // 打印标签
export const printLabel = data => createAPI('/label/setting/printLabel','post',data) export const printLabel = data => createAPI('/label/setting/printLabel','post',data)
// 打印标签
export const printLabelTest = data => createAPI('/label/setting/printLabelTest','post',data)
// 使用真实数据预览标签 // 使用真实数据预览标签
export const previewLabelWithRealData = data => createAPI('/label/setting/previewLabelWithRealData','post',data) export const previewLabelWithRealData = data => createAPI('/label/setting/previewLabelWithRealData','post',data)

410
src/components/print/PrintService.vue

@ -1,103 +1,37 @@
<template> <template>
<div class="print-service"> <div class="print-service">
<!-- 打印方式选择对话框 -->
<!-- IP地址输入对话框 -->
<el-dialog <el-dialog
title="选择打印方式"
title="打印机设置"
:visible.sync="printDialogVisible" :visible.sync="printDialogVisible"
width="480px"
:close-on-click-modal="false"
class="print-dialog"
>
<div class="print-options">
<div class="option-description">
<i class="el-icon-info"></i>
<span>请选择适合您环境的打印方式</span>
</div>
<div class="print-methods">
<div class="print-method recommended" @click="selectPrintMethod('server')">
<div class="method-icon">
<i class="el-icon-s-platform"></i>
</div>
<div class="method-content">
<h4>服务器打印</h4>
<p>通过WMS系统管理打印任务支持打印机配置和权限控制</p>
<div class="method-badge">推荐</div>
</div>
<div class="method-arrow">
<i class="el-icon-arrow-right"></i>
</div>
</div>
<div class="print-method" @click="selectPrintMethod('network')">
<div class="method-icon">
<i class="el-icon-connection"></i>
</div>
<div class="method-content">
<h4>直接网络打印</h4>
<p>直接连接网络打印机适合简单的网络环境</p>
</div>
<div class="method-arrow">
<i class="el-icon-arrow-right"></i>
</div>
</div>
</div>
</div>
<div slot="footer" class="dialog-footer">
<el-button @click="printDialogVisible = false">取消</el-button>
</div>
</el-dialog>
<!-- 打印机选择对话框 -->
<el-dialog
title="服务器打印设置"
:visible.sync="printerSelectionVisible"
width="350px" width="350px"
:close-on-click-modal="false" :close-on-click-modal="false"
class="printer-selection-dialog"
class="printer-ip-dialog"
> >
<div class="printer-selection-content">
<div class="form-item">
<label class="form-label">选择打印机:</label>
<el-select
v-model="selectedPrinter"
placeholder="请选择打印机"
style="width: 100%;"
>
<el-option
v-for="printer in availablePrinters"
:key="printer.printerName"
:label="`${printer.printerName} (${printer.ipAddress})`"
:value="printer.printerName"
/>
</el-select>
</div>
<div class="printer-ip-content">
<div class="form-item"> <div class="form-item">
<label class="form-label">打印份数:</label>
<label class="form-label">打印机IP地址:</label>
<el-input <el-input
v-model="printCopies"
:min="1"
:max="10"
size="mini"
v-model="printerIP"
placeholder="例如: 192.168.1.100"
style="width: 100%;" style="width: 100%;"
controls-position="right"
@keyup.enter="confirmPrint"
ref="ipInput"
/> />
<div class="form-hint">支持1-10份打印RFID标签将逐张处理</div>
<div class="form-hint">请输入网络打印机的IP地址</div>
</div> </div>
</div> </div>
<div slot="footer" class="dialog-footer"> <div slot="footer" class="dialog-footer">
<el-button @click="printerSelectionVisible = false">取消</el-button>
<el-button type="primary" @click="confirmPrint" :disabled="!selectedPrinter">开始打印</el-button>
<el-button @click="printDialogVisible = false">取消</el-button>
<el-button type="primary" @click="confirmPrint" :disabled="!canPrint">开始打印</el-button>
</div> </div>
</el-dialog> </el-dialog>
</div> </div>
</template> </template>
<script> <script>
import { getUserLabelPrinters, printLabel } from '@/api/labelSetting/label_setting.js'
import { getUserLabelPrinters, printLabelTest } from '@/api/labelSetting/label_setting.js'
export default { export default {
name: 'PrintService', name: 'PrintService',
@ -136,10 +70,7 @@ export default {
data() { data() {
return { return {
printLoading: false, printLoading: false,
printerSelectionVisible: false,
availablePrinters: [],
selectedPrinter: '',
printCopies: 1
printerIP: ''
} }
}, },
computed: { computed: {
@ -150,6 +81,9 @@ export default {
set(value) { set(value) {
this.$emit('update:visible', value) this.$emit('update:visible', value)
} }
},
canPrint() {
return !!this.printerIP && /^(\d{1,3}\.){3}\d{1,3}$/.test(this.printerIP)
} }
}, },
methods: { methods: {
@ -162,310 +96,81 @@ export default {
return return
} }
// 使IP
this.printerIP = localStorage.getItem('lastPrinterIP') || ''
this.printDialogVisible = true this.printDialogVisible = true
},
/**
* 选择打印方式
*/
selectPrintMethod(method) {
this.printDialogVisible = false
switch (method) {
case 'server':
this.showServerPrintDialog()
break
case 'network':
this.showNetworkPrinterDialog()
break
default:
console.warn('未知的打印方式:', method)
}
},
/**
* 显示服务器打印对话框
*/
async showServerPrintDialog() {
try {
//
const { data } = await getUserLabelPrinters({
userId: localStorage.getItem('userName'),
username: localStorage.getItem('userName'),
site: this.$store.state.user.site
})
if (!data.rows || data.rows.length === 0) {
this.$confirm(
'您还没有配置打印机,是否前往配置?',
'未找到打印机',
{
confirmButtonText: '去配置',
cancelButtonText: '取消',
type: 'warning'
}
).then(() => {
this.$message.warning('请联系管理员配置打印机')
})
return
//
this.$nextTick(() => {
if (this.$refs.ipInput) {
this.$refs.ipInput.focus()
} }
//
this.showPrinterSelectionDialog(data.rows)
} catch (error) {
console.error('获取打印机列表失败:', error)
this.$message.error('获取打印机列表失败,请稍后重试')
}
},
/**
* 显示打印机选择对话框
*/
showPrinterSelectionDialog(printers) {
this.availablePrinters = printers
this.selectedPrinter = printers.length > 0 ? printers[0].printerName : ''
this.printCopies = 1
this.printerSelectionVisible = true
})
}, },
/** /**
* 确认打印 * 确认打印
*/ */
confirmPrint() { confirmPrint() {
if (!this.selectedPrinter) {
this.$message.warning('请选择打印机')
if (!this.printerIP || !/^(\d{1,3}\.){3}\d{1,3}$/.test(this.printerIP)) {
this.$message.warning('请输入正确的IP地址')
return return
} }
this.printerSelectionVisible = false
this.printViaServer(this.selectedPrinter, this.printCopies)
// IP
localStorage.setItem('lastPrinterIP', this.printerIP)
this.printDialogVisible = false
this.printViaIPAddress(this.printerIP)
}, },
/** /**
* 通过服务器打印
* 通过IP地址打印
*/ */
async printViaServer(printerName, copies) {
async printViaIPAddress(printerIP) {
this.printLoading = true this.printLoading = true
this.$emit('print-start') this.$emit('print-start')
try { try {
// IP
const printRequest = { const printRequest = {
reportId: this.reportId, reportId: this.reportId,
zplCode: this.zplCode, zplCode: this.zplCode,
printerName: printerName,
copies: copies,
printerIP: printerIP, // 使IP
copies: 1, // 1
paperSize: this.paperSize, paperSize: this.paperSize,
orientation: this.orientation, orientation: this.orientation,
dpi: this.dpi, dpi: this.dpi,
userId: localStorage.getItem('userName'), userId: localStorage.getItem('userName'),
username: localStorage.getItem('userName'), username: localStorage.getItem('userName'),
site: this.$store.state.user.site
site: this.$store.state.user.site,
printMode: 'ip' // IP
} }
const { data } = await printLabel(printRequest)
const { data } = await printLabelTest(printRequest)
if (data.code === 200) { if (data.code === 200) {
this.$message.success(`打印任务已发送!打印机: ${printerName}, 份数: ${copies}`)
this.$emit('print-success', { printerName, copies })
this.$message.success(`打印任务已发送!打印机IP: ${printerIP}`)
this.$emit('print-success', { printerIP })
} else { } else {
throw new Error(data.msg || '打印失败') throw new Error(data.msg || '打印失败')
} }
} catch (error) { } catch (error) {
console.error('服务器打印失败:', error)
console.error('IP打印失败:', error)
this.$message.error(`打印失败: ${error.message || error}`) this.$message.error(`打印失败: ${error.message || error}`)
this.$emit('print-error', error) this.$emit('print-error', error)
} finally { } finally {
this.printLoading = false this.printLoading = false
this.$emit('print-end') this.$emit('print-end')
} }
},
/**
* 显示网络打印机对话框
*/
showNetworkPrinterDialog() {
this.$prompt('请输入打印机IP地址', '直接网络打印', {
confirmButtonText: '打印',
cancelButtonText: '取消',
inputPattern: /^(\d{1,3}\.){3}\d{1,3}$/,
inputErrorMessage: '请输入正确的IP地址格式',
inputPlaceholder: '例如: 192.168.1.100',
inputValue: localStorage.getItem('localPrinterIP') || ''
}).then(({ value }) => {
localStorage.setItem('localPrinterIP', value)
this.printToNetworkPrinter(value)
}).catch(() => {
this.$message.warning('已取消打印')
})
},
/**
* 直接网络打印
*/
async printToNetworkPrinter(printerIP) {
await fetch(`http://${printerIP}:9100`, {
method: 'POST',
headers: {
'Content-Type': 'text/plain',
},
body: this.zplCode,
mode: 'no-cors'
})
this.$message.success(`打印任务已发送到 ${printerIP}`)
} }
} }
} }
</script> </script>
<style scoped> <style scoped>
/* 打印对话框样式 */
.print-options {
padding: 10px 0;
}
.option-description {
display: flex;
align-items: center;
gap: 8px;
margin-bottom: 20px;
padding: 12px;
background: #f0f9ff;
border: 1px solid #e0f2fe;
border-radius: 8px;
color: #0369a1;
font-size: 14px;
}
.option-description i {
font-size: 16px;
color: #0284c7;
}
.print-methods {
display: flex;
flex-direction: column;
gap: 12px;
}
.print-method {
display: flex;
align-items: center;
padding: 16px;
border: 2px solid #e5e7eb;
border-radius: 12px;
cursor: pointer;
transition: all 0.3s ease;
background: #ffffff;
position: relative;
overflow: hidden;
}
.print-method:hover {
border-color: #3b82f6;
box-shadow: 0 4px 12px rgba(59, 130, 246, 0.15);
transform: translateY(-2px);
}
.print-method.recommended {
border-color: #10b981;
background: linear-gradient(135deg, #f0fdf4 0%, #ffffff 100%);
}
.print-method.recommended:hover {
border-color: #059669;
box-shadow: 0 4px 12px rgba(16, 185, 129, 0.2);
}
.method-icon {
flex-shrink: 0;
width: 48px;
height: 48px;
display: flex;
align-items: center;
justify-content: center;
border-radius: 12px;
margin-right: 16px;
background: #f3f4f6;
color: #6b7280;
font-size: 20px;
transition: all 0.3s ease;
}
.print-method:hover .method-icon {
background: #3b82f6;
color: white;
transform: scale(1.1);
}
.print-method.recommended .method-icon {
background: #10b981;
color: white;
}
.print-method.recommended:hover .method-icon {
background: #059669;
}
.method-content {
flex: 1;
position: relative;
}
.method-content h4 {
margin: 0 0 6px 0;
font-size: 16px;
font-weight: 600;
color: #1f2937;
line-height: 1.2;
}
.method-content p {
margin: 0;
font-size: 13px;
color: #6b7280;
line-height: 1.4;
}
.method-badge {
position: absolute;
top: -2px;
right: 0;
background: #10b981;
color: white;
font-size: 11px;
font-weight: 600;
padding: 2px 8px;
border-radius: 12px;
text-transform: uppercase;
letter-spacing: 0.5px;
}
.method-arrow {
flex-shrink: 0;
margin-left: 12px;
color: #9ca3af;
font-size: 16px;
transition: all 0.3s ease;
}
.print-method:hover .method-arrow {
color: #3b82f6;
transform: translateX(4px);
}
.print-method.recommended:hover .method-arrow {
color: #10b981;
}
.dialog-footer {
text-align: center;
padding-top: 10px;
}
/* 打印机选择对话框样式 */
.printer-selection-content {
/* IP地址输入对话框样式 */
.printer-ip-content {
padding: 10px 0; padding: 10px 0;
} }
@ -488,35 +193,14 @@ export default {
line-height: 1.4; line-height: 1.4;
} }
.form-hint {
margin-top: 6px;
font-size: 12px;
color: #909399;
line-height: 1.4;
.dialog-footer {
text-align: center;
padding-top: 10px;
} }
/* 响应式设计 */ /* 响应式设计 */
@media (max-width: 600px) { @media (max-width: 600px) {
.print-method {
padding: 12px;
}
.method-icon {
width: 40px;
height: 40px;
margin-right: 12px;
font-size: 18px;
}
.method-content h4 {
font-size: 15px;
}
.method-content p {
font-size: 12px;
}
.printer-selection-content {
.printer-ip-content {
padding: 5px 0; padding: 5px 0;
} }

9
src/views/modules/sys/user-add-or-update.vue

@ -25,6 +25,9 @@
<el-form-item :label="buttons.userDisplay||'用户名'" prop="email"> <el-form-item :label="buttons.userDisplay||'用户名'" prop="email">
<el-input v-model="dataForm.userDisplay" style="width: 150px;" ></el-input> <el-input v-model="dataForm.userDisplay" style="width: 150px;" ></el-input>
</el-form-item> </el-form-item>
<el-form-item :label="buttons.domainAccount||'域控账号'" prop="domainAccount">
<el-input v-model="dataForm.domainAccount" style="width: 150px;" placeholder="域控账号"></el-input>
</el-form-item>
<el-form-item :label="buttons.email||'邮箱'" prop="email"> <el-form-item :label="buttons.email||'邮箱'" prop="email">
<el-input v-model="dataForm.email" style="width: 150px;" ></el-input> <el-input v-model="dataForm.email" style="width: 150px;" ></el-input>
</el-form-item> </el-form-item>
@ -110,13 +113,15 @@ export default {
status: 1, status: 1,
site: '', // site: '', //
siteList: [], // siteList: [], //
userDisplay: ''
userDisplay: '',
domainAccount: ''
}, },
buttons: { buttons: {
add: '添加', add: '添加',
edit: '编辑', edit: '编辑',
username: '用户账号', username: '用户账号',
userDisplay: '用户名', userDisplay: '用户名',
domainAccount: '域控账号',
email: '邮箱', email: '邮箱',
mobile: '手机号', mobile: '手机号',
status: '状态', status: '状态',
@ -203,6 +208,7 @@ export default {
this.dataForm.languageDefault = data.user.languageDefault this.dataForm.languageDefault = data.user.languageDefault
this.dataForm.site = data.user.site.toString() this.dataForm.site = data.user.site.toString()
this.dataForm.userDisplay = data.user.userDisplay this.dataForm.userDisplay = data.user.userDisplay
this.dataForm.domainAccount = data.user.domainAccount
// //
this.getUserSiteAccess(data.user.username) this.getUserSiteAccess(data.user.username)
} }
@ -230,6 +236,7 @@ export default {
'languageDefault': this.dataForm.languageDefault, 'languageDefault': this.dataForm.languageDefault,
'site': this.dataForm.site, 'site': this.dataForm.site,
'userDisplay': this.dataForm.userDisplay, 'userDisplay': this.dataForm.userDisplay,
'domainAccount': this.dataForm.domainAccount,
'siteList': this.dataForm.siteList || [] // 'siteList': this.dataForm.siteList || [] //
}) })
}).then(({data}) => { }).then(({data}) => {

7
src/views/modules/sys/user.vue

@ -41,6 +41,12 @@
align="center" align="center"
:label="buttons.userDisplay||'用户名'"> :label="buttons.userDisplay||'用户名'">
</el-table-column> </el-table-column>
<el-table-column
prop="domainAccount"
header-align="center"
align="center"
:label="buttons.domainAccount||'域控账号'">
</el-table-column>
<el-table-column <el-table-column
prop="email" prop="email"
header-align="center" header-align="center"
@ -267,6 +273,7 @@ export default {
createTime: '创建时间', createTime: '创建时间',
username: '用户账号', username: '用户账号',
userDisplay: '用户名', userDisplay: '用户名',
domainAccount: '域控账号',
email: '邮箱', email: '邮箱',
mobile: '手机号', mobile: '手机号',
status: '状态', status: '状态',

Loading…
Cancel
Save