提交 b47fcec2 编写于 作者: G guop 提交者: ninecents

添加生成条形码功能 #89

1. 添加以来vue-color,jsbarcode。
vue-color 是一个颜色选择器.
https://github.com/xiaokaike/vue-color.git

jsbarcode 是该功能的核心工具,能够生成各类条形码
https://github.com/lindell/JsBarcode.git

2. 仿照jsbarcode的demo页面将条码生成功能集成到CTool中
https://lindell.me/JsBarcode/generator/
上级 face1458
{
"name": "c-tool",
"version": "1.8.1",
"version": "1.8.3",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
......@@ -3265,6 +3265,11 @@
"dev": true,
"optional": true
},
"clamp": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/clamp/-/clamp-1.0.1.tgz",
"integrity": "sha1-ZqDmQBGBbjcZaCj9yMjBRzEshjQ="
},
"class-utils": {
"version": "0.3.6",
"resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz",
......@@ -7001,6 +7006,11 @@
"esprima": "^4.0.0"
}
},
"jsbarcode": {
"version": "3.11.5",
"resolved": "https://registry.npmjs.org/jsbarcode/-/jsbarcode-3.11.5.tgz",
"integrity": "sha512-zv3KsH51zD00I/LrFzFSM6dst7rDn0vIMzaiZFL7qusTjPZiPtxg3zxetp0RR7obmjTw4f6NyGgbdkBCgZUIrA=="
},
"jsbn": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz",
......@@ -7636,6 +7646,11 @@
"object-visit": "^1.0.0"
}
},
"material-colors": {
"version": "1.2.6",
"resolved": "https://registry.npmjs.org/material-colors/-/material-colors-1.2.6.tgz",
"integrity": "sha512-6qE4B9deFBIa9YSpOc9O0Sgc43zTeVYbgDT5veRKSlB2+ZuHNoVVxA1L/ckMUayV9Ay9y7Z/SZCLcGteW9i7bg=="
},
"md5.js": {
"version": "1.3.5",
"resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz",
......@@ -12345,6 +12360,17 @@
"integrity": "sha512-cCjEgTD4nO5YQeRgdrrOqN7Qc2MzBx2u90J/CJ3Gp4PZ2sUONZE67/Qy+zWNHCWVCYsSEIvbnPSuiiQeEr1KSQ==",
"dev": true
},
"vue-color": {
"version": "2.8.1",
"resolved": "https://registry.npmjs.org/vue-color/-/vue-color-2.8.1.tgz",
"integrity": "sha512-BoLCEHisXi2QgwlhZBg9UepvzZZmi4176vbr+31Shen5WWZwSLVgdScEPcB+yrAtuHAz42309C0A4+WiL9lNBw==",
"requires": {
"clamp": "^1.0.1",
"lodash.throttle": "^4.0.0",
"material-colors": "^1.0.0",
"tinycolor2": "^1.1.2"
}
},
"vue-eslint-parser": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-5.0.0.tgz",
......
......@@ -21,14 +21,15 @@
"cronstrue": "^1.122.0",
"crypto-js": "^3.3.0",
"file": "^0.2.2",
"http-build-query": "^0.7.0",
"ipinyinjs": "^1.0.0",
"is-url": "^1.2.4",
"jian_fan": "^1.0.3",
"js-base64": "^2.6.4",
"js-htmlencode": "^0.3.0",
"js-yaml": "^3.14.1",
"jsbarcode": "^3.11.5",
"json-to-properties": "^1.1.3",
"json5": "^2.2.0",
"jsonlint": "^1.6.3",
"jsrsasign": "^10.4.1",
"jsrsasign-util": "^1.0.5",
......@@ -48,14 +49,14 @@
"properties-to-json": "^0.1.7",
"qrcode": "^1.4.4",
"qrcode-parser": "^1.2.0",
"query-string": "^6.14.1",
"query-string": "^6.13.7",
"serialize-php": "^1.1.2",
"sm-crypto": "^0.1.4",
"system": "^2.0.1",
"uuid": "^8.3.2",
"view-design": "^4.6.1",
"vue": "^2.6.14",
"vue-i18n": "^8.26.5",
"vue-color": "^2.8.1",
"vue-router": "^3.5.3",
"x2js": "github:abdolence/x2js"
},
......@@ -93,9 +94,6 @@
},
"parserOptions": {
"parser": "babel-eslint"
},
"globals": {
"__": "writable"
}
},
"postcss": {
......
......@@ -14,51 +14,54 @@ const DEFAULT_COMMON_TOOL = [
]
const category = [
{'name': 'common'},
{'name': 'encryption'},
{'name': 'conversion'},
{'name': 'serialize'},
{'name': 'check'},
{'name': 'generate'},
{'name': 'other'},
{'name': 'common', 'title': '常用'},
{'name': 'encryption', 'title': '加解密'},
{'name': 'conversion', 'title': '转换'},
{'name': 'serialize', 'title': '序列化'},
{'name': 'check', 'title': '校验'},
{'name': 'generate', 'title': '生成'},
{'name': 'other', 'title': '其他'},
]
const tool = [
{
'name': 'hash',
'title': '哈希(hash)',
'cat': ['encryption']
},
{
'name': 'encrypt',
'title': '加密/解密',
'cat': ['encryption']
},
{'name': 'sign', 'cat': ['encryption']},
{'name': 'base64', 'cat': ['encryption']},
{'name': 'json', 'cat': ['conversion', 'serialize']},
{'name': 'url', 'cat': ['conversion']},
{'name': 'timestamp', 'cat': ['conversion']},
{'name': 'qrCode', 'cat': ['generate']},
{'name': 'pinyin', 'cat': ['conversion']},
{'name': 'ip', 'cat': ['other']},
{'name': 'code', 'cat': ['other']},
{'name': 'unicode', 'cat': ['conversion']},
{'name': 'decimalConvert', 'cat': ['conversion']},
{'name': 'regex', 'cat': ['check']},
{'name': 'randomString', 'cat': ['generate']},
{'name': 'serializeConversion', 'cat': ['conversion', 'serialize']},
{'name': 'diffs', 'cat': ['check']},
{'name': 'crontab', 'cat': ['check']},
{'name': 'websocket', 'cat': ['other']},
{'name': 'unit', 'cat': ['other']},
{'name': 'time', 'cat': ['other']},
{'name': 'uuid', 'cat': ['generate']},
{'name': 'jsonToObject', 'cat': ['conversion', 'serialize']},
{'name': 'ascii', 'cat': ['conversion']},
{'name': 'variableConversion', 'cat': ['conversion']},
{'name': 'jwt', 'cat': ['conversion']},
{'name': 'hexString', 'cat': ['conversion']},
{'name': 'text', 'cat': ['other']},
{'name': 'html', 'cat': ['conversion']},
{'name': 'sign', 'title': '签名/验签', 'cat': ['encryption']},
{'name': 'base64', 'title': 'BASE64编码', 'cat': ['encryption']},
{'name': 'json', 'title': 'JSON工具', 'cat': ['conversion', 'serialize']},
{'name': 'url', 'title': 'URL编码', 'cat': ['conversion']},
{'name': 'timestamp', 'title': '时间戳', 'cat': ['conversion']},
{'name': 'qrCode', 'title': '二维码', 'cat': ['generate']},
{'name': 'barcode', 'title': '条形码', 'cat': ['generate']},
{'name': 'pinyin', 'title': '汉字转拼音', 'cat': ['conversion']},
{'name': 'ip', 'title': 'IP地址查询', 'cat': ['other']},
{'name': 'code', 'title': '代码格式化', 'cat': ['other']},
{'name': 'unicode', 'title': 'Unicode', 'cat': ['conversion']},
{'name': 'decimalConvert', 'title': '进制转换', 'cat': ['conversion']},
{'name': 'regex', 'title': '正则表达式', 'cat': ['check']},
{'name': 'randomString', 'title': '随机字符生成', 'cat': ['generate']},
{'name': 'serializeConversion', 'title': '序列化转换', 'cat': ['conversion', 'serialize']},
{'name': 'diffs', 'title': '文本差异化对比', 'cat': ['check']},
{'name': 'crontab', 'title': 'crontab校验', 'cat': ['check']},
{'name': 'websocket', 'title': 'websocket调试', 'cat': ['other']},
{'name': 'unit', 'title': '单位换算', 'cat': ['other']},
{'name': 'time', 'title': '时间计算器', 'cat': ['other']},
{'name': 'uuid', 'title': 'UUID生成', 'cat': ['generate']},
{'name': 'jsonToObject', 'title': 'JSON转实体类', 'cat': ['conversion', 'serialize']},
{'name': 'ascii', 'title': 'ASCII转换', 'cat': ['conversion']},
{'name': 'variableConversion', 'title': '变量名转换', 'cat': ['conversion']},
{'name': 'jwt', 'title': 'JWT解码', 'cat': ['conversion']},
{'name': 'hexString', 'title': 'Hex/String转换', 'cat': ['conversion']},
{'name': 'text', 'title': '文本处理', 'cat': ['other']},
{'name': 'html', 'title': 'html编码', 'cat': ['conversion']},
]
// 工具类功能配置
......
......@@ -70,6 +70,10 @@ const routes = [
path: '/tool/qrCode',
component: r => require(['./views/tool/qrCode.vue'], r)
},
{
path: '/tool/barcode',
component: r => require(['./views/tool/barcode.vue'], r)
},
{
path: '/tool/randomString',
component: r => require(['./views/tool/randomString.vue'], r)
......
<template>
<div>
<Row>
<Col span="12">
<Card>
<Form :label-width="100">
<FormItem label="条码内容">
<Input v-model="current.text">
<Select v-model="current.format" slot="append" style="width: 100px">
<Option v-for="type in barcodeFormat" :key="type" :value="type">{{ type }}</Option>
</Select>
</Input>
</FormItem>
<FormItem label="条码宽" class="line-item">
<Row>
<Col span="22">
<Slider v-model="current.width" :min="0" :max="4"></Slider>
</Col>
<Col span="2">
<span style="float: right">{{ this.current.width }}</span>
</Col>
</Row>
</FormItem>
<FormItem label="条码高" class="line-item">
<Row>
<Col span="22">
<Slider v-model="current.height" :min="10" :max="150"></Slider>
</Col>
<Col span="2">
<span style="float: right">{{ this.current.height }}</span>
</Col>
</Row>
</FormItem>
<FormItem label="条码外边距" class="line-item">
<Row>
<Col span="22">
<Slider v-model="current.margin" :min="0" :max="25"></Slider>
</Col>
<Col span="2">
<span style="float: right">{{ this.current.margin }}</span>
</Col>
</Row>
</FormItem>
<FormItem label="背景" class="line-item">
<Input type="text" id="backgroundInput" v-model="current.background.hex"
@on-focus="openBackgroundPicker($event)"></Input>
<chrome-picker v-show="showBackgroundPicker" id="backgroundPicker" style="position: fixed;z-index: 1000"
v-model="current.background"
@input="updateBackground"/>
</FormItem>
<FormItem label="线条颜色" class="line-item">
<Input type="text" id="lineColorInput" v-model="current.lineColor.hex"
@on-focus="openLineColorPicker"></Input>
<chrome-picker v-show="showLineColoePicker" id="lineColorPicker" style="position: fixed;z-index: 1000"
v-model="current.lineColor"
@input="updateLineColor"/>
</FormItem>
<FormItem label="显示文本" class="line-item">
<RadioGroup v-model="current.showText" type="button">
<Radio label="true">
<span>显示</span>
</Radio>
<Radio label="false">
<span>隐藏</span>
</Radio>
</RadioGroup>
</FormItem>
<div v-if="this.current.showText === 'true'">
<FormItem label="字体位置" class="line-item">
<RadioGroup v-model="current.textAlign" type="button">
<Radio label="left">
<span>居左</span>
</Radio>
<Radio label="center">
<span>居中</span>
</Radio>
<Radio label="right">
<span>居右</span>
</Radio>
</RadioGroup>
</FormItem>
<FormItem label="字体" class="line-item">
<Select v-model="current.font">
<Option v-for="font in fontFamily" :key="font" :value="font">{{ font }}</Option>
</Select>
</FormItem>
<FormItem label="字体样式" class="line-item">
<CheckboxGroup v-model="current.fontOptions">
<Checkbox label="bold">
<span>粗体</span>
</Checkbox>
<Checkbox label="italic">
<span>斜体</span>
</Checkbox>
</CheckboxGroup>
</FormItem>
<FormItem label="字体大小" class="line-item">
<Row>
<Col span="22">
<Slider v-model="current.fontSize" :min="8" :max="36"></Slider>
</Col>
<Col span="2">
<span style="float: right">{{ this.current.fontSize }}</span>
</Col>
</Row>
</FormItem>
<FormItem label="字体外边距" class="line-item">
<Row>
<Col span="22">
<Slider v-model="current.textMargin" :min="-15" :max="40"></Slider>
</Col>
<Col span="2">
<span style="float: right">{{ this.current.textMargin }}</span>
</Col>
</Row>
</FormItem>
</div>
</Form>
</Card>
</Col>
<Col span="12">
<Card>
<div>
<canvas id="barcode"></canvas>
<p style="color: red">{{ validStr }}</p>
</div>
</Card>
</Col>
</Row>
</div>
</template>
<script>
/**
* @author alvinkwok
* @date 2021/10/30
* 基于jsbarcode生成条形码,可以自定义条码各项属性
* 不支持中文
* 颜色选择器采用vue-color
*/
import JsBarcode from 'jsbarcode'
import {Chrome} from 'vue-color'
export default {
created() {
this.current = Object.assign(this.current, this.$getToolData("content"))
},
components: {
'chrome-picker': Chrome,
},
mounted() {
// 加载颜色选择器消失的事件
this.loadEvent()
// 生成默认的条形码
this.generate()
},
beforeDestroy() {
// 移除挂载时添加的事件
document.removeEventListener('click', () => {
}, true)
},
watch: {
current: {
handler() {
this.generate()
},
deep: true
}
},
methods: {
/**
* 检查
* @param event
* @param id
* @returns {boolean}
*/
checkNodeContainsId(event, id) {
// 检查目标元素及目标元素上层是否存在指定id元素
let et = event.target
while (et && et.id !== undefined) {
// 检查当前元素上是否存在指定
if (et.id === id) {
return true
}
et = et.parentNode
}
},
loadEvent() {
let _this = this
document.addEventListener('click', (e) => {
// 如果点击的区域不是输入框或者是背景色选择器则将背景选择器隐藏
if (!_this.checkNodeContainsId(e, 'backgroundInput') && !_this.checkNodeContainsId(e, 'backgroundPicker')) {
_this.showBackgroundPicker = false
}
// 同理
if (!_this.checkNodeContainsId(e, 'lineColorInput') && !_this.checkNodeContainsId(e, 'lineColorPicker')) {
_this.showLineColoePicker = false
}
})
},
openBackgroundPicker() {
this.showBackgroundPicker = true
this.showLineColoePicker = false
},
updateBackground(val) {
this.current.background = val
},
openLineColorPicker() {
this.showLineColoePicker = true
this.showBackgroundPicker = false
},
updateLineColor(val) {
this.current.lineColor = val
},
closeColorPicker() {
this.showLineColoePicker = false
this.showBackgroundPicker = false
},
generate() {
let _this = this;
// 处理字体样式
let fontOptions = this.current.fontOptions.join(" ")
JsBarcode("#barcode", this.current.text, {
format: this.current.format,//选择要使用的条形码类型
width: this.current.width,
height: this.current.height,
margin: this.current.margin,
background: this.current.background.hex,
lineColor: this.current.lineColor.hex,
displayValue: this.current.showText,//是否在条形码下方显示文字
textPosition: "bottom",//设置文本的垂直位置
textAlign: this.current.textAlign,
font: this.current.font,
fontOptions: fontOptions,
fontSize: this.current.fontSize,
textMargin: this.current.textMargin,
valid: function (valid) {
// 显示条码内容无效
if (!valid) {
_this.validStr = "无效的条码内容"
} else {
_this.validStr = ""
}
}
})
},
},
data() {
return {
current: {
text: "Test 123456789",
format: "CODE128",
width: 2,
height: 50,
margin: 10,
background: {
hex: '#FFFFFF',
},
lineColor: {
hex: '#000000',
},
showText: "true",
textAlign: "center",
font: "monospace",
fontOptions: [],
fontSize: 20,
textMargin: 0
},
validStr: '',
// 背景色选择器控制开关
showBackgroundPicker: false,
// 线条颜色选择器控制开关
showLineColoePicker: false,
// 条码格式
barcodeFormat: [
"CODE128",
"CODE128A",
"CODE128B",
"CODE128C",
"EAN13",
"EAN8",
"UPC",
"CODE39",
"ITF14",
"ITF",
"MSI",
"MSI10",
"MSI11",
"MSI1010",
"MSI1110",
"pharmacode",
],
fontFamily: [
"monospace",
"Sans-serif",
"Serif",
"Fantasy",
"Cursive"
]
}
},
}
</script>
<style scoped>
/**iview原来的formitem太高了,在浏览器直接使用插件时会被撑开,因此需要压缩下高度**/
.line-item {
margin-top: -20px;
}
</style>
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册