txlw7H^M4)hAgsOKY?Vs!563
z=`E9eEt45XpRg~k6PkTp!mzKyH?M?dPeQ^Shl3M!@>5YGkBb`l`IncykiHBu7j}fB`WZ_BB|q!~-2-^Kl_IlVYZRL7yncRFn2CDUdquAs#Id
ze@>>~+;nG|*W(VuwNGZiM_c>);TZHcC(F8@r)k5Ey9L#LSWwAxqDIz=jkAQq=5!Yks@;K86qL4%aTn;;&;_b29bQ!+iz)Wc~hR?A_>faVY$#h(@Nrb~L7C$Ab@+)op#hE-
z+}xKNBj=o{qUubQa?Y*zrbLPAtf^wIOs`r~W10TDxi`9J)IR%i`jY>6(zxWuGXbgk
ziP;d}KlG^#w0x(JTk$5XdC8BTpuA@0tarxF?R+u1ZO?bH7wiF_?WKM+>pLZx^@u!c
z$)nBYg!MR3{MN-E@MQWU9=TIg@W(uIC+e9kvS#B?>N*xI9rM_8`7!_bG?eJkr=e!%
zY~T-^nxV2GH!l4xjCnMKx-VSO<@-jbd007pwe
zFQawx*LaXGkxuTBbcgDie%JG8?elYcYi7=Z>T-HwwpabcY;Wwm#iwMavY{ex-nN(G
z32=Gk*lM5d7^r`3>91qEK6pq9`eQx$+`M|UnVb|oUJi?@`FD7T4^w>4fq$->GklZBV77waF!2Sf?xvSDV
zPMQs`%p~1@P*BYWx$Z4<$961$x{moU7U|^$fNM%&nffe%x|bJtNN8_-{f(J|V!b44
zBoqGFo-8@`-XUoG&DsFZe2NiqG7MopqK5!~{rqKnu}5ArC!Mt6eOw}Zjf{OT@aWiA
zmK5vfbpoYVI=z5H{k+A#j@nRWguaWR{ui&$2-gr5>qZ>%iJTOK!2-lGhas|lJ2Wg>
zMeB^Em=;6*D?!~OaCHJc^Xmh@vGW$w9;j~KVu++StZK?;Pu(xQ_!>KI)muIF3zkDe
zm=>-Wxu!Oz^LhRJeJ5@u#!vc@arFX^yu8n`9tllvN5X#i;BR=>4u+=?zJ
z(aLpRNgko^f^jRml*VOmK2Rwqx3rrZw`yHx9LvKv%Y|!3E4oGumF4A@rnzy;yJ!w>
zWq=KNIM>Q9rL+!gjVrr+?97kW@#E`Pth~yAdc~vk|zX5w)+c
zxKp`wH^;5rl;PHH^z&gJ%uV?bc@-|*GwR2a=328MQ^LaXgmWRL5Y`CAh&2N$`EJOZ
zl3|96U~}BMEt$x=t+{r1W^(>+`Sv2}0rhRMf6bNE;xvTh5jgLoX{bq`IO1rhMrW@
zrk$DQ&ArgHsTU~U-0L-M-sLrI+6he?cZ~W)g&?_}Uao0#Z>9<3Dedy`+}ZT@E^jzj
zDKF5RL9M2q-Ia&i-NPX^8nbC9Z_kKXa
z7>teKu?pi+X0~_H#{5w4`%vAx`@QI%gB6EMYwcpSSl;0rem%cNwD-eweD{Iz;l9oY
znd?2o#r7Vk_*@b)hq!pAFB8ukhS>FpsvYrG6t7AI#s#
zYvgf3C23K$@Dj!oRSSfG(~B6@0@RHlt!y3GS)8B}Ptfd&!#x_N|I<22F;evBaD_}0
zHS!NQARNA=J1-&$I(bphh%altEGX6t^ph|K|C_vGr0_p7p9zEdU(_fSPso*CO8@`>
M07*qoM6N<$f+!j83IG5A
literal 0
HcmV?d00001
diff --git a/src/views/projectLarge/digitalizationScreen/components/leftPage.vue b/src/views/projectLarge/digitalizationScreen/components/leftPage.vue
index b7e438b..eb8590c 100644
--- a/src/views/projectLarge/digitalizationScreen/components/leftPage.vue
+++ b/src/views/projectLarge/digitalizationScreen/components/leftPage.vue
@@ -1,7 +1,7 @@
-
+

From d92a54078602161ec5348f3900a5bb99108e5e0f Mon Sep 17 00:00:00 2001
From: taoge1020
Date: Tue, 9 Sep 2025 17:03:01 +0800
Subject: [PATCH 11/29] =?UTF-8?q?=E9=87=91=E9=A2=9D=E6=A0=BC=E5=BC=8F?=
=?UTF-8?q?=E8=AE=BE=E7=BD=AE?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.env.development | 2 +-
src/plugins/index.ts | 3 +-
src/utils/ruoyi.ts | 16 +
src/views/contract/bidCost/index.vue | 6 +-
src/views/contract/division/index.vue | 35 +-
src/views/contract/limitPrice/index.vue | 10 +-
src/views/contract/limitPrice/indexEdit.vue | 18 +-
src/views/ctr/update/index.vue | 355 +++++++++---------
src/views/design/designChange/indexEdit.vue | 8 +-
src/views/out/constructionValue/index.vue | 12 +-
src/views/out/designCompletion/index.vue | 18 +-
src/views/out/monthPlan/index.vue | 20 +-
src/views/out/monthPlanAudit/index.vue | 26 +-
src/views/out/outDesignTable/index.vue | 34 +-
src/views/out/outDesignTableVS/index.vue | 74 +++-
src/views/out/outTable/index.vue | 79 +++-
src/views/out/purchase/comm/purchPage.vue | 6 +-
.../out/settlementValueSubcontract/index.vue | 6 +-
src/views/out/valueAllocation/index.vue | 48 ++-
src/views/progress/progressCategory/index.vue | 10 +-
src/views/project/constructionUser/index.vue | 4 +-
.../landTransferLedger/index.vue | 40 +-
.../landTransferLedgerFangzhen/index.vue | 20 +-
src/views/project/projectUser/index.vue | 4 +-
src/views/project/salaryExcel/index.vue | 6 +-
src/views/project/subManagementUser/index.vue | 4 +-
src/views/project/subcontract/index.vue | 8 +-
src/views/project/workWage/index.vue | 8 +-
src/views/tender/bidd/index.vue | 8 +-
src/views/tender/bidd/indexEdit.vue | 8 +-
src/views/tender/bidd/indexEdit2.vue | 8 +-
src/views/tender/plan/index.vue | 47 ++-
32 files changed, 633 insertions(+), 318 deletions(-)
diff --git a/.env.development b/.env.development
index 4a874b9..6359576 100644
--- a/.env.development
+++ b/.env.development
@@ -14,7 +14,7 @@ VITE_APP_BASE_API = 'http://192.168.110.149:8899'
# 罗成
# VITE_APP_BASE_API = 'http://192.168.110.188:8899'
# 朱银
-VITE_APP_BASE_API = 'http://192.168.110.149:8899'
+# VITE_APP_BASE_API = 'http://192.168.110.149:8899'
#曾涛
# VITE_APP_BASE_API = 'http://192.168.110.171:8899'
diff --git a/src/plugins/index.ts b/src/plugins/index.ts
index 7449bde..1b5d412 100644
--- a/src/plugins/index.ts
+++ b/src/plugins/index.ts
@@ -9,7 +9,7 @@ import animate from '@/animate';
import { download as dl } from '@/utils/request';
import { useDict } from '@/utils/dict';
import { getConfigKey, updateConfigByKey } from '@/api/system/config';
-import { parseTime, addDateRange, handleTree, selectDictLabel, selectDictLabels } from '@/utils/ruoyi';
+import { parseTime, addDateRange, handleTree, selectDictLabel, selectDictLabels,formatPrice } from '@/utils/ruoyi';
import { downloadFile } from '@/utils/useFileDownload';
import { App } from 'vue';
@@ -42,4 +42,5 @@ export default function installPlugin(app: App) {
app.config.globalProperties.selectDictLabels = selectDictLabels;
app.config.globalProperties.animate = animate;
app.config.globalProperties.downloadFile = downloadFile;
+ app.config.globalProperties.formatPrice = formatPrice;
}
diff --git a/src/utils/ruoyi.ts b/src/utils/ruoyi.ts
index 8efd12c..c92994d 100644
--- a/src/utils/ruoyi.ts
+++ b/src/utils/ruoyi.ts
@@ -62,7 +62,23 @@ export const addDateRange = (params: any, dateRange: any[], propName?: string) =
}
return search;
};
+// 价格格式化函数
+export const formatPrice = (price, show = true) => {
+ if ((!show && price == 0) || price == '' || price == undefined || price == null) return '';
+ if (!price && price !== 0) return '0.0000';
+ // 转换为数字并保留四位小数
+ const num = Number(price);
+ if (isNaN(num)) return '0.0000';
+
+ const fixedNum = num.toFixed(4);
+ const [integer, decimal] = fixedNum.split('.');
+
+ // 千分位处理
+ const formattedInteger = integer.replace(/\B(?=(\d{3})+(?!\d))/g, ',');
+
+ return `${formattedInteger}.${decimal}`;
+};
// 回显数据字典
export const selectDictLabel = (datas: any, value: number | string) => {
if (value === undefined) {
diff --git a/src/views/contract/bidCost/index.vue b/src/views/contract/bidCost/index.vue
index a69eb4c..8df9d45 100644
--- a/src/views/contract/bidCost/index.vue
+++ b/src/views/contract/bidCost/index.vue
@@ -77,8 +77,8 @@
changePrice(scope.row);
}
"
- :precision="2"
- :step="0.1"
+ :min="0"
+ :precision="4"
:controls="false"
v-if="scope.row.quantity && scope.row.quantity != 0"
/>
@@ -86,7 +86,7 @@
- {{ scope.row.price != 0 ? Number(scope.row.price).toFixed(2) : null }}
+ {{ proxy.formatPrice(scope.row.price) }}
diff --git a/src/views/contract/division/index.vue b/src/views/contract/division/index.vue
index 1f085b2..23c50f5 100644
--- a/src/views/contract/division/index.vue
+++ b/src/views/contract/division/index.vue
@@ -25,7 +25,11 @@
-
+
+
+ {{ proxy.formatPrice(scope.row.price) }}
+
+
*计划招标时间
@@ -158,22 +162,28 @@
-
+
+
+ {{ proxy.formatPrice(scope.row.unitPrice) }}
+
+
+
{{
- ((scope.row.quantity ? Number(scope.row.quantity) : 0) -
- (scope.row.useQuantity ? Number(scope.row.useQuantity) : 0) -
- (scope.row.selectNum ? Number(scope.row.selectNum) : 0)) *
- Number(scope.row.unitPrice) ==
- 0
- ? ''
- : (
- ((scope.row.quantity ? Number(scope.row.quantity) : 0) -
+ proxy.formatPrice(
+ ((scope.row.quantity ? Number(scope.row.quantity) : 0) -
+ (scope.row.useQuantity ? Number(scope.row.useQuantity) : 0) -
+ (scope.row.selectNum ? Number(scope.row.selectNum) : 0)) *
+ Number(scope.row.unitPrice) ==
+ 0
+ ? ''
+ : ((scope.row.quantity ? Number(scope.row.quantity) : 0) -
(scope.row.useQuantity ? Number(scope.row.useQuantity) : 0) -
(scope.row.selectNum ? Number(scope.row.selectNum) : 0)) *
- Number(scope.row.unitPrice)
- ).toFixed(2)
+ Number(scope.row.unitPrice),
+ false
+ )
}}
@@ -207,6 +217,7 @@ import { useUserStoreHook } from '@/store/modules/user';
import { getDicts } from '@/api/system/dict/data';
import { Plus } from '@element-plus/icons-vue';
import { FormInstance } from 'element-plus';
+const { proxy } = getCurrentInstance();
import {
treeList,
sheetList,
diff --git a/src/views/contract/limitPrice/index.vue b/src/views/contract/limitPrice/index.vue
index 505add3..dce5f23 100644
--- a/src/views/contract/limitPrice/index.vue
+++ b/src/views/contract/limitPrice/index.vue
@@ -79,18 +79,16 @@
changePrice(scope.row);
}
"
- :precision="2"
- :step="0.1"
+ :min="0"
+ :precision="4"
:controls="false"
v-if="scope.row.quantity && scope.row.quantity != 0"
/>
-
+
-
- {{ scope.row.price != 0 ? Number(scope.row.price).toFixed(2) : null }}
-
+ {{ proxy.formatPrice(scope.row.price) }}
diff --git a/src/views/contract/limitPrice/indexEdit.vue b/src/views/contract/limitPrice/indexEdit.vue
index facd683..4665f32 100644
--- a/src/views/contract/limitPrice/indexEdit.vue
+++ b/src/views/contract/limitPrice/indexEdit.vue
@@ -41,10 +41,14 @@
-
-
+
- {{ scope.row.price != 0 ? Number(scope.row.price).toFixed(2) : null }}
+ {{ proxy.formatPrice(scope.row.unitPrice, false) }}
+
+
+
+
+ {{ proxy.formatPrice(scope.row.price) }}
@@ -70,8 +74,12 @@
diff --git a/src/views/ctr/update/index.vue b/src/views/ctr/update/index.vue
index 4908951..d813daf 100644
--- a/src/views/ctr/update/index.vue
+++ b/src/views/ctr/update/index.vue
@@ -1,79 +1,80 @@
-
-
-
-
-
-
-
-
- 修改收入合同
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 下一步
-
-
-
- 修改收入合同
-
-
-
- 月结算
- 形象节点
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 上一步
- 提交
-
-
-
-
+
+
+
+
+
+
+
+
+ 修改收入合同
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 下一步
+
+
+ 修改收入合同
+
+
+
+ 月结算
+ 形象节点
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 上一步
+ 提交
+
+
+
+
+
diff --git a/src/views/design/designChange/indexEdit.vue b/src/views/design/designChange/indexEdit.vue
index 9e6e857..7e0c7e5 100644
--- a/src/views/design/designChange/indexEdit.vue
+++ b/src/views/design/designChange/indexEdit.vue
@@ -145,7 +145,13 @@
>
-
diff --git a/src/views/out/constructionValue/index.vue b/src/views/out/constructionValue/index.vue
index b6d49e0..50d0699 100644
--- a/src/views/out/constructionValue/index.vue
+++ b/src/views/out/constructionValue/index.vue
@@ -39,8 +39,16 @@
-
-
+
+
+ {{ proxy.formatPrice(scope.row.outValue) }}
+
+
+
+
+ {{ proxy.formatPrice(scope.row.ownerValue) }}
+
+
diff --git a/src/views/out/designCompletion/index.vue b/src/views/out/designCompletion/index.vue
index 92f6638..fe4a233 100644
--- a/src/views/out/designCompletion/index.vue
+++ b/src/views/out/designCompletion/index.vue
@@ -24,9 +24,21 @@
-
-
-
+
+
+ {{ proxy.formatPrice(scope.row.planValue) }}
+
+
+
+
+ {{ proxy.formatPrice(scope.row.completeValue) }}
+
+
+
+
+ {{ proxy.formatPrice(scope.row.differenceValue) }}
+
+
对甲
diff --git a/src/views/out/monthPlan/index.vue b/src/views/out/monthPlan/index.vue
index af7bebd..e64d670 100644
--- a/src/views/out/monthPlan/index.vue
+++ b/src/views/out/monthPlan/index.vue
@@ -40,9 +40,21 @@
-
-
-
+
+
+ {{ proxy.formatPrice(scope.row.planValue) }}
+
+
+
+
+ {{ proxy.formatPrice(scope.row.completeValue) }}
+
+
+
+
+ {{ proxy.formatPrice(scope.row.differenceValue) }}
+
+
@@ -104,7 +116,7 @@
+
+
+
+
\ No newline at end of file
diff --git a/src/views/projectLarge/ProjectScreen/js/CesiumFlyToRoamingController.js b/src/views/projectLarge/ProjectScreen/js/CesiumFlyToRoamingController.js
new file mode 100644
index 0000000..e6b4d4f
--- /dev/null
+++ b/src/views/projectLarge/ProjectScreen/js/CesiumFlyToRoamingController.js
@@ -0,0 +1,293 @@
+export default class CesiumFlyToRoamingController {
+ /**
+ * 构造函数 - 创建基于flyTo的漫游控制器
+ * @param {Cesium.Viewer} viewer - Cesium Viewer实例
+ * @param {Object} [options] - 漫游配置选项
+ * @param {number} [options.duration=3] - 飞行持续时间(秒)
+ * @param {number} [options.pitch=-30] - 俯仰角(度)
+ * @param {number} [options.headingOffset=0] - 航向偏移(度)
+ */
+ constructor(viewer, options = {}) {
+ if (!viewer || !(viewer instanceof Cesium.Viewer)) {
+ throw new Error('必须提供有效的Cesium Viewer实例');
+ }
+
+ this.viewer = viewer;
+ this.isRoaming = false;
+ this.path = [];
+ this.currentIndex = -1; // 初始为-1,表示尚未开始
+ this.loop = false;
+ this.duration = options.duration || 3;
+ this.pitch = Cesium.Math.toRadians(options.pitch || -30);
+ this.headingOffset = Cesium.Math.toRadians(options.headingOffset || 0);
+ this.flyToOptions = null;
+ }
+
+ /**
+ * 开始路径漫游 - 严格按照路径点顺序,首先飞入第一个点位
+ * @param {Array} path - 路径点数组(按顺序排列)
+ * @param {number} [duration] - 飞行持续时间(秒)
+ * @param {boolean} [loop=false] - 是否循环漫游
+ */
+ startPathRoaming(path, duration, loop = false) {
+ if (!path || path.length < 1) {
+ throw new Error('路径漫游需要至少1个路径点');
+ }
+
+ // 停止当前可能的漫游
+ this.stopRoaming();
+
+ // 初始化参数
+ this.path = [...path];
+ this.loop = loop;
+ this.currentIndex = -1; // 重置为初始状态
+
+ if (duration !== undefined) {
+ this.duration = duration;
+ }
+
+ this.isRoaming = true;
+
+ // 第一步:飞到第一个点位
+ this.flyToFirstPoint();
+ }
+
+ /**
+ * 专门用于飞到第一个点位的方法
+ */
+ flyToFirstPoint() {
+ if (!this.isRoaming || this.path.length === 0) return;
+
+ const firstPointIndex = 0;
+ const firstPoint = this.path[firstPointIndex];
+
+ // 计算朝向:如果有第二个点,则面向第二个点,否则保持当前朝向
+ let orientation;
+ if (this.path.length > 1) {
+ orientation = this.calculateOrientation(firstPoint, this.path[1]);
+ } else {
+ orientation = {
+ heading: this.viewer.camera.heading,
+ pitch: this.pitch,
+ roll: 0
+ };
+ }
+
+ // 飞行到第一个点
+ this.flyToOptions = {
+ destination: firstPoint,
+ orientation: orientation,
+ duration: this.duration,
+ complete: () => {
+ // 第一个点到达后更新索引
+ this.currentIndex = firstPointIndex;
+
+ // 如果有更多点,继续飞行到下一个点
+ if (this.path.length > 1) {
+ this.flyToNextPoint();
+ } else {
+ // 只有一个点时,完成后停止漫游
+ this.isRoaming = false;
+ }
+ },
+ cancel: () => {
+ this.isRoaming = false;
+ }
+ };
+
+ this.viewer.camera.flyTo(this.flyToOptions);
+ }
+
+ /**
+ * 飞行到下一个路径点
+ */
+ flyToNextPoint() {
+ if (!this.isRoaming || this.currentIndex === -1) return;
+
+ // 计算下一个点的索引
+ const nextIndex = this.currentIndex + 1;
+
+ // 检查是否超出路径范围
+ if (nextIndex >= this.path.length) {
+ if (this.loop) {
+ // 循环模式:回到第一个点
+ this.currentIndex = -1;
+ this.flyToFirstPoint();
+ } else {
+ // 非循环模式:到达终点,停止漫游
+ this.isRoaming = false;
+ }
+ return;
+ }
+
+ // 更新当前索引并获取目标点
+ this.currentIndex = nextIndex;
+ const targetPoint = this.path[this.currentIndex];
+
+ // 计算朝向
+ let orientation;
+ if (this.currentIndex < this.path.length - 1) {
+ // 面向下一个点
+ orientation = this.calculateOrientation(targetPoint, this.path[this.currentIndex + 1]);
+ } else if (this.loop) {
+ // 最后一个点且循环模式,面向第一个点
+ orientation = this.calculateOrientation(targetPoint, this.path[0]);
+ } else {
+ // 最后一个点且不循环,保持当前朝向
+ orientation = {
+ heading: this.viewer.camera.heading,
+ pitch: this.pitch,
+ roll: 0
+ };
+ }
+
+ // 执行飞行
+ this.flyToOptions = {
+ destination: targetPoint,
+ orientation: orientation,
+ duration: this.duration,
+ complete: () => this.flyToNextPoint(),
+ cancel: () => { this.isRoaming = false; }
+ };
+
+ this.viewer.camera.flyTo(this.flyToOptions);
+ }
+
+ /**
+ * 计算相机朝向
+ * @param {Cesium.Cartesian3} position - 相机位置
+ * @param {Cesium.Cartesian3} lookAtPoint - 看向的点
+ * @returns {Object} 朝向配置
+ */
+ calculateOrientation(position, lookAtPoint) {
+ const direction = Cesium.Cartesian3.subtract(lookAtPoint, position, new Cesium.Cartesian3());
+ const heading = Math.atan2(direction.x, direction.y) + this.headingOffset;
+
+ return {
+ heading: heading,
+ pitch: this.pitch,
+ roll: 0
+ };
+ }
+
+ /**
+ * 停止漫游
+ */
+ stopRoaming() {
+ if (this.isRoaming) {
+ this.isRoaming = false;
+ if (this.flyToOptions) {
+ this.viewer.camera.cancelFlight();
+ this.flyToOptions = null;
+ }
+ }
+ }
+
+ /**
+ * 暂停漫游
+ */
+ pauseRoaming() {
+ if (this.isRoaming) {
+ this.isRoaming = false;
+ if (this.flyToOptions) {
+ this.viewer.camera.cancelFlight();
+ }
+ }
+ }
+
+ /**
+ * 恢复漫游
+ */
+ resumeRoaming() {
+ if (!this.isRoaming && this.path.length > 0) {
+ this.isRoaming = true;
+ if (this.currentIndex === -1) {
+ this.flyToFirstPoint();
+ } else {
+ this.flyToNextPoint();
+ }
+ }
+ }
+
+ /**
+ * 添加路径点
+ * @param {Cesium.Cartesian3} point - 路径点
+ */
+ addPathPoint(point) {
+ if (point instanceof Cesium.Cartesian3) {
+ this.path.push(point);
+ } else {
+ console.warn('路径点必须是Cesium.Cartesian3类型');
+ }
+ }
+
+ /**
+ * 清除路径
+ */
+ clearPath() {
+ this.stopRoaming();
+ this.path = [];
+ this.currentIndex = -1;
+ }
+
+ /**
+ * 设置飞行持续时间
+ * @param {number} duration - 持续时间(秒)
+ */
+ setDuration(duration) {
+ if (typeof duration === 'number' && duration > 0) {
+ this.duration = duration;
+ }
+ }
+
+ /**
+ * 销毁控制器
+ */
+ destroy() {
+ this.stopRoaming();
+ this.viewer = null;
+ this.path = null;
+ }
+}
+
+// 使用示例:
+// 假设已经有一个Cesium Viewer实例叫做viewer
+//
+// // 创建漫游控制器
+// const roamingController = new CesiumRoamingController(viewer, {
+// speed: 20,
+// pitch: -20, // 20度俯角
+// headingOffset: 0
+// });
+//
+// // 示例1: 自由漫游
+// // 开始自由漫游
+// document.getElementById('startFreeRoam').addEventListener('click', () => {
+// roamingController.startFreeRoaming(15); // 速度15米/秒
+// });
+//
+// // 示例2: 路径漫游
+// // 创建路径点
+// const pathPoints = [
+// Cesium.Cartesian3.fromDegrees(116.3, 39.9, 200),
+// Cesium.Cartesian3.fromDegrees(116.4, 39.9, 200),
+// Cesium.Cartesian3.fromDegrees(116.4, 40.0, 200),
+// Cesium.Cartesian3.fromDegrees(116.3, 40.0, 200)
+// ];
+//
+// // 开始路径漫游
+// document.getElementById('startPathRoam').addEventListener('click', () => {
+// roamingController.startPathRoaming(pathPoints, 30, true); // 速度30米/秒,循环漫游
+// });
+//
+// // 停止漫游
+// document.getElementById('stopRoam').addEventListener('click', () => {
+// roamingController.stopRoaming();
+// });
+//
+// // 调整速度
+// document.getElementById('speedUp').addEventListener('click', () => {
+// const currentSpeed = roamingController.speed;
+// roamingController.setSpeed(currentSpeed + 5);
+// });
+
\ No newline at end of file
diff --git a/src/views/projectLarge/ProjectScreen/js/CesiumImageLabelEntity.js b/src/views/projectLarge/ProjectScreen/js/CesiumImageLabelEntity.js
new file mode 100644
index 0000000..fea29ec
--- /dev/null
+++ b/src/views/projectLarge/ProjectScreen/js/CesiumImageLabelEntity.js
@@ -0,0 +1,293 @@
+export default class CesiumImageLabelEntity {
+ /**
+ * 构造函数 - 创建带有图片和名称的Cesium Entity
+ * @param {Cesium.Viewer} viewer - Cesium Viewer实例
+ * @param {Object} options - 配置选项
+ * @param {Cesium.Cartesian3} options.position - 实体位置坐标
+ * @param {string} options.name - 实体名称(标签文本)
+ * @param {string} options.imageUrl - 图片URL
+ * @param {Function} [options.onClick] - 左击事件回调函数
+ * @param {string} [options.id] - 实体ID,可选
+ * @param {number} [options.imageWidth=64] - 图片宽度
+ * @param {number} [options.imageHeight=64] - 图片高度
+ * @param {Cesium.Color} [options.imageColor=Cesium.Color.WHITE] - 图片颜色(用于色调调整)
+ * @param {Cesium.Color} [options.labelColor=Cesium.Color.WHITE] - 标签颜色
+ * @param {string} [options.labelFont='16px sans-serif'] - 标签字体
+ * @param {number} [options.labelOffsetY=-70] - 标签Y轴偏移量(相对于图片)
+ * @param {boolean} [options.show=true] - 是否显示实体
+ * @param {Cesium.HorizontalOrigin} [options.horizontalOrigin=Cesium.HorizontalOrigin.CENTER] - 水平对齐方式
+ * @param {Cesium.VerticalOrigin} [options.verticalOrigin=Cesium.VerticalOrigin.BOTTOM] - 垂直对齐方式
+ */
+ constructor(viewer, options) {
+ // 验证必要参数
+ if (!viewer || !(viewer instanceof Cesium.Viewer)) {
+ throw new Error('必须提供有效的Cesium Viewer实例');
+ }
+ if (!options || !options.position) {
+ throw new Error('必须提供实体位置信息');
+ }
+ if (!options.name) {
+ throw new Error('必须提供实体名称');
+ }
+ if (!options.imageUrl) {
+ throw new Error('必须提供图片URL');
+ }
+
+ this.viewer = viewer;
+ this.onClickCallback = options.onClick || null;
+ this.options = {
+ // 默认配置
+ id: options.id || `image-label-entity-${Date.now()}`,
+ imageWidth: options.imageWidth || 64,
+ imageHeight: options.imageHeight || 64,
+ imageColor: options.imageColor || Cesium.Color.WHITE,
+ labelColor: options.labelColor || Cesium.Color.WHITE,
+ labelFont: options.labelFont || '16px sans-serif',
+ labelOffsetY: options.labelOffsetY || -80,
+ show: options.show !== undefined ? options.show : true,
+ horizontalOrigin: options.horizontalOrigin || Cesium.HorizontalOrigin.CENTER,
+ verticalOrigin: options.verticalOrigin || Cesium.VerticalOrigin.BOTTOM,
+ ...options
+ };
+
+ // 创建实体
+ this.entity = this.createEntity();
+
+ // 初始化点击事件监听
+ this.initClickHandler();
+ }
+
+ /**
+ * 创建实体
+ * @returns {Cesium.Entity} 创建的实体对象
+ */
+ createEntity() {
+ const entity = new Cesium.Entity({
+ id: this.options.id,
+ position: Cesium.Cartesian3.fromDegrees(
+ this.options.position.lng,
+ this.options.position.lat,
+ this.options.position.alt
+ ),
+ show: this.options.show,
+
+ // 图片属性
+ billboard: {
+ image: this.options.imageUrl,
+ width: this.options.imageWidth,
+ height: this.options.imageHeight,
+ color: this.options.imageColor,
+ horizontalOrigin: this.options.horizontalOrigin,
+ verticalOrigin: this.options.verticalOrigin,
+ // 允许实体被选中
+ pickable: true
+ },
+
+ // 名称标签属性
+ label: {
+ text: this.options.name,
+ font: this.options.labelFont,
+ fillColor: this.options.labelColor,
+ horizontalOrigin: this.options.horizontalOrigin,
+ verticalOrigin: Cesium.VerticalOrigin.TOP,
+ pixelOffset: new Cesium.Cartesian2(0, this.options.labelOffsetY),
+ // 添加背景
+ backgroundColor: new Cesium.Color(0, 0, 0, 0),
+ backgroundPadding: new Cesium.Cartesian2(5, 5),
+ showBackground: true,
+ // 允许标签被选中
+ pickable: true
+ }
+ });
+
+ // 将实体添加到viewer
+ this.viewer.entities.add(entity);
+
+ return entity;
+ }
+
+ /**
+ * 初始化点击事件处理器
+ */
+ initClickHandler() {
+ // 存储当前实例的引用,方便在回调中使用
+ const self = this;
+
+ // 注册左击事件
+ this.viewer.screenSpaceEventHandler.setInputAction(function onLeftClick(movement) {
+ // 检测是否点击了当前实体
+ const pickedObject = self.viewer.scene.pick(movement.position);
+
+ // 检查是否点击了当前实体或其实体的子组件(billboard、label等)
+ if (Cesium.defined(pickedObject) &&
+ (pickedObject.id === self.entity ||
+ pickedObject.id === self.entity.billboard ||
+ pickedObject.id === self.entity.label)) {
+
+ // 如果设置了点击回调,则执行
+ if (self.onClickCallback && typeof self.onClickCallback === 'function') {
+ self.onClickCallback(self.entity, movement.position);
+ }
+ }
+ }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
+ }
+
+ /**
+ * 设置点击事件回调函数
+ * @param {Function} callback - 回调函数,接收(entity, position)参数
+ */
+ setOnClick(callback) {
+ if (typeof callback === 'function') {
+ this.onClickCallback = callback;
+ } else {
+ console.warn('回调函数必须是一个函数');
+ }
+ }
+
+ /**
+ * 平滑飞行到实体当前位置
+ * @param {Object} [options] - 飞行参数配置
+ * @param {number} [options.duration=3] - 飞行持续时间(秒)
+ * @param {number} [options.offsetDistance=1000] - 距离目标点的距离(米)
+ * @param {Cesium.HeadingPitchRange} [options.headingPitchRange] - 方向、俯仰和范围,优先级高于offsetDistance
+ * @param {Function} [options.complete] - 飞行完成后的回调函数
+ * @param {Function} [options.cancel] - 飞行被取消后的回调函数
+ */
+ flyTo(options = {}) {
+ // 获取实体当前位置(考虑可能已更新的情况)
+ const currentPosition = this.entity?.position?.getValue(Cesium.JulianDate.now());
+
+ if (!currentPosition) {
+ console.warn('无法飞行到实体,实体或实体位置不存在');
+ return;
+ }
+
+ // 默认飞行参数
+ const defaultOptions = {
+ duration: 3,
+ offsetDistance: 1000,
+ complete: () => {},
+ cancel: () => {}
+ };
+
+ // 合并用户配置和默认配置
+ const flyOptions = { ...defaultOptions, ...options };
+
+ // 计算飞行视角
+ let headingPitchRange;
+ if (flyOptions.headingPitchRange) {
+ headingPitchRange = flyOptions.headingPitchRange;
+ } else {
+ // 默认视角:从上方稍远处看向实体
+ headingPitchRange = new Cesium.HeadingPitchRange(
+ 0, // 方向角(弧度)
+ Cesium.Math.toRadians(-30), // 俯仰角(弧度),负值表示向下看
+ flyOptions.offsetDistance // 距离目标点的距离
+ );
+ }
+
+ // 执行飞行到当前位置
+ this.viewer.flyTo(this.entity, {
+ destination: currentPosition, // 明确指定当前位置作为目标
+ duration: flyOptions.duration,
+ offset: headingPitchRange,
+ complete: flyOptions.complete,
+ cancel: flyOptions.cancel
+ });
+ }
+
+ /**
+ * 更新实体位置
+ * @param {Cesium.Cartesian3} position - 新的位置坐标
+ */
+ updatePosition(position) {
+ if (position && this.entity) {
+ this.entity.position = position;
+ // 更新options中的位置,保持同步
+ this.options.position = position;
+ }
+ }
+
+ /**
+ * 更新实体名称
+ * @param {string} name - 新的名称
+ */
+ updateName(name) {
+ if (name && this.entity && this.entity.label) {
+ this.entity.label.text = name;
+ }
+ }
+
+ /**
+ * 更新实体图片
+ * @param {string} imageUrl - 新的图片URL
+ */
+ updateImage(imageUrl) {
+ if (imageUrl && this.entity && this.entity.billboard) {
+ this.entity.billboard.image = imageUrl;
+ }
+ }
+
+ /**
+ * 显示实体
+ */
+ show() {
+ if (this.entity) {
+ this.entity.show = true;
+ }
+ }
+
+ /**
+ * 隐藏实体
+ */
+ hide() {
+ if (this.entity) {
+ this.entity.show = false;
+ }
+ }
+
+ /**
+ * 移除实体
+ */
+ remove() {
+ if (this.entity) {
+ this.viewer.entities.remove(this.entity);
+ this.entity = null;
+ }
+ }
+
+ /**
+ * 获取当前实体
+ * @returns {Cesium.Entity} 当前实体对象
+ */
+ getEntity() {
+ return this.entity;
+ }
+}
+
+// 使用示例:
+// 假设已经有一个Cesium Viewer实例叫做viewer
+// // 创建实体
+// const initialPosition = Cesium.Cartesian3.fromDegrees(116.39, 39.9, 100);
+// const imageEntity = new CesiumImageLabelEntity(viewer, {
+// position: initialPosition,
+// name: "可移动点",
+// imageUrl: "path/to/your/image.png",
+// onClick: function(entity) {
+// console.log("点击了实体,飞向当前位置");
+// entity.flyTo(); // 飞向当前位置
+// }
+// });
+//
+// // 一段时间后更新位置
+// setTimeout(() => {
+// const newPosition = Cesium.Cartesian3.fromDegrees(116.45, 39.92, 100);
+// imageEntity.updatePosition(newPosition);
+// console.log("实体位置已更新");
+// }, 2000);
+//
+// // 调用flyTo将飞向最新的位置
+// setTimeout(() => {
+// imageEntity.flyTo({duration: 2});
+// }, 4000);
+
\ No newline at end of file
From e6f235036e0d387ae238a4fc21a754282ddba28d Mon Sep 17 00:00:00 2001
From: tcy <1193318383@qq.com>
Date: Tue, 9 Sep 2025 21:12:04 +0800
Subject: [PATCH 14/29] =?UTF-8?q?refactor(components):=20=E4=BC=98?=
=?UTF-8?q?=E5=8C=96=E5=A4=9A=E4=B8=AA=E7=BB=84=E4=BB=B6=E7=9A=84=E6=A0=B7?=
=?UTF-8?q?=E5=BC=8F=E5=92=8C=E5=B8=83=E5=B1=80?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- 调整了多个组件的输入框、按钮等元素的样式
- 优化了部分对话框的布局结构
- 统一了表单项的样式
- 调整了部分字体大小和颜色
---
src/components/FileUpload/index.vue | 52 ++----
.../formalitiesAreConsolidated/index.vue | 132 +++++--------
src/views/progress/plan/index.vue | 104 ++++-------
src/views/progress/progressCategory/index.vue | 176 +++++++++++++++---
src/views/tender/plan/comm/planPage.vue | 18 +-
src/views/tender/plan/comm/winTheBid.vue | 14 +-
src/views/tender/plan/index.vue | 171 ++++++-----------
7 files changed, 306 insertions(+), 361 deletions(-)
diff --git a/src/components/FileUpload/index.vue b/src/components/FileUpload/index.vue
index bd0b93c..e7a4f60 100644
--- a/src/components/FileUpload/index.vue
+++ b/src/components/FileUpload/index.vue
@@ -1,29 +1,11 @@
-
+
@@ -42,20 +24,10 @@
的文件
-
-
+
+
{{ getFileName(file.name) }}
@@ -305,8 +277,6 @@ const handleChange = (file: any, filelist: any) => {
// 删除文件
const handleRemove = (file: any, fileList: any) => {
- console.log(11);
-
emit('handleRemove', file, fileList);
};
@@ -470,7 +440,7 @@ defineExpose({ submitUpload });
}
}
- > span {
+ >span {
width: 100%;
}
}
diff --git a/src/views/formalities/formalitiesAreConsolidated/index.vue b/src/views/formalities/formalitiesAreConsolidated/index.vue
index b276f4d..d848aa7 100644
--- a/src/views/formalities/formalitiesAreConsolidated/index.vue
+++ b/src/views/formalities/formalitiesAreConsolidated/index.vue
@@ -1,6 +1,7 @@
-
+
@@ -11,25 +12,15 @@
-->
-
+
-
+
-
+
-
+
@@ -181,7 +161,8 @@
-
+
{{ scope.row.fileName || '查看文件' }}
@@ -192,13 +173,8 @@
-
+
关闭
@@ -208,18 +184,9 @@
-
+
@@ -247,18 +214,14 @@
-
+
@@ -284,7 +247,8 @@
-
+
diff --git a/src/views/progress/plan/index.vue b/src/views/progress/plan/index.vue
index b4eb9cf..433cb9b 100644
--- a/src/views/progress/plan/index.vue
+++ b/src/views/progress/plan/index.vue
@@ -1,12 +1,14 @@
-
+
-
+
@@ -21,24 +23,16 @@
-
+
-
+ @click="handleToggleExpandAll">
+
+
@@ -46,9 +40,8 @@
- {{ row.name }}
+ {{ row.name }}
{{ row.name }}
@@ -60,7 +53,8 @@
- {{ row.isDelay == '1' ? '是' : '否' }}
+ {{ row.isDelay == '1' ? '是' : '否'
+ }}
@@ -71,7 +65,8 @@
-
+
@@ -87,35 +82,17 @@
-
+ v-hasPermi="['progress:progressCategory:add']">
导入表格
-
+
计划
-
+
日报
@@ -132,7 +109,8 @@
-
+
@@ -140,7 +118,8 @@
- {{ row.name }}
+ {{ row.name }}
{{ row.name }}
@@ -163,7 +142,8 @@
-
+
@@ -179,28 +159,17 @@
-
+ v-hasPermi="['progress:progressCategory:add']">
导入表格
-
+
计划
-
+
日报
@@ -211,7 +180,8 @@
-
+