| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193 |
- import componentMap from '..'
- import { getImageByPath } from '@/utils'
- import { useProjectStore } from '@/store/modules/project'
- import { assign } from 'lodash-es'
- import { ref, watch } from 'vue'
- import type { IStyleConfig } from '../type'
- import type { CSSProperties } from 'vue'
- type StyleParam = {
- widget: keyof typeof componentMap
- props: {
- part?: string
- state?: string
- styles: IStyleConfig[]
- [key: string]: any
- }
- }
- type StyleMap = Record<
- string,
- CSSProperties & { imageSrc?: string; imageColorStyle?: CSSProperties }
- >
- /**
- * 获取样式
- * @param key
- * @param value
- * @returns
- */
- export const getStyle = (key, value) => {
- const style: CSSProperties = {}
- switch (key) {
- // 背景样式
- case 'background': {
- style.backgroundColor = value?.color
- break
- }
- // 文字样式
- case 'text': {
- style.color = value?.color
- style.fontSize = `${value?.size}px`
- style.fontFamily = value?.family
- style.textAlign = value?.align
- style.fontWeight = value?.weight === 'bold' ? 'bold' : 'normal'
- style.fontStyle = value?.italic ? 'italic' : 'normal'
- style.textDecoration = value?.strike
- ? 'line-through'
- : value?.underline
- ? 'underline'
- : 'none'
- break
- }
- // 边框样式
- case 'border': {
- style.borderColor = 'transparent'
- style.borderWidth = 0
- style.borderRadius = `${value?.radius}px`
- style.borderStyle = 'solid'
- if (value?.side?.includes('all') || value?.side?.includes('top')) {
- style.borderTopColor = value?.color
- style.borderTopWidth = `${value?.width || 0}px`
- }
- if (value?.side?.includes('all') || value?.side?.includes('right')) {
- style.borderRightColor = value?.color
- style.borderRightWidth = `${value?.width || 0}px`
- }
- if (value?.side?.includes('all') || value?.side?.includes('bottom')) {
- style.borderBottomColor = value?.color
- style.borderBottomWidth = `${value?.width || 0}px`
- }
- if (value?.side?.includes('all') || value?.side?.includes('left')) {
- style.borderLeftColor = value?.color
- style.borderLeftWidth = `${value?.width || 0}px`
- }
- break
- }
- // 外边框样式
- case 'outline': {
- style.outlineColor = value?.color
- style.outlineWidth = `${value?.width}px`
- style.outlineStyle = 'solid'
- break
- }
- // 阴影样式
- case 'shadow': {
- style.boxShadow = `${value?.x}px ${value?.y}px ${value?.width}px ${value?.spread}px ${value?.color}`
- break
- }
- // 内边距样式
- case 'padding': {
- style.padding = `${value?.top || 0}px ${value?.right || 0}px ${value?.bottom || 0}px ${value?.left || 0}px`
- if (value?.row) {
- style.rowGap = `${value?.row}px`
- }
- if (value?.column) {
- style.columnGap = `${value?.column}px`
- }
- break
- }
- // 外边距样式
- case 'margin': {
- style.margin = `${value?.top || 0}px ${value?.right || 0}px ${value?.bottom || 0}px ${value?.left || 0}px`
- break
- }
- // 间距样式
- case 'spacer': {
- style.letterSpacing = `${value?.letterSpacing}px`
- break
- }
- }
- return style
- }
- /**
- * 根据控件part、state获取控件样式
- * @param param - StyleParam
- * @returns
- */
- export const useWidgetStyle = (param: StyleParam) => {
- const projectStore = useProjectStore()
- const widget = param.widget
- // 全局默认样式
- const defaultStyle = componentMap[widget]?.defaultStyle
- // 控件模块状态
- const parts = componentMap[widget].parts
- // 控件样式集合
- const styleMap = ref<StyleMap>({})
- const handleStyle = () => {
- const { part, state, styles = [] } = param.props
- parts.forEach((partItem) => {
- styleMap.value[`${partItem.name}Style`] = {}
- // 从控件配置的样式列表查找对应样式
- let style = styles.find(
- // part为当前part时,根据state获取 否则取第一个state样式
- (s) =>
- s.part?.name === partItem.name &&
- s.part?.state === (part === partItem.name ? state : partItem.stateList?.[0])
- )
- // 配置样式未配置时,从默认样式中获取
- if (!style) {
- style = defaultStyle?.part
- ?.find((item) => item.partName === partItem.name)
- ?.state?.find(
- (s) => s.state === (part === partItem.name ? state : partItem.stateList?.[0])
- )?.style
- }
- // 遍历style 获取样式
- Object.keys(style || {}).forEach((key) => {
- // 合并样式
- assign(styleMap.value[`${partItem.name}Style`], getStyle(key, style?.[key]))
- // 获取背景图片src及颜色
- if (key === 'background' && style?.[key]?.image?.imgId) {
- const basePath = projectStore?.project?.meta.path
- const imagePath = projectStore?.project?.resources.images.find(
- (item) => item.id === style?.[key]?.image?.imgId
- )?.path
- if (basePath && imagePath) {
- getImageByPath(basePath + imagePath).then((res) => {
- if (res?.base64) {
- styleMap.value[`${partItem.name}Style`].imageSrc = res.base64
- styleMap.value[`${partItem.name}Style`].imageColorStyle = {
- background: style?.[key]?.image?.color
- }
- }
- })
- }
- }
- })
- // 处理行高 默认行高为1.2倍
- if (style?.spacer?.lineHeight && style?.text?.size) {
- const baseHeight = style.text.size * 1.2
- styleMap.value[`${partItem.name}Style`].lineHeight =
- `${baseHeight + style.spacer.lineHeight}px`
- }
- })
- }
- watch(() => param.props, handleStyle, {
- deep: true,
- immediate: true
- })
- return styleMap
- }
|