Bläddra i källkod

feat: 计算器

ystl_myq 8 månader sedan
förälder
incheckning
157c03997a

+ 4 - 3
src/components/ELPicker/index.vue

@@ -2,7 +2,7 @@
 import { Calendar } from "@element-plus/icons-vue";
 import dayjs from "dayjs";
 import { ref } from "vue";
-const value = ref("");
+const timeValue = ref("");
 const dropdownShow = ref(false);
 const yearTime = ref<any>(dayjs(new Date()).format("YYYY"));
 const decreaseYear = () => {
@@ -45,7 +45,7 @@ const monthOne = item => {
       end = `${yearTime.value}-12-31`;
       break;
   }
-  value.value = `${yearTime.value}年${item}`;
+  timeValue.value = `${yearTime.value}年${item}`;
   console.log(start, end);
   return `从 ${start} 到 ${end}`; // 设置时间区间
 };
@@ -53,6 +53,7 @@ const monthOne = item => {
 const quarterValue = ref(false);
 const open = value => {
   console.log(value);
+  timeValue.value = "";
   if (value === "quarter") {
     quarterValue.value = true;
   } else {
@@ -68,7 +69,7 @@ defineExpose({
     <el-dropdown trigger="click">
       <span class="el-dropdown-link navbar-bg-hover select-none">
         <el-input
-          v-model="value"
+          v-model="timeValue"
           style="width: 240px"
           placeholder="请选择日期"
           :prefix-icon="Calendar"

+ 51 - 0
src/components/echarts/radar.vue

@@ -0,0 +1,51 @@
+<script setup lang="ts">
+import { ref, computed } from "vue";
+import { useDark, useECharts } from "@pureadmin/utils";
+
+// 兼容dark主题
+const { isDark } = useDark();
+let theme = computed(() => {
+  return isDark.value ? "dark" : "default";
+});
+
+// 初始化ECharts
+const chartRef = ref();
+const { setOptions } = useECharts(chartRef, { theme });
+
+// 根据配置项渲染ECharts
+setOptions({
+  tooltip: {},
+  legend: {
+    top: 10,
+    left: "left",
+    data: ["支出"]
+  },
+  radar: {
+    // shape: 'circle',
+    radius: "60%",
+    indicator: [
+      { name: "周一" },
+      { name: "周二" },
+      { name: "周三" },
+      { name: "周四" },
+      { name: "周五" }
+    ]
+  },
+  series: [
+    {
+      name: "Budget vs spending",
+      type: "radar",
+      data: [
+        {
+          value: [30, 60, 90, 120, 150],
+          name: "支出"
+        }
+      ]
+    }
+  ]
+});
+</script>
+
+<template>
+  <div ref="chartRef" style="width: 100%; height: 35vh" />
+</template>

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

@@ -3,6 +3,7 @@ defineOptions({
   name: "workerDrak"
 });
 import { ref } from "vue";
+
 const value = ref("");
 const options = [
   {

+ 4 - 1
src/views/evaluate/children/change/components/editMould.vue

@@ -10,6 +10,7 @@ const formLabelAlign = reactive({
   region: "",
   type: ""
 });
+const newAddItem = ref();
 const handleClose = (done: () => void) => {
   ElMessageBox.confirm("配置项未保存,确认关闭", {
     type: "warning"
@@ -25,6 +26,8 @@ function confirmClick() {
 }
 const open = row => {
   drawer.value = true;
+  // newAddItem.value = row;
+  formLabelAlign.name = row.name;
 };
 defineExpose({
   open
@@ -50,7 +53,7 @@ const radio1 = ref("1");
             :model="formLabelAlign"
           >
             <el-form-item label="维度名称" label-position="top">
-              <el-input />
+              <el-input v-model="formLabelAlign.name" />
             </el-form-item>
             <el-form-item label="维度权重" label-position="top">
               <el-switch class="mr-4" />

+ 122 - 0
src/views/evaluate/children/change/components/evaluate.ts

@@ -0,0 +1,122 @@
+class Counter {
+  constructor() {
+    this.result = 0;
+  }
+
+  // 加法
+  addition(val) {
+    this.result += val;
+    return this;
+  }
+
+  // 减法
+  subtraction(val) {
+    this.result -= val;
+    return this;
+  }
+
+  // 乘法
+  multiplication(val) {
+    this.result *= val;
+    return this;
+  }
+
+  // 除法
+  division(val) {
+    this.result /= val;
+    return this;
+  }
+
+  // 计算表达式
+  calculate(expression) {
+    const tokens = this.tokenize(expression);
+    const parsedExpression = this.parse(tokens);
+    this.result = this.evaluate(parsedExpression);
+    return this;
+  }
+
+  // 获取结果
+  get() {
+    return this.result;
+  }
+
+  // 词法分析,将字符串分割为token
+  tokenize(expression) {
+    return expression.match(/(\d+(\.\d+)?|[-+*/()])/g);
+  }
+
+  // 解析表达式
+  parse(tokens) {
+    const output = [];
+    const operators = [];
+    const precedence = {
+      "+": 1,
+      "-": 1,
+      "*": 2,
+      "/": 2
+    };
+
+    for (const token of tokens) {
+      if (!isNaN(token)) {
+        output.push(Number(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;
+  }
+
+  // 计算解析后的表达式
+  evaluate(parsedExpression) {
+    const stack = [];
+
+    for (const token of parsedExpression) {
+      if (typeof token === "number") {
+        stack.push(token);
+      } else {
+        const b = stack.pop();
+        const a = stack.pop();
+        switch (token) {
+          case "+":
+            stack.push(a + b);
+            break;
+          case "-":
+            stack.push(a - b);
+            break;
+          case "*":
+            stack.push(a * b);
+            break;
+          case "/":
+            stack.push(a / b);
+            break;
+        }
+      }
+    }
+
+    return stack[0];
+  }
+}
+
+// 使用示例
+// const calculator = new Counter();
+// calculator.calculate("3.5 + 2.3 * (2 - 8)");
+// console.log(calculator.get()); // 输出结果
+export const calculator = new Counter();

+ 26 - 8
src/views/evaluate/children/change/components/newAdd.vue

@@ -28,6 +28,21 @@ const tepName = ref();
 const tepNameForm = reactive({
   name: ""
 });
+// 考核维度卡片
+const eaxmCard = ref([
+  { name: "工作量", value: 1 },
+  { name: "效率", value: 2 },
+  { name: "考核维度", value: 3 },
+  { name: "维度", value: 4 }
+]);
+// 创建考核维度
+const createAdd = () => {
+  eaxmCard.value.push({ name: "考核维度", value: eaxmCard.value.length + 1 });
+  ElMessage({
+    type: "success",
+    message: "创建成功"
+  });
+};
 const backChange = () => {
   router.back();
 };
@@ -128,11 +143,11 @@ const deleteRow = row => {
     });
 };
 // 编辑
-const editPen = row => {
-  editDrawer.value.open();
+const editPen = item => {
+  editDrawer.value.open(item);
 };
 // 删除考核维度
-const deletePen = row => {
+const deletePen = index => {
   ElMessageBox.confirm(
     "该维度删除后不可恢复,请谨慎操作!",
     "确定删除考核维度",
@@ -143,6 +158,7 @@ const deletePen = row => {
     }
   )
     .then(() => {
+      eaxmCard.value.splice(index, 1);
       ElMessage({
         type: "success",
         message: "删除成功"
@@ -236,17 +252,19 @@ const importIndexDialog = row => {
       </div>
       <div v-if="active == 1" class="w-[90%] m-auto mt-4">
         <div class="relative h-10">
-          <el-button class="float-right" type="primary" plain
+          <el-button class="float-right" type="primary" plain @click="createAdd"
             >创建考核维度</el-button
           >
         </div>
-        <el-card class="mb-3">
+        <el-card v-for="(item, index) in eaxmCard" :key="index" class="mb-3">
           <template #header>
             <div class="card-header">
-              <span>工作量(30%)</span>
+              <span>{{ item.name }}(30%)</span>
               <div class="float-right mr-7">
-                <el-icon class="mr-3" @click="editPen"><EditPen /></el-icon>
-                <el-icon @click="deletePen"
+                <el-icon class="mr-3" @click="editPen(item)"
+                  ><EditPen
+                /></el-icon>
+                <el-icon @click="deletePen(index)"
                   ><Delete class="text-red-500"
                 /></el-icon>
               </div>

+ 295 - 2
src/views/evaluate/children/change/components/settingIndexDrawer.vue

@@ -1,6 +1,7 @@
 <script setup lang="ts">
 import { ref, reactive } from "vue";
 import { ElMessageBox, ElMessage } from "element-plus";
+import { calculator } from "./evaluate";
 import type { DrawerProps, FormItemProps, FormProps } from "element-plus";
 // const itemLabelPosition = ref<FormItemProps["labelPosition"]>("");
 const drawer = ref(false);
@@ -9,6 +10,8 @@ const direction = ref<DrawerProps["direction"]>("rtl");
 const formLabelAlign = reactive({
   name: "",
   region: "",
+  grade: "",
+  compute: "",
   type: ""
 });
 const handleClose = (done: () => void) => {
@@ -42,6 +45,67 @@ defineExpose({
   open
 });
 const timer = ref("");
+// 评分方式------------------------
+const options = [
+  {
+    value: "1",
+    label: "手动输入方式"
+  },
+  {
+    value: "2",
+    label: "公式自动计算"
+  }
+];
+// 公式计算
+const compute = [
+  {
+    value: "1",
+    label: "无公式计算"
+  },
+  {
+    value: "2",
+    label: "多公式计算"
+  }
+];
+const bgColor = ref(null);
+const rolesList = reactive({
+  data: [
+    { name: "完成值 / 目标值", id: 1 },
+    { name: "完成值 - 目标值", id: 2 },
+    { name: "目标值 - 完成值", id: 3 },
+    { name: "门槛值", id: 4 },
+    { name: "目标值", id: 5 },
+    { name: "挑战值", id: 6 },
+    { name: "完成值", id: 7 },
+    { name: "增幅", id: 8 },
+    { name: "降幅", id: 9 }
+  ],
+  value: "",
+  num: null
+});
+const lookRoles = item => {
+  bgColor.value = item.id;
+};
+// 字符拼接
+const countNumber = (item: string) => {
+  rolesList.value = rolesList.value + item;
+};
+// 清除
+const remove = () => {
+  if (rolesList.value.length > 0) {
+    rolesList.value = rolesList.value.slice(0, -1);
+  }
+};
+// 清空
+const removeVoid = () => {
+  rolesList.value = "";
+};
+// 计算确认
+const count = item => {
+  calculator.calculate(rolesList.value);
+  // console.log(calculator.get()); // 输出结果
+  rolesList.num = calculator.get();
+};
 </script>
 
 <template>
@@ -50,6 +114,7 @@ const timer = ref("");
       v-model="drawer"
       :direction="direction"
       :before-close="handleClose"
+      size="600px"
     >
       <template #header>
         <h4>指标设置</h4>
@@ -62,11 +127,224 @@ const timer = ref("");
             :model="formLabelAlign"
           >
             <el-form-item label="完成值录入人" label-position="top">
-              <el-input />
+              <el-select v-model="formLabelAlign.grade" placeholder="请选择">
+                <el-option
+                  v-for="item in options"
+                  :key="item.value"
+                  :label="item.label"
+                  :value="item.value"
+                />
+              </el-select>
             </el-form-item>
             <el-form-item label="评分方式" label-position="top">
-              <el-input />
+              <el-select v-model="formLabelAlign.grade" placeholder="请选择">
+                <el-option
+                  v-for="item in options"
+                  :key="item.value"
+                  :label="item.label"
+                  :value="item.value"
+                />
+              </el-select>
             </el-form-item>
+            <div v-if="formLabelAlign.grade === '2'">
+              <el-form-item label="公式类型" label-position="top">
+                <el-select
+                  v-model="formLabelAlign.compute"
+                  placeholder="请选择"
+                >
+                  <el-option
+                    v-for="item in compute"
+                    :key="item.value"
+                    :label="item.label"
+                    :value="item.value"
+                  />
+                </el-select>
+              </el-form-item>
+              <el-form-item
+                v-if="formLabelAlign.compute === '1'"
+                label="公式设置"
+                label-position="top"
+              >
+                <div>
+                  <el-text>得分 =</el-text>
+                  <el-input
+                    v-model="rolesList.num"
+                    class="ml-2 mr-2"
+                    style="width: 240px"
+                  />
+                  <el-text>
+                    <el-button type="primary">公式验证</el-button>
+                  </el-text>
+                </div>
+                <div
+                  class="w-[500px] compute h-64 mt-1 ml-12 flex justify-evenly items-center"
+                  style="user-select: none"
+                >
+                  <div class="w-1/3 h-60 pl-1 bg-white rounded-md">
+                    <div class="w-[100%] text-xs mt-2">
+                      <div><el-text type="info">::变量</el-text></div>
+                    </div>
+                    <div v-for="item in rolesList.data" :key="item.id">
+                      <div
+                        :class="[
+                          'cursor-pointer text-xs mt-1',
+                          { 'bg-blue-200': bgColor === item.id }
+                        ]"
+                        @click="lookRoles(item)"
+                      >
+                        <el-text class="">{{ item.name }}</el-text>
+                      </div>
+                    </div>
+                  </div>
+                  <div class="w-3/5 ml-2 h-60 flex flex-col">
+                    <div class="w-[100%] text-xs h-24 bg-white rounded-md">
+                      <div class="p-1"><el-text>得分 = </el-text></div>
+                      <!-- style="height: 95px" -->
+                      <el-input
+                        v-model="rolesList.value"
+                        :rows="3"
+                        type="textarea"
+                        placeholder=""
+                      />
+                    </div>
+                    <div class="w-[100%] h-32 mt-2 rounded-md flex flex-col">
+                      <div class="flex justify-between h-8">
+                        <div
+                          class="h-full w-[50px] bg-white mx-1 flex justify-center items-center rounded-lg cursor-pointer"
+                          @click="countNumber('1')"
+                        >
+                          1
+                        </div>
+                        <div
+                          class="h-full w-[50px] bg-white mx-1 flex justify-center items-center rounded-lg cursor-pointer"
+                          @click="countNumber('2')"
+                        >
+                          2
+                        </div>
+                        <div
+                          class="h-full w-[50px] bg-white mx-1 flex justify-center items-center rounded-lg cursor-pointer"
+                          @click="countNumber('3')"
+                        >
+                          3
+                        </div>
+                        <div
+                          class="h-full w-[50px] bg-white mx-1 flex justify-center items-center rounded-lg cursor-pointer"
+                          @click="countNumber('+')"
+                        >
+                          +
+                        </div>
+                        <div
+                          class="h-full w-[50px] text-white bg-orange-400 mx-1 flex justify-center items-center rounded-lg cursor-pointer"
+                          @click="remove"
+                        >
+                          x
+                        </div>
+                      </div>
+                      <div class="flex justify-between h-8 mt-1">
+                        <div
+                          class="h-full w-[50px] bg-white mx-1 flex justify-center items-center rounded-lg cursor-pointer"
+                          @click="countNumber('4')"
+                        >
+                          4
+                        </div>
+                        <div
+                          class="h-full w-[50px] bg-white mx-1 flex justify-center items-center rounded-lg cursor-pointer"
+                          @click="countNumber('5')"
+                        >
+                          5
+                        </div>
+                        <div
+                          class="h-full w-[50px] bg-white mx-1 flex justify-center items-center rounded-lg cursor-pointer"
+                          @click="countNumber('6')"
+                        >
+                          6
+                        </div>
+                        <div
+                          class="h-full w-[50px] bg-white mx-1 flex justify-center items-center rounded-lg cursor-pointer"
+                          @click="countNumber('-')"
+                        >
+                          -
+                        </div>
+                        <div
+                          class="text-xs h-full w-[50px] text-white bg-orange-400 mx-1 flex justify-center items-center rounded-lg cursor-pointer"
+                          @click="removeVoid"
+                        >
+                          清空
+                        </div>
+                      </div>
+                      <div class="flex justify-between h-16 mt-1">
+                        <div>
+                          <div class="flex justify-between">
+                            <div
+                              class="h-full w-[50px] bg-white mx-1 flex justify-center items-center rounded-lg cursor-pointer"
+                              @click="countNumber('7')"
+                            >
+                              7
+                            </div>
+                            <div
+                              class="h-full ml-1 w-[50px] bg-white mx-1 flex justify-center items-center rounded-lg cursor-pointer"
+                              @click="countNumber('8')"
+                            >
+                              8
+                            </div>
+                            <div
+                              class="h-full ml-2 w-[50px] bg-white mx-1 flex justify-center items-center rounded-lg cursor-pointer"
+                              @click="countNumber('9')"
+                            >
+                              9
+                            </div>
+                            <div
+                              class="h-full w-[50px] bg-white mx-1 flex justify-center items-center rounded-lg cursor-pointer"
+                              @click="countNumber('*')"
+                            >
+                              *
+                            </div>
+                          </div>
+                          <div class="flex mt-1 justify-between">
+                            <div
+                              class="h-full w-[50px] bg-white mx-1 flex justify-center items-center rounded-lg cursor-pointer"
+                              @click="countNumber('0')"
+                            >
+                              0
+                            </div>
+                            <div
+                              class="h-full ml-1 w-[50px] bg-white mx-1 flex justify-center items-center rounded-lg cursor-pointer"
+                              @click="countNumber('.')"
+                            >
+                              .
+                            </div>
+                            <div
+                              class="h-full ml-2 w-[50px] bg-white mx-1 flex justify-center items-center rounded-lg cursor-pointer"
+                              @click="countNumber('()')"
+                            >
+                              ()
+                            </div>
+                            <div
+                              class="h-full w-[50px] bg-white mx-1 flex justify-center items-center rounded-lg cursor-pointer"
+                              @click="countNumber('/')"
+                            >
+                              /
+                            </div>
+                          </div>
+                        </div>
+                        <div
+                          class="h-full mr-1 w-[50px] text-white flex justify-center items-center rounded-lg cursor-pointer areYouOK"
+                          @click="count"
+                        >
+                          确认
+                        </div>
+                      </div>
+                    </div>
+                  </div>
+                </div>
+              </el-form-item>
+              <el-form-item v-else label="公式设置">
+                <div>
+                  <el-text>条件填 = </el-text
+                  ><el-input v-model="formLabelAlign.name" />
+                </div>
+              </el-form-item>
+            </div>
           </el-form>
         </div>
       </template>
@@ -79,3 +357,18 @@ const timer = ref("");
     </el-drawer>
   </div>
 </template>
+<style lang="scss" scoped>
+.compute {
+  // border: 1px solid #f3f3f3;
+  background-color: #f3f3f3;
+  border-radius: 5px;
+}
+
+.text-color {
+  color: #f3f3f3;
+}
+
+.areYouOK {
+  background-color: #409eff;
+}
+</style>