全栈小学生 0e47055ccb v1.0.0-beta.1
2023-04-15 17:12:49 +08:00

268 lines
8.9 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import {defineStore} from 'pinia'
import {t} from '@/lang'
import {toRaw, watch} from 'vue'
import {ElMessage, ElMessageBox} from 'element-plus'
import {cloneDeep, range, isEmpty} from 'lodash-es'
interface Diy {
// 全局属性
id: number
load: boolean,
currentIndex: number,
currentComponent: string, // 当前正在编辑的组件
name: string, // 页面标识
type: string, // 页面类型
typeName: string, // 页面类型名称
components: any[], // 组件集合
global: {
title: string,
pageBgColor: string, // 页面背景颜色
tabbarSwitch: boolean, // 底部导航开关
},
// 组件集合
value: any[]
}
const useDiyStore = defineStore('diy', {
state: (): Diy => {
return {
id: 0,
load: false, // 加载状态
currentIndex: -99,
currentComponent: 'edit-page',
name: '',
type: '',
typeName: '',
components: [],
global: {
title: "页面",
pageBgColor: "", // 页面背景颜色
tabbarSwitch: true
},
// 组件集合
value: []
}
},
getters: {
editComponent: (state) => {
return state.value[state.currentIndex];
},
},
actions: {
// 添加组件
addComponent(data: any) {
// 加载完才能添加组件
if(!this.load) return;
// 删除不用的字段
let component = cloneDeep(data);
component.id = this.generateRandom();
component.componentName = component.name;
component.componentTitle = component.title;
component.maxCount = component.max_count;
Object.assign(component, component.value);
delete component.name;
delete component.title;
delete component.value;
delete component.type;
delete component.icon;
delete component.max_count;
if (!this.checkComponentIsAdd(component)) return;
if (this.currentIndex === -99) {
this.value.push(component);
// 添加组件后(不是编辑调用的),选择最后一个
this.currentIndex = this.value.length - 1;
} else {
// 指定位置添加组件
this.value.splice(++this.currentIndex, 0, component);
}
this.currentComponent = component.path;
},
generateRandom(len: number = 5) {
return Number(Math.random().toString().substr(3, len) + Date.now()).toString(36);
},
// 将数据发送到uniapp
postMessage() {
var diyData = JSON.stringify({
currentIndex: this.currentIndex,
global: toRaw(this.global),
value: toRaw(this.value)
});
window.previewIframe.contentWindow.postMessage(diyData, '*');
},
// 选中正在编辑的组件
changeCurrentIndex(index: number, component: any = null) {
this.currentIndex = index;
if (this.currentIndex == -99) {
this.currentComponent = 'edit-page';
} else if (component) {
this.currentComponent = component.path;
}
},
// 删除组件
delComponent() {
if (this.currentIndex == -99) return;
ElMessageBox.confirm(
t('delComponentTips'),
t('warning'),
{
confirmButtonText: t('confirm'),
cancelButtonText: t('cancel'),
type: 'warning',
autofocus: false
}
).then(() => {
this.value.splice(this.currentIndex, 1);
// 如果组件全部删除,则选中页面设置
if (this.value.length === 0) {
this.currentIndex = -99;
}
// 如果当前选中的组件不存在,则选择上一个
if (this.currentIndex === this.value.length) {
this.currentIndex--;
}
let component = cloneDeep(this.value[this.currentIndex]);
this.changeCurrentIndex(this.currentIndex, component)
}).catch(() => {
})
},
// 上移组件
moveUpComponent() {
if ((this.currentIndex - 1) < 0) return; // 从0开始
var temp = cloneDeep(this.value[this.currentIndex]); // 当前选中组件
temp.id = this.generateRandom(); // 更新id刷新组件数据
let prevIndex = this.currentIndex - 1;
var temp2 = cloneDeep(this.value[prevIndex]); // 上个组件
temp2.id = this.generateRandom(); // 更新id刷新组件数据
this.value[this.currentIndex] = temp2;
this.value[prevIndex] = temp;
this.changeCurrentIndex(prevIndex, temp);
},
// 下移组件
moveDownComponent() {
if ((this.currentIndex + 1) >= this.value.length) return; // 最后一个不能下移
var nextIndex = this.currentIndex + 1;
var temp = cloneDeep(this.value[this.currentIndex]); // 当前选中组件
temp.id = this.generateRandom(); // 更新id刷新组件数据
var temp2 = cloneDeep(this.value[nextIndex]); // 下个组件
temp2.id = this.generateRandom(); // 更新id刷新组件数据
this.value[this.currentIndex] = temp2;
this.value[nextIndex] = temp;
this.changeCurrentIndex(nextIndex, temp);
},
// 复制组件
copyComponent() {
if (this.currentIndex < 0) return; // 从0开始
let component = cloneDeep(this.value[this.currentIndex]); // 当前选中组件
component.id = this.generateRandom(); // 更新id刷新组件数据
if (!this.checkComponentIsAdd(component)) {
ElMessage({
type: 'warning',
message: `${t('notCopy')}${component.componentTitle}${t('componentCanOnlyAdd')}${component.maxCount}${t('piece')}`,
});
return;
}
var index = this.currentIndex + 1;
this.value.splice(index, 0, component);
this.changeCurrentIndex(index, component);
},
// 检测组件是否允许添加true允许 false不允许
checkComponentIsAdd(component: any) {
//maxCount为0时不处理
if (component.maxCount === 0) return true;
var count = 0;
//遍历已添加的自定义组件,检测是否超出数量
for (var i in this.value) if (this.value[i].componentName === component.componentName) count++;
if (count >= component.maxCount) return false;
else return true;
},
// 重置当前组件数据
resetComponent() {
if (this.currentIndex < 0) return; // 从0开始
ElMessageBox.confirm(
t('resetComponentTips'),
t('warning'),
{
confirmButtonText: t('confirm'),
cancelButtonText: t('cancel'),
type: 'warning',
autofocus: false
}
).then(() => {
// 重置当前选中的组件数据
for (let i = 0; i < this.components.length; i++) {
if (this.components[i].componentName == this.editComponent.componentName) {
Object.assign(this.editComponent, this.components[i]);
break;
}
}
}).catch(() => {
})
},
// 组件验证
verify() {
if (this.global.title === "") {
ElMessage({
message: t('pageNamePlaceholder'),
type: 'warning'
})
this.changeCurrentIndex(-99);
return false;
}
for (var i = 0; i < this.value.length; i++) {
try {
if (this.value[i].verify) {
var res = this.value[i].verify(i);
if (!res.code) {
this.changeCurrentIndex(i, this.value[i])
ElMessage({
message: res.message,
type: 'warning'
})
return false;
}
}
} catch (e) {
console.log("verify Error:", e, i, this.value[i]);
}
}
return true;
}
}
})
export default useDiyStore