add: 添加模板管理页面

This commit is contained in:
yanps
2024-07-30 10:20:49 +08:00
parent 6a7d5fe8f8
commit 1d3db3b9f1
13 changed files with 577 additions and 479 deletions

View File

@@ -66,6 +66,8 @@
"particles.js": "^2.0.0",
"path-to-regexp": "2.4.0",
"qrcode": "^1.5.3",
"qrcode-generator": "^1.4.4",
"qrcode.vue": "^3.4.1",
"qrcodejs2": "0.0.2",
"qs": "^6.9.1",
"save": "^2.9.0",
@@ -74,6 +76,7 @@
"tailwindcss": "^3.4.6",
"throttle-debounce": "^5.0.0",
"vue": "^2.6.10",
"vue-barcode": "^1.3.0",
"vue-bus": "^1.2.1",
"vue-color": "^2.8.1",
"vue-count-to": "1.0.13",
@@ -85,6 +88,8 @@
"vue-image-crop-upload": "^2.5.0",
"vue-plugin-hiprint": "0.0.56",
"vue-print-nb": "^1.7.5",
"vue-qrcode": "^2.2.2",
"vue-qrcode-reader": "^5.5.7",
"vue-router": "3.0.2",
"vue-seamless-scroll": "^1.1.23",
"vue-splitpane": "1.0.4",

View File

@@ -26,7 +26,7 @@ export function edit(data) {
export function query(id) {
return request({
url: 'api/tickets/selectOne?id=' + id,
url: 'api/tickets/selectOne?id =' + id,
method: 'get'
})
}

View File

@@ -0,0 +1,18 @@
import request from '@/utils/request'
export function savePdf(data) {
return request({
url: 'api/template',
method: 'post',
data
})
}
export function see(id) {
return request({
url: 'api/template/id?id=' + id,
method: 'get'
})
}
export default { savePdf, see }

View File

@@ -0,0 +1,190 @@
<template>
<div class="app-container">
<div id="app" class="head-container">
<!-- <button @click="seeTemp">预览 </button> -->
<div v-if="crud.props.searchToggle">
<!-- 搜索 -->
<el-form
:inline="true"
class="demo-form-inline"
label-position="right"
label-suffix=":"
>
<el-form-item label="模板名称">
<el-input
v-model="query.template_name"
size="small"
placeholder="模板名称"
class="filter-item"
style="width: 200px"
@change="crud.toQuery"
/>
</el-form-item>
<rrOperation />
</el-form>
</div>
<crudOperation :permission="permission">
<!-- <el-button
slot="left"
v-permission="['admin','task:add']"
class="filter-item"
size="mini"
type="primary"
icon="el-icon-plus"
@click="formDia=true"
>
{{ $t('auto.common.Create') }}
</el-button> -->
</crudOperation>
<div v-if="isModalVisible" class="modal" :style="{ width: modalWidth + 'px', height: modalHeight + 'px' }">
<button class="close-button" @click="hideModal">关闭</button>
<div v-for="element in printElements" :key="element.options.left + element.options.top" class="modal-content" :style="{position: 'absolute',left: element.options.left + 'px',top: element.options.top + 'px'}">
<div v-if="element.printElementType.type === 'table'">
<table border="1" :style="{width: element.options.width + 'px',height: element.options.height + 'px'}">
<thead>
<tr v-for="(row, rowIndex) in element.options.columns" :key="rowIndex">
<th v-for="(col) in row" :key="col.field" :style="{ width: col.width + 'px' }">{{ col.title }}</th>
</tr>
</thead>
<tbody>
<!-- 这里填充表格内容 -->
</tbody>
</table>
</div>
<div v-else-if="element.printElementType.type === 'barcode'" :style="{ position: 'absolute', left: element.options.left + 'px', top: element.options.top + 'px' }">
<barcode :value="element.options.testData" :type="element.options.barcodeType" color="#000000" />
</div>
<div v-else-if="element.printElementType.type === 'qrcode'" :style="{ position: 'absolute', left: element.options.left + 'px', top: element.options.top + 'px' }">
<qrcode-vue :value="element.options.testData" :size="80" :color="{ dark: '#000000', light: '#ffffff' }" />
</div>
<div v-else-if="element.printElementType.type === 'text'">
<div v-if="element.options.title" :style="{ color: '#000000', display: 'inline' }">{{ element.options.title }}</div>
<div v-else>没有文本数据可显示</div>
</div>
<div v-else-if="element.printElementType.type === 'image'" :style="{ position: 'absolute', left: element.options.left + 'px', top: element.options.top + 'px' }">
<img :src="element.options.src" alt="Image" :width="element.options.width" :height="element.options.height">
</div>
<div v-else-if="element.printElementType.type === 'longText'">
<div v-if="element.options.title" :style="{ color: '#000000' }">{{ element.options.title }}</div>
<div v-else>没有文本数据可显示</div>
</div>
</div>
</div>
<el-table ref="table" v-loading="crud.loading" :data="crud.data" size="small" style="width: 100%;" @selection-change="crud.selectionChangeHandler">
<el-table-column type="selection" width="50px" />
<el-table-column v-if="false" prop="template_id" label="模板标识" />
<el-table-column prop="template_name" label="模板名称" :min-width="flexWidth('template_name',crud.data,'模板名称')" />
<el-table-column prop="template_status" label="模板状态" width="100px" />
<el-table-column prop="create_by" :label="$t('task.select.Creator')" :min-width="flexWidth('create_by',crud.data,$t('task.select.Creator'))" />
<el-table-column prop="create_time" :label="$t('task.select.Create_time')" :min-width="flexWidth('create_time',crud.data,$t('task.select.Create_time'))" />
<el-table-column v-permission="['admin','task:edit','task:del']" :label="$t('task.select.Operation')" width="80px" align="center" fixed="right">
<template slot-scope="scope">
<el-button
type="text"
icon="el-icon-edit"
@click="seeTemp(scope.row.template_id)"
>
修改
</el-button>
</template>
</el-table-column>
</el-table>
<pagination />
</div>
</div>
</template>
<script>
import Barcode from 'vue-barcode' // 确保安装了 vue-barcode
// import Qrcode from 'vue-qrcode' // 确保安装了 vue-qrcode
import QrcodeVue from 'qrcode.vue' // 确保安装了 vue-qrcode
import template from '@/api/acs/order/template'
import CRUD, { crud, header, presenter } from '@crud/crud'
import crudOperation from '@crud/CRUD.operation'
import rrOperation from '@crud/RR.operation'
import pagination from '@crud/Pagination'
export default {
components: {
'qrcode-vue': QrcodeVue,
Barcode,
crudOperation,
pagination,
rrOperation
},
mixins: [presenter(), header(), crud()],
cruds() {
return CRUD({ title: '模板', url: 'api/template', idField: 'template_id', sort: 'create_time,desc',
optShow: {
add: false,
edit: false,
del: true,
reset: false,
download: false
},
crudMethod: { ...template }})
},
data() {
return {
isModalVisible: false, // 控制弹框显示的状态
modalWidth: 800, // 弹框宽度
modalHeight: 600, // 弹框高度
printElements: [],
permission: {
add: ['admin', 'task:add'],
edit: ['admin', 'task:edit'],
del: ['admin', 'task:del']
}
}
},
computed: {
typeClass() {
return `type-${this.type}`
}
},
methods: {
seeTemp(id) {
template.see(id).then((data) => {
console.log('====================', data.printElements)
this.printElements = JSON.parse(data.printElements)
// 确保 data 对象中的 printElements 是数组
if (Array.isArray(this.printElements)) {
this.isModalVisible = true
} else {
console.error('data.printElements 不是数组')
}
console.log('====================', this.printElements)
}).catch(error => {
console.error('获取数据失败:', error)
})
},
hideModal() {
this.isModalVisible = false // 隐藏弹框
}
}
}
</script>
<style>
/* 添加一些样式来调节页面布局 */
.modal {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background: white;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
z-index: 1000;
overflow: hidden; /* 处理溢出内容 */
}
.close-button {
position: absolute;
top: 10px;
right: 10px;
}
</style>

View File

@@ -5,6 +5,12 @@
<i class="iconfont sv-printer" />
浏览器打印
</button>
<!-- <button class="secondary circle-10 ml-10" @click.stop="getHtml">
<i class="iconfont sv-preview" />
预览
</button> -->
<el-button type="primary" @click="PreviewData"> 导出 </el-button>
<el-button type="primary" @click="addTable"> 保存 </el-button>
<!-- <button class="warning circle-10 ml-10" @click.stop="print2">
直接打印(需要连接客户端)
<i class="iconfont sv-printer" />
@@ -30,12 +36,12 @@
<i class="iconfont sv-table" />
<span>表格</span>
</div>
<div class="ep-draggable-item item" tid="defaultModule.html">
<i class="iconfont sv-html" />
<div class="ep-draggable-item item" tid="defaultModule.qrcode">
<i class="iconfont sv-qrcode" />
<span>html</span>
</div>
<div class="ep-draggable-item item" tid="defaultModule.customText">
<i class="iconfont sv-text" />
<div class="ep-draggable-item item" tid="defaultModule.barcode">
<i class="iconfont sv-barcode" />
<span>自定义</span>
</div>
<div class="title">辅助元素</div>
@@ -66,25 +72,60 @@
<div id="PrintElementOptionSetting" />
</div>
</div>
<div>
<el-dialog :close-on-click-modal="false" :visible.sync="formDias" title="模板" width="550px">
<el-form ref="form" :model="form" :rules="rules" size="small" label-width="110px">
<el-row>
<el-col :span="24">
<div class="grid-content bg-purple" />
<el-form-item label="模板名称" prop="template_name">
<el-input v-model="form.template_name" style="width: 370px;" @change="isDisabled=false" />
</el-form-item>
<el-form-item label="模板状态" prop="template_status">
<el-input v-model="form.template_status" style="width: 370px;" @change="isDisabled=false" />
</el-form-item>
</el-col>
</el-row>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="formDias=false">{{ $t('task.select.Cancel') }}</el-button>
<el-button :disabled="isDisabled" type="primary" @click="editBtn">{{ $t('task.select.Confirm') }}</el-button>
</div>
</el-dialog>
</div>
</div>
</template>
<script>
import $ from 'jquery'
import { hiprint, defaultElementTypeProvider } from 'vue-plugin-hiprint'
import template from '@/api/acs/order/template'
// 初始化 provider
hiprint.init({
providers: [defaultElementTypeProvider()]
})
export default {
name: 'Hrprint',
data() {
return {
hiprintTemplate: null // 声明 hiprintTemplate 以便在 buildDesigner 中使用
formDias: false,
hiprintTemplate: null, // 声明 hiprintTemplate 以便在 buildDesigner 中使用
printResults: [],
isDisabled: false,
form: {
template_name: '',
template_status: '',
template: Object
},
rules: {
template_name: [
{ required: true, message: '模板名称不能为空', trigger: 'blur' }
]
}
}
},
mounted() {
// 确保 hiprint 初始化完成后再执行构建操作
this.$nextTick(() => {
@@ -93,6 +134,10 @@ export default {
})
},
methods: {
addTable() {
this.formDias = true
this.isDisabled = false
},
/**
* 构建左侧可拖拽元素
* 注意: 可拖拽元素必须在 hiprint.init() 之后调用
@@ -158,6 +203,44 @@ export default {
} else {
alert('请先连接客户端(刷新网页), 然后再点击「直接打印」')
}
},
PreviewData() {
this.hiprintTemplate.toPdf('', '').then((tempPrintResults) => {
// 处理生成的 PDF 数据
console.log('获取pdf结果::::' + tempPrintResults)
// 创建 Blob 对象
const blob = new Blob([tempPrintResults], { type: 'application/pdf' })
const url = URL.createObjectURL(blob)
// 创建下载链接并设置文件名
const link = document.createElement('a')
link.href = url
link.download = 'your-custom-file-name.pdf' // 设置文件名
document.body.appendChild(link) // 追加到 DOM 中
link.click() // 触发下载
document.body.removeChild(link) // 下载后移除链接
// 清理 URL 对象
URL.revokeObjectURL(url)
}).catch((error) => {
console.error('PDF 生成失败:', error)
})
},
editBtn() {
// console.log('保存数据', this.hiprintTemplate.getJson())
this.isDisabled = true
this.form = {
...this.form, // 保留原有属性
...this.hiprintTemplate.getJson() // 赋值新属性
}
template.savePdf(this.form).then((data) => {
this.formDias = false
// 设置定时器,等待一定时间后再次允许请求
setTimeout(() => {
this.isDisabled = false // 可根据具体需求进行调整
}, 1000) // 5000 毫秒,即 5 秒钟
})
}
}
}