import _ from "lodash" import { getDefaultProps } from "../libs/props.js" import { customAlphabet } from "nanoid" import getWidgetsSetting from "../components/components/widgets/widgetsSetting" const nanoid = customAlphabet("1234567890abcdef", 10) export interface printProps { zoom: number type: string index: number uuid: number originX: number originY: number startX: number startY: number moving: boolean optionItems: Array page: pageApi tempId: string loading: boolean backgroundUrl: string activeElement: any widgetSetting: any resizing: boolean } export interface pageApi { title: string width: number height: number pageWidth: number pageHeight: number topMargin: number leftMargin: number printerName: string operatorPrinterName: string direction: string tempItems: Array // 模板已选项 copies: number } export const initState: printProps = { zoom: 100, // 画布缩放百分比 type: "page", // 选中元素类型 index: -1, // 选中元素索引 uuid: -1, // 选中元素uuid originX: 0, // 选中元件的横向初始值 originY: 0, // 选中元件的纵向初始值 startX: 0, // 鼠标摁下时的横坐标 startY: 0, // 鼠标摁下时的纵坐标 moving: false, // 是否正在移动元件(参考线仅在移动元件时显示) activeElement: getDefaultProps(), // 选中对象,要么是元件,要么是页面 // 模板信息 page: { title: "demo", width: 770, height: 500, pageWidth: 215, pageHeight: 140, topMargin: 0, leftMargin: 0, printerName: "", operatorPrinterName: "", direction: "2", tempItems: [], // 模板已选项 copies: 1, }, optionItems: [], // 可选项 //模板参数 tempId: "", // 模板Id loading: false, // 是否正在初始化中 backgroundUrl: "", widgetSetting: getWidgetsSetting(), // 模板组件默认属性 resizing: false } export default { namespace: "printer", state: _.cloneDeep(initState), reducers: { updateState(state, { payload }): printProps { return { ...state, ...payload } }, }, effects: { *initPage({ payload }, { put, call, select }) { let state = yield select((state) => state.printer) let pageInfo = payload.pageInfo // 补全默认样式 let tempItems = pageInfo.tempItems ? pageInfo.tempItems.map((item) => { let optionItem = { ...state.widgetSetting[item.type], ...item, style: { ...state.widgetSetting[item.type].style, ...(item.style || {}), }, } return optionItem }) : [] yield put({ type: "updateState", payload: { page: { ...pageInfo, tempItems }, }, }) }, // 初始化可选对象 *initOptionItems({ payload }, { put, call, select }) { // 补全默认属性 const state = yield select((state) => state.printer) let { options } = payload let optionsObject = options || [] optionsObject.length && optionsObject.forEach((oo) => { let ooArr = [] oo.children.forEach((item) => { ooArr.push({ ...state.widgetSetting[item.type], ...item, style: { ...state.widgetSetting[item.type].style, ...(item.style || {}), }, }) }) oo.children = _.cloneDeep(ooArr) }) yield put({ type: "updateState", payload: { optionItems: optionsObject, }, }) }, // 初始化选中对象 *initActive({ payload }, { put, call, select }) { yield put({ type: "updateState", payload: { activeElement: getDefaultProps(), }, }) }, // 设置 mousemove 操作的初始值 *initmove({ payload }, { put, call, select }) { yield put({ type: "updateState", payload: { startX: payload.startX, startY: payload.startY, originX: payload.originX, originY: payload.originY, moving: true, }, }) }, *updateActiveElement({ payload }, { put, call, select }) { const state = yield select((state) => state.printer) var activeElement = state.activeElement for (var key in payload) { activeElement[key] = payload[key] } yield put({ type: "updateState", payload: { activeElement, }, }) }, // 选中元件与取消选中 *select({ payload }, { put, call, select }) { const { uuid } = payload const state = yield select((state) => state.printer) if (uuid === -1) { yield put({ type: "updateState", payload: { uuid: uuid, activeElement: getDefaultProps(), type: "page", }, }) } else { let widget = state.page.tempItems.find((w) => w.uuid === uuid) if (widget) { yield put({ type: "updateState", payload: { uuid: uuid, activeElement: widget, type: widget.type, }, }) } } }, // 元件移动结束 *stopmove({ payload }, { put, call, select }) { yield put({ type: "updateState", payload: { moving: false, resizing: false }, }) }, // 移动元件 *move({ payload }, { put, call, select }) { const state = yield select((state) => state.printer) const { x, y } = payload let {tempItems} = state.page var activeElement = state.activeElement var dx = x - state.startX var dy = y - state.startY var left = state.originX + Math.floor((dx * 100) / state.zoom) var top = state.originY + Math.floor((dy * 100) / state.zoom) tempItems = (tempItems || []).map(item => { if (item.uuid === activeElement.uuid) { item = {...item, left: left > 0 ? left : 0, top: top > 0 ? top : 0} } return item }) yield put({ type: "updateState", payload: { activeElement: { ...activeElement, left: left > 0 ? left : 0, top: top > 0 ? top : 0, }, page: {...state.page, tempItems} }, }) }, // 调整元件尺寸 *resize({ payload }, { put, call, select }) { const state = yield select((state) => state.printer) const { x, y, type } = payload let {tempItems} = state.page let dx = x - state.startX let dy = y - state.startY let value let activeElement = state.activeElement switch (type) { case "right": value = state.originX + Math.floor((dx * 100) / state.zoom) activeElement.width = value > 10 ? value : 10 break case "down": value = state.originX + Math.floor((dy * 100) / state.zoom) activeElement.height = value > 10 ? value : 10 break case "left": let left = state.originX + Math.floor((dx * 100) / state.zoom) let width = state.originY - Math.floor((dx * 100) / state.zoom) activeElement.left = left > 0 ? left : 0 activeElement.width = width > 10 ? width : 10 break case "up": let top = state.originX + Math.floor((dy * 100) / state.zoom) let height = state.originY - Math.floor((dy * 100) / state.zoom) activeElement.top = top > 0 ? top : 0 activeElement.height = height > 10 ? height : 10 break default: break } tempItems = tempItems.map(item => { if (item.uuid === activeElement.uuid) { item = {...item, ...activeElement} } return item }) console.log(tempItems, 'tempItems') yield put({ type: "updateState", payload: { activeElement: { ...activeElement }, page: {...state.page, tempItems} }, }) }, // 更新元件初始 top 值 *updateSrollTop({ payload }, { put, call, select }) { yield put({ type: "updateState", payload: { top: payload.top, }, }) }, // 页面缩放 *zoom({ payload }, { put, call, select }) { yield put({ type: "updateState", payload: { zoom: payload.val, }, }) }, // 删除选中元件 *delete({ payload }, { put, call, select }) { const state = yield select((state) => state.printer) const { uuid } = payload let type = state.type if (type === "page") return let index = 0 let page = state.page page.tempItems.forEach((item, idx) => { if (item.uuid === uuid) { index = idx } }) // 删除元件 page.tempItems.splice(index, 1) // 重置 activeElement state.type = "page" state.uuid = -1 yield put({ type: "updateState", payload: { activeElement: getDefaultProps(), type: "page", uuid: -1, page: page, }, }) }, // 添加背景项 ,永远前置第一位 *shiftTempItem({ payload }, { put, call, select }) { const state = yield select((state) => state.printer) const { item } = payload let page = state.page let def = { uuid: yield nanoid() } let setting = JSON.parse(JSON.stringify(item)) page.tempItems.unshift(Object.assign(setting, def)) yield put({ type: "updateState", payload: { page: { ...page }, }, }) }, // 添加组件 *addTempItem({ payload }, { put, call, select }) { const state = yield select((state) => state.printer) const { item } = payload let page = state.page let def = { uuid: yield nanoid() } console.log(def) let setting = JSON.parse(JSON.stringify(item)) page.tempItems.push(Object.assign(setting, def)) yield put({ type: "updateState", payload: { page: { ...page }, }, }) }, // 更新数据 *updateData({ payload }, { put, call, select }) { const state = yield select((state) => state.printer) const { uuid, value } = payload let page = state.page let widget = page.tempItems.find((w) => w.uuid === uuid) if (widget) { widget.value = value } yield put({ type: "updateState", payload: { page: { ...page }, }, }) }, // 设置模板Id *setTempId({ payload }, { put, call, select }) { yield put({ type: "updateState", payload: { tempId: payload.id, }, }) }, *setLoading({ payload }, { put, call, select }) { yield put({ type: "updateState", payload: { loading: payload.flag, }, }) }, // 设置模板默认属性 *setWidgetSetting({ payload }, { put, call, select }) { yield put({ type: "updateState", payload: { widgetSetting: payload.settingObj, }, }) }, }, }