This commit is contained in:
@@ -96,6 +96,12 @@
|
|||||||
"navigationBarTitleText": "客户列表"
|
"navigationBarTitleText": "客户列表"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"path": "pages/printer/list",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "打印机管理"
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"path": "pages/category/index",
|
"path": "pages/category/index",
|
||||||
"style": {
|
"style": {
|
||||||
|
|||||||
@@ -74,6 +74,10 @@
|
|||||||
<view class="menu-icon-box pink"><text class="icon-text">类</text></view>
|
<view class="menu-icon-box pink"><text class="icon-text">类</text></view>
|
||||||
<text class="menu-text">种类管理</text>
|
<text class="menu-text">种类管理</text>
|
||||||
</view>
|
</view>
|
||||||
|
<view class="menu-item" @click="goTo('/pages/printer/list')">
|
||||||
|
<view class="menu-icon-box green"><text class="icon-text">打印</text></view>
|
||||||
|
<text class="menu-text">打印机</text>
|
||||||
|
</view>
|
||||||
<view class="menu-item" @click="goStock()">
|
<view class="menu-item" @click="goStock()">
|
||||||
<view class="menu-icon-box cyan"><text class="icon-text">库</text></view>
|
<view class="menu-icon-box cyan"><text class="icon-text">库</text></view>
|
||||||
<text class="menu-text">库存管理</text>
|
<text class="menu-text">库存管理</text>
|
||||||
|
|||||||
@@ -210,8 +210,29 @@ export default {
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
printOrder() {
|
printOrder() {
|
||||||
uni.showToast({ title: '打印功能开发中', icon: 'none' })
|
uni.showModal({
|
||||||
// TODO: 实现打印功能
|
title: '确认打印',
|
||||||
|
content: '确定要打印此订单小票吗?',
|
||||||
|
success: async (res) => {
|
||||||
|
if (res.confirm) {
|
||||||
|
try {
|
||||||
|
const token = uni.getStorageSync('token')
|
||||||
|
const res = await uni.request({
|
||||||
|
url: `${getApp().globalData.apiBaseUrl}/printers/print/${this.orderId}`,
|
||||||
|
method: 'POST',
|
||||||
|
header: { 'Authorization': `Bearer ${token}` }
|
||||||
|
})
|
||||||
|
if (res.data.code === 0) {
|
||||||
|
uni.showToast({ title: '打印成功', icon: 'success' })
|
||||||
|
} else {
|
||||||
|
uni.showToast({ title: res.data.message || '打印失败', icon: 'none' })
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
uni.showToast({ title: '打印失败', icon: 'none' })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
377
src/pages/printer/list.vue
Normal file
377
src/pages/printer/list.vue
Normal file
@@ -0,0 +1,377 @@
|
|||||||
|
<template>
|
||||||
|
<view class="page">
|
||||||
|
<view class="header">
|
||||||
|
<text class="title">打印机管理</text>
|
||||||
|
<text class="add-btn" @click="goToAdd">+ 添加</text>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="printer-list" v-if="printers.length > 0">
|
||||||
|
<view
|
||||||
|
v-for="item in printers"
|
||||||
|
:key="item.printerId"
|
||||||
|
class="printer-card"
|
||||||
|
:class="{ 'is-default': item.isDefault === 1 }"
|
||||||
|
>
|
||||||
|
<view class="printer-info">
|
||||||
|
<view class="printer-name">{{ item.name }}</view>
|
||||||
|
<view class="printer-detail">{{ item.ip }}:{{ item.port }}</view>
|
||||||
|
<view class="printer-status" :class="{ 'online': item.status === 1 }">
|
||||||
|
{{ item.status === 1 ? '已启用' : '已禁用' }}
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="printer-actions">
|
||||||
|
<text
|
||||||
|
class="action-btn set-default"
|
||||||
|
v-if="item.isDefault !== 1"
|
||||||
|
@click="setDefault(item)"
|
||||||
|
>设默认</text>
|
||||||
|
<text class="action-btn default-tag" v-else>默认</text>
|
||||||
|
<text class="action-btn delete" @click="deletePrinter(item)">删除</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="empty" v-else>
|
||||||
|
<text class="empty-icon">🖨️</text>
|
||||||
|
<text class="empty-text">暂无打印机</text>
|
||||||
|
<text class="empty-hint">点击右上角添加打印机</text>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 添加/编辑弹窗 -->
|
||||||
|
<view class="modal" v-if="showModal" @click="showModal = false">
|
||||||
|
<view class="modal-content" @click.stop>
|
||||||
|
<view class="modal-title">{{ editingId ? '编辑' : '添加' }}打印机</view>
|
||||||
|
<view class="form-item">
|
||||||
|
<text class="label">名称</text>
|
||||||
|
<input class="input" v-model="form.name" placeholder="如:前台打印机" />
|
||||||
|
</view>
|
||||||
|
<view class="form-item">
|
||||||
|
<text class="label">IP地址</text>
|
||||||
|
<input class="input" v-model="form.ip" placeholder="如:192.168.1.100" />
|
||||||
|
</view>
|
||||||
|
<view class="form-item">
|
||||||
|
<text class="label">端口</text>
|
||||||
|
<input class="input" v-model="form.port" type="number" placeholder="默认9100" />
|
||||||
|
</view>
|
||||||
|
<view class="form-item">
|
||||||
|
<text class="label">状态</text>
|
||||||
|
<switch :checked="form.status === 1" @change="onStatusChange" />
|
||||||
|
</view>
|
||||||
|
<view class="modal-btns">
|
||||||
|
<button class="btn cancel" @click="showModal = false">取消</button>
|
||||||
|
<button class="btn confirm" @click="savePrinter">保存</button>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import api from '@/utils/api'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
printers: [],
|
||||||
|
showModal: false,
|
||||||
|
editingId: '',
|
||||||
|
form: {
|
||||||
|
name: '',
|
||||||
|
ip: '',
|
||||||
|
port: '9100',
|
||||||
|
status: 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onLoad() {
|
||||||
|
this.loadPrinters()
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
async loadPrinters() {
|
||||||
|
try {
|
||||||
|
const res = await uni.request({
|
||||||
|
url: `${api.baseUrl}/printers`,
|
||||||
|
method: 'GET',
|
||||||
|
header: { 'Authorization': `Bearer ${uni.getStorageSync('token')}` }
|
||||||
|
})
|
||||||
|
if (res.data.code === 0) {
|
||||||
|
this.printers = res.data.data || []
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
goToAdd() {
|
||||||
|
this.editingId = ''
|
||||||
|
this.form = { name: '', ip: '', port: '9100', status: 1 }
|
||||||
|
this.showModal = true
|
||||||
|
},
|
||||||
|
onStatusChange(e) {
|
||||||
|
this.form.status = e.detail.value ? 1 : 0
|
||||||
|
},
|
||||||
|
async savePrinter() {
|
||||||
|
if (!this.form.name || !this.form.ip) {
|
||||||
|
uni.showToast({ title: '请填写名称和IP', icon: 'none' })
|
||||||
|
return
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
const url = this.editingId
|
||||||
|
? `${api.baseUrl}/printers/${this.editingId}`
|
||||||
|
: `${api.baseUrl}/printers`
|
||||||
|
const method = this.editingId ? 'PUT' : 'POST'
|
||||||
|
const res = await uni.request({
|
||||||
|
url,
|
||||||
|
method,
|
||||||
|
header: {
|
||||||
|
'Authorization': `Bearer ${uni.getStorageSync('token')}`,
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
},
|
||||||
|
data: this.form
|
||||||
|
})
|
||||||
|
if (res.data.code === 0) {
|
||||||
|
uni.showToast({ title: '保存成功', icon: 'success' })
|
||||||
|
this.showModal = false
|
||||||
|
this.loadPrinters()
|
||||||
|
} else {
|
||||||
|
uni.showToast({ title: res.data.message || '保存失败', icon: 'none' })
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
uni.showToast({ title: '保存失败', icon: 'none' })
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async setDefault(item) {
|
||||||
|
try {
|
||||||
|
const res = await uni.request({
|
||||||
|
url: `${api.baseUrl}/printers/${item.printerId}/default`,
|
||||||
|
method: 'PUT',
|
||||||
|
header: { 'Authorization': `Bearer ${uni.getStorageSync('token')}` }
|
||||||
|
})
|
||||||
|
if (res.data.code === 0) {
|
||||||
|
uni.showToast({ title: '设置成功', icon: 'success' })
|
||||||
|
this.loadPrinters()
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
uni.showToast({ title: '设置失败', icon: 'none' })
|
||||||
|
}
|
||||||
|
},
|
||||||
|
deletePrinter(item) {
|
||||||
|
uni.showModal({
|
||||||
|
title: '确认删除',
|
||||||
|
content: `确定要删除打印机"${item.name}"吗?`,
|
||||||
|
success: async (res) => {
|
||||||
|
if (res.confirm) {
|
||||||
|
try {
|
||||||
|
const res = await uni.request({
|
||||||
|
url: `${api.baseUrl}/printers/${item.printerId}`,
|
||||||
|
method: 'DELETE',
|
||||||
|
header: { 'Authorization': `Bearer ${uni.getStorageSync('token')}` }
|
||||||
|
})
|
||||||
|
if (res.data.code === 0) {
|
||||||
|
uni.showToast({ title: '已删除', icon: 'success' })
|
||||||
|
this.loadPrinters()
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
uni.showToast({ title: '删除失败', icon: 'none' })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.page {
|
||||||
|
padding: 20rpx;
|
||||||
|
min-height: 100vh;
|
||||||
|
background: #f5f5f5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
padding: 30rpx;
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 16rpx;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
font-size: 32rpx;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.add-btn {
|
||||||
|
color: #1890ff;
|
||||||
|
font-size: 28rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.printer-list {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 16rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.printer-card {
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 16rpx;
|
||||||
|
padding: 24rpx;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.printer-card.is-default {
|
||||||
|
border: 2rpx solid #52c41a;
|
||||||
|
}
|
||||||
|
|
||||||
|
.printer-info {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.printer-name {
|
||||||
|
font-size: 28rpx;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.printer-detail {
|
||||||
|
font-size: 24rpx;
|
||||||
|
color: #999;
|
||||||
|
margin-top: 8rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.printer-status {
|
||||||
|
font-size: 22rpx;
|
||||||
|
color: #999;
|
||||||
|
margin-top: 8rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.printer-status.online {
|
||||||
|
color: #52c41a;
|
||||||
|
}
|
||||||
|
|
||||||
|
.printer-actions {
|
||||||
|
display: flex;
|
||||||
|
gap: 16rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-btn {
|
||||||
|
font-size: 24rpx;
|
||||||
|
padding: 8rpx 16rpx;
|
||||||
|
border-radius: 8rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-btn.set-default {
|
||||||
|
color: #1890ff;
|
||||||
|
background: #e6f7ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-btn.default-tag {
|
||||||
|
color: #52c41a;
|
||||||
|
background: #f6ffed;
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-btn.delete {
|
||||||
|
color: #ff4d4f;
|
||||||
|
background: #fff1f0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.empty {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
padding: 100rpx 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.empty-icon {
|
||||||
|
font-size: 80rpx;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.empty-text {
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
|
||||||
|
.empty-hint {
|
||||||
|
font-size: 24rpx;
|
||||||
|
color: #999;
|
||||||
|
margin-top: 12rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 弹窗 */
|
||||||
|
.modal {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
background: rgba(0, 0, 0, 0.5);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
z-index: 999;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-content {
|
||||||
|
width: 600rpx;
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
padding: 30rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-title {
|
||||||
|
font-size: 30rpx;
|
||||||
|
font-weight: bold;
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 30rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-item {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-item .label {
|
||||||
|
width: 140rpx;
|
||||||
|
font-size: 26rpx;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-item .input {
|
||||||
|
flex: 1;
|
||||||
|
height: 64rpx;
|
||||||
|
background: #f5f5f5;
|
||||||
|
border-radius: 12rpx;
|
||||||
|
padding: 0 20rpx;
|
||||||
|
font-size: 26rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-btns {
|
||||||
|
display: flex;
|
||||||
|
gap: 20rpx;
|
||||||
|
margin-top: 30rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-btns .btn {
|
||||||
|
flex: 1;
|
||||||
|
height: 80rpx;
|
||||||
|
line-height: 80rpx;
|
||||||
|
border-radius: 40rpx;
|
||||||
|
font-size: 28rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-btns .cancel {
|
||||||
|
background: #f5f5f5;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-btns .confirm {
|
||||||
|
background: #1890ff;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
Reference in New Issue
Block a user