138 lines
5.4 KiB
Vue
138 lines
5.4 KiB
Vue
<template>
|
||
<el-card shadow="never">
|
||
<div class="toolbar">
|
||
<el-input v-model="search" placeholder="搜索模板编码/名称" style="width: 240px" clearable @keyup.enter="load" />
|
||
<el-button type="primary" @click="load">查询</el-button>
|
||
<el-button type="primary" @click="openCreate">新建模板</el-button>
|
||
<span class="summary" v-pre>安全占位符语法:{{path}} 取值、{{#each lines}}…{{/each}} 行循环</span>
|
||
</div>
|
||
|
||
<el-table :data="rows" v-loading="loading" size="small" stripe>
|
||
<el-table-column prop="code" label="模板编码" width="150" />
|
||
<el-table-column prop="name" label="模板名称" min-width="160" />
|
||
<el-table-column prop="doc_type" label="单据类型" width="140" />
|
||
<el-table-column prop="paper_size" label="纸张" width="90" />
|
||
<el-table-column label="默认" width="80">
|
||
<template #default="{ row }"><el-tag v-if="row.is_default" type="success">默认</el-tag></template>
|
||
</el-table-column>
|
||
<el-table-column label="操作" width="150">
|
||
<template #default="{ row }">
|
||
<el-button link type="primary" size="small" @click="openEdit(row)">编辑</el-button>
|
||
<el-button link type="danger" size="small" @click="remove(row)">删除</el-button>
|
||
</template>
|
||
</el-table-column>
|
||
</el-table>
|
||
|
||
<el-pagination
|
||
style="margin-top: 14px"
|
||
layout="prev, pager, next, total"
|
||
:total="count"
|
||
:page-size="pageSize"
|
||
v-model:current-page="page"
|
||
@current-change="load"
|
||
/>
|
||
|
||
<el-dialog v-model="dialogVisible" :title="editing ? '编辑打印模板' : '新建打印模板'" width="640px">
|
||
<el-form ref="formRef" :model="form" :rules="rules" label-width="100px">
|
||
<el-form-item label="模板编码" prop="code"><el-input v-model="form.code" /></el-form-item>
|
||
<el-form-item label="模板名称" prop="name"><el-input v-model="form.name" /></el-form-item>
|
||
<el-form-item label="单据类型" prop="doc_type">
|
||
<el-select v-model="form.doc_type" style="width: 100%">
|
||
<el-option label="销售单/送货单" value="sales_bill" />
|
||
<el-option label="采购单/进货单" value="purchase_bill" />
|
||
</el-select>
|
||
</el-form-item>
|
||
<el-form-item label="纸张" prop="paper_size"><el-input v-model="form.paper_size" /></el-form-item>
|
||
<el-form-item label="默认模板" prop="is_default"><el-switch v-model="form.is_default" /></el-form-item>
|
||
<el-form-item label="模板正文" prop="body_html">
|
||
<el-input v-model="form.body_html" type="textarea" :rows="8" placeholder="{{bill_no}} {{#each lines}}…" />
|
||
</el-form-item>
|
||
</el-form>
|
||
<template #footer>
|
||
<el-button @click="dialogVisible = false">取消</el-button>
|
||
<el-button type="primary" :loading="saving" @click="save">保存</el-button>
|
||
</template>
|
||
</el-dialog>
|
||
</el-card>
|
||
</template>
|
||
|
||
<script setup>
|
||
import { onMounted, ref, reactive } from 'vue'
|
||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||
import api from '../api/client'
|
||
|
||
const rows = ref([])
|
||
const count = ref(0)
|
||
const page = ref(1)
|
||
const pageSize = 20
|
||
const search = ref('')
|
||
const loading = ref(false)
|
||
const saving = ref(false)
|
||
const dialogVisible = ref(false)
|
||
const editing = ref(null)
|
||
const formRef = ref(null)
|
||
const form = reactive({ code: '', name: '', doc_type: 'sales_bill', paper_size: 'A4', is_default: false, body_html: '' })
|
||
const rules = {
|
||
code: [{ required: true, message: '请输入模板编码', trigger: 'blur' }],
|
||
name: [{ required: true, message: '请输入模板名称', trigger: 'blur' }],
|
||
doc_type: [{ required: true, message: '请选择单据类型', trigger: 'change' }],
|
||
body_html: [{ required: true, message: '请输入模板正文', trigger: 'blur' }],
|
||
}
|
||
|
||
async function load() {
|
||
loading.value = true
|
||
try {
|
||
const data = await api.get('/printing/templates/', {
|
||
params: { page: page.value, page_size: pageSize, search: search.value },
|
||
})
|
||
rows.value = data.results || []
|
||
count.value = data.count || 0
|
||
} finally {
|
||
loading.value = false
|
||
}
|
||
}
|
||
|
||
function openCreate() {
|
||
editing.value = null
|
||
Object.assign(form, { code: '', name: '', doc_type: 'sales_bill', paper_size: 'A4', is_default: false, body_html: '' })
|
||
dialogVisible.value = true
|
||
}
|
||
|
||
function openEdit(row) {
|
||
editing.value = row
|
||
Object.assign(form, { code: row.code, name: row.name, doc_type: row.doc_type, paper_size: row.paper_size, is_default: row.is_default, body_html: row.body_html })
|
||
dialogVisible.value = true
|
||
}
|
||
|
||
async function save() {
|
||
const ok = await formRef.value.validate().catch(() => false)
|
||
if (!ok) return
|
||
saving.value = true
|
||
try {
|
||
if (editing.value) await api.patch(`/printing/templates/${editing.value.id}/`, { ...form })
|
||
else await api.post('/printing/templates/', { ...form })
|
||
ElMessage.success('已保存')
|
||
dialogVisible.value = false
|
||
await load()
|
||
} finally {
|
||
saving.value = false
|
||
}
|
||
}
|
||
|
||
async function remove(row) {
|
||
try {
|
||
await ElMessageBox.confirm(`删除模板 ${row.code}(${row.name})?`, '删除确认', { type: 'warning' })
|
||
} catch (e) { return }
|
||
await api.delete(`/printing/templates/${row.id}/`)
|
||
ElMessage.success('已删除')
|
||
await load()
|
||
}
|
||
|
||
onMounted(load)
|
||
</script>
|
||
|
||
<style scoped>
|
||
.toolbar { display: flex; gap: 10px; margin-bottom: 14px; align-items: center; flex-wrap: wrap; }
|
||
.summary { color: #909399; font-size: 12px; }
|
||
</style>
|