Selaa lähdekoodia

Merge branch 'dev-frontend' of http://gitlab.pubdata.cn/liangyibo/CameraMachine into dev-frontend

kongwenhao 8 kuukautta sitten
vanhempi
commit
c091e1850a
2 muutettua tiedostoa jossa 382 lisäystä ja 2 poistoa
  1. 14 1
      frontend/src/utils/http.ts
  2. 368 1
      frontend/src/views/Setting/index.vue

+ 14 - 1
frontend/src/utils/http.ts

@@ -1,6 +1,7 @@
 import axios, { AxiosRequestConfig, AxiosResponse, AxiosError } from 'axios';
 import { ElMessage as Message, ElMessageBox as MessageBox, ElLoading as Loading } from 'element-plus';
 import  tokenInfo  from '@/stores/modules/token';
+import useUserInfo from "@/stores/modules/user";
 
 // 加载动画的并发管理
 const activeRequests = new Set<string>();
@@ -62,6 +63,7 @@ service.interceptors.response.use(
     (response: AxiosResponse) => {
         // 对响应数据做点什么
         const res = response.data;
+        const useUserInfoStore = useUserInfo();
 
         // 如果配置中启用了加载动画,则关闭加载动画
         if (response.config?.loading && response.config.requestId) {
@@ -71,6 +73,14 @@ service.interceptors.response.use(
         // 如果自定义状态码不为0,则判断为错误
         if (res.code !== 0) {
             switch (res.code) {
+                case 401:
+                    Message({
+                        message: '登录状态已失效,请重新登录',
+                        type: 'error',
+                        duration: 3 * 1000,
+                    });
+                    useUserInfoStore.updateLoginShow(true)
+                    break;
                 default:
                     if (response.config.showErrorMessage) {
                         if (res.message?.length > 30 || res.code === 400011) {
@@ -103,11 +113,14 @@ service.interceptors.response.use(
             loadingClose(error.config.requestId as string);
         }
 
+        const useUserInfoStore = useUserInfo();
         try {
             if (error.response) {
                 switch (error.response.status) {
                     case 400: errMessage = '请求错误(400)'; break;
-                    case 401: errMessage = '登录失效'; break;
+                    case 401: errMessage = '登录状态已失效,请重新登录';
+                    useUserInfoStore.updateLoginShow(true)
+                     break;
                     case 403: errMessage = '拒绝访问(403)'; break;
                     case 404: errMessage = '请求出错(404)'; break;
                     case 408: errMessage = '请求超时(408)'; break;

+ 368 - 1
frontend/src/views/Setting/index.vue

@@ -21,6 +21,11 @@
         <img src="@/assets/images/setting/icon4a.png" class="nav-icon" v-else/>
         <span>遥控器设置</span>
       </div>
+      <div class="nav-item" :class="{'active': activeIndex === 4}" @click="activeIndex = 4">
+        <img src="@/assets/images/setting/icon4.png" class="nav-icon" v-if="activeIndex !== 4"/>
+        <img src="@/assets/images/setting/icon4a.png" class="nav-icon" v-else/>
+        <span>左右脚程序设置</span>
+      </div>
     </nav>
 
     <div class="form-container">
@@ -180,12 +185,125 @@
                     </div>
                 </div>
           </div>
+          <div class="selectBox" style="padding-top: 0px;padding-left: 0;" v-if="activeIndex === 4">
+            <el-tabs v-model="activeTab" type="card">
+              <el-tab-pane label="执行左脚程序" name="left">
+              </el-tab-pane>
+              <el-tab-pane label="执行右脚程序" name="right"></el-tab-pane>
+            </el-tabs>
+            <div class="form-table">
+              <div class="btnBox">
+                <div class="primary-btn" @click="addRow">新增一行</div>
+                <div class="normal-btn">重新初始化</div>
+              </div>
+              <el-table height="200px" :data="activeTab === 'left' ? lefttableData : righttableData" style="width: 100%" border>
+                <el-table-column prop="id" label="ID" />
+                <el-table-column prop="name" label="步骤" />
+                <el-table-column prop="value" label="是否拍照" width="200px">
+                  <template #default="scope">
+                    <el-radio-group v-model="scope.row.value">
+                      <el-radio :label="1">拍照</el-radio>
+                      <el-radio :label="0">不拍照</el-radio>
+                    </el-radio-group>
+                  </template>
+                </el-table-column>
+                <el-table-column prop="value" label="排序" >
+                  <template #default="{row, $index}">
+                    <a v-if="$index !== 0" class="cursor-pointer" @click="upRow(row)">上移</a>
+                    <a class="mar-left-10 cursor-pointer" v-if="$index !== activeTab === 'left' ? lefttableData.length - 1 : righttableData.length - 1" @click="downRow(row)">下移</a>
+                  </template>
+                </el-table-column>
+                <el-table-column prop="value" label="操作" >
+                  <template #default="{row, $index}">
+                    <a class="mar-right-10 cursor-pointer" @click="editRow(row, $index)">编辑</a>
+                    <a class="cursor-pointer" @click="deleteRow(row, $index)">删除</a>
+                  </template>
+                </el-table-column>
+              </el-table>
+            </div>
+          </div>
     </div>
       <div class="text-center mt-8">
         <button class="bg-gradient-to-r from-primary" @click="saveSetting">
           保存
         </button>
       </div>
+      <el-dialog custom-class="editDialog" v-model="dialogVisible" :title="editTitle" width="620px">
+        <div class="config-type">配置类型:执行{{ activeTab === 'left' ? '左脚' : '右脚' }}程序 <el-checkbox v-model="editRowData.isDefault">开启运动调试</el-checkbox></div>
+        <el-form class="editForm" :model="editRowData" label-width="100px">
+          <el-form-item label="动作名称">
+            <el-input v-model="editRowData.name" style="width: 170px;"/>
+          </el-form-item>
+          <el-form-item label="是否拍照">
+            <el-radio-group v-model="editRowData.value">
+              <el-radio :label="1">拍照</el-radio>
+              <el-radio :label="0">不拍照</el-radio>
+            </el-radio-group>
+          </el-form-item>
+          <el-form-item label="相机高度(mm)">
+            <el-input v-model="editRowData.cameraHeight" style="width: 170px;" type="number">
+            </el-input>
+          </el-form-item>
+          <el-form-item label="相机倾角">
+            <el-input v-model="editRowData.cameraAngle" style="width: 170px;" type="number">
+            </el-input>
+          </el-form-item>
+          <el-form-item label="转盘前后位置">
+            <el-input v-model="editRowData.position" style="width: 170px;" type="number">
+            </el-input>
+          </el-form-item>
+          <el-form-item label="转盘角度">
+            <el-input v-model="editRowData.angle" style="width: 170px;" type="number">
+            </el-input>
+          </el-form-item>
+          <el-form-item label="鞋子翻转">
+            <div class="flex-row">
+            <el-radio-group v-model="editRowData.shoesFlip">
+              <el-radio :label="1">翻转</el-radio>
+              <el-radio :label="0">不翻转</el-radio>
+              </el-radio-group>
+              <a class="cursor-pointer" @click="testShoesFlip">测试翻转</a>
+            </div>
+          </el-form-item>
+          <el-form-item label="LED灯光开光">
+            <el-radio-group v-model="editRowData.ledLight">
+              <el-radio :label="0">关闭</el-radio>
+              <el-radio :label="1">开启</el-radio>
+            </el-radio-group>
+          </el-form-item>
+          <el-form-item label="对焦次数">
+            <el-input v-model="editRowData.focusTimes" style="width: 170px;" type="number">
+            </el-input>
+          </el-form-item>
+          <el-form-item label="拍照前延时(秒)">
+            <el-input v-model="editRowData.photoDelay" style="width: 170px;" type="number">
+            </el-input>
+          </el-form-item>
+          <el-form-item label="拍照后延时(秒)">
+            <el-input v-model="editRowData.photoAfterDelay" style="width: 170px;" type="number">
+            </el-input>
+          </el-form-item>
+          <el-form-item label="是否等待">
+            <el-radio-group v-model="editRowData.wait">
+              <el-radio :label="0">否</el-radio>
+              <el-radio :label="1">是</el-radio>
+            </el-radio-group>
+          </el-form-item>
+          <el-form-item label="待用户确认照片">
+            <el-radio-group v-model="editRowData.confirmPhoto">
+              <el-radio :label="0">否</el-radio>
+              <el-radio :label="1">是</el-radio>
+            </el-radio-group>
+          </el-form-item>
+        </el-form>
+        <template #footer>
+          <div class="btn-row">
+            <div class="normal-btn" @click="dialogVisible = false">后退</div>
+            <div class="primary-btn" @click="testShoesFlip">拍照测试</div>
+            <div class="primary-btn" @click="saveRow">保存并后退</div>
+          </div>
+        </template>
+      </el-dialog>
   </div>
 </template>
 
@@ -299,7 +417,23 @@ const downList = ref([
   { label: '下移', value: '2' },
   { label: '左右移', value: '3' },
 ]);
-
+const lefttableData = ref([
+  { id: 1, name: '步骤1', value: 1, order: 1, operation: 1, confirmPhoto: 0, wait: 0, photoDelay: 0, photoAfterDelay: 0, focusTimes: 0, ledLight: 0, shoesFlip: 0, position: 0, angle: 0, cameraHeight: 0, cameraAngle: 0, isDefault: false },
+  { id: 2, name: '步骤2', value: 1, order: 2, operation: 1, confirmPhoto: 0, wait: 0, photoDelay: 0, photoAfterDelay: 0, focusTimes: 0, ledLight: 0, shoesFlip: 0, position: 0, angle: 0, cameraHeight: 0, cameraAngle: 0, isDefault: false  },
+  { id: 3, name: '步骤3', value: 1, order: 3, operation: 1, confirmPhoto: 0, wait: 0, photoDelay: 0, photoAfterDelay: 0, focusTimes: 0, ledLight: 0, shoesFlip: 0, position: 0, angle: 0, cameraHeight: 0, cameraAngle: 0, isDefault: false },
+  { id: 4, name: '步骤4', value: 1, order: 4, operation: 1, confirmPhoto: 0, wait: 0, photoDelay: 0, photoAfterDelay: 0, focusTimes: 0, ledLight: 0, shoesFlip: 0, position: 0, angle: 0, cameraHeight: 0, cameraAngle: 0, isDefault: false },
+]);
+const righttableData = ref([
+  { id: 1, name: '步骤1', value: 1, order: 1, operation: 1, confirmPhoto: 0, wait: 0, photoDelay: 0, photoAfterDelay: 0, focusTimes: 0, ledLight: 0, shoesFlip: 0, position: 0, angle: 0, cameraHeight: 0, cameraAngle: 0, isDefault: false },
+  { id: 2, name: '步骤2', value: 1, order: 2, operation: 1, confirmPhoto: 0, wait: 0, photoDelay: 0, photoAfterDelay: 0, focusTimes: 0, ledLight: 0, shoesFlip: 0, position: 0, angle: 0, cameraHeight: 0, cameraAngle: 0, isDefault: false },
+  { id: 3, name: '步骤3', value: 1, order: 3, operation: 1, confirmPhoto: 0, wait: 0, photoDelay: 0, photoAfterDelay: 0, focusTimes: 0, ledLight: 0, shoesFlip: 0, position: 0, angle: 0, cameraHeight: 0, cameraAngle: 0, isDefault: false },
+  { id: 4, name: '步骤4', value: 1, order: 4, operation: 1, confirmPhoto: 0, wait: 0, photoDelay: 0, photoAfterDelay: 0, focusTimes: 0, ledLight: 0, shoesFlip: 0, position: 0, angle: 0, cameraHeight: 0, cameraAngle: 0, isDefault: false },
+]);
+const dialogVisible = ref(false);
+const editTitle = ref('');
+const editRowData = ref({});
+const activeTab = ref('left');
+const editIndex = ref(0);
 // Watch for changes in the route query parameter 'type'
 watch(() => route.query.type, (newType) => {
   if (newType) {
@@ -342,6 +476,68 @@ const selectFolder = () => {
 const saveSetting = () => {
   console.log(formData.value);
 }
+const addRow = () => {
+  if (activeTab.value === 'left') {
+    lefttableData.value.push({ id: lefttableData.value.length + 1, name: '步骤' + (lefttableData.value.length + 1), value: 1, order: lefttableData.value.length + 1, operation: 1 });
+  } else {
+    righttableData.value.push({ id: righttableData.value.length + 1, name: '步骤' + (righttableData.value.length + 1), value: 1, order: righttableData.value.length + 1, operation: 1 });
+  }
+}
+const upRow = (row) => {
+  if (activeTab.value === 'left') {
+    const index = lefttableData.value.indexOf(row);
+    if (index > 0) {
+      const temp = lefttableData.value[index - 1];
+      lefttableData.value[index - 1] = row;
+      lefttableData.value[index] = temp;
+    }
+  } else {
+    const index = righttableData.value.indexOf(row);
+    if (index > 0) {
+      const temp = righttableData.value[index - 1];
+      righttableData.value[index - 1] = row;
+      righttableData.value[index] = temp;
+    }
+  }
+}
+const downRow = (row) => {
+  if (activeTab.value === 'left') {
+    const index = lefttableData.value.indexOf(row);
+    if (index < lefttableData.value.length - 1) {
+      const temp = lefttableData.value[index + 1];
+      lefttableData.value[index + 1] = row;
+      lefttableData.value[index] = temp;
+    }
+  } else {
+    const index = righttableData.value.indexOf(row);
+    if (index < righttableData.value.length - 1) {
+      const temp = righttableData.value[index + 1];
+      righttableData.value[index + 1] = row;
+      righttableData.value[index] = temp;
+    }
+  }
+}
+const editRow = (row, index) => {
+  dialogVisible.value = true;
+  editTitle.value = row.name+'编辑';
+  editRowData.value = row;
+  editIndex.value = index;
+}
+const deleteRow = (row, index) => {
+  if (activeTab.value === 'left') {
+    lefttableData.value = lefttableData.value.filter(item => item.id !== row.id);
+  } else {
+    righttableData.value = righttableData.value.filter(item => item.id !== row.id);
+  }
+}
+const saveRow = () => {
+  if (activeTab.value === 'left') {
+    lefttableData.value[editIndex.value] = editRowData.value;
+  } else {
+    righttableData.value[editIndex.value] = editRowData.value;
+  }
+  dialogVisible.value = false;
+}
 </script>
 
 <style lang="scss" scoped>
@@ -392,6 +588,7 @@ body {
 .form-container {
   border-radius: 12px;
   padding: 30px;
+  padding-top: 10px;
   width: 800px;
   margin: 0 auto;
   height: 306px;
@@ -448,6 +645,24 @@ body {
     padding-top: 30px;
     padding-left: 100px;
     border-bottom: 1px solid rgba(0,0,0,0.1);
+    :deep(.el-tabs__header){
+      padding-left: 0;
+    }
+    :deep(.el-tabs--card>.el-tabs__header){
+      border-bottom: 1px solid #CCCCCC;
+    }
+    :deep(.el-tabs__item){
+      height: 30px;
+      line-height: 30px;
+    }
+    :deep(.el-tabs__nav-wrap){
+      margin-bottom: 0;
+    }
+    :deep(.el-tabs__item.is-active){
+      color: #333;
+      font-weight: bold;
+      background: #fff;
+    }
 }
 .select-btn{
   display: flex;
@@ -472,4 +687,156 @@ body {
   justify-content: center;
   padding: 30px 0;
 }
+.form-table{
+  margin-top: 10px;
+  .btnBox{
+    display: flex;
+    align-items: center;
+    margin-bottom: 12px;
+  }
+  :deep(.el-table .el-table__header){
+    padding: 0;
+    height: 30px;
+    .el-table__cell{
+      background: #F1F4FF;
+    }
+  }
+  :deep(.el-table .el-table__cell){
+    padding: 0;
+    text-align: center;
+  }
+  :deep(.el-table__row) {
+    height: 30px;
+    padding: 0;
+    &:nth-child(even) {
+      background: #F1F4FF;
+    }
+    &:nth-child(odd) {
+      background: #FFFFFF;
+    }
+  }
+  .primary-btn{
+    width: 80px;
+    height: 30px;
+    background: linear-gradient( 135deg, #2FB0FF 0%, #B863FB 100%);
+    border-radius: 4px;
+    color: #fff;
+    font-size: 14px;
+    text-align: center;
+    cursor: pointer;
+    line-height: 30px;
+    margin-right: 10px;
+  }
+  .normal-btn{
+    width: 80px;
+    height: 30px;
+    background: #fff;
+    border: 1px solid #CCCCCC;
+    border-radius: 4px;
+    font-size: 14px;
+    text-align: center;
+    line-height: 30px;
+    cursor: pointer;
+  }
+  .cursor-pointer{
+    cursor: pointer;
+  }
+}
+.editDialog{  
+  .el-dialog__body{
+    padding: 0 !important;
+  }
+  .btn-row{
+    display: flex;
+    align-items: center;
+    justify-content: flex-end;
+    gap: 10px;
+  }
+  .primary-btn{
+    width: 100px;
+    height: 30px;
+    background: linear-gradient( 135deg, #2FB0FF 0%, #B863FB 100%);
+    border-radius: 4px;
+    color: #fff;
+    font-size: 14px;
+    text-align: center;
+    line-height: 30px;
+    cursor: pointer;
+  }
+  .normal-btn{
+    width: 100px;
+    height: 30px;
+    background: #fff;
+    border: 1px solid #CCCCCC;
+    border-radius: 4px;
+    font-size: 14px;
+    text-align: center;
+    line-height: 30px;
+    cursor: pointer;
+  }
+}
+  .config-type{
+    font-size: 14px;
+    color: #333333;
+    display: flex;
+    align-items: center;
+    justify-content: flex-start;
+    padding: 10px 0;
+    .el-checkbox{
+      margin-left: 10px;
+    }
+  }
+.editForm{
+  display: grid;
+  grid-template-columns: repeat(2, 1fr);
+  gap: 0;
+  .flex-row{
+    display: flex;
+    align-items: center;
+    :deep(.el-radio){
+      margin-right: 6px !important;
+    }
+    :deep(.el-radio__label){
+      padding-left: 4px;
+    }
+  }
+  :deep(.el-form-item) {
+    margin-bottom: 0;
+    .el-form-item__label {
+      width: 105px !important;
+      padding-right: 0 !important;
+        background: #FBFCFF;
+        border: 1px solid #EEEEEE;
+        height: 41px;
+        line-height: 41px;
+        padding-left: 5px;
+        text-align: left;
+      }
+      .el-form-item__content {
+        width: 190px;
+        height: 41px;
+        background: #FFFFFF;
+        padding-left: 7px;
+        border: 1px solid #EEEEEE;
+        .el-input__wrapper {
+          box-shadow: none;
+        }
+        
+        // 确保number类型输入框的上下箭头始终显示
+        input[type="number"]::-webkit-inner-spin-button,
+        input[type="number"]::-webkit-outer-spin-button {
+          opacity: 1;
+          height: 28px;
+          position: absolute;
+          top: 2px;
+          right: 2px;
+          cursor: pointer;
+        }
+        
+        input[type="number"] {
+          -moz-appearance: number-input; /* Firefox */
+        }
+      }
+    }
+}
 </style>