223 lines
6.7 KiB
Plaintext
223 lines
6.7 KiB
Plaintext
<template>
|
||
<!-- #ifdef APP-->
|
||
<view class="l-barcode" ref="barcodeRef"></view>
|
||
<!-- #endif -->
|
||
<!-- #ifndef APP-->
|
||
<view class="l-barcode" :style="[styles, lStyle]">
|
||
<canvas class="l-barcode__canvas" id="barcode"></canvas>
|
||
</view>
|
||
<!-- #endif -->
|
||
</template>
|
||
<script lang="uts" setup>
|
||
/**
|
||
* BarCode 条形码组件
|
||
* @description 用于生成各类条形码的显示组件,支持多种编码格式和样式配置
|
||
* <br> 插件类型:LBarcodeComponentPublicInstance
|
||
* @tutorial https://ext.dcloud.net.cn/plugin?name=lime-barcode
|
||
*
|
||
* @property {string} format 条形码格式(必填)'CODE128' | 'EAN-13' | 'UPC' | 'CODE39' | 'ITF-14' 等标准格式
|
||
* @value 'CODE128'
|
||
* @value 'EAN-13'
|
||
* @value 'UPC'
|
||
* @value 'CODE39'
|
||
* @value 'ITF-14'
|
||
* @property {string | number} lineWidth 条线宽度(单位px)
|
||
* @property {string | number} lineLength 条线长度(单位px)
|
||
* @property {boolean} displayValue 是否显示条码下方文本
|
||
* @property {string} text 自定义显示文本(覆盖默认编码值)
|
||
* @property {string} fontOptions 字体样式扩展(预留字段)
|
||
* @property {string} [font] 字体名称(例:'bold 16px Arial')
|
||
* @property {'left' | 'center' | 'right'} textAlign 文本水平对齐
|
||
* @property {'top' | 'bottom'} textPosition 文本相对位置
|
||
* @property {string | number} textMargin 文本与条码间距(单位px)
|
||
* @property {string | number} fontSize 文本字号(单位px)
|
||
* @property {string} background 背景颜色(支持CSS颜色值)
|
||
* @property {string} lineColor 条线颜色(支持CSS颜色值)
|
||
* @property {string | number} margin 整体外边距(单位px)
|
||
* @property {string | number} marginTop 上边距(优先级高于margin)
|
||
* @property {string | number} marginBottom 下边距(优先级高于margin)
|
||
* @property {string | number} marginLeft 左边距(优先级高于margin)
|
||
* @property {string | number} marginRight 右边距(优先级高于margin)
|
||
* @property {boolean} flat 是否启用扁平样式(去除空白区域)
|
||
* @property {boolean} ean128 是否启用EAN-128扩展格式
|
||
* @property {boolean} useCanvasToTempFilePath 是否启用canvas生成临时路径
|
||
* @property {string} lStyle 预留样式扩展字段
|
||
* @event {Function} success 条码生成成功时触发
|
||
*/
|
||
import { unitConvert } from '@/uni_modules/lime-shared/unitConvert';
|
||
// #ifdef APP
|
||
import { renderer, LBarcodeGenOptions } from '@/uni_modules/lime-barcodegen';
|
||
// #endif
|
||
// #ifndef APP
|
||
import { addUnit } from '@/uni_modules/lime-shared/addUnit'
|
||
import { useCanvas } from './useCanvas'
|
||
import { CanvasRenderer } from './barcode.ts'
|
||
import { LBarcodeGenOptions } from '@/uni_modules/lime-barcodegen/utssdk/interface';
|
||
// #endif
|
||
import type { LBarcodeFailCallback, LBarcodeCompleteCallback, LBarcodeSuccessCallback, BarCodeProps} from './type'
|
||
// defineOptions({name: 'l-barcode'})
|
||
|
||
const emits = defineEmits(['success'])
|
||
const props = withDefaults(defineProps<BarCodeProps>(), {
|
||
format:'',
|
||
displayValue: true,
|
||
text: '',
|
||
fontOptions: '',
|
||
textPosition: '',
|
||
flat: false,
|
||
ean128: false,
|
||
useCanvasToTempFilePath: false,
|
||
})
|
||
const barcodeRef = ref<UniElement|null>(null)
|
||
// #ifndef APP
|
||
const canvasId = 'barcode'
|
||
const instance = getCurrentInstance()!.proxy!;
|
||
const canvas = useCanvas(canvasId, instance)
|
||
const styles = computed(() => {
|
||
return {
|
||
width: addUnit(canvas.width),
|
||
height: addUnit(canvas.height),
|
||
}
|
||
})
|
||
// #endif
|
||
|
||
const canvasToTempFilePath = (options: UTSJSONObject)=>{
|
||
// #ifdef APP
|
||
const format = options.getString('format') ?? 'png';
|
||
const fail = options.get('fail') as LBarcodeFailCallback | null;
|
||
const complete = options.get('complete') as LBarcodeCompleteCallback | null;
|
||
const success = options.get('success') as LBarcodeSuccessCallback | null;
|
||
|
||
if(barcodeRef.value == null) {
|
||
fail?.({
|
||
errMsg: '插件未加载完成!'
|
||
})
|
||
return
|
||
}
|
||
|
||
barcodeRef.value?.takeSnapshot({
|
||
format,
|
||
success(res : TakeSnapshotSuccess) {
|
||
if(success == null) return
|
||
success({
|
||
errMsg: "canvasToTempFilePath:ok",
|
||
tempFilePath: res.tempFilePath
|
||
})
|
||
|
||
},
|
||
fail(err: TakeSnapshotFail) {
|
||
if(fail == null) return
|
||
fail({
|
||
errMsg: err.errMsg
|
||
})
|
||
},
|
||
complete(res: any) {
|
||
if(complete == null) return
|
||
complete(res)
|
||
}
|
||
})
|
||
// #endif
|
||
// #ifndef APP
|
||
if(canvas.node){
|
||
if(canvas._node){
|
||
const result = {
|
||
errMsg: "canvasToTempFilePath:ok",
|
||
tempFilePath: canvas.node?.toDataURL()
|
||
}
|
||
options.success?.(result)
|
||
} else {
|
||
uni.canvasToTempFilePath({
|
||
canvasId,
|
||
...options,
|
||
}, instance)
|
||
}
|
||
}
|
||
// #endif
|
||
}
|
||
const callback = ()=>{
|
||
if (props.useCanvasToTempFilePath) {
|
||
setTimeout(() => {
|
||
canvasToTempFilePath({
|
||
success: (res: TakeSnapshotSuccess) => {
|
||
emits('success', res.tempFilePath)
|
||
},
|
||
fail: (_: TakeSnapshotFail) => {
|
||
uni.showToast({
|
||
icon: 'error',
|
||
title: '截图失败'
|
||
})
|
||
}
|
||
})
|
||
},200)
|
||
}
|
||
}
|
||
|
||
const setOptions = () => {
|
||
const options:LBarcodeGenOptions = {
|
||
format: props.format,
|
||
displayValue: props.displayValue,
|
||
text: props.text,
|
||
textPosition: props.textPosition,
|
||
lineColor: props.lineColor,
|
||
flat: props.flat,
|
||
ean128: props.ean128,
|
||
fontOptions: props.fontOptions,
|
||
width: unitConvert(props.lineWidth ?? 2),
|
||
height: unitConvert(props.lineLength ?? 60),
|
||
textMargin: props.textMargin == null ? null : unitConvert(props.textMargin),
|
||
fontSize: props.fontSize == null ? null : unitConvert(props.fontSize),
|
||
margin: unitConvert(props.margin ?? 10),
|
||
marginTop: props.marginTop == null ? null : unitConvert(props.marginTop),
|
||
marginBottom: props.marginBottom == null ? null : unitConvert(props.marginBottom),
|
||
marginLeft: props.marginLeft == null ? null : unitConvert(props.marginLeft),
|
||
marginRight: props.marginRight == null ? null : unitConvert(props.marginRight)
|
||
}
|
||
// #ifdef APP
|
||
if(barcodeRef.value == null) return
|
||
barcodeRef.value?.getBoundingClientRectAsync()?.then(res=>{
|
||
renderer(barcodeRef.value!, `${props.text}`, options)
|
||
callback()
|
||
})
|
||
// #endif
|
||
// #ifndef APP
|
||
// @ts-ignore
|
||
if(canvas.node == null) return
|
||
// @ts-ignore
|
||
CanvasRenderer(canvas.node, `${props.text}`, options, callback)
|
||
// #endif
|
||
}
|
||
|
||
onMounted(()=>{
|
||
nextTick(()=>{
|
||
watchEffect(setOptions)
|
||
})
|
||
})
|
||
|
||
defineExpose({
|
||
canvasToTempFilePath
|
||
})
|
||
|
||
</script>
|
||
<style lang="scss">
|
||
/* #ifndef APP-ANDROID || APP-IOS || APP-HARMONY */
|
||
:host {
|
||
display: inline-block;
|
||
}
|
||
/* #endif */
|
||
|
||
.l-barcode {
|
||
&__text {
|
||
align-self: flex-start;
|
||
}
|
||
&__canvas {
|
||
width: 100%;
|
||
height: 100%;
|
||
}
|
||
/* #ifdef WEB */
|
||
align-self: start;
|
||
/* #endif */
|
||
}
|
||
|
||
</style>
|
||
|