370 lines
12 KiB
JavaScript
370 lines
12 KiB
JavaScript
/**
|
||
* 业务逻辑 - 全局脚本版本
|
||
* 适配全局脚本方式调用
|
||
*/
|
||
(function (window) {
|
||
'use strict';
|
||
|
||
// API 配置
|
||
var apiConfig = {
|
||
baseUrl: 'https://ztserver.zguiy.com',
|
||
getApiUrl: function (path) {
|
||
return this.baseUrl + path;
|
||
}
|
||
};
|
||
|
||
// 存储 kernel 实例
|
||
var kernelInstance = null;
|
||
|
||
/**
|
||
* 初始化应用逻辑 - 注入 kernel 实例
|
||
*/
|
||
function initApp(kernel) {
|
||
if (!kernel) {
|
||
throw new Error('kernel 实例是必需的');
|
||
}
|
||
kernelInstance = kernel;
|
||
console.log('应用逻辑已初始化,kernel 实例已注入');
|
||
return kernelInstance;
|
||
}
|
||
|
||
/**
|
||
* 获取当前 kernel 实例
|
||
*/
|
||
function getKernel() {
|
||
if (!kernelInstance) {
|
||
throw new Error('请先调用 initApp(kernel) 初始化 kernel 实例');
|
||
}
|
||
return kernelInstance;
|
||
}
|
||
|
||
/**
|
||
* 初始化
|
||
*/
|
||
async function init(customConfig) {
|
||
var kernel = getKernel();
|
||
customConfig = customConfig || {};
|
||
|
||
var defaultConfig = {
|
||
container: document.querySelector('#renderDom'),
|
||
modelUrlList: [],
|
||
env: {
|
||
envPath: 'https://sdk.zguiy.com/resurces/hdr/hdr.env',
|
||
intensity: 1.2,
|
||
rotationY: 0.3,
|
||
background: true
|
||
},
|
||
gizmo: {
|
||
position: true,
|
||
rotation: true,
|
||
scale: true
|
||
},
|
||
outline: {
|
||
enable: true,
|
||
color: "#2196F3",
|
||
thickness: 1,
|
||
occlusionStrength: 0.1,
|
||
occlusionThreshold: 0.0002
|
||
}
|
||
};
|
||
|
||
// 合并配置
|
||
var config = Object.assign({}, defaultConfig, customConfig);
|
||
kernel.init(config);
|
||
}
|
||
|
||
/**
|
||
* 初始化加载模型
|
||
*/
|
||
async function getAutoLoadModelList() {
|
||
var kernel = getKernel();
|
||
|
||
var url = apiConfig.getApiUrl('/api/models/auto-load/list');
|
||
console.log('API URL:', url);
|
||
|
||
var response = await fetch(url);
|
||
var data = await response.json();
|
||
var models = data.data;
|
||
|
||
models.forEach(function (model) {
|
||
console.log(model.placement_zone);
|
||
if (model.placement_zone) {
|
||
var placementZone = model.placement_zone;
|
||
kernel.dropZone.setData({
|
||
color: placementZone.color,
|
||
alpha: +placementZone.alpha,
|
||
thickness: placementZone.thickness,
|
||
showBorder: !placementZone.show_border,
|
||
borderColor: placementZone.border_color,
|
||
walls: placementZone.walls
|
||
});
|
||
}
|
||
|
||
kernel.model.add({
|
||
modelId: model.category,
|
||
modelUrl: model.file_url,
|
||
modelControlType: model.model_control_type
|
||
});
|
||
});
|
||
}
|
||
|
||
/**
|
||
* 获取放置区域
|
||
*/
|
||
async function getPlacementZone(sku) {
|
||
var kernel = getKernel();
|
||
|
||
var response = await fetch(apiConfig.getApiUrl('/api/product-configs/by-sku/' + sku));
|
||
var result = await response.json();
|
||
|
||
if (result.code === 200) {
|
||
var data = result.data;
|
||
var enable_placement_zone = data.enable_placement_zone;
|
||
var wall_divisions = data.wall_divisions;
|
||
|
||
if (enable_placement_zone && wall_divisions !== undefined) {
|
||
kernel.dropZone.clearZones();
|
||
|
||
var divisions = wall_divisions.map(function (wall) {
|
||
return {
|
||
name: wall.name,
|
||
divisions: wall.divisions
|
||
};
|
||
});
|
||
|
||
kernel.dropZone.updateDivisions(divisions);
|
||
kernel.dropZone.show();
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 执行事件
|
||
*/
|
||
async function getEvent(dropzone_data, sku) {
|
||
console.log(sku);
|
||
|
||
try {
|
||
var response = await fetch(apiConfig.getApiUrl('/api/product-configs/by-sku/' + sku));
|
||
var result = await response.json();
|
||
|
||
if (result.code === 200 && result.data) {
|
||
console.log('SKU配置数据:', result.data);
|
||
console.log('关联事件:', result.data.events);
|
||
|
||
await executeEvent(dropzone_data, result);
|
||
} else {
|
||
console.log('未查询到数据');
|
||
}
|
||
} catch (error) {
|
||
console.error('查询SKU配置或替换模型失败:', error);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 点击放置区域执行事件
|
||
*/
|
||
async function executeEvent(dropzone_data, result) {
|
||
var kernel = getKernel();
|
||
|
||
var wallName = dropzone_data.wallName;
|
||
var index = dropzone_data.index;
|
||
var transform = dropzone_data.transform;
|
||
var position = transform.position;
|
||
var rotation = transform.rotation;
|
||
|
||
var events = result.data.events;
|
||
for (var i = 0; i < events.length; i++) {
|
||
var event = events[i];
|
||
|
||
if (event.event_type === 'change_model') {
|
||
console.log(event);
|
||
|
||
var targetData = event.target_data;
|
||
var id = targetData.id;
|
||
var name = targetData.name;
|
||
var file_url = targetData.file_url;
|
||
var model_control_type = targetData.model_control_type;
|
||
var category = targetData.category;
|
||
|
||
console.log('替换百叶模型:', event);
|
||
console.log('替换百叶模型类型:', category);
|
||
|
||
var modelId = id + '_' + Date.now();
|
||
|
||
kernel.dropZone.recordModelPlacement(wallName, index, modelId);
|
||
|
||
await kernel.model.add({
|
||
modelId: modelId,
|
||
modelUrl: file_url,
|
||
modelControlType: model_control_type,
|
||
drag: {
|
||
enable: true,
|
||
axis: rotation.y === 0 || rotation.y === 180 ? 'x' : 'z',
|
||
step: 0.1
|
||
},
|
||
transform: {
|
||
position: position,
|
||
rotation: rotation
|
||
}
|
||
});
|
||
|
||
console.log('百叶模型已放置为 ' + name);
|
||
}
|
||
|
||
if (event.event_type === 'change_color') {
|
||
var materialName = event.material_name;
|
||
var colorData = event.target_data;
|
||
|
||
console.log('替换百叶模型颜色:', colorData);
|
||
|
||
kernel.material.apply({
|
||
target: materialName,
|
||
albedoColor: colorData.color,
|
||
albedoTexture: colorData.color_map_url,
|
||
normalMap: colorData.normal_map_url,
|
||
metallic: colorData.metallic,
|
||
roughness: colorData.roughness
|
||
});
|
||
|
||
console.log('百叶模型颜色已替换为 ' + colorData.color);
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 换棚子
|
||
*/
|
||
const executeEvent2 = async (result) => {
|
||
const kernel = getKernel();
|
||
|
||
const { wallName, index, transform } = dropzone_data;
|
||
const { position, rotation } = transform;
|
||
|
||
for (const event of result.data.events) {
|
||
if (event.event_type === 'change_model') {
|
||
console.log(event.target_data);
|
||
|
||
const { id, name, file_url, model_control_type, category } = event.target_data;
|
||
console.log('替换百叶模型:', event);
|
||
console.log('替换百叶模型类型:', category);
|
||
|
||
// 生成唯一的模型ID
|
||
const modelId = id + '_' + Date.now();
|
||
|
||
// 先记录模型放置(会自动处理替换逻辑)
|
||
kernel.dropZone.recordModelPlacement(wallName, index, modelId);
|
||
console.log(Math.abs(rotation.y - 90), Math.abs(rotation.y - 90) > 5 ? 'x' : 'z');
|
||
// 加载并放置模型
|
||
await kernel.model.add({
|
||
modelId: modelId,
|
||
modelUrl: file_url,
|
||
modelControlType: model_control_type,
|
||
drag: {
|
||
enable: true,
|
||
axis: rotation.y === 0 || rotation.y === 180 ? 'x' : 'z',
|
||
step: 0.1,
|
||
},
|
||
transform: {
|
||
position: position,
|
||
rotation: rotation,
|
||
}
|
||
});
|
||
|
||
console.log(`百叶模型已放置为 ${name}`);
|
||
}
|
||
|
||
if (event.event_type === 'change_color') {
|
||
const materialName = event.material_name;
|
||
const { color, color_map_url, normal_map_url, metallic, roughness } = event.target_data;
|
||
console.log('替换百叶模型颜色:', event.target_data);
|
||
|
||
kernel.material.apply({
|
||
target: materialName,
|
||
albedoColor: color,
|
||
albedoTexture: color_map_url,
|
||
normalMap: normal_map_url,
|
||
metallic: metallic,
|
||
roughness: roughness
|
||
});
|
||
|
||
console.log(`百叶模型颜色已替换为 ${color}`);
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 加载热点
|
||
*/
|
||
async function getHotspot() {
|
||
var kernel = getKernel();
|
||
|
||
try {
|
||
var response = await fetch(apiConfig.getApiUrl('/api/hotspots?status=active&page=1&pageSize=100'));
|
||
var result = await response.json();
|
||
|
||
if (result.code === 200 && result.data.list.length > 0) {
|
||
var hotspots = result.data.list.map(function (item) {
|
||
return {
|
||
id: item.id,
|
||
type: 'hotspot',
|
||
name: item.name,
|
||
meshName: item.name,
|
||
icon: item.image_url,
|
||
position: [item.position_x, item.position_y, item.position_z],
|
||
radius: item.radius,
|
||
color: "#000000",
|
||
payload: {
|
||
skus: item.skus || []
|
||
}
|
||
};
|
||
});
|
||
|
||
kernel.hotspot.render(hotspots);
|
||
console.log('热点渲染成功:', hotspots);
|
||
} else {
|
||
console.log('没有可用的热点数据');
|
||
}
|
||
} catch (error) {
|
||
console.error('获取热点数据失败:', error);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 获取产品配置
|
||
*/
|
||
async function getProductConfig(sku) {
|
||
try {
|
||
var response = await fetch(apiConfig.getApiUrl('/api/product-configs/by-sku/' + sku));
|
||
var result = await response.json();
|
||
|
||
if (result.code === 200) {
|
||
console.log(result.data);
|
||
var enable_placement_zone = result.data.enable_placement_zone;
|
||
|
||
if (enable_placement_zone) {
|
||
getPlacementZone(sku);
|
||
} else {
|
||
executeEvent2(result);
|
||
}
|
||
}
|
||
} catch (error) {
|
||
console.error('获取产品配置失败:', error);
|
||
}
|
||
}
|
||
|
||
// 暴露到全局
|
||
window.AppLogic = {
|
||
initApp: initApp,
|
||
init: init,
|
||
getAutoLoadModelList: getAutoLoadModelList,
|
||
getPlacementZone: getPlacementZone,
|
||
getEvent: getEvent,
|
||
executeEvent: executeEvent,
|
||
executeEvent2: executeEvent2,
|
||
getHotspot: getHotspot,
|
||
getProductConfig: getProductConfig
|
||
};
|
||
|
||
})(window);
|