:$FLEX$.值集名称

报表参数中定义关联值集时报上述错误,是因为:$FLEX$小写引起,应为大写。

------------------------ DataManager.js ------------------------ //{ 实体类的关联和属性列表 // “entities”: { // “Dingdan”: { // “properties”: { // “id”: “Integer”, // “number”: “String”, // “xiadan”: “Date”, // “jiaohuo”: “Date”, // “dingdan_chanpin”: “List<Dingdan_chanpin> (OneToMany)”, // “dingdan_chanpins_zujian”: “List<Dingdan_chanpin_zujian> (OneToMany)” // }, // “relations”: [ // “关联订单产品(Dingdan_chanpin)”, // “关联订单组件(Dingdan_chanpin_zujian)” // ] // }, // “Dingdan_chanpin”: { // “properties”: { // “id”: “Integer”, // “shuliang”: “Integer” // }, // “relations”: [ // “多对一关联订单(Dingdan)”, // “多对一关联产品(Chanpin)” // ] // }, // “Dingdan_chanpin_zujian”: { // “properties”: { // “id”: “Integer”, // “shuliang”: “Integer” // }, // “relations”: [ // “多对一关联订单(Dingdan)”, // “多对一关联组件(Chanpin_zujian)”, // “多对一关联板材(Bancai)” // ] // }, // “Jinhuo”: { // “properties”: { // “id”: “Integer”, // “shuliang”: “Integer”, // “date”: “Date” // }, // “relations”: [ // “多对一关联订单(Dingdan)”, // “多对一关联产品(Chanpin)”, // “多对一关联组件(Zujian)”, // “多对一关联板材(Bancai)”, // “多对一关联用户(User)” // ] // }, // “Kucun”: { // “properties”: { // “id”: “Integer”, // “shuliang”: “Long” // }, // “relations”: [ // “一对一关联板材(Bancai)” // ] // }, // “Mupi”: { // “properties”: { // “id”: “Integer”, // “name”: “String”, // “you”: “Boolean” // }, // “relations”: [ // “被板材关联(Bancai - mupi1/mupi2)” // ] // }, // “User”: { // “properties”: { // “id”: “Integer”, // “name”: “String”, // “andy”: “String”, // “pass”: “String”, // “role”: “int” // } // }, // “Zujian”: { // “properties”: { // “id”: “Integer”, // “name”: “String” // }, // “relations”: [ // “一对多关联产品组件(Chanpin_zujian)” // ] // }, // “Bancai”: { // “properties”: { // “id”: “Integer”, // “houdu”: “Double” // }, // “relations”: [ // “多对一关联材质(Caizhi)”, // “多对一关联木皮(Mupi - mupi1/mupi2)”, // “一对一关联库存(Kucun)” // ] // }, // “Caizhi”: { // “properties”: { // “id”: “Integer”, // “name”: “String” // }, // “relations”: [ // “一对多关联板材(Bancai)” // ] // }, // “Chanpin”: { // “properties”: { // “id”: “Integer”, // “bianhao”: “String” // }, // “relations”: [ // “一对多关联订单产品(Dingdan_chanpin)”, // “一对多关联产品组件(Chanpin_zujian)” // ] // }, // “Chanpin_zujian”: { // “properties”: { // “id”: “Integer”, // “one_howmany”: “Double” // }, // “relations”: [ // “多对一关联产品(Chanpin)”, // “多对一关联组件(Zujian)”, // “多对一关联板材(Bancai)” // ] // } // }, // “relationsSummary”: [ // “订单(Dingdan) 1:N 订单产品(Dingdan_chanpin)”, // “订单(Dingdan) 1:N 订单组件(Dingdan_chanpin_zujian)”, // “产品(Chanpin) 1:N 产品组件(Chanpin_zujian)”, // “组件(Zujian) 1:N 产品组件(Chanpin_zujian)”, // “板材(Bancai) 1:1 库存(Kucun)”, // “材质(Caizhi) 1:N 板材(Bancai)” // ] //} /** 优化后的关联解析函数(解决空问题) @param {Object} data - 后端原始数据 @returns {Object} 处理后的完整关联数据 */ function __resolveDataReferences(data) { // 创建ID映射表(带空保护) const idMaps = {}; Object.keys(data).forEach(key => { if (Array.isArray(data[key])) { idMaps[key] = new Map(); data[key].forEach(item => item.id && idMaps[key].set(item.id, item)); } }); // 通用关联解析方法(带安全检测) const resolveRef = (sourceArray, sourceKey, targetKey, refProperty) => { if (!Array.isArray(sourceArray)) return; sourceArray.forEach(item => { const refObj = item[refProperty]; if (refObj && refObj.id && idMaps[targetKey]) { const target = idMaps[targetKey].get(refObj.id); if (target) { // 建立正向引用 item[refProperty] = target; // 建立反向引用(自动创建关联数组) const reverseProp = sourceKey.endsWith('s') ? sourceKey.slice(0, -1) + '_list' : sourceKey + '_list'; if (!target[reverseProp]) target[reverseProp] = []; if (!target[reverseProp].includes(item)) { target[reverseProp].push(item); } } } }); }; // 处理特定关联(使用新安全方法) // 订单 ↔ 订单产品 if (data.dingdans && data.dingdan_chanpins) { resolveRef(data.dingdan_chanpins, ‘dingdans’, ‘dingdans’, ‘dingdan’); } // 订单 ↔ 订单组件 if (data.dingdans && data.dingdan_chanpin_zujians) { resolveRef(data.dingdan_chanpin_zujians, ‘dingdans’, ‘dingdans’, ‘dingdan’); } // 产品 ↔ 产品组件 if (data.chanpins && data.chanpin_zujians) { resolveRef(data.chanpin_zujians, ‘chanpins’, ‘chanpins’, ‘chanpin’); } // 组件 ↔ 产品组件 if (data.zujians && data.chanpin_zujians) { resolveRef(data.chanpin_zujians, ‘zujians’, ‘zujians’, ‘zujian’); } // 材质 ↔ 板材 if (data.caizhis && data.bancais) { resolveRef(data.bancais, ‘caizhis’, ‘caizhis’, ‘caizhi’); } // 板材 ↔ 库存(一对一) if (data.bancais && data.kucuns) { resolveRef(data.bancais, ‘kucuns’, ‘kucuns’, ‘kucun’); resolveRef(data.kucuns, ‘bancais’, ‘bancais’, ‘bancai’); // 反向引用 } // 板材 ↔ 木皮(mupi1/mupi2) if (data.bancais && data.mupis) { resolveRef(data.bancais, ‘mupis’, ‘mupis’, ‘mupi1’); resolveRef(data.bancais, ‘mupis’, ‘mupis’, ‘mupi2’); } // 订单产品 ↔ 产品 if (data.dingdan_chanpins && data.chanpins) { resolveRef(data.dingdan_chanpins, ‘chanpins’, ‘chanpins’, ‘chanpin’); } // 订单组件 ↔ 产品组件 if (data.dingdan_chanpin_zujians && data.chanpin_zujians) { resolveRef(data.dingdan_chanpin_zujians, ‘chanpin_zujians’, ‘chanpin_zujians’, ‘chanpin_zujian’); } // 订单组件 ↔ 板材 if (data.dingdan_chanpin_zujians && data.bancais) { resolveRef(data.dingdan_chanpin_zujians, ‘bancais’, ‘bancais’, ‘bancai’); } // 进货 ↔ 相关实体 if (data.jinhuos) { [‘dingdan’, ‘chanpin’, ‘zujian’, ‘bancai’, ‘user’].forEach(entity => { const plural = entity + ‘s’; if (data[plural]) { resolveRef(data.jinhuos, plural, plural, entity); } }); } return data; } function resolveDataReferences(data) { // 获取 data 对象的所有顶层键 const keys = Object.keys(data); // 遍历每个顶层键(如 users, posts 等) for (const key of keys) { const entities = data[key]; // 遍历该顶层键下的每个实体(如每个 user 或 post) for (const entity of entities) { // 遍历实体的每个属性 for (const attribute in entity) { if (entity.hasOwnProperty(attribute)) { var trpe=attribute.replace(/\d/g, ''); // 确保属性属于当前实体 if (Array.isArray(entity[attribute])) { if(data[trpe]==null){ trpe+="s" } // 如果属性是一个数组,则将数组中的每个 ID 替换为对应的实际对象 entity[attribute] = entity[attribute].map(item => data[trpe ]?.find(updateItem => updateItem.id === item.id) || item ); } else if (typeof entity[attribute] === "object" && entity[attribute] !== null) { // 如果属性是一个对象,则将其替换为对应的实际对象 entity[attribute] = data[trpe + "s"]?.find(updateItem => updateItem.id === entity[attribute].id); } } } } } console.log(data) return data; } /** 数据管理器类,负责与后端API通信并管理数据 */ class DataManager { constructor(baseUrl) { this.baseUrl = baseUrl; this.data = { bancais: [], dingdans: [], mupis: [], chanpins: [], kucuns: [], dingdan_chanpin_zujians: [], chanpin_zujians: [], zujians: [], caizhis: [], dingdan_chanpins: [], users: [] }; this.isSyncing = false; this.lastSync = null; // 回调注册表 this.callbacks = { // 全局回调 all: [], // 按实体类型分类的回调 bancais: [], dingdan: [], mupi: [], chanpin: [], kucun: [], dingdan_chanpin_zujian: [], chanpin_zujian: [], zujian: [], caizhi: [], dingdan_chanpin: [], user: [], // …其他实体 }; this.syncQueue = Promise.resolve(); } /** 获取所有数据 @returns {Promise} 是否成功 */ async fetchAll() { console.log(this) try { const response = await fetch(${this.baseUrl}/app/all); if (!response.ok) throw new Error(‘Network response was not ok’); const result = await response.json(); if (result.status !== 200) throw new Error(result.text || ‘API error’); const resolvedData = resolveDataReferences(result.data); // 更新本地数据 Object.keys(this.data).forEach(key => { if (resolvedData[key]) { this.data[key] = resolvedData[key]; } }); this.lastSync = new Date(); // 关键改进:数据更新后触发刷新回调 this.triggerCallbacks(‘refresh’, ‘all’, this.data); return true; } catch (error) { console.error(‘Fetch error:’, error); // 触发错误回调 this.triggerCallbacks(‘fetch_error’, ‘all’, { error }); return false; } } /** 注册回调函数 @param {string} entity - 实体类型(如’bancai’)或’all’表示全局回调 @param {Function} callback - 回调函数,参数为(operation, data) */ registerCallback(entity, callback) { if (!this.callbacks[entity]) { this.callbacks[entity] = []; } this.callbacks[entity].push(callback); } /** 移除回调函数 @param {string} entity - 实体类型单数性质 @param {Function} callback - 要移除的回调函数 */ unregisterCallback(entity, callback) { if (!this.callbacks[entity]) return; const index = this.callbacks[entity].indexOf(callback); if (index !== -1) { this.callbacks[entity].splice(index, 1); } } /** 触发回调 @param {string} operation - 操作类型(‘add’, ‘update’, ‘delete’) @param {string} entity - 实体类型单数性质 @param {Object} data - 相关数据 */ triggerCallbacks(operation, entity, data) { // 触发全局回调 this.callbacks.all.forEach(cb => cb(operation, entity, data)); // 触发特定实体回调 if (this.callbacks[entity]) { this.callbacks[entity].forEach(cb => cb(operation, data)); } } /** 执行CRUD操作并触发回调 */ async crudOperation(operation, entity, data) { try { const response = await fetch(${this.baseUrl}/app/${operation}/${entity}, { method: ‘POST’, headers: {‘Content-Type’: ‘application/json’}, body: JSON.stringify(data) }); if (!response.ok) throw new Error(‘Network response was not ok’); const result = await response.json(); if (result.status !== 200) throw new Error(result.text || ‘API error’); // 自动同步数据 this.syncData(); // 触发操作成功的回调 this.triggerCallbacks(operation, entity, data); return result; } catch (error) { console.error(‘CRUD error:’, error); // 触发操作失败的回调 this.triggerCallbacks(${operation}_error, entity, { data, error: error.message }); throw error; } } /** 执行CRUD操作 @param {string} operation - ‘add’, ‘delete’, ‘update’ @param {string} entity - 实体名称单数性质(小写) @param {Object} data - 要发送的数据 后端要求数据格式为{属性:”, 关联对象: {id:0}, 关联对象: [{id:0}]} @returns {Promise} 响应结果 */ async crudOperation(operation, entity, data) { try { const response = await fetch(${this.baseUrl}/app/${operation}/${entity}, { method: ‘POST’, headers: {‘Content-Type’: ‘application/json’}, body: JSON.stringify(data) }); if (!response.ok) throw new Error('Network response was not ok'); const result = await response.json(); if (result.status !== 200) throw new Error(result.text || 'API error'); // 自动同步数据 this.syncQueue = this.syncQueue.then(async () => { await this.syncData(); // 同步完成后触发操作回调 this.triggerCallbacks(operation, entity, data); }); return result; } catch (error) { console.error(‘CRUD error:’, error); // 触发操作失败的回调 this.triggerCallbacks(${operation}_error, entity, { data, error: error.message }); throw error; } } /** 自动同步数据(防止频繁请求) */ async syncData() { if (this.isSyncing) { this.pendingSync = true; return; } this.isSyncing = true; try { await this.fetchAll(); } catch (error) { console.error(‘Sync failed:’, error); } finally { this.isSyncing = false; // 处理等待中的同步请求 if (this.pendingSync) { this.pendingSync = false; setTimeout(() => this.syncData(), 1000); } } } /** 添加实体 @param {string} entity - 实体名称单数性质 @param {Object} data - 实体数据 */ async addEntity(entity, data) { return this.crudOperation(‘add’, entity, data); } /** 更新实体 @param {string} entity - 实体名称单数性质 @param {Object} data - 实体数据(必须包含id) */ async updateEntity(entity, data) { return this.crudOperation(‘update’, entity, data); } /** 删除实体 @param {string} entity - 实体名称单数性质 @param {number} id - 实体ID */ async deleteEntity(entity, id) { return this.crudOperation(‘delete’, entity, {id}); } /** 新增方法:手动触发数据刷新 */ async refreshData() { return this.syncQueue = this.syncQueue.then(() => this.syncData()); } } export { DataManager }; // 创建单例实例 //const dataManager = new DataManager(‘http://127.0.0.1:8080/KuCun2’); //// 初始化时获取所有数据 //dataManager.fetchAll().then(() => { // console.log(‘Initial data loaded’); //}); // 导出数据对象,外部可以直接访问 data.bancais, data.dingdans 等 //export const data = dataManager.data; //// 导出操作方法 //export const addEntity = dataManager.addEntity.bind(dataManager); //export const updateEntity = dataManager.updateEntity.bind(dataManager); //export const deleteEntity = dataManager.deleteEntity.bind(dataManager); //export const fetchAll = dataManager.fetchAll.bind(dataManager); ------------------------ dingdan.html ------------------------ <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>订单-产品-组件-板材查询系统</title> <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script> <style> body { font-family: Arial, sans-serif; max-width: 1000px; margin: 0 auto; padding: 20px; background-color: #f5f5f5; } .container { background: white; border-radius: 8px; padding: 20px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); } h1 { color: #2c3e50; text-align: center; margin-bottom: 30px; } .query-section { background: #f8f9fa; border-radius: 6px; padding: 15px; margin-bottom: 25px; border-left: 4px solid #3498db; } .query-section h2 { color: #2c3e50; margin-top: 0; } label { display: block; margin-bottom: 8px; font-weight: bold; color: #34495e; } input, select, button { padding: 10px; border: 1px solid #ddd; border-radius: 4px; font-size: 16px; margin-bottom: 15px; width: 100%; box-sizing: border-box; } button { background: #3498db; color: white; border: none; cursor: pointer; transition: background 0.3s; font-weight: bold; } button:hover { background: #2980b9; } .query-row { display: flex; gap: 15px; align-items: flex-end; } .query-row .form-group { flex: 1; } .results { background: white; border: 1px solid #eee; border-radius: 6px; padding: 15px; margin-top: 20px; max-height: 300px; overflow-y: auto; } .results h3 { margin-top: 0; color: #2c3e50; border-bottom: 2px solid #3498db; padding-bottom: 8px; } table { width: 100%; border-collapse: collapse; margin-top: 10px; } th, td { padding: 10px; text-align: left; border-bottom: 1px solid #eee; } th { background: #f8f9fa; font-weight: bold; color: #2c3e50; } tr:hover td { background-color: #f1f8ff; } .loading { display: none; text-align: center; padding: 10px; color: #3498db; } .loading::after { content: "加载中..."; } </style> </head> <body> <div class="container"> <h1>订单-产品-组件-板材查询系统</h1> <!-- 查询面板 --> <div class="query-section"> <h2>查询条件</h2> <div class="query-row"> <div class="form-group"> <label for="orderId">订单ID:</label> <input type="text" id="orderId" placeholder="输入订单ID"> </div> <div class="form-group"> <button id="searchButton">查询订单</button> </div> </div> <div class="loading" id="orderLoading"></div> <div class="results" id="orderResults"></div> </div> <div class="query-section"> <h2>产品查询</h2> <div class="query-row"> <div class="form-group"> <label for="productId">产品ID (从上方选择):</label> <select id="productId"></select> </div> <div class="form-group"> <button id="searchProductButton">查询产品</button> </div> </div> <div class="loading" id="productLoading"></div> <div class="results" id="productResults"></div> </div> <div class="query-section"> <h2>组件查询</h2> <div class="query-row"> <div class="form-group"> <label for="componentId">组件ID (从上方选择):</label> <select id="componentId"></select> </div> <div class="form-group"> <button id="searchComponentButton">查询组件</button> </div> </div> <div class="loading" id="componentLoading"></div> <div class="results" id="componentResults"></div> </div> <div class="query-section"> <h2>板材查询</h2> <div class="loading" id="boardLoading"></div> <div class="results" id="boardResults"></div> </div> </div> <script> // 全局数据存储 let globalData = { orders: [], products: [], components: [], boards: [] }; // 模拟后端数据存储 const mockData = { orders: [ {id: 1, number: "ORD-2023-001"}, {id: 2, number: "ORD-2023-002"} ], products: [ {id: 101, bianhao: "P-001", orderId: 1}, {id: 102, bianhao: "P-002", orderId: 1}, {id: 103, bianhao: "P-003", orderId: 2} ], components: [ {id: 201, name: "门板", productId: 101}, {id: 202, name: "抽屉面板", productId: 101}, {id: 203, name: "框架", productId: 102} ], boards: [ { id: 301, caizhi: {id: 401, name: "橡木"}, mupi1: {id: 501, name: "直纹橡木"}, houdu: 18.0, kucun: {id: 601, shuliang: 150} }, { id: 302, caizhi: {id: 402, name: "胡桃木"}, mupi1: {id: 502, name: "直纹胡桃木"}, houdu: 25.0, kucun: {id: 602, shuliang: 80} } ] }; // 通信函数实现 async function https(url, data, callback) { const defaultConfig = { contentType: 'application/json', dataType: 'json', timeout: 10000 }; // 显示对应区域的加载动画 const domain = url.split("/")[1]; const loadingElement = $("#" + domain + "Loading"); loadingElement.show(); try { // 在实际项目中是AJAX请求 // 这里用模拟数据代替 let response; // 模拟不同端点的响应 switch(url) { case "/order/search": // 模拟搜索延迟 await new Promise(resolve => setTimeout(resolve, 800)); response = new Information(200, "success", mockData.orders.filter( o => o.id == data.id )); break; case "/product/searchByOrder": await new Promise(resolve => setTimeout(resolve, 600)); response = new Information(200, "success", mockData.products.filter( p => p.orderId == data.orderId )); break; case "/component/searchByProduct": await new Promise(resolve => setTimeout(resolve, 500)); response = new Information(200, "success", mockData.components.filter( c => c.productId == data.productId )); break; case "/board/searchByComponent": await new Promise(resolve => setTimeout(resolve, 400)); // 在实际应用中,组件到板材可能有复杂的映射关系 response = new Information(200, "success", mockData.boards); break; default: response = new Information(404, "Endpoint not found", null); } console.log(response) console.log(mockData) // 在实际项目中: // const response = await $.ajax({ // ...defaultConfig, // url: BASE_URL + url, // method: 'POST', // data: JSON.stringify(data) // }); if (response.Status === 200) { callback?.(response.data); } else { handleBusinessError(response); } return response.data; } catch (error) { handleNetworkError(error, url); return null; } finally { loadingElement.hide(); } } function handleBusinessError(response) { console.error('业务错误:', response.text); alert(`业务错误: ${response.text}`); } function handleNetworkError(error, url) { console.error(`网络请求错误: ${url}`, error); alert(`网络请求错误: ${url}, 请检查控制台`); } // 通信信息类 class Information { constructor(status, text, data) { this.Status = status; this.text = text; this.data = data; } static NewSuccess(data) { return new Information(200, "success", data); } static Newfail(status, text, data) { return new Information(status, text, data); } } // 订单查询 $("#searchButton").click(() => { const orderId = $("#orderId").val(); if (!orderId) { alert("请输入订单ID"); return; } https("/order/search", { id: parseInt(orderId) }, function(orders) { globalData.orders = orders; renderOrderResults(); $("#productId").empty(); // 清除产品选择框 }); }); // 产品查询 $("#searchProductButton").click(() => { const productId = $("#productId").val(); if (!productId) { alert("请先查询订单并选择产品"); return; } // 查找当前订单ID const selectedOrderId = globalData.orders[0].id; https("/product/searchByOrder", { orderId: selectedOrderId }, function(products) { globalData.products = products; renderProductResults(); $("#componentId").empty(); // 清除组件选择框 }); }); // 组件查询 $("#searchComponentButton").click(() => { const componentId = $("#componentId").val(); if (!componentId) { alert("请先查询产品并选择组件"); return; } // 查找当前产品ID const selectedProductId = $("#productId").val(); https("/component/searchByProduct", { productId: parseInt(selectedProductId) }, function(components) { globalData.components = components; renderComponentResults(); // 自动发起板材查询 $("#boardLoading").show(); https("/board/searchByComponent", { componentId: parseInt(componentId) }, function(boards) { globalData.boards = boards; renderBoardResults(); }); }); }); // 渲染函数 function renderOrderResults() { const container = $("#orderResults"); container.empty(); if (!globalData.orders || globalData.orders.length === 0) { container.html("<p>未找到相关订单</p>"); return; } let html = `<h3>订单查询结果 (${globalData.orders.length})</h3>`; html += `<table> <tr> <th>ID</th> <th>订单号</th> </tr>`; globalData.orders.forEach(order => { html += `<tr> <td>${order.id}</td> <td>${order.number}</td> </tr>`; }); html += `</table>`; container.html(html); // 填充产品选择框 $("#productId").empty(); $("#productId").append('<option value="">-- 选择产品 --</option>'); globalData.products.forEach(product => { $("#productId").append(`<option value="${product.id}">${product.bianhao}</option>`); console.log(product) }); } function renderProductResults() { const container = $("#productResults"); container.empty(); if (!globalData.products || globalData.products.length === 0) { container.html("<p>该订单下无产品</p>"); return; } let html = `<h3>产品查询结果 (${globalData.products.length})</h3>`; html += `<table> <tr> <th>ID</th> <th>产品编号</th> <th>所属订单</th> </tr>`; globalData.products.forEach(product => { html += `<tr> <td>${product.id}</td> <td>${product.bianhao}</td> <td>${product.orderId}</td> </tr>`; }); html += `</table>`; container.html(html); // 填充组件选择框 $("#componentId").empty(); $("#componentId").append('<option value="">-- 选择组件 --</option>'); globalData.components.forEach(component => { $("#componentId").append(`<option value="${component.id}">${component.name}</option>`); }); } function renderComponentResults() { const container = $("#componentResults"); container.empty(); if (!globalData.components || globalData.components.length === 0) { container.html("<p>该产品下无组件</p>"); return; } let html = `<h3>组件查询结果 (${globalData.components.length})</h3>`; html += `<table> <tr> <th>ID</th> <th>组件名称</th> <th>所属产品</th> </tr>`; globalData.components.forEach(component => { html += `<tr> <td>${component.id}</td> <td>${component.name}</td> <td>${component.productId}</td> </tr>`; }); container.html(html); } function renderBoardResults() { const container = $("#boardResults"); container.empty(); if (!globalData.boards || globalData.boards.length === 0) { container.html("<p>该组件无相关板材信息</p>"); return; } let html = `<h3>板材查询结果 (${globalData.boards.length})</h3>`; html += `<table> <tr> <th>板材ID</th> <th>材质</th> <th>木皮1</th> <th>厚度(mm)</th> <th>库存量</th> </tr>`; globalData.boards.forEach(board => { html += `<tr> <td>${board.id}</td> <td>${board.caizhi.name}</td> <td>${board.mupi1.name}</td> <td>${board.houdu}</td> <td>${board.kucun ? board.kucun.shuliang : 0}</td> </tr>`; }); container.html(html); } // 为选择框添加变更事件 $("#productId").change(function() { $("#searchProductButton").click(); }); $("#componentId").change(function() { $("#searchComponentButton").click(); }); </script> </body> </html> ------------------------ index.html ------------------------ <!doctype html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"> <title>峤丞板材库存管理</title> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" type="text/css" href="fonts/font-awesome-4.7.0/css/font-awesome.min.css"> <link rel="stylesheet" type="text/css" href="main/bootstrap-3.3.7-dist/css/bootstrap.css.map"> <link rel="stylesheet" type="text/css" href="css/util.css"> <link rel="stylesheet" type="text/css" href="css/main.css"> <link rel="stylesheet" type="text/css" href="css/index2.css"> <script type="text/javascript" src="js/jquery-3.2.1.min.js"></script> <script type="text/javascript" src="js/jsyilai.js"></script> <script type="module"> // 共享的DataManager类 import { DataManager } from './data/DataManager.js?'; document.addEventListener('DOMContentLoaded', async () => { try { // 创建实例并挂载到window window.dataManager = new DataManager('/KuCun2'); // 初始化数据 await window.dataManager.fetchAll(); console.log('Data Manager initialized successfully'); // 设置iframe通信 const iframe = document.getElementById('iframeid'); iframe.onload = () => { // 通知iframe数据已准备好 iframe.contentWindow.postMessage('DataManagerReady', '*'); }; // 如果iframe已经加载,立即发送消息 if (iframe.contentDocument.readyState === 'complete') { iframe.contentWindow.postMessage('DataManagerReady', '*'); } } catch (error) { console.error('Failed to initialize DataManager:', error); } }); </script> <style type="text/css"> *{ margin:0; padding:0; } .frame-header { height: 60px; background-color: #23262E; justify-content: space-between; } .frame-header-li{ font-family: Arial, Helvetica, sans-serif; font-size:40px; } .frame-ul{ } .frame-ul li{ border-style: solid; border-width:1px 0px 1px 0px; margin-top: 1px; height: 35px; text-align: center } #username{ position: absolute; right: 0; /* 靠右 */ } .frame-body { position: fixed; top: 60px; right: 0; bottom: 0; left: 0; display: flex; flex-direction: row; } .frame-side { scrollbar-width: none; /* firefox隐藏滚动条 */ -ms-overflow-style: none; /* IE 10+隐藏滚动条 */ overflow-x: hidden; overflow-y: auto; width: 200px; background-color:#9e5; } .frame-side::-webkit-scrollbar { display: none; /* Chrome Safari 隐藏滚动条*/ } .frame-main { flex-grow: 1; background-color:#fff; } .jiaoluo{ margin: auto; margin-right: 0px; } .menu { display: none; position: absolute; background-color: #f9f9f9; border: 1px solid #ccc; padding: 10px; list-style-type: none; margin: 0; z-index: 10; } </style> </head> <body> <div class="frame-header"> <a class='frame-header-li' style="color:#fff">峤丞木材仓库管理</a> <a id="username" class='frame-header-li' style="color:#520">峤丞木材仓库管理</a> <!-- 菜单 --> <ul class="menu"> <li id="profile">个人资料</li> <li id="change-password">修改密码</li> <li id="logout-btn">注销</li> </ul> </div> <div class="frame-body"> <div class="frame-side"> <ul id="main_u" class='frame-ul' style="text-align:center;"> <li ><a href="main/test.html" target="main">首页</a></li> <li><a href="main/bancai.html" target="main">板材查询</a></li> <li><a href="main/tianjia.html" target="main">订单板材录入</a></li> <li><a href="main/Guanli.html" target="main">人员管理</a></li> </ul> </div> <div class="frame-main"> <!-- 内容主体区域 --> <iframe id="iframeid" name="main" src="main/bancai.html" width="100%" height="100%" frameborder="0"> </iframe> </div> </div> </body> </html> ------------------------ dingdan.js ------------------------ // 监听来自父窗口的消息 window.addEventListener('message', function(event) { // 确保消息来自父窗口且是 DataManagerReady 事件 if (event.source === window.parent && event.data === 'DataManagerReady') { initializeDataManager(); } }); // 初始化数据管理器 function initializeDataManager() { // 从父窗口获取 DataManager 实例 const dataManager = window.parent.dataManager; if (dataManager) { // 注册数据刷新回调 dataManager.registerCallback('all', function(operation, entity, data) { console.log("dhdhdh") // 当数据更新时刷新页面 updatePageData(dataManager); }); // 初始页面数据更新 updatePageData(dataManager); // 设置搜索功能 setupSearch(dataManager); } else { console.error('DataManager not available'); } } // 更新页面数据 function updatePageData(dataManager) { // 更新统计卡片 updateStats(dataManager); // 更新结果表格 updateTable(dataManager); // 更新最后更新时间 document.getElementById('lastUpdate').textContent = new Date().toLocaleTimeString(); } // 更新统计卡片数据 function updateStats(dataManager) { const data = dataManager.data; // 订单总数 document.getElementById('orderCount').textContent = data.dingdans?.length || 0; // 产品种类 document.getElementById('productCount').textContent = data.chanpins?.length || 0; // 板材库存种类 document.getElementById('materialCount').textContent = data.bancais?.length || 0; // 库存总量(所有库存数量之和) const totalStock = data.kucuns?.reduce((sum, kucun) => sum + kucun.shuliang, 0) || 0; document.getElementById('totalStock').textContent = totalStock; } // 更新结果表格 function updateTable(dataManager) { const tableBody = document.getElementById(‘resultBody’); tableBody.innerHTML = ‘’; // 清空现有内容 const data = dataManager.data; const results = []; let resultCount = 0; // 处理订单产品数据 if (data.dingdan_chanpins) { data.dingdan_chanpins.forEach(dc => { if (!dc.dingdan || !dc.chanpin) return; // 处理产品组件 if (dc.chanpin.chanpin_zujians) { dc.chanpin.chanpin_zujians.forEach(cz => { if (!cz.zujian || !cz.bancai) return; results.push({ orderNumber: dc.dingdan.number, productInfo: dc.chanpin.bianhao, productQuantity: dc.shuliang, component: cz.zujian.name, material: `${cz.bancai.id} (${cz.bancai.caizhi?.name || '未知材质'})`, materialPerComponent: cz.one_howmany, materialOrderQuantity: dc.shuliang * cz.one_howmany, operation: '<button class="btn btn-sm btn-outline-primary">详情</button>' }); resultCount++; }); } }); } // 处理直接订单组件数据 if (data.dingdan_chanpin_zujians) { data.dingdan_chanpin_zujians.forEach(dcz => { if (!dcz.dingdan || !dcz.chanpin_zujian || !dcz.chanpin_zujian.zujian || !dcz.bancai) return; results.push({ orderNumber: dcz.dingdan.number, productInfo: dcz.chanpin_zujian.chanpin?.bianhao || '独立组件', productQuantity: dcz.shuliang, component: dcz.chanpin_zujian.zujian.name, material: `${dcz.bancai.id} (${dcz.bancai.caizhi?.name || '未知材质'})`, materialPerComponent: dcz.chanpin_zujian.one_howmany, materialOrderQuantity: dcz.shuliang * dcz.chanpin_zujian.one_howmany, operation: '<button class="btn btn-sm btn-outline-primary">详情</button>' }); resultCount++; }); } // 填充表格 if (resultCount > 0) { document.getElementById('noResults').style.display = 'none'; results.forEach(row => { const tr = document.createElement('tr'); tr.innerHTML = ` <td>${row.orderNumber}</td> <td>${row.productInfo}</td> <td>${row.productQuantity}</td> <td>${row.component}</td> <td>${row.material}</td> <td>${row.materialPerComponent}</td> <td>${row.materialOrderQuantity}</td> <td>${row.operation}</td> `; tableBody.appendChild(tr); }); } else { document.getElementById('noResults').style.display = 'flex'; } // 更新结果计数 document.getElementById('resultCount').textContent = resultCount; } // 设置搜索功能 function setupSearch(dataManager) { // 订单搜索 ParseError: KaTeX parse error: Expected 'EOF', got '#' at position 3: ('#̲orderSearch').o…(this).val().toLowerCase(), 0); }); // 产品搜索 $('#productSearch').on('input', function() { filterTable($(this).val().toLowerCase(), 1); }); // 板材搜索 $('#materialSearch').on('input', function() { filterTable($(this).val().toLowerCase(), 4); }); // 木皮搜索 $('#woodSearch').on('input', function() { filterTable($(this).val().toLowerCase(), 4); // 假设材质信息在第4列 }); // 厚度搜索 $('#thicknessBtn').click(function() { const thickness = parseFloat($('#minThickness').val()); if (!isNaN(thickness)) { filterByThickness(thickness); } }); } // 表格过滤函数 function filterTable(searchTerm, columnIndex) { const rows = $(‘#resultBody tr’); let visibleCount = 0; rows.each(function() { const cellText = $(this).find(`td:eq(${columnIndex})`).text().toLowerCase(); const isMatch = cellText.includes(searchTerm); $(this).toggle(isMatch); // 高亮匹配文本 if (isMatch && searchTerm) { $(this).addClass('highlight'); } else { $(this).removeClass('highlight'); } if (isMatch) visibleCount++; }); // 更新结果计数 document.getElementById('resultCount').textContent = visibleCount; document.getElementById('noResults').style.display = visibleCount > 0 ? 'none' : 'flex'; } // 按厚度过滤 function filterByThickness(thickness) { const rows = $(‘#resultBody tr’); let visibleCount = 0; rows.each(function() { const materialText = $(this).find('td:eq(4)').text(); // 从文本中提取厚度(假设格式为"ID (材质) 厚度mm") const match = materialText.match(/(\d+(\.\d+)?)\s*mm/); if (match) { const materialThickness = parseFloat(match[1]); const isMatch = !isNaN(materialThickness) && materialThickness >= thickness; $(this).toggle(isMatch); if (isMatch) visibleCount++; } else { $(this).hide(); } }); // 更新结果计数 document.getElementById('resultCount').textContent = visibleCount; document.getElementById('noResults').style.display = visibleCount > 0 ? 'none' : 'flex'; } // 如果直接加载test.html,尝试请求DataManager if (window.parent) { window.parent.postMessage(‘RequestDataManager’, ‘*’); } 修改dingdan.js,使之更契合数据原,板材显示要全面材质和木皮都要显示
06-20
<template> <myModal :params="{title: $t('选择报警类型')}" :modalWidthSize="'middle'" :visible="visible" @submit="handleOk" @cancel="handleCancel"> <template v-slot:header><span></span></template> <template v-slot:body> <div class="alarm_type_modal"> <div class="main_content" v-if="alarmTypeList.length"> <div class="search_item"> <a-input-search @search="handleAlarmTypeSearch" :placeholder="$t('请输入报警类型名称')" /> </div> <template v-if="isShowList"> <div class="check_item"> <div class="all_check"> <a-checkbox :indeterminate="indeterminate" :checked="checkAll" @change="onCheckAllChange"> {{ $t("用电告警")}} </a-checkbox> <img class="down" @click="changeIcon" :class="{'up': expanded}" src="~@/assets/img/down.png" /> </div> <div :class="['check_group_list', expanded ? 'checkboxUp': 'checkboxDown' ]"> <a-checkbox-group v-model="checkedList" @change="onCheckChange"> <template v-for="el in alarmTypeList"> <a-checkbox v-if="el.isShow" :key="el.alarmTypeCode" :value="el.alarmTypeCode"> <span :title="$t(el.alarmTypeName)"> {{ $t(el.alarmTypeName) }} </span> </a-checkbox> </template> </a-checkbox-group> </div> </div> </template> <noData v-else /> </div> <a-space :size="64" v-else> <a-spin tip="加载中,请稍候..." /> </a-space> </div> </template> </myModal> </template> <script> import factory from '../../factory'; import noData from '@/components/tableNoData' import myModal from "@/components/scfComponents/modalComponents/modal.vue"; export default { components: { noData, myModal }, data() { return { visible: false, isShowList: true, indeterminate: false, checkAll: false, expanded: true, checkedList: [], // 所有选中项 alarmTypeList: [], // 原始数据 checkListBak: [] } }, methods: { getAlarmTypeList() { factory.getAlarmTypeList().then(res => { this.alarmTypeList = res.map(item => ({ ...item, isShow: true })) || [] this.updateCheckStatus() }) }, // 打开弹窗 showModal(data) { this.visible = true this.checkedList = [...data]; this.getAlarmTypeList(); }, // 报警类型搜索 handleAlarmTypeSearch(val) { const searchTerm = val.toLowerCase().trim(); if (!searchTerm) { this.alarmTypeList.forEach(item => { item.isShow = true }) if (this.checkListBak.length) { this.checkedList = [...this.checkedList, ...this.checkListBak] } } else { this.checkListBak = this.checkedList // 搜索将之前选中数据备份 this.alarmTypeList.forEach(item => { if (item.alarmTypeName.toLowerCase().includes(searchTerm)) { item.isShow = true } else { item.isShow = false } }) this.checkedList = [] } this.updateCheckStatus() this.$forceUpdate() }, updateCheckStatus() { let alarmTypeCodes = this.alarmTypeList.filter(item => item.isShow) let checkedList = this.checkedList this.indeterminate = !!checkedList.length && checkedList.length < alarmTypeCodes.length; this.checkAll = alarmTypeCodes.length > 0 && checkedList.length === alarmTypeCodes.length; this.isShowList = alarmTypeCodes.length > 0 }, // 全选 onCheckAllChange(e) { const alarmTypeCodes = this.alarmTypeList.filter(item => item.isShow).map(el => el.alarmTypeCode) Object.assign(this, { checkedList: e.target.checked ? [...alarmTypeCodes] : [], indeterminate: false, checkAll: e.target.checked, }); }, changeIcon() { this.expanded = !this.expanded }, // 单选 onCheckChange() { this.updateCheckStatus() }, // 确定 handleOk() { console.log(this.checkedList, 'this.checkedListthis.checkedList'); this.$emit('ok', this.checkedList) this.visible = false }, // 取消 handleCancel() { this.visible = false } }, } </script> <style lang="less" scoped> .alarm_type_modal { width: 100%; display: flex; padding: 24px; box-sizing: border-box; justify-content: center; .main_content { width: 100%; min-height: 400px; position: relative; border-radius: 8px; border: solid 1px #c5cdd6; padding: 23px 10px 10px 16px; .search_item { width: 100%; margin-bottom: 15px; } .check_item { border-radius: 4px; margin-bottom: 10px; border: 1px solid var(--split); .all_check { display: flex; padding: 10px 16px; align-items: center; justify-content: space-between; background-color: #f0f3f7; .down { width: 13px; height: 8px; transition: all 0.5s; cursor: pointer; } .up { transform: rotate(180deg); } } .check_group_list { width: 100%; overflow: hidden; transition: all 1s; .ant-checkbox-group { width: 100%; padding: 8px 0 8px 14px; .ant-checkbox-wrapper { margin: 0; width: 25%; padding: 4px; overflow: hidden; line-height: 28px; padding-left: 18px; white-space: nowrap; text-overflow: ellipsis; border-right: 1px solid #f0f3f7; &:nth-child(4n) { border-right: none; } } } } .checkboxDown { height: 0px; } .checkboxUp { min-height: 30px; } } } } </style> 不改变原有逻辑情况下优化代码 alarmTypeList 1800条数据
最新发布
08-15
<template> <div class="monitor-container"> <!-- 顶部导航栏 --> <div class="top-bar"> <!-- 天气模块 --> <div class="weather-module"> <i class="fas fa-sun weather-icon"></i> <span>晴 31℃/西北风</span> </div> <!-- 中间平台标题 --> <div class="platform-title"> <div class="trapezoid-bg"> <h1>株洲市"天空地水"动态监测平台</h1> </div> </div> <!-- 时间模块 --> <div class="time-module"> {{ currentTime }} {{ currentWeek }} </div> <!-- 网络切换控件 --> <div class="network-switcher"> <select v-model="networkType" @change="switchNetworkType"> <option value="internal">内网地图</option> <option value="external">外网地图</option> </select> </div> <!-- 天地图切换控件 --> <div class="map-switcher"> <select v-model="selectedMapType" @change="switchMapType"> <!-- 动态选项 --> <option v-for="option in mapOptions" :value="option.value" :key="option.value"> {{ option.label }} </option> </select> </div> </div> <!-- Cesium地图容器 --> <div id="cesiumContainer"></div> </div> </template> <script setup> import { ref, onMounted, watch } from 'vue'; import * as Cesium from 'cesium'; import "cesium/Build/Cesium/Widgets/widgets.css"; // 天地图服务密钥 const TIANDITU_TOKEN = '72d487f15710ca558987b9baaba13736'; // 当前时间和星期 const currentTime = ref("2025年07月03日 14:37:46"); const currentWeek = ref("星期四"); const weekMap = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六']; const updateTime = () => { const now = new Date(); currentTime.value = now.toLocaleString('zh-CN', { year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit', second: '2-digit', hour12: false }).replace(/\//g, '-').replace(/(\d{4})-(\d{2})-(\d{2})/, '$ 1年$ 2月$ 3日'); currentWeek.value = weekMap[now.getDay()]; }; setInterval(updateTime, 1000); updateTime(); // 网络类型选择 const networkType = ref('external'); // 默认外网 const selectedMapType = ref('img_c'); // 默认显示影像+注记 // 地图选项配置 const mapOptions = ref([ { value: 'img_c', label: '影像+注记' }, { value: 'vec_c', label: '矢量+注记' } ]); // Cesium相关变量 let viewer = null; let tiandituLayers = { baseLayer: null, annotationLayer: null }; // 网络类型切换 const switchNetworkType = () => { // 根据网络类型更新地图选项 if (networkType.value === 'internal') { mapOptions.value = [ { value: 'img_c', label: '内网影像地图' }, { value: 'vec_c', label: '内网矢量地图' } ]; // 设置内网默认地图类型 selectedMapType.value = 'img_c'; } else { mapOptions.value = [ { value: 'img', label: '天地图影像' }, { value: 'img_c', label: '影像+注记' }, { value: 'vec', label: '矢量地图' }, { value: 'vec_c', label: '矢量+注记' }, { value: 'ter', label: '地形图' } ]; // 设置外网默认地图类型 selectedMapType.value = 'img_c'; } // 重新加载地图 loadMapService(selectedMapType.value); }; // 地图类型切换 const switchMapType = () => { if (viewer) { loadMapService(selectedMapType.value); } }; // 加载地图服务 const loadMapService = (type) => { if (!viewer || !viewer.imageryLayers) return; // 清除现有图层 if (tiandituLayers.baseLayer) viewer.imageryLayers.remove(tiandituLayers.baseLayer); if (tiandituLayers.annotationLayer) viewer.imageryLayers.remove(tiandituLayers.annotationLayer); if (networkType.value === 'internal') { // 内网地图服务 const baseUrl = "http://59.255.48.160:81"; if (type === 'img_c') { // 内网影像地图 tiandituLayers.baseLayer = viewer.imageryLayers.addImageryProvider( new Cesium.WebMapTileServiceImageryProvider({ url: `${baseUrl}/img_c/wmts`, layer: "img", style: "default", tileMatrixSetID: "c", format: "tiles", credit: new Cesium.Credit("内网影像地图"), maximumLevel: 18 }) ); } else if (type === 'vec_c') { // 内网矢量地图 tiandituLayers.baseLayer = viewer.imageryLayers.addImageryProvider( new Cesium.WebMapTileServiceImageryProvider({ url: `${baseUrl}/vec_c/wmts`, layer: "vec", style: "default", tileMatrixSetID: "c", format: "tiles", credit: new Cesium.Credit("内网矢量地图"), maximumLevel: 18 }) ); } } else { // 外网天地图服务 const baseUrlTemplate = `https://t{s}.tianditu.gov.cn/{layer}_c/wmts?tk=${TIANDITU_TOKEN}`; // 图层配置映射表 const layerConfigs = { img: { layer: "img", credit: "天地图影像" }, img_c: { baseLayer: { layer: "img", credit: "天地图影像" }, annotationLayer: { layer: "cia", credit: "天地图注记" } }, vec: { layer: "vec", credit: "天地图矢量" }, vec_c: { baseLayer: { layer: "vec", credit: "天地图矢量" }, annotationLayer: { layer: "cva", credit: "天地图注记" } }, ter: { layer: "ter", credit: "天地图地形" } }; const config = layerConfigs[type]; if (!config) return; // 添加基础图层 tiandituLayers.baseLayer = viewer.imageryLayers.addImageryProvider( new Cesium.WebMapTileServiceImageryProvider({ url: baseUrlTemplate.replace('{layer}', config.layer || config.baseLayer.layer), layer: config.layer || config.baseLayer.layer, style: "default", tileMatrixSetID: "c", format: "tiles", credit: new Cesium.Credit(config.credit || config.baseLayer.credit), subdomains: ['0', '1', '2', '3', '4', '5', '6', '7'], maximumLevel: 18 }) ); // 添加注记图层(如果需要) if (config.annotationLayer) { tiandituLayers.annotationLayer = viewer.imageryLayers.addImageryProvider( new Cesium.WebMapTileServiceImageryProvider({ url: baseUrlTemplate.replace('{layer}', config.annotationLayer.layer), layer: config.annotationLayer.layer, style: "default", tileMatrixSetID: "c", format: "tiles", credit: new Cesium.Credit(config.annotationLayer.credit), subdomains: ['0', '1', '2', '3', '4', '5', '6', '7'], maximumLevel: 18 }) ); } } }; // 加载株洲矢量数据 const loadZhuzhouVector = async (viewer) => { try { // 加载株洲市整体边界 const cityDataSource = await Cesium.GeoJsonDataSource.load( "https://geo.datav.aliyun.com/areas_v3/bound/geojson?code=430200", { clampToGround: true, stroke: Cesium.Color.GREEN.withAlpha(0.8), strokeWidth: 2, fill: Cesium.Color.WHITE.withAlpha(0.3) } ); viewer.dataSources.add(cityDataSource); // 加载株洲各区县边界 const countyDataSource = await Cesium.GeoJsonDataSource.load( "https://geo.datav.aliyun.com/areas_v3/bound/geojson?code=430200_full", { clampToGround: true, stroke: Cesium.Color.WHITE, strokeWidth: 1, fill: Cesium.Color.TRANSPARENT } ); viewer.dataSources.add(countyDataSource); // 添加区县标签 countyDataSource.entities.values.forEach(entity => { if (entity.polygon && entity.properties && entity.properties.name) { const hierarchy = entity.polygon.hierarchy.getValue(Cesium.JulianDate.now()); const center = Cesium.BoundingSphere.fromPoints(hierarchy.positions).center; entity.label = { text: entity.properties.name, font: '18px 黑体', fillColor: Cesium.Color.WHITE, outlineColor: Cesium.Color.BLACK, outlineWidth: 3, style: Cesium.LabelStyle.FILL_AND_OUTLINE, verticalOrigin: Cesium.VerticalOrigin.CENTER, horizontalOrigin: Cesium.HorizontalOrigin.CENTER, pixelOffset: new Cesium.Cartesian2(0, 0), disableDepthTestDistance: Number.POSITIVE_INFINITY, scaleByDistance: new Cesium.NearFarScalar(1e3, 1.0, 1e6, 0.5) }; entity.position = center; } }); // 定位到株洲范围 const rectangle = Cesium.Rectangle.fromDegrees(113.50, 24.94, 113.60, 26.84); viewer.camera.flyTo({ destination: rectangle, orientation: { heading: Cesium.Math.toRadians(0), pitch: Cesium.Math.toRadians(-70), roll: 0 }, duration: 2 }); } catch (error) { console.error("加载株洲数据失败:", error); const chinaRectangle = Cesium.Rectangle.fromDegrees(73.0, 3.0, 136.0, 59.0); viewer.camera.flyTo({ destination: chinaRectangle }); } }; onMounted(async () => { try { // 设置Cesium Ion访问令牌 Cesium.Ion.defaultAccessToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiI0ZTdiZDBhZS0xNzBhLTRjZGUtOTY4NC1kYzA5ZDEyNGEyNjUiLCJpZCI6MzE2OTI5LCJpYXQiOjE3NTEzMzg2Mzh9.9QHGIwaWkUOX0NOSre5369rrf1k6bGhZu7xUQia4JmE'; // 初始化Cesium Viewer viewer = new Cesium.Viewer('cesiumContainer', { baseLayerPicker: false, timeline: false, animation: false, geocoder: false, sceneModePicker: false, navigationHelpButton: false, homeButton: false, selectionIndicator: false, infoBox: false, navigationInstructionsInitiallyVisible: false, scene3DOnly: true, terrainProvider: new Cesium.EllipsoidTerrainProvider(), imageryProvider: new Cesium.WebMapTileServiceImageryProvider({ url: `https://t{s}.tianditu.gov.cn/img_w/wmts?tk=${TIANDITU_TOKEN}`, layer: "img", style: "default", tileMatrixSetID: "c", subdomains: ['0', '1', '2', '3', '4', '5', '6', '7'], maximumLevel: 18 }) }); // 强制设置中国视角 viewer.camera.setView({ destination: Cesium.Rectangle.fromDegrees(73.0, 3.0, 136.0, 59.0) }); // 加载株洲数据 loadZhuzhouVector(viewer); // 加载地图服务 loadMapService(selectedMapType.value); } catch (error) { console.error("初始化失败:", error); } }); </script> <style scoped> /* 基础样式 */ * { margin: 0; padding: 0; box-sizing: border-box; font-family: "Microsoft YaHei", sans-serif; } .monitor-container { width: 100vw; height: 100vh; background: radial-gradient(circle at center, #0c2a50 0%, #0a1a35 100%); overflow: hidden; position: fixed; top: 0; left: 0; display: flex; flex-direction: column; } /* 顶部导航栏样式 */ .top-bar { height: 70px; background: linear-gradient(90deg, #0a1a35 0%, #1a3a6e 50%, #0a1a35 100%); display: flex; align-items: center; justify-content: space-between; padding: 0 15px; position: relative; z-index: 100; border-bottom: 1px solid rgba(0, 150, 255, 0.3); } /* 天气模块 */ .weather-module { display: flex; align-items: center; color: white; font-size: 14px; min-width: 120px; justify-content: center; } .weather-icon { color: #ffcc00; margin-right: 8px; font-size: 16px; } /* 梯形标题样式 */ .platform-title { position: absolute; left: 50%; top: 0; transform: translateX(-50%); z-index: 10; } .trapezoid-bg { position: relative; padding: 0 40px; height: 70px; display: flex; align-items: center; } .trapezoid-bg::before { content: ''; position: absolute; top: 0; left: 0; right: 0; bottom: 0; background: rgba(0, 60, 113, 0.6); clip-path: polygon(0% 0%, 100% 0%, 90% 100%, 10% 100%); z-index: -1; } .platform-title h1 { font-size: 24px; font-weight: bold; background: linear-gradient(to bottom, #a2e7eb, #00f2fe); -webkit-background-clip: text; background-clip: text; color: transparent; text-shadow: 0 0 8px rgba(0, 242, 254, 0.3); white-space: nowrap; } /* 时间模块 */ .time-module { color: white; font-size: 14px; min-width: 220px; text-align: center; } /* 网络切换控件 */ .network-switcher { margin-left: 20px; margin-right: 10px; } .network-switcher select { background: rgba(10, 26, 53, 0.8); color: #66ffff; border: 1px solid rgba(0, 150, 255, 0.5); border-radius: 4px; padding: 6px 12px; font-size: 14px; outline: none; cursor: pointer; box-shadow: 0 0 8px rgba(0, 150, 255, 0.3); transition: all 0.3s ease; } .network-switcher select:hover { background: rgba(26, 58, 110, 0.8); border-color: #00f2fe; box-shadow: 0 0 12px rgba(0, 242, 254, 0.5); } .network-switcher select:focus { border-color: #00f2fe; } /* 天地图切换控件 */ .map-switcher select { background: rgba(10, 26, 53, 0.8); color: #66ffff; border: 1px solid rgba(0, 150, 255, 0.5); border-radius: 4px; padding: 6px 12px; font-size: 14px; outline: none; cursor: pointer; box-shadow: 0 0 8px rgba(0, 150, 255, 0.3); transition: all 0.3s ease; } .map-switcher select:hover { background: rgba(26, 58, 110, 0.8); border-color: #00f2fe; box-shadow: 0 0 12px rgba(0, 242, 254, 0.5); } .map-switcher select:focus { border-color: #00f2fe; } /* Cesium容器 */ #cesiumContainer { width: 100%; height: calc(100vh - 70px); background-color: #000; position: relative; } /* 响应式调整 */ @media (max-width: 1400px) { .platform-title h1 { font-size: 20px; } .weather-module, .time-module { font-size: 13px; } .network-switcher select, .map-switcher select { padding: 5px 10px; font-size: 13px; } } @media (max-width: 1200px) { .platform-title h1 { font-size: 18px; } .trapezoid-bg { padding: 0 30px; } .time-module { min-width: 180px; } .network-switcher, .map-switcher { margin-left: 5px; margin-right: 5px; } } @media (max-width: 992px) { .time-module { display: none; } .network-switcher select, .map-switcher select { padding: 4px 8px; font-size: 12px; } } </style> 在 实现内外网切换功能下,现在还有一个要求:因为前面不是既有w代表球面墨卡托投影,也有c代表经纬度投影,基于此还要加一个w与c可以互相切换展示天地图的功能,基于此修改代码发我
07-08
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值