Selaa lähdekoodia

用户管理+联调

liujiejie 1 vuosi sitten
vanhempi
commit
a37ff92b01

+ 4 - 4
public/config/config.js

@@ -1,8 +1,8 @@
 const config = {
-  API: '/api',
-  upload: 'http://xxx'
-}
-window._BASE_CONFIG = config
+  API: "/api",
+  // upload: "http://192.168.50.235:16200",
+};
+window._BASE_CONFIG = config;
 //冻结对象
 // if (Object.freeze) {
 //   Object.freeze(window._BASE_CONFIG)

+ 91 - 0
src/api/system.js

@@ -0,0 +1,91 @@
+/*
+ * @Author: your name
+ * @Date: 2024-05-20 09:36:55
+ * @LastEditTime: 2024-05-20 15:50:56
+ * @LastEditors: bogon
+ * @Description: In User Settings Edit
+ * @FilePath: /performance-test/src/api/system.js
+ */
+import request from "@/utils/request";
+//用户退出登录
+
+export function userLogout(data) {
+  return request({
+    url: "/energy-manage-service/sysuserinfo/userLogout",
+    method: "post",
+    data,
+  });
+}
+export function getUserTableList(data) {
+  return request({
+    url: "/energy-manage-service/sysuserinfo/getUserByName",
+    method: "post",
+    data,
+  });
+}
+//用户启用
+export function enableUser(data) {
+  return request({
+    url: "/energy-manage-service/sysuserinfo/enableUser",
+    method: "post",
+    data,
+  });
+}
+//用户禁用
+export function disableUser(data) {
+  return request({
+    url: "/energy-manage-service/sysuserinfo/disableUser",
+    method: "post",
+    data,
+  });
+}
+//查看用户详情信息
+export function getUserInfoByUserId(data) {
+  return request({
+    url: "/energy-manage-service/sysuserinfo/getUserInfoByUserId",
+    method: "get",
+    params: data,
+  });
+}
+//修改用户密码
+export function updatePWD(data) {
+  return request({
+    url: "/energy-manage-service/sysuserinfo/updatePWD",
+    method: "post",
+    data,
+  });
+}
+//删除用户接口
+
+export function deleteUserInfo(data) {
+  return request({
+    url: "/energy-manage-service/sysuserinfo/deleteUser",
+    method: "post",
+    data,
+  });
+}
+//新增用户接口
+export function addUser(data) {
+  return request({
+    url: "/energy-manage-service/sysuserinfo/addUser",
+    method: "post",
+    data,
+  });
+}
+//编辑用户接口
+export function editUser(data) {
+  return request({
+    url: "/energy-manage-service/sysuserinfo/updateUser",
+    method: "post",
+    data,
+  });
+}
+//角色列表
+///energy-manage-service/sysrole
+export function getRoleTableList(data) {
+  return request({
+    url: "/energy-manage-service/sysrole/通过角色名称查询角色列表",
+    method: "post",
+    data,
+  });
+}

+ 10 - 0
src/components/HeaderCom.vue

@@ -44,6 +44,7 @@
 </template>
 
 <script>
+import { userLogout } from "@/api/system";
 import ThemePicker from "@/components/ThemePicker";
 export default {
   data() {
@@ -79,6 +80,15 @@ export default {
       // 设置当前时间数据
       this.currentDate = `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
     },
+    skip() {
+      userLogout({
+        phone: this.$store.state.auth.userInfo.userInfo.userPhone,
+      }).then((res) => {
+        console.log(res);
+        this.$store.commit("auth/DEL_TOKEN");
+        this.$router.push("/login");
+      });
+    },
   },
 };
 </script>

+ 3 - 0
src/store/auth.js

@@ -12,6 +12,9 @@ export default {
     SET_USERINFO(state, payload) {
       state.userInfo = payload;
     },
+    DEL_TOKEN(state, payload) {
+      state.userInfo.token = null;
+    },
     // SET_ROUTES(state, routes) {
     //   state.routes = routes;
     // },

+ 11 - 13
src/styles/base.css

@@ -45,8 +45,8 @@ td {
   margin: 0;
   padding: 0;
   border: 0;
-  font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei",
-    "微软雅黑", Arial, sans-serif;
+  font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB",
+    "Microsoft YaHei", "微软雅黑", Arial, sans-serif;
 }
 
 header,
@@ -130,9 +130,7 @@ small {
 }
 
 input:-webkit-autofill {
-
   -webkit-box-shadow: 0 0 0 1000px white inset;
-
 }
 
 sub,
@@ -225,8 +223,9 @@ body {
   background: #ffffff;
   font-size: 22px;
   color: #333;
-  font-family: "HYQiHei", "Helvetica Neue", Helvetica, Arial, "PingFang SC", "Hiragino Sans GB",
-    "Heiti SC", "MicrosoftYaHei", "WenQuanYi Micro Hei", sans-serif;
+  font-family: "HYQiHei", "Helvetica Neue", Helvetica, Arial, "PingFang SC",
+    "Hiragino Sans GB", "Heiti SC", "MicrosoftYaHei", "WenQuanYi Micro Hei",
+    sans-serif;
 }
 
 .maxWidth {
@@ -255,7 +254,8 @@ body {
   margin: 20px;
   padding: 20px;
   background: #ffffff;
-  height: 89vh;
+  min-height: 89vh;
+  /* height: 89vh; */
 }
 
 /* 列表点击 */
@@ -276,7 +276,6 @@ body {
   margin-bottom: 20px;
 }
 
-
 .centeredH3 {
   text-align: center;
   font-size: 26px;
@@ -284,16 +283,15 @@ body {
   margin-bottom: 20px;
 }
 
-.el-date-editor .el-range-separator{
+.el-date-editor .el-range-separator {
   padding: 0;
 }
 
-
-.el-form-item--small.el-form-item{
+.el-form-item--small.el-form-item {
   margin-bottom: 0px;
   margin-top: 4px;
 }
 
-.el-dialog__body{
+.el-dialog__body {
   padding-top: 15px;
-}
+}

+ 10 - 2
src/utils/request.js

@@ -1,17 +1,25 @@
 import axios from "axios";
 import { Message } from "element-ui";
-console.log(window?._BASE_CONFIG?.API, "window?._BASE_CONFIG?.API");
+
 const service = axios.create({
   baseURL: window?._BASE_CONFIG?.API || "/api",
   withCredentials: true,
 });
-
+const writeList = ["/api/energy-manage-service/sysuserinfo/open/userLogin"];
 /**
  * 请求拦截器
  * 统一处理请求拦截,如:添加token等
  */
 service.interceptors.request.use(
   (config) => {
+    if (!writeList.includes(config.url)) {
+      return {
+        ...config,
+        headers: {
+          token: JSON.parse(sessionStorage.getItem("vuex")).auth.userInfo.token,
+        },
+      };
+    }
     return config;
   },
   (error) => {

+ 4 - 4
src/views/admin/cockpitManage/electronicMap.vue

@@ -8,14 +8,14 @@
 
 <script>
 export default {
-  name: 'PerformanceTestIndex',
+  name: "PerformanceTestIndex",
 
   data() {
-    return {}
+    return {};
   },
 
   mounted() {},
 
-  methods: {}
-}
+  methods: {},
+};
 </script>

+ 345 - 297
src/views/ledger/anemometer.vue

@@ -1,338 +1,386 @@
 <template>
-    <div class="global-variable">
+  <div class="global-variable">
+    <div class="condition">
+      <el-form :inline="true" :model="formInline" class="demo-form-inline">
+        <el-form-item label="测风塔名称:">
+          <el-input
+            v-model="formInline.user"
+            placeholder="请输入批次编号"
+            size="small"
+          ></el-input>
+        </el-form-item>
+        <el-form-item label="选择日期:" size="small">
+          <el-date-picker
+            v-model="formInline.timeQuantum"
+            type="daterange"
+            range-separator="至"
+            start-placeholder="开始日期"
+            end-placeholder="结束日期"
+          >
+          </el-date-picker>
+        </el-form-item>
+        <el-form-item>
+          <el-button type="primary" @click="onSubmit" size="small"
+            >查询</el-button
+          >
+          <el-button @click="reset" size="small">重置</el-button>
+        </el-form-item>
+      </el-form>
+    </div>
+    <div class="list-page">
+      <div class="newly">
+        <el-button type="primary" @click="newnuedialog" size="small"
+          >新增</el-button
+        >
+      </div>
+
+      <el-table
+        class="center-align-table"
+        :data="tableData"
+        border
+        :cell-style="rowStyle"
+      >
+        <el-table-column align="center" fixed prop="" label="测风塔名称">
+          <template slot-scope="scope">
+            <el-button @click="particulars(scope.row)" type="text" size="small"
+              >泗洪风场</el-button
+            >
+          </template>
+        </el-table-column>
+
+        <el-table-column align="center" label="测风塔编号"> </el-table-column>
+
+        <el-table-column prop="" align="center" label="机型类型">
+        </el-table-column>
+        <el-table-column prop="" align="center" label="经度" width="100">
+        </el-table-column>
+
+        <el-table-column prop="" align="center" label="纬度" width="100">
+        </el-table-column>
+        <el-table-column prop="" align="center" label="状态" width="100">
+        </el-table-column>
+        <el-table-column prop="" align="center" label="创建时间">
+        </el-table-column>
+        <el-table-column
+          prop="transition"
+          align="center"
+          fixed="right"
+          label="操作"
+          width="200"
+        >
+          <template slot-scope="scope">
+            <el-button @click="compile(scope.row)" type="text" size="small"
+              >编辑</el-button
+            >
+
+            <el-button
+              v-if="scope.row.transition == 1"
+              @click="start(scope.row)"
+              type="text"
+              size="small"
+              >启用</el-button
+            >
+            <el-button
+              v-else
+              style="color: #666"
+              @click="stop(scope.row)"
+              type="text"
+              size="small"
+              >停用</el-button
+            >
+            <el-button
+              style="color: #f00"
+              @click="deleted(scope.row)"
+              type="text"
+              size="small"
+              >删除</el-button
+            >
+          </template>
+        </el-table-column>
+      </el-table>
+      <div class="pagination-container">
+        <el-pagination
+          :page-size="10"
+          :pager-count="11"
+          layout="total, prev, pager, next"
+          :total="35"
+        >
+        </el-pagination>
+      </div>
+    </div>
+
+    <!-- 弹出层 -->
+
+    <!-- 新增 -->
+    <el-dialog :title="title" :visible.sync="nuedialog" width="800px">
+      <div class="addition">
+        <span @click="addition">
+          <SvgIcon
+            name="jia"
+            class="jia"
+            width="20px"
+            height="22px"
+            color="#222"
+          ></SvgIcon>
+        </span>
+        <span @click="subtraction">
+          <SvgIcon
+            name="jian"
+            class="jian"
+            width="20px"
+            height="22px"
+            color="#222"
+          ></SvgIcon>
+        </span>
+      </div>
+      <div class="general">
         <div class="condition">
-            <el-form :inline="true" :model="formInline" class="demo-form-inline">
-                <el-form-item label="测风塔名称:">
-                    <el-input v-model="formInline.user" placeholder="请输入批次编号" size="small"></el-input>
-                </el-form-item>
-                <el-form-item label="选择日期:" size="small">
-                    <el-date-picker v-model="formInline.timeQuantum" type="daterange" range-separator="至"
-                        start-placeholder="开始日期" end-placeholder="结束日期">
-                    </el-date-picker>
-                </el-form-item>
-                <el-form-item>
-                    <el-button type="primary" @click="onSubmit" size="small">查询</el-button>
-                    <el-button @click="reset" size="small">重置</el-button>
-                </el-form-item>
-            </el-form>
+          <p>测风塔名称:</p>
+          <el-input v-model="windsiteName"></el-input>
         </div>
-        <div class="list-page">
-            <div class="newly">
-
-                <el-button type="primary" @click="newnuedialog" size="small">新增</el-button>
-            </div>
-
-            <el-table class="center-align-table" :data="tableData" border :cell-style="rowStyle">
-                <el-table-column align="center" fixed prop="" label="测风塔名称">
-                    <template slot-scope="scope">
-                        <el-button @click="particulars(scope.row)" type="text" size="small">泗洪风场</el-button>
-                    </template>
-                </el-table-column>
-
-                <el-table-column align="center" label="测风塔编号"> </el-table-column>
-
-
-                <el-table-column prop="" align="center" label="机型类型">
-                </el-table-column>
-                <el-table-column prop="" align="center" label="经度" width="100">
-                </el-table-column>
-
-                <el-table-column prop="" align="center" label="纬度" width="100">
-                </el-table-column>
-                <el-table-column prop="" align="center" label="状态" width="100">
-                </el-table-column>
-                <el-table-column prop="" align="center" label="创建时间">
-                </el-table-column>
-                <el-table-column prop="transition" align="center" fixed="right" label="操作" width="200">
-                    <template slot-scope="scope">
-                        <el-button @click="compile(scope.row)" type="text" size="small">编辑</el-button>
-
-                        <el-button v-if="scope.row.transition == 1" @click="start(scope.row)" type="text"
-                            size="small">启用</el-button>
-                        <el-button v-else style="color: #666" @click="stop(scope.row)" type="text"
-                            size="small">停用</el-button>
-                        <el-button style="color: #f00" @click="deleted(scope.row)" type="text"
-                            size="small">删除</el-button>
-                    </template>
-                </el-table-column>
-            </el-table>
-            <div class="pagination-container">
-                <el-pagination :page-size="10" :pager-count="11" layout="total, prev, pager, next" :total="35">
-                </el-pagination>
-            </div>
+        <div class="condition">
+          <p>经度:</p>
+          <el-input v-model="airdensity"></el-input>
         </div>
 
-        <!-- 弹出层 -->
-
-        <!-- 新增 -->
-        <el-dialog :title="title" :visible.sync="nuedialog" width="800px">
-            <div class="addition ">
-                <span @click="addition">
-                    <SvgIcon name="jia" class="jia" width="20px" height="22px" color="#222"></SvgIcon>
-                </span>
-                <span @click="subtraction">
-                    <SvgIcon name="jian" class="jian" width="20px" height="22px" color="#222"></SvgIcon>
-                </span>
-            </div>
-            <div class="general">
-
-                <div class="condition">
-                    <p>测风塔名称:</p>
-                    <el-input v-model="windsiteName"></el-input>
-                </div>
-                <div class="condition">
-                    <p>经度:</p>
-                    <el-input v-model="airdensity"></el-input>
-                </div>
-
-
-                <div class="condition">
-                    <p>纬度:</p>
-                    <el-input v-model="altitude"></el-input>
-                </div>
-
-
-                <div v-for="(input, index) in heightInputs" :key="index" class="condition">
-                    <p>测风塔高度:</p>
-                    <el-input v-model="input.value" placeholder="请输入测风塔高度"></el-input>
-                </div>
-
-
-            </div>
-
-            <span slot="footer" class="dialog-footer">
-                <el-button @click="nuedialog = false" size="small">取 消</el-button>
-                <el-button type="primary" @click="newly" size="small">确 定</el-button>
-            </span>
-        </el-dialog>
-
-        <!-- 风场详情 -->
-        <el-dialog title="详情" :visible.sync="unusualdialog" width="800px">
-
-        </el-dialog>
-
-
-
+        <div class="condition">
+          <p>纬度:</p>
+          <el-input v-model="altitude"></el-input>
+        </div>
 
-    </div>
+        <div
+          v-for="(input, index) in heightInputs"
+          :key="index"
+          class="condition"
+        >
+          <p>测风塔高度:</p>
+          <el-input
+            v-model="input.value"
+            placeholder="请输入测风塔高度"
+          ></el-input>
+        </div>
+      </div>
+
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="nuedialog = false" size="small">取 消</el-button>
+        <el-button type="primary" @click="newly" size="small">确 定</el-button>
+      </span>
+    </el-dialog>
+
+    <!-- 风场详情 -->
+    <el-dialog title="详情" :visible.sync="unusualdialog" width="800px">
+    </el-dialog>
+  </div>
 </template>
 
 <script>
 export default {
-    data() {
-        return {
-            // 新增信息
-            windsiteName: "",
-            airdensity: "",
-            superior: "",
-            superiorOptions: [],
-            altitude: "",
-            sheng: "",
-            shengOptions: [],
-            shi: "",
-            shiOptions: [],
-            longitude: "",
-            dimensionality: "",
-            anemometer: "",
-            anemometerOptions: [],
-
-            fileList: [
-                {
-                    name: "food.jpeg",
-                    url: "https://fuss10.elemecdn.com/3/63/4e7f3a15429bfda99bce42a18cdd1jpeg.jpeg?imageMogr2/thumbnail/360x360/format/webp/quality/100",
-                },
-
-            ],
-            formInline: {
-                user: "",
-                region: "",
-                timeQuantum: "",
-            },
-            tableData: [
-                {
-                    id: 1,
-                    name: "王小虎",
-                    transition: "1",
-                },
-                {
-                    id: 3,
-                    name: "王小虎",
-                    abnormal: "1",
-                    transition: "0",
-                    children: [
-                        {
-                            id: 31,
-
-                            name: "王小虎",
-
-                            abnormal: "1",
-                        },
-                    ],
-                },
-            ],
-            nuedialog: false,
-            unusualdialog: false,
-
-
-
-
-            newform: {
-                unit: "",
-                province: "",
-                city: "",
-                descr: "",
-            },
-            title: "",
-            heightInputs: [{ value: '' }],
-        };
-    },
-    methods: {
-        rowStyle() {
-            return "text-align:center";
+  data() {
+    return {
+      // 新增信息
+      windsiteName: "",
+      airdensity: "",
+      superior: "",
+      superiorOptions: [],
+      altitude: "",
+      sheng: "",
+      shengOptions: [],
+      shi: "",
+      shiOptions: [],
+      longitude: "",
+      dimensionality: "",
+      anemometer: "",
+      anemometerOptions: [],
+
+      fileList: [
+        {
+          name: "food.jpeg",
+          url: "https://fuss10.elemecdn.com/3/63/4e7f3a15429bfda99bce42a18cdd1jpeg.jpeg?imageMogr2/thumbnail/360x360/format/webp/quality/100",
         },
-
-        // 查询
-        onSubmit() {
-            console.log("submit!");
+      ],
+      formInline: {
+        user: "",
+        region: "",
+        timeQuantum: "",
+      },
+      tableData: [
+        {
+          id: 1,
+          name: "王小虎",
+          transition: "1",
         },
-        // 重置
-        reset() { },
-
-        // 新增
-        newly() {
-
-            this.heightInputs.forEach((value, index) => {
-                console.log(`测风塔高度 ${index + 1}:`, value);
-            });
-
-            this.nuedialog = false;
-            this.heightInputs = [{ value: '' }];
+        {
+          id: 3,
+          name: "王小虎",
+          abnormal: "1",
+          transition: "0",
+          children: [
+            {
+              id: 31,
+
+              name: "王小虎",
+
+              abnormal: "1",
+            },
+          ],
         },
+      ],
+      nuedialog: false,
+      unusualdialog: false,
+
+      newform: {
+        unit: "",
+        province: "",
+        city: "",
+        descr: "",
+      },
+      title: "",
+      heightInputs: [{ value: "" }],
+    };
+  },
+  methods: {
+    rowStyle() {
+      return "text-align:center";
+    },
 
-        //异常详情
-        particulars(row) {
-            this.unusualdialog = true;
-        },
+    // 查询
+    onSubmit() {
+      console.log("submit!");
+    },
+    // 重置
+    reset() {},
 
+    // 新增
+    newly() {
+      this.heightInputs.forEach((value, index) => {
+        console.log(`测风塔高度 ${index + 1}:`, value);
+      });
 
-        // 编辑
-        compile(row) {
-            this.nuedialog = true;
-            this.title = "编辑";
-        },
+      this.nuedialog = false;
+      this.heightInputs = [{ value: "" }];
+    },
 
+    //异常详情
+    particulars(row) {
+      this.unusualdialog = true;
+    },
 
-        // 启用
-        start(row) { },
-        // 停用
-        stop(row) { },
-        // 删除
-        deleted(row) {
-            this.$confirm("此操作将永久删除该文件, 是否继续?", "提示", {
-                confirmButtonText: "确定",
-                cancelButtonText: "取消",
-                type: "warning",
-            })
-                .then(() => {
-                    this.$message({
-                        type: "success",
-                        message: "删除成功!",
-                    });
-                })
-                .catch(() => {
-                    this.$message({
-                        type: "info",
-                        message: "已取消删除",
-                    });
-                });
-        },
-        // 删除附件
-        deleteRow(row) {
-            this.$confirm("此操作将永久删除该文件, 是否继续?", "提示", {
-                confirmButtonText: "确定",
-                cancelButtonText: "取消",
-                type: "warning",
-            })
-                .then(() => {
-                    this.$message({
-                        type: "success",
-                        message: "删除成功!",
-                    });
-                })
-                .catch(() => {
-                    this.$message({
-                        type: "info",
-                        message: "已取消删除",
-                    });
-                });
-        },
-        addition() {
-            this.heightInputs.push({ value: '' }); // Add a new object with an empty string property
-        },
+    // 编辑
+    compile(row) {
+      this.nuedialog = true;
+      this.title = "编辑";
+    },
 
-        // Method to remove the last input for "测风塔高度"
-        subtraction() {
-            if (this.heightInputs.length > 1) { // Ensure at least one input remains
-                this.heightInputs.pop();
-            }
-        },
+    // 启用
+    start(row) {},
+    // 停用
+    stop(row) {},
+    // 删除
+    deleted(row) {
+      this.$confirm("此操作将永久删除该文件, 是否继续?", "提示", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning",
+      })
+        .then(() => {
+          this.$message({
+            type: "success",
+            message: "删除成功!",
+          });
+        })
+        .catch(() => {
+          this.$message({
+            type: "info",
+            message: "已取消删除",
+          });
+        });
+    },
+    // 删除附件
+    deleteRow(row) {
+      this.$confirm("此操作将永久删除该文件, 是否继续?", "提示", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning",
+      })
+        .then(() => {
+          this.$message({
+            type: "success",
+            message: "删除成功!",
+          });
+        })
+        .catch(() => {
+          this.$message({
+            type: "info",
+            message: "已取消删除",
+          });
+        });
+    },
+    addition() {
+      this.heightInputs.push({ value: "" }); // Add a new object with an empty string property
+    },
 
-        // 新增
-        newnuedialog() {
-            this.nuedialog = true;
-            this.title = "新增";
-        },
+    // Method to remove the last input for "测风塔高度"
+    subtraction() {
+      if (this.heightInputs.length > 1) {
+        // Ensure at least one input remains
+        this.heightInputs.pop();
+      }
     },
+
+    // 新增
+    newnuedialog() {
+      this.nuedialog = true;
+      this.title = "新增";
+    },
+  },
 };
 </script>
 
 <style lang="scss" scoped>
 .general {
-    display: flex;
-    flex-wrap: wrap;
+  display: flex;
+  flex-wrap: wrap;
 
-    .condition {
-        width: 50%;
-        display: flex;
+  .condition {
+    width: 50%;
+    display: flex;
 
-        p {
-            width: 100px;
-            text-align: right;
-            line-height: 40px;
-        }
+    p {
+      width: 100px;
+      text-align: right;
+      line-height: 40px;
+    }
 
-        span {
-            line-height: 40px;
+    span {
+      line-height: 40px;
 
-            padding-left: 20px;
-        }
+      padding-left: 20px;
+    }
 
-        .el-select {
-            width: 100%;
-            margin-bottom: 20px;
-        }
+    .el-select {
+      width: 100%;
+      margin-bottom: 20px;
+    }
 
-        .el-input {
-            margin-bottom: 20px;
-        }
+    .el-input {
+      margin-bottom: 20px;
     }
+  }
 }
 
-
-
 .attachment {
-    display: flex;
-    padding-top: 10px;
+  display: flex;
+  padding-top: 10px;
 
-    p {
-        margin-right: 20px;
-        color: #409eff;
-    }
+  p {
+    margin-right: 20px;
+    color: #409eff;
+  }
 }
 
 .addition {
-    display: flex;
-    justify-content: flex-end;
-    margin-bottom: 10px;
+  display: flex;
+  justify-content: flex-end;
+  margin-bottom: 10px;
 }
-</style>
+</style>

+ 295 - 67
src/views/system/menuMag/index.vue

@@ -1,93 +1,321 @@
-<!--
- * @Author: your name
- * @Date: 2024-05-17 15:59:21
- * @LastEditTime: 2024-05-19 22:59:39
- * @LastEditors: bogon
- * @Description: In User Settings Edit
- * @FilePath: /dasheng/performance-test/src/views/system/menuMag/index.vue
--->
 <template>
-  <div>
-    <el-table :data="tableData" style="width: 100%">
-      <el-table-column label="日期" width="180">
-        <template slot-scope="scope">
-          <i class="el-icon-time"></i>
-          <span style="margin-left: 10px">{{ scope.row.date }}</span>
-        </template>
-      </el-table-column>
-      <el-table-column label="姓名" width="180">
-        <template slot-scope="scope">
-          <el-popover trigger="hover" placement="top">
-            <p>姓名: {{ scope.row.name }}</p>
-            <p>住址: {{ scope.row.address }}</p>
-            <div slot="reference" class="name-wrapper">
-              <el-tag size="medium">{{ scope.row.name }}</el-tag>
-            </div>
-          </el-popover>
-        </template>
-      </el-table-column>
-      <el-table-column label="操作">
-        <template slot-scope="scope">
-          <el-button size="mini" @click="handleEdit(scope.$index, scope.row)"
-            >编辑</el-button
+  <div class="global-variable">
+    <div class="condition">
+      <el-form :inline="true" :model="formInline" class="demo-form-inline">
+        <el-form-item label="单位名称:">
+          <el-input
+            v-model="formInline.user"
+            placeholder="请输入单位名称"
+            size="small"
+          ></el-input>
+        </el-form-item>
+        <el-form-item label="状态:">
+          <el-select
+            v-model="formInline.region"
+            placeholder="选择状态"
+            size="small "
           >
-          <el-button
-            size="mini"
-            type="danger"
-            @click="handleDelete(scope.$index, scope.row)"
-            >删除</el-button
+            <el-option label="启用" value="1"></el-option>
+            <el-option label="停用" value="2"></el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item>
+          <el-button type="primary" @click="onSubmit" size="small"
+            >查询</el-button
           >
-        </template>
-      </el-table-column>
-    </el-table>
+          <el-button @click="reset" size="small">重置</el-button>
+        </el-form-item>
+      </el-form>
+    </div>
+    <div class="list-page">
+      <div class="newly">
+        <el-button type="primary" @click="newnuedialog" size="small"
+          >新增</el-button
+        >
+      </div>
+      <el-table
+        class="center-align-table"
+        :data="tableData"
+        border
+        :cell-style="rowStyle"
+        stripe
+        row-key="id"
+        default-expand-all
+        :tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
+      >
+        <el-table-column fixed prop="name" align="center" label="单位名称">
+        </el-table-column>
+        <el-table-column prop="" align="center" label="类型"> </el-table-column>
+
+        <el-table-column prop="abnormal" label="排序" width="80">
+          <template slot-scope="scope">
+            <el-button
+              v-if="scope.row.abnormal == 1"
+              @click="particulars(scope.row)"
+              type="text"
+              size="small"
+              >10</el-button
+            >
+            <span v-else>/</span>
+          </template>
+        </el-table-column>
+
+        <el-table-column prop="" align="center" label="权限标识" width="100">
+        </el-table-column>
+        <el-table-column prop="" align="center" label="路径"> </el-table-column>
+        <el-table-column prop="" align="center" label="状态"> </el-table-column>
+        <el-table-column
+          prop="transition"
+          align="center"
+          fixed="right"
+          label="操作"
+          width="200"
+        >
+          <template slot-scope="scope">
+            <el-button @click="compile(scope.row)" type="text" size="small"
+              >编辑</el-button
+            >
+            <el-button @click="newcomer(scope.row)" type="text" size="small"
+              >新增</el-button
+            >
+            <el-button
+              v-if="scope.row.transition == 1"
+              @click="start(scope.row)"
+              type="text"
+              size="small"
+              >启用</el-button
+            >
+            <el-button
+              v-else
+              style="color: #666"
+              @click="stop(scope.row)"
+              type="text"
+              size="small"
+              >停用</el-button
+            >
+            <el-button
+              style="color: #f00"
+              @click="deleted(scope.row)"
+              type="text"
+              size="small"
+              >删除</el-button
+            >
+          </template>
+        </el-table-column>
+      </el-table>
+      <div class="pagination-container">
+        <el-pagination
+          :page-size="10"
+          :pager-count="11"
+          layout="total, prev, pager, next"
+          :total="35"
+        >
+        </el-pagination>
+      </div>
+    </div>
+
+    <!-- 弹出层 -->
+    <!-- 新增 -->
+    <el-dialog :title="title" :visible.sync="nuedialog" width="380px">
+      <el-form ref="newform" :rules="rules" :model="newform" label-width="90px">
+        <el-form-item label="单位名称:" prop="unit">
+          <el-input v-model="newform.unit" size="small"></el-input>
+        </el-form-item>
+        <el-form-item label="所属省:" prop="province">
+          <el-select
+            v-model="newform.province"
+            placeholder="请选择"
+            size="small"
+          >
+            <el-option label="区域一" value="shanghai"></el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item label="所属市:" prop="city">
+          <el-select v-model="newform.city" placeholder="请选择" size="small">
+            <el-option label="区域一" value="shanghai"></el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item label="备注:">
+          <el-input
+            v-model="newform.name"
+            size="small"
+            type="textarea"
+          ></el-input>
+        </el-form-item>
+      </el-form>
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="nuedialog = false" size="small">取 消</el-button>
+        <el-button type="primary" @click="newly" size="small">确 定</el-button>
+      </span>
+    </el-dialog>
+
+    <!-- 风场数量 -->
+    <el-dialog title="风场数量" :visible.sync="unusualdialog" width="1000px">
+      <el-table
+        class="center-align-table"
+        :data="tableData"
+        border
+        :cell-style="rowStyle"
+        stripe
+      >
+        <!-- Table Columns -->
+        <el-table-column fixed prop="name" align="center" label="风场名称">
+        </el-table-column>
+        <el-table-column prop="" align="center" label="所在省">
+        </el-table-column>
+        <el-table-column prop="" align="center" label="所在市">
+        </el-table-column>
+        <el-table-column prop="" align="center" label="海拔高度" width="80">
+        </el-table-column>
+        <el-table-column prop="" align="center" label="经度" width="80">
+        </el-table-column>
+        <el-table-column prop="" align="center" label="纬度" width="80">
+        </el-table-column>
+        <el-table-column prop="" align="center" label="额定容量">
+        </el-table-column>
+      </el-table>
+
+      <div class="pagination-container">
+        <el-pagination
+          :page-size="10"
+          :pager-count="11"
+          layout="total, prev, pager, next"
+          :total="35"
+        >
+        </el-pagination>
+      </div>
+    </el-dialog>
   </div>
 </template>
+
 <script>
 export default {
   data() {
     return {
+      rules: {
+        unit: [{ required: true, message: "请填写单位名称", trigger: "blur" }],
+        province: [{ required: true, message: "请选择省", trigger: "change" }],
+        city: [{ required: true, message: "请选择省", trigger: "change" }],
+      },
+      formInline: {
+        user: "",
+        region: "",
+      },
       tableData: [
         {
-          date: "2016-05-02",
-          name: "王小虎",
-          address: "上海市普陀区金沙江路 1518 弄",
-        },
-        {
-          date: "2016-05-04",
-          name: "王小虎",
-          address: "上海市普陀区金沙江路 1517 弄",
-        },
-        {
-          date: "2016-05-01",
+          id: 1,
           name: "王小虎",
-          address: "上海市普陀区金沙江路 1519 弄",
+          transition: "1",
         },
         {
-          date: "2016-05-03",
+          id: 3,
           name: "王小虎",
-          address: "上海市普陀区金沙江路 1516 弄",
+          abnormal: "1",
+          transition: "0",
+          children: [
+            {
+              id: 31,
+
+              name: "王小虎",
+
+              abnormal: "1",
+            },
+          ],
         },
       ],
+      nuedialog: false,
+      unusualdialog: false,
+      newform: {
+        unit: "",
+        province: "",
+        city: "",
+        descr: "",
+      },
+      title: "新增",
+      warningShown: false,
     };
   },
   methods: {
-    handleEdit(index, row) {
-      console.log(index, row);
+    rowStyle() {
+      return "text-align:center";
+    },
+
+    // 查询
+    onSubmit() {
+      console.log("submit!");
+    },
+    // 重置
+    reset() {
+      this.formInline.user = "";
+      this.formInline.region = "";
+    },
+    // 新增
+    newly() {
+      this.nuedialog = false;
+    },
+
+    //异常详情
+    particulars(row) {
+      this.unusualdialog = true;
+    },
+    // 编辑
+    compile(row) {
+      this.nuedialog = true;
+      this.title = "编辑";
+    },
+    // 新增子级
+    newcomer(row) {
+      this.nuedialog = true;
+      this.title = "新增";
+    },
+    // 启用
+    start(row) {},
+    // 停用
+    stop(row) {},
+    // 删除
+    deleted(row) {
+      if (row.transition === "0") {
+        if (!this.warningShown) {
+          this.$message({
+            type: "error",
+            message: "该项处于停用状态,无法删除!",
+          });
+          this.warningShown = true; // 设置警告消息已经显示过了的标志位为true
+        }
+        return;
+      }
+
+      this.$confirm("此操作将永久删除该文件,是否继续?", "提示", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning",
+      })
+        .then(() => {
+          // 执行删除操作
+          this.$message({
+            type: "success",
+            message: "删除成功!",
+          });
+        })
+        .catch(() => {
+          // 取消删除
+          this.$message({
+            type: "info",
+            message: "已取消删除",
+          });
+        });
     },
-    handleDelete(index, row) {
-      console.log(index, row);
+
+    newnuedialog() {
+      this.nuedialog = true;
+      this.title = "新增";
     },
   },
 };
 </script>
-<!-- <style lang="scss">
-// .box {
-//   width: 100px;
-//   height: 100px;
-//   background-color: var(--color);
-// }
-.el-table th.el-table__cell {
-  background-color: var(--color);
-  color: aliceblue;
+
+<style lang="scss" scoped>
+.el-select {
+  width: 250px;
 }
-</style> -->
+</style>

+ 569 - 3
src/views/system/userMag/index.vue

@@ -1,5 +1,571 @@
 <template>
-  <div>用户管理</div>
+  <div class="global-variable">
+    <div class="condition">
+      <el-form
+        :inline="true"
+        ref="ruleForm"
+        :model="formInline"
+        class="demo-form-inline"
+        :rules="rules"
+      >
+        <el-form-item label="用户名称:" prop="userName">
+          <el-input
+            v-model="formInline.userName"
+            placeholder="请输入用户名称"
+            size="small"
+          ></el-input>
+        </el-form-item>
+        <el-form-item label="角色名称:" prop="roleId">
+          <el-select
+            v-model="formInline.roleId"
+            placeholder="请选择角色"
+            size="small "
+          >
+            <el-option
+              :label="item.roleDescription"
+              v-for="item in roleList"
+              :value="item.id + ''"
+            ></el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item>
+          <el-button type="primary" @click="onSubmit" size="small"
+            >查询</el-button
+          >
+          <el-button @click="reset('ruleForm')" size="small">重置</el-button>
+        </el-form-item>
+      </el-form>
+    </div>
+    <div class="list-page">
+      <div class="newly">
+        <el-button type="primary" @click="newnuedialog" size="small"
+          >新增</el-button
+        >
+      </div>
+      <el-table
+        v-loading="loading"
+        class="center-align-table"
+        :data="tableData"
+        border
+        :cell-style="rowStyle"
+      >
+        <el-table-column
+          align="center"
+          fixed
+          prop="userId"
+          label="员工ID"
+          width="100"
+        >
+        </el-table-column>
+
+        <el-table-column align="center" label="员工名称" prop="userName">
+        </el-table-column>
+
+        <el-table-column prop="userName" align="center" label="登录账号">
+        </el-table-column>
+        <el-table-column align="center" prop="userPhone" label="手机号">
+        </el-table-column>
+
+        <el-table-column prop="roleName" align="center" label="角色">
+        </el-table-column>
+        <el-table-column prop="state" align="center" label="状态" width="100">
+          <template slot-scope="scope">
+            <span>
+              {{
+                scope.row.state == 0
+                  ? "未启用"
+                  : scope.row.state == 1
+                  ? "启用"
+                  : "禁用"
+              }}</span
+            >
+          </template>
+        </el-table-column>
+
+        <el-table-column
+          prop="transition"
+          align="center"
+          fixed="right"
+          label="操作"
+          width="200"
+        >
+          <template slot-scope="scope">
+            <el-button @click="compile(scope.row)" type="text" size="small"
+              >编辑</el-button
+            >
+            <el-button
+              v-if="scope.row.state == 0 || scope.row.state == 2"
+              @click="setState(1, scope.row.userId)"
+              type="text"
+              size="small"
+              >启用</el-button
+            >
+            <el-button
+              v-else
+              style="color: #666"
+              @click="setState(2, scope.row.userId)"
+              type="text"
+              size="small"
+              >停用</el-button
+            >
+            <el-button
+              style="color: #f90"
+              @click="editPwd(scope.row)"
+              type="text"
+              size="small"
+              >修改密码</el-button
+            >
+            <el-button
+              style="color: #f00"
+              @click="deleted(scope.row)"
+              type="text"
+              size="small"
+              >删除</el-button
+            >
+          </template>
+        </el-table-column>
+      </el-table>
+      <div class="pagination-container">
+        <el-pagination
+          @current-change="handleCurrentChange"
+          :current-page.sync="formInline.pageNum"
+          layout="total, prev, pager, next"
+          :page-size="formInline.pageSize"
+          :total="formInline.totalSize"
+        >
+        </el-pagination>
+      </div>
+    </div>
+
+    <!-- 弹出层 -->
+    <!-- 新增 /编辑-->
+    <el-dialog :title="title" :visible.sync="nuedialog" width="500px">
+      <el-form
+        :model="ruleForm"
+        :rules="addUserRules"
+        ref="addUserForm"
+        label-width="100px"
+        class="demo-ruleForm"
+      >
+        <!-- <el-form-item label="员工名称" prop="userName">
+          <el-input v-model="ruleForm.userName"></el-input>
+        </el-form-item> -->
+        <el-form-item label="电话号码" prop="phone">
+          <el-input v-model="ruleForm.phone"></el-input>
+        </el-form-item>
+        <el-form-item label="账号名称" prop="userName">
+          <el-input v-model="ruleForm.userName" autocomplete="off"></el-input>
+        </el-form-item>
+        <el-form-item label="密码" prop="pwd" v-if="title === '新增'">
+          <el-input
+            v-model="ruleForm.pwd"
+            autocomplete="new-password"
+            show-password
+          ></el-input>
+        </el-form-item>
+        <el-form-item label="角色名称:" prop="roleId">
+          <el-select
+            v-model="ruleForm.roleId"
+            placeholder="请选择角色"
+            size="small "
+          >
+            <el-option
+              :label="item.roleDescription"
+              v-for="item in roleList"
+              :value="item.id + ''"
+            ></el-option>
+          </el-select>
+        </el-form-item>
+      </el-form>
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="cancel('addUserForm')" size="small">取 消</el-button>
+        <el-button
+          type="primary"
+          @click="submitForm('addUserForm')"
+          size="small"
+          >确 定</el-button
+        >
+      </span>
+    </el-dialog>
+    <!-- 风场详情 -->
+    <el-dialog title="修改密码" :visible.sync="unusualdialog" width="500px">
+      <el-form
+        :model="editUserPassword"
+        ref="editUserPassword"
+        label-width="100px"
+      >
+        <el-form-item
+          label="旧密码"
+          prop="oldPWD"
+          :rules="[{ required: true, message: '旧密码不能为空' }]"
+        >
+          <el-input
+            v-model.number="editUserPassword.oldPWD"
+            autocomplete="off"
+            show-password
+          ></el-input>
+        </el-form-item>
+        <el-form-item
+          label="新密码"
+          prop="newPWD"
+          :rules="[{ required: true, message: '新密码不能为空' }]"
+        >
+          <el-input
+            v-model.number="editUserPassword.newPWD"
+            autocomplete="off"
+            show-password
+          ></el-input>
+        </el-form-item>
+      </el-form>
+      <span slot="footer" class="dialog-footer">
+        <el-button
+          @click="
+            () => {
+              this.$refs['editUserPassword'].resetFields();
+              this.unusualdialog = false;
+            }
+          "
+          size="small"
+          >取 消</el-button
+        >
+        <el-button
+          type="primary"
+          @click="editUserPwd('editUserPassword')"
+          size="small"
+          >确 定</el-button
+        >
+      </span>
+    </el-dialog>
+  </div>
 </template>
-<script></script>
-<style lang="scss"></style>
+
+<script>
+import {
+  getUserTableList,
+  getRoleTableList,
+  enableUser,
+  disableUser,
+  getUserInfoByUserId,
+  addUser,
+  editUser,
+  deleteUserInfo,
+  updatePWD,
+} from "@/api/system.js";
+export default {
+  data() {
+    const validatePhone = (rule, value, callback) => {
+      const phoneRegex = /^[1][3-9][0-9]{9}$/;
+      if (!value) {
+        return callback(new Error("手机号不能为空"));
+      }
+      if (!phoneRegex.test(value)) {
+        return callback(new Error("请输入正确的手机号"));
+      }
+      callback();
+    };
+    return {
+      loading: false, //数据加载中
+      rules: {
+        roleId: { trigger: "change" },
+        userName: { trigger: "blur" },
+      },
+      roleList: [],
+      formInline: {
+        userName: undefined,
+        roleId: undefined,
+        pageNum: 1,
+        pageSize: 10,
+        // sort: "desc",
+        totalSize: 0,
+      },
+      tableData: [],
+      // 新增编辑表单
+      ruleForm: {
+        phone: null,
+        pwd: null,
+        roleId: null,
+        userName: null,
+      },
+      addUserRules: {
+        phone: [
+          { required: true, message: "请输入手机号", trigger: "blur" },
+          { validator: validatePhone, trigger: "blur" },
+        ],
+        pwd: { required: true, message: "请输入密码", trigger: "blur" },
+        roleId: { required: true, message: "请选择角色", trigger: "change" },
+        userName: { required: true, message: "请输入账号", trigger: "blur" },
+      },
+      //修改密码
+      editUserPassword: {
+        oldPWD: "",
+        newPWD: "",
+        userId: "",
+      },
+      nuedialog: false,
+      unusualdialog: false,
+      title: "",
+    };
+  },
+  created() {
+    this.getTableList();
+    this.getRoleList();
+  },
+
+  methods: {
+    //修改密码
+    editUserPwd(formName) {
+      this.$refs[formName].validate((valid) => {
+        if (valid) {
+          updatePWD({ ...this.editUserPassword })
+            .then((res) => {
+              this.$message({
+                message: "密码修改成功",
+                type: "success",
+              });
+              this.getTableList();
+            })
+            .catch(() => {});
+        } else {
+          console.log("error submit!!");
+          return false;
+        }
+      });
+    },
+    //分页数据切换
+    handleCurrentChange(val) {
+      console.log(`当前页: ${val}`);
+      this.formInline.pageNum = val;
+      this.getTableList();
+    },
+    //修改状态
+    setState(state, userId) {
+      switch (state) {
+        case 1:
+          //启用接口
+          enableUser({ userId })
+            .then((res) => {
+              this.$message({
+                message: res.msg,
+                type: "success",
+              });
+              this.getTableList();
+            })
+            .catch((error) => {});
+          break;
+        case 2:
+          //禁用接口
+          disableUser({ userId })
+            .then((res) => {
+              this.$message({
+                message: res.msg,
+                type: "success",
+              });
+              this.getTableList();
+            })
+            .catch((error) => {
+              console.log(error, "errrr");
+            });
+          break;
+        default:
+          return;
+      }
+    },
+    async getTableList() {
+      this.loading = true;
+      const result = await getUserTableList({
+        ...this.formInline,
+        totalSize: undefined,
+      });
+      console.log(result, "获取用户列表的结果");
+      this.tableData = result.data.list;
+      this.formInline.totalSize = result.data.totalSize;
+      this.loading = false;
+    },
+    async getRoleList() {
+      const result = await getRoleTableList({ pageNum: 1, pageSize: 100000 });
+      this.roleList = result.data.list;
+      console.log(this.roleList, " this.roleList ");
+    },
+    rowStyle() {
+      return "text-align:center";
+    },
+    // 查询
+    onSubmit() {
+      this.getTableList();
+    },
+    // 重置
+    reset(formName) {
+      this.$refs[formName].resetFields();
+      this.getTableList();
+    },
+
+    // 新增,编辑确定
+    submitForm(formName) {
+      this.$refs[formName].validate((valid) => {
+        if (valid) {
+          switch (this.title) {
+            case "新增":
+              addUser({ ...this.ruleForm, userId: undefined })
+                .then((res) => {
+                  console.log(res, "新增成功");
+                  this.$message({
+                    type: "success",
+                    message: res.msg,
+                  });
+                  this.getTableList();
+                  this.nuedialog = false;
+                })
+                .catch(() => {});
+
+              break;
+            case "编辑":
+              editUser({ ...this.ruleForm })
+                .then((res) => {
+                  console.log(res, "编辑成功");
+                  this.$message({
+                    type: "success",
+                    message: res.msg,
+                  });
+                  this.getTableList();
+                  this.nuedialog = false;
+                })
+                .catch(() => {});
+
+              break;
+          }
+          // this.nuedialog = false;
+        } else {
+          // console.log("error submit!!");
+          return false;
+        }
+      });
+    },
+    //点击取消
+    cancel(formName) {
+      console.log("取消");
+      this.$refs[formName] && this.$refs[formName].resetFields();
+      this.ruleForm = {
+        phone: null,
+        pwd: null,
+        roleId: null,
+        userName: null,
+        userId: null,
+      };
+
+      console.log(this.ruleForm, "biaji ");
+      this.nuedialog = false;
+    },
+    //异常详情
+    particulars(row) {
+      this.unusualdialog = true;
+    },
+    // 编辑 回显数据
+    async compile(row) {
+      try {
+        const result = await getUserInfoByUserId({ userId: row.userId });
+        const userInfo = result.data;
+
+        // 直接替换整个对象,以确保 Vue 的响应式系统能够检测到变化
+        this.ruleForm = {
+          phone: userInfo.userPhone,
+          pwd: "", // 如果需要重置密码字段
+          roleId: userInfo.roleId.toString(),
+          userName: userInfo.userName,
+          userId: userInfo.userId, // 如果需要用户ID
+        };
+        this.nuedialog = true;
+        this.title = "编辑";
+      } catch (error) {
+        console.error("Error fetching user info:", error);
+        this.$message.error("获取用户信息失败");
+      }
+    },
+    // 删除
+    deleted(row) {
+      this.$confirm("此操作将永久删除该用户, 是否继续?", "提示", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning",
+      })
+        .then(() => {
+          deleteUserInfo({ userId: row.userId })
+            .then((res) => {
+              this.$message({
+                type: "success",
+                message: "删除成功!",
+              });
+              this.getTableList();
+            })
+            .catch(() => {});
+        })
+        .catch(() => {
+          this.$message({
+            type: "info",
+            message: "已取消删除",
+          });
+        });
+    },
+    editPwd(row) {
+      this.editUserPassword.userId = row.userId;
+      this.unusualdialog = true;
+    },
+    // 新增
+    newnuedialog() {
+      this.cancel("addUserForm");
+      this.ruleForm.pwd = "";
+      this.ruleForm.userName = "";
+      this.nuedialog = true;
+      this.title = "新增";
+    },
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+.general {
+  display: flex;
+  flex-wrap: wrap;
+
+  .condition {
+    width: 50%;
+    display: flex;
+
+    p {
+      width: 100px;
+      text-align: right;
+      line-height: 40px;
+    }
+
+    span {
+      line-height: 40px;
+
+      padding-left: 20px;
+    }
+
+    .el-select {
+      width: 100%;
+      margin-bottom: 20px;
+    }
+
+    .el-input {
+      margin-bottom: 20px;
+    }
+  }
+}
+
+.attachment {
+  display: flex;
+  padding-top: 10px;
+
+  p {
+    margin-right: 20px;
+    color: #409eff;
+  }
+}
+
+.addition {
+  display: flex;
+  justify-content: flex-end;
+  margin-bottom: 10px;
+}
+</style>