index.ts 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. import Barcode from './Barcode.vue'
  2. import icon from '../assets/icon/icon_41barcode.svg'
  3. import type { IComponentModelConfig } from '../type'
  4. import i18n from '@/locales'
  5. import { stateList, flagOptions, stateOptions } from '@/constants'
  6. import defaultStyle from './style.json'
  7. import { getCode128BUnitLength } from './code128'
  8. const DEFAULT_TEXT = 'https://www.sv-elec.com/'
  9. const DEFAULT_SCALE = 1
  10. const DEFAULT_DIRECTION = 'horizontal'
  11. const BASE_THICKNESS = 60
  12. const normalizeScale = (value: number) => {
  13. return Math.max(1, Math.min(5, Math.round(Number(value) || DEFAULT_SCALE)))
  14. }
  15. const normalizeDirection = (value: string) => {
  16. return value === 'vertical' ? 'vertical' : DEFAULT_DIRECTION
  17. }
  18. const normalizeText = (value?: string) => {
  19. return value?.trim() || DEFAULT_TEXT
  20. }
  21. const getBarcodeWidth = (text?: string, scale?: number, direction?: string) => {
  22. const unitLength =
  23. getCode128BUnitLength(normalizeText(text)) ?? getCode128BUnitLength(DEFAULT_TEXT) ?? 1
  24. const currentScale = normalizeScale(scale || DEFAULT_SCALE)
  25. const currentDirection = normalizeDirection(direction || DEFAULT_DIRECTION)
  26. const longSide = Math.max(1, unitLength * currentScale)
  27. const shortSide = BASE_THICKNESS * currentScale
  28. return currentDirection === 'vertical' ? shortSide : longSide
  29. }
  30. const syncBarcodeWidth = (formData: any) => {
  31. formData.props.width = getBarcodeWidth(
  32. formData?.props?.text,
  33. formData?.props?.scale,
  34. formData?.props?.direction
  35. )
  36. }
  37. export default {
  38. label: i18n.global.t('barcode'),
  39. icon,
  40. component: Barcode,
  41. key: 'barcode',
  42. group: i18n.global.t('advance'),
  43. sort: 3,
  44. hasChildren: false,
  45. defaultStyle,
  46. onChangeSize: (props, size) => {
  47. return {
  48. width: getBarcodeWidth(props?.text, props?.scale, props?.direction),
  49. height: Math.max(1, Math.round(size.currentHeight || props?.height || BASE_THICKNESS))
  50. }
  51. },
  52. parts: [
  53. {
  54. name: 'main',
  55. stateList
  56. }
  57. ],
  58. defaultSchema: {
  59. name: 'barcode',
  60. props: {
  61. x: 0,
  62. y: 0,
  63. flags: [
  64. 'LV_OBJ_FLAG_CLICKABLE',
  65. 'LV_OBJ_FLAG_CLICK_FOCUSABLE',
  66. 'LV_OBJ_FLAG_SCROLLABLE',
  67. 'LV_OBJ_FLAG_SCROLL_ELASTIC',
  68. 'LV_OBJ_FLAG_SCROLL_MOMENTUM',
  69. 'LV_OBJ_FLAG_SCROLL_CHAIN_HOR',
  70. 'LV_OBJ_FLAG_SCROLL_CHAIN_VER',
  71. 'LV_OBJ_FLAG_SCROLL_CHAIN',
  72. 'LV_OBJ_FLAG_SCROLL_WITH_ARROW',
  73. 'LV_OBJ_FLAG_SNAPPABLE',
  74. 'LV_OBJ_FLAG_PRESS_LOCK',
  75. 'LV_OBJ_FLAG_GESTURE_BUBBLE'
  76. ],
  77. states: [],
  78. width: getBarcodeWidth(DEFAULT_TEXT, DEFAULT_SCALE, DEFAULT_DIRECTION),
  79. height: BASE_THICKNESS,
  80. text: DEFAULT_TEXT,
  81. lightColor: '#ffffff',
  82. darkColor: '#000000',
  83. scale: DEFAULT_SCALE,
  84. direction: DEFAULT_DIRECTION
  85. },
  86. styles: []
  87. },
  88. config: {
  89. props: [
  90. {
  91. label: '名称',
  92. field: 'name',
  93. valueType: 'text'
  94. },
  95. {
  96. label: '位置/大小',
  97. valueType: 'group',
  98. children: [
  99. {
  100. label: '',
  101. field: 'props.x',
  102. valueType: 'number',
  103. componentProps: {
  104. span: 12,
  105. min: -10000,
  106. max: 10000
  107. },
  108. slots: { prefix: 'X' }
  109. },
  110. {
  111. label: '',
  112. field: 'props.y',
  113. valueType: 'number',
  114. componentProps: {
  115. span: 12,
  116. min: -10000,
  117. max: 10000
  118. },
  119. slots: { prefix: 'Y' }
  120. },
  121. {
  122. label: '',
  123. field: 'props.height',
  124. valueType: 'number',
  125. componentProps: {
  126. span: 12,
  127. min: 1,
  128. max: 10000
  129. },
  130. slots: { prefix: 'H' }
  131. }
  132. ]
  133. },
  134. {
  135. label: '标识',
  136. field: 'props.flags',
  137. valueType: 'checkbox',
  138. componentProps: {
  139. options: flagOptions,
  140. defaultCollapsed: true
  141. }
  142. },
  143. {
  144. label: '状态',
  145. field: 'props.states',
  146. valueType: 'checkbox',
  147. componentProps: {
  148. options: stateOptions,
  149. defaultCollapsed: true
  150. }
  151. }
  152. ],
  153. coreProps: [
  154. {
  155. label: '暗色',
  156. field: 'props.darkColor',
  157. valueType: 'color'
  158. },
  159. {
  160. label: '亮色',
  161. field: 'props.lightColor',
  162. valueType: 'color'
  163. },
  164. {
  165. label: '缩放',
  166. field: 'props.scale',
  167. valueType: 'number',
  168. componentProps: {
  169. min: 1,
  170. max: 5,
  171. onValueChange: (_value: number, formData: any) => {
  172. syncBarcodeWidth(formData)
  173. }
  174. }
  175. },
  176. {
  177. label: '方向',
  178. field: 'props.direction',
  179. valueType: 'select',
  180. componentProps: {
  181. options: [
  182. { label: 'Horitional', value: 'horizontal' },
  183. { label: 'Vertical', value: 'vertical' }
  184. ],
  185. onValueChange: (_value: string, formData: any) => {
  186. syncBarcodeWidth(formData)
  187. }
  188. }
  189. },
  190. {
  191. label: '文本',
  192. field: 'props.text',
  193. valueType: 'textarea',
  194. componentProps: {
  195. onValueChange: (_value: string, formData: any) => {
  196. syncBarcodeWidth(formData)
  197. }
  198. }
  199. }
  200. ],
  201. styles: []
  202. }
  203. } as IComponentModelConfig