富茂A端打印模板内嵌编辑器
選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

index.vue 13 KiB

6ヶ月前
6ヶ月前
6ヶ月前
6ヶ月前
6ヶ月前
6ヶ月前
6ヶ月前
6ヶ月前
6ヶ月前
6ヶ月前
6ヶ月前
6ヶ月前
6ヶ月前
6ヶ月前
6ヶ月前
6ヶ月前
6ヶ月前
6ヶ月前
6ヶ月前
6ヶ月前
6ヶ月前
6ヶ月前
6ヶ月前
6ヶ月前
6ヶ月前
6ヶ月前
6ヶ月前
6ヶ月前
6ヶ月前
6ヶ月前
6ヶ月前
6ヶ月前
6ヶ月前
6ヶ月前
6ヶ月前
6ヶ月前
6ヶ月前
6ヶ月前
6ヶ月前
6ヶ月前
6ヶ月前
6ヶ月前
6ヶ月前
6ヶ月前
6ヶ月前
6ヶ月前
6ヶ月前
6ヶ月前
6ヶ月前
6ヶ月前
6ヶ月前
6ヶ月前
6ヶ月前
6ヶ月前
6ヶ月前
6ヶ月前
6ヶ月前
6ヶ月前
6ヶ月前
6ヶ月前
6ヶ月前
6ヶ月前
6ヶ月前
6ヶ月前
6ヶ月前
6ヶ月前
6ヶ月前
6ヶ月前
6ヶ月前
6ヶ月前
6ヶ月前
6ヶ月前
6ヶ月前
6ヶ月前
6ヶ月前
6ヶ月前
6ヶ月前
6ヶ月前
6ヶ月前
6ヶ月前
6ヶ月前
6ヶ月前
6ヶ月前
6ヶ月前
6ヶ月前
6ヶ月前
6ヶ月前
6ヶ月前
6ヶ月前
6ヶ月前
6ヶ月前
6ヶ月前
6ヶ月前
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418
  1. <template>
  2. <div class="box">
  3. <div class="title">打印模板设计器</div>
  4. <section>
  5. <div class="section">模板管理</div>
  6. <el-form :inline="true" :model="searchForm" size="small" label-width="80px" label-position="right">
  7. <el-form-item label="模板名称" prop="name">
  8. <el-input v-model="searchForm.name" clearable></el-input>
  9. </el-form-item>
  10. <el-form-item label="模板类型" prop="type">
  11. <el-select v-model="searchForm.type" clearable>
  12. <el-option v-for="(item, index) in typeArr" :key="index" :label="item.name" :value="item.id"></el-option>
  13. </el-select>
  14. </el-form-item>
  15. <el-form-item label="状态" prop="isDel">
  16. <el-select v-model="searchForm.isDel" clearable>
  17. <el-option v-for="(item, index) in isDelArr" :key="index" :label="item.name" :value="item.id"></el-option>
  18. </el-select>
  19. </el-form-item>
  20. <el-form-item>
  21. <el-button size="mini" type="primary" @click="getList">查询模板</el-button>
  22. </el-form-item>
  23. </el-form>
  24. <el-table :data="tempList" style="width: 100%" size="mini" border>
  25. <el-table-column label="模板名称" prop="title"></el-table-column>
  26. <el-table-column label="模板类型">
  27. <template slot-scope="scope">
  28. <span>{{ getType(scope.row.type) }}</span>
  29. </template>
  30. </el-table-column>
  31. <el-table-column label="模板状态">
  32. <template slot-scope="scope">
  33. <span>{{ getIsDel(scope.row.isDel) }}</span>
  34. </template>
  35. </el-table-column>
  36. <el-table-column label="模板宽高">
  37. <template slot-scope="scope">
  38. <span>{{ scope.row.width + ' * ' + scope.row.height }}</span>
  39. </template>
  40. </el-table-column>
  41. <el-table-column label="纸张大小">
  42. <template slot-scope="scope">
  43. <span>{{ scope.row.pageWidth + 'mm * ' + scope.row.pageHeight + 'mm' }}</span>
  44. </template>
  45. </el-table-column>
  46. <el-table-column align="right">
  47. <template slot="header">
  48. <el-button size="mini" type="primary" @click="openCreate">创建模板</el-button>
  49. </template>
  50. <template slot-scope="scope">
  51. <el-button type="text" size="mini" @click="handleEdit(scope.row)">设计</el-button>
  52. <el-button type="text" size="mini" @click="handlePreview(scope.row)">预览</el-button>
  53. <el-button type="text" size="mini" @click="handlePrint(scope.row)">打印</el-button>
  54. <el-button v-if="scope.row.isDel" type="text" size="mini" @click="handleRecover(scope.row)">恢复</el-button>
  55. <el-button v-if="!scope.row.isDel" type="text" size="mini" @click="handleDelete(scope.row)">删除</el-button>
  56. <el-button type="text" size="mini" @click="handleCopy(scope.row)">复制新增</el-button>
  57. </template>
  58. </el-table-column>
  59. </el-table>
  60. <el-dialog title="添加模板" :visible.sync="visible" width="310px">
  61. <el-form ref="form" :model="form" size="small" :rules="rules" label-width="80px">
  62. <el-form-item label="模板名称" prop="title">
  63. <el-input v-model="form.title"></el-input>
  64. </el-form-item>
  65. <el-form-item label="模板类型" prop="type">
  66. <el-select v-model="form.type">
  67. <el-option v-for="(item, index) in typeArr" :key="index" :label="item.name" :value="item.id"></el-option>
  68. </el-select>
  69. </el-form-item>
  70. <!-- <el-form-item label="模板宽度" prop="width">
  71. <el-input v-model="form.width"></el-input>
  72. </el-form-item>
  73. <el-form-item label="模板高度" prop="height">
  74. <el-input v-model="form.height"></el-input>
  75. </el-form-item>
  76. <el-form-item label="纸张宽度" prop="pageWidth">
  77. <el-input v-model="form.pageWidth"></el-input>
  78. </el-form-item>
  79. <el-form-item label="纸张高度" prop="pageHeight">
  80. <el-input v-model="form.pageHeight"></el-input>
  81. </el-form-item> -->
  82. </el-form>
  83. <div slot="footer" class="dialog-footer">
  84. <el-button size="mini" @click="visible = false">取 消</el-button>
  85. <el-button type="primary" size="mini" @click="savaTemp">确 定</el-button>
  86. </div>
  87. </el-dialog>
  88. </section>
  89. <!-- <section v-if="false">
  90. <div class="section">模板打印测试</div>
  91. <el-form ref="printForm" :model="printForm" size="small" :rules="printRules" :inline="true">
  92. <el-form-item label="打印模板" prop="tempIndex">
  93. <el-select v-model="printForm.tempIndex">
  94. <el-option v-for="(item, index) in tempList" :key="index" :label="item.title" :value="index"></el-option>
  95. </el-select>
  96. </el-form-item>
  97. <el-form-item label="测试数据" prop="data">
  98. <el-input type="textarea" style="width:520px" :rows="6" v-model="printForm.data"
  99. placeholder="数据模板对应的数据,数据格式为json对象"></el-input>
  100. </el-form-item>
  101. <el-form-item>
  102. <div>
  103. <el-button size="mini" type="primary" @click="printPreview(1)">打印预览</el-button>
  104. </div>
  105. <div style="margin-top:10px">
  106. <el-button size="mini" type="success" @click="printPreview(2)">直接打印</el-button>
  107. </div>
  108. </el-form-item>
  109. </el-form>
  110. </section>
  111. <section v-if="false">
  112. <el-collapse>
  113. <el-collapse-item title="测试数据" name="1">
  114. <el-form ref="testData" :model="testData" size="small" :inline="true">
  115. <el-form-item label="出库数据">
  116. <el-input type="textarea" style="width:920px" :rows="8" v-model="testData.OutStock"
  117. placeholder="数据模板对应的数据,数据格式为json对象"></el-input>
  118. </el-form-item>
  119. <el-form-item label="入库数据">
  120. <el-input type="textarea" style="width:920px" :rows="8" v-model="testData.InStock"
  121. placeholder="数据模板对应的数据,数据格式为json对象"></el-input>
  122. </el-form-item>
  123. </el-form>
  124. </el-collapse-item>
  125. </el-collapse>
  126. </section> -->
  127. </div>
  128. </template>
  129. <script>
  130. import { Table, TableColumn, Dialog, MessageBox, Message } from 'element-ui'
  131. import Vue from 'vue'
  132. Vue.prototype.$confirm = (...args) => MessageBox.confirm(...args)
  133. Vue.prototype.$message = Message
  134. const baseUrl = process.env.VUE_APP_BASE_API;
  135. import { OutStockData, InStockData } from '../data/test'
  136. export default {
  137. data() {
  138. return {
  139. visible: false,
  140. tenantId: "",
  141. value: {},
  142. tempList: [],
  143. typeArr: [],
  144. searchForm: {
  145. name: '',
  146. type: '',
  147. isDel: ''
  148. },
  149. isDelArr: [
  150. { name: "正常", id: 0 },
  151. { name: "已删除", id: 1 },
  152. ],
  153. form: {
  154. title: '',
  155. type: '',
  156. width: '',
  157. height: '',
  158. pageWidth: '',
  159. pageHeight: ''
  160. },
  161. rules: {
  162. title: { required: true, message: '请输入模板名称' },
  163. type: { required: true, message: '请选择模板类型' },
  164. width: { required: true, message: '请输入模板宽度' },
  165. height: { required: true, message: '请输入模板高度' },
  166. pageWidth: { required: true, message: '请输入纸张宽度' },
  167. pageHeight: { required: true, message: '请输入纸张高度' },
  168. },
  169. printForm: {
  170. tempIndex: '',
  171. data: '',
  172. },
  173. printRules: {
  174. tempIndex: { required: true, message: '请选择模板' },
  175. data: { required: true, message: '请输入模板测试数据' },
  176. },
  177. testData: {
  178. OutStock: JSON.stringify(OutStockData),
  179. InStock: JSON.stringify(InStockData),
  180. },
  181. }
  182. },
  183. methods: {
  184. // 预览
  185. handlePreview(row) {
  186. console.log(row, 'row')
  187. if (row.tempItems) {
  188. this.$lodop.previewTemp(row)
  189. } else {
  190. this.$message.error("空模板无法预览,请先点击设计添加模板数据!")
  191. }
  192. },
  193. // 打印
  194. handlePrint(row) {
  195. console.log(row, 'row')
  196. if (row.tempItems) {
  197. this.$lodop.print(row)
  198. } else {
  199. this.$message.error("空模板无法打印,请先点击设计添加模板数据!")
  200. }
  201. },
  202. // 设计
  203. handleEdit(row) {
  204. console.log(row, 'row')
  205. // 初次新增时,没有tempItems(Arry)字段,需要手动添加
  206. if (!row.tempItems || !row.tempItems.length) {
  207. row.tempItems = []
  208. }
  209. this.$router.push({
  210. path: '/designer',
  211. query: {
  212. tenantId: this.tenantId,
  213. printData: row
  214. },
  215. })
  216. },
  217. // 恢复
  218. handleRecover(row) {
  219. console.log(row, 'row')
  220. this.deleteOrRecover(row, 0)
  221. },
  222. // 删除
  223. handleDelete(row) {
  224. console.log(row, 'row')
  225. this.$confirm('删除该模板?, 是否继续?', '提示', {
  226. confirmButtonText: '确定',
  227. cancelButtonText: '取消',
  228. type: 'warning'
  229. }).then(() => {
  230. this.deleteOrRecover(row, 1)
  231. }).catch(() => {
  232. });
  233. },
  234. deleteOrRecover(item, flag) {
  235. const data = {
  236. id: item.id,
  237. tenantId: this.tenantId,
  238. isDel: flag,
  239. }
  240. this.$axios.post(baseUrl + "/print/setTemplatesDel", data)
  241. .then(res => {
  242. console.log(res, 'res')
  243. if (res.data.code == 200) {
  244. this.$message.success(flag ? "删除成功!" : "恢复成功!")
  245. this.getData()
  246. } else {
  247. this.$message.error(flag ? "删除失败!" : "恢复失败!")
  248. }
  249. })
  250. .catch(err => {
  251. console.error(err);
  252. this.$message.error(flag ? "删除失败!" : "恢复失败!")
  253. });
  254. },
  255. getType(num) {
  256. let name
  257. this.typeArr.forEach(item => {
  258. if (item.id == num)
  259. name = item.name
  260. })
  261. return name
  262. },
  263. getIsDel(num) {
  264. let name
  265. this.isDelArr.forEach(item => {
  266. if (item.id == num)
  267. name = item.name
  268. })
  269. return name
  270. },
  271. //复制新增
  272. handleCopy(row) {
  273. const data = {
  274. id: row.id,
  275. tenantId: this.tenantId,
  276. }
  277. this.$axios.post(baseUrl + "/print/copyTemplates", data)
  278. .then(res => {
  279. if (res.data.code == 200) {
  280. this.$message.success("新增成功!")
  281. this.getData()
  282. } else {
  283. this.$message.error("新增失败!")
  284. }
  285. })
  286. .catch(err => {
  287. console.error(err);
  288. this.$message.error("新增失败!")
  289. });
  290. },
  291. // 新增
  292. openCreate() {
  293. this.visible = true
  294. },
  295. // 保存新增
  296. savaTemp() {
  297. this.$refs.form.validate((valid) => {
  298. if (valid) {
  299. const data = {
  300. tenantId: this.tenantId,
  301. title: this.form.title,
  302. type: this.form.type
  303. }
  304. this.addNewModel(data)
  305. this.visible = false
  306. }
  307. })
  308. },
  309. addNewModel(data) {
  310. this.$axios.post(baseUrl + "/print/saveTemplates", data)
  311. .then(res => {
  312. console.log(res, 'res')
  313. if (res.data.code == 200) {
  314. this.$message.success("新增成功!")
  315. this.getData()
  316. } else {
  317. this.$message.error("新增失败!")
  318. }
  319. })
  320. .catch(err => {
  321. console.error(err);
  322. this.$message.error("新增失败!")
  323. });
  324. },
  325. getData() {
  326. this.getPrintTypes()
  327. this.getList()
  328. },
  329. getPrintTypes() {
  330. this.$axios.get(baseUrl + "/print/types")
  331. .then(res => {
  332. console.log(res, 'res')
  333. this.typeArr = res.data.data
  334. })
  335. .catch(err => {
  336. console.error(err);
  337. });
  338. },
  339. getList() {
  340. const url = baseUrl +
  341. "/print/printTemplates?isDel=" +
  342. this.searchForm.isDel +
  343. "&name=" +
  344. this.searchForm.name +
  345. "&type=" +
  346. this.searchForm.type +
  347. "&tenantId=" +
  348. this.tenantId
  349. this.$axios.get(url)
  350. .then(res => {
  351. console.log(res, 'res')
  352. const arr = []
  353. res.data.data.forEach(item => {
  354. item.contentJson.isDel = item.isDel
  355. arr.push(item.contentJson)
  356. });
  357. this.tempList = arr
  358. })
  359. .catch(err => {
  360. console.error(err);
  361. });
  362. }
  363. },
  364. created() {
  365. Vue.use(Table)
  366. Vue.use(TableColumn)
  367. Vue.use(Dialog)
  368. this.tempList = []
  369. const tenantId = this.$route.query.tenantId
  370. if (tenantId) this.tenantId = tenantId
  371. this.getData()
  372. },
  373. }
  374. </script>
  375. <style lang="scss" scoped>
  376. .box {
  377. width: 1000px;
  378. margin: auto;
  379. padding: 10px 0;
  380. font-family: Arial, Helvetica, sans-serif;
  381. }
  382. .title {
  383. text-align: center;
  384. font-size: 24px;
  385. color: #1890ff;
  386. margin: 20px;
  387. font-weight: bold;
  388. }
  389. .section {
  390. font-size: 18px;
  391. color: #333333;
  392. padding: 10px 0;
  393. }
  394. .el-message-box {
  395. background-color: #1890ff;
  396. }
  397. </style>