Ver código fonte

fix: 计算器

ystl_myq 8 meses atrás
pai
commit
76a7d1e09a

+ 1 - 0
package.json

@@ -57,6 +57,7 @@
     "animate.css": "^4.1.1",
     "axios": "^1.6.8",
     "dayjs": "^1.11.10",
+    "decimal.js": "^10.4.3",
     "default-passive-events": "^2.0.0",
     "echarts": "^5.5.0",
     "element-plus": "^2.6.2",

+ 8 - 0
pnpm-lock.yaml

@@ -35,6 +35,9 @@ importers:
       dayjs:
         specifier: ^1.11.10
         version: 1.11.10
+      decimal.js:
+        specifier: ^10.4.3
+        version: 10.4.3
       default-passive-events:
         specifier: ^2.0.0
         version: 2.0.0
@@ -1655,6 +1658,9 @@ packages:
       supports-color:
         optional: true
 
+  decimal.js@10.4.3:
+    resolution: {integrity: sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==}
+
   deep-is@0.1.4:
     resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==}
 
@@ -5319,6 +5325,8 @@ snapshots:
     dependencies:
       ms: 2.1.2
 
+  decimal.js@10.4.3: {}
+
   deep-is@0.1.4: {}
 
   default-passive-events@2.0.0: {}

+ 2 - 0
src/main.ts

@@ -6,6 +6,7 @@ import { MotionPlugin } from "@vueuse/motion";
 // import { useEcharts } from "@/plugins/echarts";
 import { createApp, type Directive } from "vue";
 import { useElementPlus } from "@/plugins/elementPlus";
+import * as echarts from "echarts";
 import { injectResponsiveStorage } from "@/utils/responsive";
 import * as ElementPlusIconsVue from "@element-plus/icons-vue";
 import Table from "@pureadmin/table";
@@ -58,6 +59,7 @@ getPlatformConfig(app).then(async config => {
   app.use(router);
   await router.isReady();
   injectResponsiveStorage(app, config);
+  app.config.globalProperties.$echarts = echarts;
   app.use(MotionPlugin).use(useElementPlus).use(Table);
   // .use(PureDescriptions)
   // .use(useEcharts);

+ 4 - 1
src/views/draw/children/worker/workerDrak.vue

@@ -3,7 +3,7 @@ defineOptions({
   name: "workerDrak"
 });
 import { ref } from "vue";
-
+import radar from "@/components/echarts/radar.vue";
 const value = ref("");
 const options = [
   {
@@ -100,6 +100,9 @@ const options = [
           </div>
         </div>
       </div>
+      <div class="flex mr-2">
+        <radar />
+      </div>
     </div>
   </div>
 </template>

+ 215 - 36
src/views/evaluate/children/change/components/evaluate.ts

@@ -1,69 +1,231 @@
+import Decimal from "decimal.js";
+import { ElMessage } from "element-plus";
+
+// class Counter {
+//   private result: Decimal;
+
+//   constructor() {
+//     this.result = new Decimal(0);
+//   }
+
+//   // 加法
+//   addition(val: number | string): this {
+//     this.result = this.result.plus(new Decimal(val));
+//     return this;
+//   }
+
+//   // 减法
+//   subtraction(val: number | string): this {
+//     this.result = this.result.minus(new Decimal(val));
+//     return this;
+//   }
+
+//   // 乘法
+//   multiplication(val: number | string): this {
+//     this.result = this.result.times(new Decimal(val));
+//     return this;
+//   }
+
+//   // 除法
+//   division(val: number | string): this {
+//     if (new Decimal(val).isZero()) {
+//       throw new Error("除数不能为零");
+//     }
+//     this.result = this.result.dividedBy(new Decimal(val));
+//     return this;
+//   }
+
+//   // 计算表达式
+//   calculate(expression: string): this {
+//     const tokens = this.tokenize(expression);
+//     const parsedExpression = this.parse(tokens);
+//     this.result = new Decimal(this.evaluate(parsedExpression));
+//     return this;
+//   }
+
+//   // 获取结果
+//   get(): number {
+//     return this.result.toNumber(); // 返回普通数字
+//   }
+
+//   // 词法分析,将字符串分割为token
+//   private tokenize(expression: string): Array<string> {
+//     return expression.match(/(\d+(\.\d+)?|[-+*/()])/g) || [];
+//   }
+
+//   // 解析表达式
+//   private parse(tokens: Array<string>): Array<Decimal | string> {
+//     const output: Array<Decimal | string> = [];
+//     const operators: Array<string> = [];
+//     const precedence: { [key: string]: number } = {
+//       "+": 1,
+//       "-": 1,
+//       "*": 2,
+//       "/": 2
+//     };
+
+//     for (let i = 0; i < tokens.length; i++) {
+//       const token = tokens[i];
+
+//       // 检查连续运算符
+//       if (i > 0 && this.isOperator(token) && this.isOperator(tokens[i - 1])) {
+//         this.showWarning("公式错误");
+//         return []; // 返回空数组表示错误
+//       }
+
+//       if (!isNaN(Number(token))) {
+//         output.push(new Decimal(token));
+//       } else if (token === "(") {
+//         operators.push(token);
+//       } else if (token === ")") {
+//         while (operators.length && operators[operators.length - 1] !== "(") {
+//           output.push(operators.pop()!);
+//         }
+//         operators.pop(); // 弹出 '('
+//       } else {
+//         while (
+//           operators.length &&
+//           precedence[operators[operators.length - 1]] >= precedence[token]
+//         ) {
+//           output.push(operators.pop()!);
+//         }
+//         operators.push(token);
+//       }
+//     }
+
+//     while (operators.length) {
+//       output.push(operators.pop()!);
+//     }
+
+//     return output;
+//   }
+
+//   // 判断是否为运算符
+//   private isOperator(token: string): boolean {
+//     return ["+", "-", "*", "/"].includes(token);
+//   }
+
+//   private showWarning(message: string): void {
+//     ElMessage({
+//       message: message,
+//       type: "warning"
+//     });
+//   }
+
+//   // 计算解析后的表达式
+//   private evaluate(parsedExpression: Array<Decimal | string>): number {
+//     const stack: Array<Decimal> = [];
+
+//     for (const token of parsedExpression) {
+//       if (token instanceof Decimal) {
+//         stack.push(token);
+//       } else {
+//         const b = stack.pop()!;
+//         const a = stack.pop()!;
+//         switch (token) {
+//           case "+":
+//             stack.push(a.plus(b));
+//             break;
+//           case "-":
+//             stack.push(a.minus(b));
+//             break;
+//           case "*":
+//             stack.push(a.times(b));
+//             break;
+//           case "/":
+//             if (b.isZero()) {
+//               this.showWarning("除数不能为零");
+//               throw new Error("除数不能为零");
+//             }
+//             stack.push(a.dividedBy(b));
+//             break;
+//         }
+//       }
+//     }
+
+//     return stack[0].toNumber(); // 返回计算结果
+//   }
+// }
 class Counter {
+  private result: Decimal;
+
   constructor() {
-    this.result = 0;
+    this.result = new Decimal(0);
   }
 
   // 加法
-  addition(val) {
-    this.result += val;
+  addition(val: number | string): this {
+    this.result = this.result.plus(new Decimal(val));
     return this;
   }
 
   // 减法
-  subtraction(val) {
-    this.result -= val;
+  subtraction(val: number | string): this {
+    this.result = this.result.minus(new Decimal(val));
     return this;
   }
 
   // 乘法
-  multiplication(val) {
-    this.result *= val;
+  multiplication(val: number | string): this {
+    this.result = this.result.times(new Decimal(val));
     return this;
   }
 
   // 除法
-  division(val) {
-    this.result /= val;
+  division(val: number | string): this {
+    if (new Decimal(val).isZero()) {
+      throw new Error("除数不能为零");
+    }
+    this.result = this.result.dividedBy(new Decimal(val));
     return this;
   }
 
   // 计算表达式
-  calculate(expression) {
+  calculate(expression: string): this {
     const tokens = this.tokenize(expression);
     const parsedExpression = this.parse(tokens);
-    this.result = this.evaluate(parsedExpression);
+    this.result = new Decimal(this.evaluate(parsedExpression));
     return this;
   }
 
   // 获取结果
-  get() {
-    return this.result;
+  get(): number {
+    return this.result.toNumber(); // 返回普通数字
   }
 
   // 词法分析,将字符串分割为token
-  tokenize(expression) {
-    return expression.match(/(\d+(\.\d+)?|[-+*/()])/g);
+  private tokenize(expression: string): Array<string> {
+    // 使用正则表达式来允许负数
+    return expression.match(/-?\d+(\.\d+)?|[-+*/()]/g) || [];
   }
 
   // 解析表达式
-  parse(tokens) {
-    const output = [];
-    const operators = [];
-    const precedence = {
+  private parse(tokens: Array<string>): Array<Decimal | string> {
+    const output: Array<Decimal | string> = [];
+    const operators: Array<string> = [];
+    const precedence: { [key: string]: number } = {
       "+": 1,
       "-": 1,
       "*": 2,
       "/": 2
     };
 
-    for (const token of tokens) {
-      if (!isNaN(token)) {
-        output.push(Number(token));
+    for (let i = 0; i < tokens.length; i++) {
+      const token = tokens[i];
+
+      // 检查连续运算符
+      if (i > 0 && this.isOperator(token) && this.isOperator(tokens[i - 1])) {
+        this.showWarning("公式错误");
+        return []; // 返回空数组表示错误
+      }
+
+      if (!isNaN(Number(token))) {
+        output.push(new Decimal(token));
       } else if (token === "(") {
         operators.push(token);
       } else if (token === ")") {
         while (operators.length && operators[operators.length - 1] !== "(") {
-          output.push(operators.pop());
+          output.push(operators.pop()!);
         }
         operators.pop(); // 弹出 '('
       } else {
@@ -71,50 +233,67 @@ class Counter {
           operators.length &&
           precedence[operators[operators.length - 1]] >= precedence[token]
         ) {
-          output.push(operators.pop());
+          output.push(operators.pop()!);
         }
         operators.push(token);
       }
     }
 
     while (operators.length) {
-      output.push(operators.pop());
+      output.push(operators.pop()!);
     }
 
     return output;
   }
 
+  // 判断是否为运算符
+  private isOperator(token: string): boolean {
+    return ["+", "-", "*", "/"].includes(token);
+  }
+
+  private showWarning(message: string): void {
+    // 假设 ElMessage 是某个库的消息提示函数
+    // 假设 ElMessage 是某个库的消息提示函数
+    ElMessage({
+      message: message,
+      type: "warning"
+    });
+  }
+
   // 计算解析后的表达式
-  evaluate(parsedExpression) {
-    const stack = [];
+  private evaluate(parsedExpression: Array<Decimal | string>): number {
+    const stack: Array<Decimal> = [];
 
     for (const token of parsedExpression) {
-      if (typeof token === "number") {
+      if (token instanceof Decimal) {
         stack.push(token);
       } else {
-        const b = stack.pop();
-        const a = stack.pop();
+        const b = stack.pop()!;
+        const a = stack.pop()!;
         switch (token) {
           case "+":
-            stack.push(a + b);
+            stack.push(a.plus(b));
             break;
           case "-":
-            stack.push(a - b);
+            stack.push(a.minus(b));
             break;
           case "*":
-            stack.push(a * b);
+            stack.push(a.times(b));
             break;
           case "/":
-            stack.push(a / b);
+            if (b.isZero()) {
+              this.showWarning("除数不能为零");
+              throw new Error("除数不能为零");
+            }
+            stack.push(a.dividedBy(b));
             break;
         }
       }
     }
 
-    return stack[0];
+    return stack[0].toNumber(); // 返回计算结果
   }
 }
-
 // 使用示例
 // const calculator = new Counter();
 // calculator.calculate("3.5 + 2.3 * (2 - 8)");

+ 19 - 3
src/views/evaluate/children/change/components/settingIndexDrawer.vue

@@ -102,9 +102,25 @@ const removeVoid = () => {
 };
 // 计算确认
 const count = item => {
-  calculator.calculate(rolesList.value);
-  // console.log(calculator.get()); // 输出结果
-  rolesList.num = calculator.get();
+  try {
+    calculator.calculate(rolesList.value);
+    // console.log(calculator.get()); // 输出结果
+    rolesList.num = calculator.get();
+    // if (calculator.get()) {
+    // } else {
+    //   rolesList.num = 0;
+    //   ElMessage({
+    //     message: "计算错误",
+    //     type: "warning"
+    //   });
+    // }
+  } catch (error) {
+    // ElMessage({
+    //   message: "计算错误",
+    //   type: "warning"
+    // });
+    console.log(error);
+  }
 };
 </script>