Răsfoiți Sursa

Merge branch 'main' into whr

wanghairong 5 luni în urmă
părinte
comite
7785062720

+ 68 - 77
src/api/axios.js

@@ -1,111 +1,102 @@
+import axios from "axios";
+import Router from "@/router";
+import { Message, Notification } from "@arco-design/web-vue";
+import { useSystemStore } from "@/store/modules/systemStore";
 
-import axios from 'axios'
-import Router from '@/router'
-import { Message, Notification } from '@arco-design/web-vue'
-import { useSystemStore } from '@/store/modules/systemStore'
-
- 
-import { fn_logout } from '@/utils'
-
+import { fn_logout } from "@/utils";
 
 // console.log(import.meta.env.BASE_URL)
 const axiosInstance = axios.create({
   // baseURL: `${import.meta.env.PROD ? import.meta.env.VITE_PRO_PATH : ''}/api`,
   baseURL: import.meta.env.BASE_URL + "api",
   timeout: 300000,
-})
-
+});
 
 const requestState = {
   // 得到正确响应
-  success: [ 200],
+  success: [200],
   // token 跳转
   beOverdue: [886],
   // 没有访问权限
   NotAccessRight: [500],
   // 异常code
-  exception: [400]
-
-}
-
+  exception: [400],
+};
 
-const pathArr = ['/api/user/login', '/api/logout']
+const pathArr = ["/api/admin/system/login", "/api/logout"];
 axiosInstance.interceptors.request.use(
   (config) => {
-    const systemStore = useSystemStore()
-    systemStore.localLoading(true)
-   
+    const systemStore = useSystemStore();
+    systemStore.localLoading(true);
+
     // 在发送请求之前做些什么
     if (!pathArr.includes(config.url)) {
-      const token = localStorage.getItem('token')
+      const token = localStorage.getItem("token");
       if (token && config.headers) {
-        config.headers['Authorization'] = token
+        config.headers["Authorization"] = token;
       }
     }
-    return config
-  },(err) => {
-    const systemStore = useSystemStore()
-    systemStore.localLoading()
-    Promise.reject(err)
+    return config;
+  },
+  (err) => {
+    const systemStore = useSystemStore();
+    systemStore.localLoading();
+    Promise.reject(err);
   }
-)
+);
 
 // 响应拦截器
 axiosInstance.interceptors.response.use(
   (res) => {
-  const systemStore = useSystemStore()
-  systemStore.localLoading()
-  const { code, data, message:msg } = res.data
-  // 成功
-  if (code === 200) {
-    return Promise.resolve(res.data)
-  }
-
-  // 服务端错误信息
-  if(requestState.NotAccessRight.includes(code)){
-    Notification.warning({
-      title: '系统信息',
-      content: msg,
-    })
-    return Promise.reject(msg);
-  }
+    const systemStore = useSystemStore();
+    systemStore.localLoading();
+    const { code, data, message: msg } = res.data;
+    // 成功
+    if (code === 200) {
+      return Promise.resolve(res.data);
+    }
 
-  // 异常code
-  if(requestState.exception.includes(code)){
-    Notification.warning({
-      title: '系统提示',
-      content: msg,
-    })
-    return Promise.reject(msg);
-  }
-  //token失效
-  if(requestState.beOverdue.includes(code)){
-    fn_logout(Router)
-    Notification.warning({
-      title: '系统信息',
-      content: msg,
-      duration: 2000,
-    })
-    return Promise.reject(msg); 
-  }
+    // 服务端错误信息
+    if (requestState.NotAccessRight.includes(code)) {
+      Notification.warning({
+        title: "系统信息",
+        content: msg,
+      });
+      return Promise.reject(msg);
+    }
 
-  return Promise.resolve(data)
-  },(err) => {
-    const systemStore = useSystemStore()
-    systemStore.localLoading()
-    const res = err['response']
-    if(err.code === "ERR_CANCELED") {
-      console.log('请求中断')
-      return
+    // 异常code
+    if (requestState.exception.includes(code)) {
+      Notification.warning({
+        title: "系统提示",
+        content: msg,
+      });
+      return Promise.reject(msg);
+    }
+    
+    return Promise.resolve(data);
+  },
+  (err) => {
+    const systemStore = useSystemStore();
+    systemStore.localLoading();
+    const res = err["response"];
+    if (err.code === "ERR_CANCELED") {
+      console.log("请求中断");
+      return;
     }
-    console.log("err.response-",err.response)
+    const msg = err.response.data ? err.response.data.message : ""
     Notification.warning({
-      title: '系统信息',
-      content: err.response.data ? err.response.data.message : '',
-    })
-    Promise.reject(err)
+      title: "系统信息",
+      content: msg
+    });
+    //token失效
+    if (requestState.beOverdue.includes(err.status)) {
+      fn_logout(Router);
+      // 直接终止请求
+      return undefined;
+    }
+    Promise.reject(err);
   }
-)
-
-export default axiosInstance
+);
 
+export default axiosInstance;

+ 21 - 17
src/router/router.update.js

@@ -50,21 +50,25 @@ export const updateRouteByMenu = async (router, systemStore) => {
     })
     return
   }
-  const { data: menuList } = await systemUserInfoMenu();
-  systemStore.setStateValue({
-    key: "menus",
-    value: menuList || [],
-    localStorage: true,
-  });
-  const pathHome = findPath(menuList[0]);
-  const mainRoutes = toRoutesJson(menuList);
-  const routes = {
-    path: "/",
-    name: "main",
-    redirect: pathHome.path,
-    component: LAYOUT,
-    children: mainRoutes,
-  };
-  router.options.routes = [routes, ...systemRoutes];
-  await router.addRoute(routes);
+  try {
+    const { data: menuList } = await systemUserInfoMenu();
+    systemStore.setStateValue({
+      key: "menus",
+      value: menuList || [],
+      localStorage: true,
+    });
+    const pathHome = findPath(menuList[0]);
+    const mainRoutes = toRoutesJson(menuList);
+    const routes = {
+      path: "/",
+      name: "main",
+      redirect: pathHome.path,
+      component: LAYOUT,
+      children: mainRoutes,
+    };
+    router.options.routes = [routes, ...systemRoutes];
+    await router.addRoute(routes);
+  } catch(err) {
+    console.log(err)
+  }
 };

+ 4 - 7
src/store/modules/systemStore.js

@@ -67,14 +67,13 @@ export const useSystemStore = defineStore({
 
           const info = res.data
           const systemStore = useSystemStore()
-          console.log(info)
           const getInfoData = info => {
             const infoData = {
               endpoint: 'https://cardiot.oss-cn-beijing.aliyuncs.com',
               region: 'oss-cn-beijing',
-              accessKeyId: info.accessKeyId,
-              accessKeySecret: info.accessKeySecret,
-              stsToken: info.securityToken,
+              accessKeyId: info.AccessKeyId,
+              accessKeySecret: info.AccessKeySecret,
+              stsToken: info.SecurityToken,
               bucket: 'cardiot',
               cname: true
             }
@@ -83,14 +82,12 @@ export const useSystemStore = defineStore({
             return infoData
           }
           getInfoData(info)
-          console.log(this.stsClientInfo)
+        
           const client = new windowVar.OSS({
             ...this.stsClientInfo,
             refreshSTSToken: async () => {
               const res = await getSTSInfo({})
-
               getInfoData(res.data)
-
               return {
                 accessKeyId: info.AccessKeyId,
                 accessKeySecret: info.AccessKeySecret,

+ 6 - 0
src/views/lotCard/cardList/index.vue

@@ -67,6 +67,12 @@ const cardStatusOptions = [
   dataSource.value = data.records ||[]
   pagination.value.total = data.total
 }
+
+const handleSearch = () => {
+}
+const resetSearch = () => {
+ 
+}
   
 onMounted(() => {
   intData()

+ 8 - 0
src/views/lotCard/trafficList/index.vue

@@ -80,6 +80,14 @@ const evChangePageSize = (pageSize) => {
   pagination.value.pageSize = pageSize
 }
 
+const resetSearch = () => {
+ 
+}
+
+const handleSearch = () => {
+}
+
+
 onMounted(() => {
   intData()
 })

+ 0 - 171
src/views/plan-management/NewFeeForm.vue

@@ -1,171 +0,0 @@
-<template>
-  <a-modal
-    :visible="visible"
-    :title="editMode ? $t('plan.editFee') : $t('plan.addFee')"
-    @ok="handleSubmit"
-    @cancel="handleCancel"
-    :width="800"
-  >
-    <a-form :model="formData" :rules="rules" ref="formRef" >
-      <a-divider>{{ $t('plan.basicInfo') }}</a-divider>
-      <a-form-item field="feeCode" :label="$t('plan.feeCode')" required>
-        <a-input v-model="formData.feeCode" :placeholder="$t('plan.enterFeeCode')" :maxLength="60" show-word-limit />
-      </a-form-item>
-      <a-form-item field="feeName" :label="$t('plan.feeName')" required>
-        <a-input v-model="formData.feeName" :placeholder="$t('plan.enterFeeName')" :maxLength="60" show-word-limit />
-      </a-form-item>
-      <a-form-item field="supplier" :label="$t('plan.supplier')" required>
-        <a-select v-model="formData.supplier" :placeholder="$t('plan.selectSupplier')">
-          <a-option value="supplier1">{{ $t('plan.supplier1') }}</a-option>
-          <a-option value="supplier2">{{ $t('plan.supplier2') }}</a-option>
-        </a-select>
-      </a-form-item>
-      <a-form-item field="dataType" :label="$t('plan.dataType')" required>
-        <a-radio-group v-model="formData.dataType">
-          <a-radio value="general">{{ $t('plan.general') }}</a-radio>
-          <a-radio value="specific">{{ $t('plan.specific') }}</a-radio>
-        </a-radio-group>
-      </a-form-item>
-      <a-form-item field="billingCategory" :label="$t('plan.billingCategory')" required>
-        <a-radio-group v-model="formData.billingCategory">
-          <a-radio value="data">{{ $t('plan.data') }}</a-radio>
-          <a-radio value="voice">{{ $t('plan.voice') }}</a-radio>
-          <a-radio value="nb">{{ $t('plan.nb') }}</a-radio>
-          <a-radio value="sms">{{ $t('plan.sms') }}</a-radio>
-        </a-radio-group>
-      </a-form-item>
-      <a-form-item field="status" :label="$t('plan.status')" required>
-        <a-radio-group v-model="formData.status">
-          <a-radio value="normal">{{ $t('plan.status.normal') }}</a-radio>
-          <a-radio value="disabled">{{ $t('plan.status.disabled') }}</a-radio>
-          <a-radio value="offline">{{ $t('plan.status.offline') }}</a-radio>
-        </a-radio-group>
-      </a-form-item>
-
-      <a-divider>{{ $t('plan.billingInfo') }}</a-divider>
-      <a-form-item field="billingCycle" :label="$t('plan.billingCycle')" required>
-        <a-radio-group v-model="formData.billingCycle">
-          <a-radio value="daily">{{ $t('plan.daily') }}</a-radio>
-          <a-radio value="monthly">{{ $t('plan.monthly') }}</a-radio>
-        </a-radio-group>
-      </a-form-item>
-      <a-form-item field="packageSize" :label="$t('plan.packageSize')" required>
-        <a-input-number v-model="formData.packageSize" :placeholder="$t('plan.enterPackageSize')" style="width: 200px" />
-        <a-select v-model="formData.packageUnit" style="width: 80px; margin-left: 10px;">
-          <a-option value="KB">KB</a-option>
-          <a-option value="MB">MB</a-option>
-          <a-option value="GB">GB</a-option>
-        </a-select>
-      </a-form-item>
-      <a-form-item field="standardPrice" :label="$t('plan.standardPrice')" required>
-        <a-input-number v-model="formData.standardPrice" :placeholder="$t('plan.enterPrice')" style="width: 200px" />
-        <span style="margin: 0 10px;">{{ $t('plan.currency') }}/</span>
-        <a-select v-model="formData.priceUnit" style="width: 120px;">
-          <a-option value="day">{{ $t('plan.billingCycleType') }}</a-option>
-          <a-option value="month">{{ $t('plan.month') }}</a-option>
-        </a-select>
-      </a-form-item>
-      <a-form-item field="subscriptionPeriod" :label="$t('plan.subscriptionPeriod')" required>
-        <a-input-number v-model="formData.minPeriod" :placeholder="$t('plan.minimum')" style="width: 100px" />
-        <span style="margin: 0 10px;">{{ $t('plan.monthsMin') }}</span>
-        <a-input-number v-model="formData.maxPeriod" :placeholder="$t('plan.maximum')" style="width: 100px" />
-        <span style="margin-left: 10px;">{{ $t('plan.monthsMax') }}</span>
-      </a-form-item>
-      <a-form-item field="overagePrice" :label="$t('plan.overagePrice')">
-        <a-input-number v-model="formData.overagePrice" :placeholder="$t('plan.enterOveragePrice')" style="width: 200px" />
-        <span style="margin: 0 10px;">{{ $t('plan.currency') }}/</span>
-        <a-select v-model="formData.overageUnit" style="width: 80px;">
-          <a-option value="KB">KB</a-option>
-          <a-option value="MB">MB</a-option>
-          <a-option value="GB">GB</a-option>
-        </a-select>
-      </a-form-item>
-      <a-form-item field="connectionTimes" :label="$t('plan.connectionTimes')">
-        <a-input-number v-model="formData.connectionTimes" placeholder="0" />
-        <span style="margin-left: 10px;">{{ $t('plan.times') }}</span>
-      </a-form-item>
-      <a-form-item field="voiceRate" :label="$t('plan.voiceRate')">
-        <a-input-number v-model="formData.voiceRate" placeholder="0" />
-        <span style="margin-left: 10px;">{{ $t('plan.currency') }}/{{ $t('plan.minute') }}</span>
-      </a-form-item>
-      <a-form-item field="billingCode" :label="$t('plan.billingCode')">
-        <a-input v-model="formData.billingCode" :placeholder="$t('plan.autoGenerated')" disabled />
-      </a-form-item>
-    </a-form>
-  </a-modal>
-</template>
-
-<script setup>
-import { ref, reactive } from 'vue';
-import { Message } from '@arco-design/web-vue';
-import { useI18n } from 'vue-i18n';
-
-const { t } = useI18n();
-
-const props = defineProps({
-  visible: Boolean,
-  editMode: Boolean,
-  editData: Object,
-});
-
-const emit = defineEmits(['update:visible', 'submit']);
-
-const formRef = ref(null);
-
-const formData = reactive({
-  feeCode: '',
-  feeName: '',
-  supplier: '',
-  dataType: 'general',
-  billingCategory: 'data',
-  status: 'normal',
-  billingCycle: 'daily',
-  packageSize: null,
-  packageUnit: 'MB',
-  standardPrice: null,
-  priceUnit: 'day',
-  minPeriod: 1,
-  maxPeriod: 60,
-  overagePrice: null,
-  overageUnit: 'MB',
-  connectionTimes: 0,
-  voiceRate: 0,
-  billingCode: t('plan.autoGenerated'),
-});
-
-const rules = {
-  feeCode: [{ required: true, message: t('plan.feeCodeRequired') }],
-  feeName: [{ required: true, message: t('plan.feeNameRequired') }],
-  supplier: [{ required: true, message: t('plan.supplierRequired') }],
-  dataType: [{ required: true, message: t('plan.dataTypeRequired') }],
-  billingCategory: [{ required: true, message: t('plan.billingCategoryRequired') }],
-  status: [{ required: true, message: t('plan.statusRequired') }],
-  billingCycle: [{ required: true, message: t('plan.billingCycleRequired') }],
-  packageSize: [{ required: true, type: 'number', message: t('plan.packageSizeRequired') }],
-  standardPrice: [{ required: true, type: 'number', message: t('plan.standardPriceRequired') }],
-  minPeriod: [{ required: true, type: 'number', message: t('plan.minPeriodRequired') }],
-  maxPeriod: [{ required: true, type: 'number', message: t('plan.maxPeriodRequired') }],
-};
-
-const handleSubmit = () => {
-  formRef.value.validate((errors) => {
-    if (!errors) {
-      emit('submit', { ...formData });
-      emit('update:visible', false);
-    } else {
-      console.error('Validation failed', errors);
-      Message.error(t('plan.fillRequiredFields'));
-    }
-  });
-};
-
-const handleCancel = () => {
-  emit('update:visible', false);
-};
-</script>
-
-<style scoped>
-.arco-form-item {
-  margin-bottom: 18px;
-}
-</style>

+ 0 - 176
src/views/plan-management/index.vue

@@ -1,176 +0,0 @@
-<template>
-  <div class="fee-management">
-    <!-- Search section -->
-    <div class="search-section">
-      <a-form :model="searchForm" layout="inline">
-        <a-form-item field="feeName" :label="$t('plan.feeName')">
-          <a-input v-model="searchForm.feeName" :placeholder="$t('plan.enterFeeName')" allow-clear />
-        </a-form-item>
-        <a-form-item field="operatorType" :label="$t('plan.operatorType')">
-          <a-select
-            v-model="searchForm.operatorType"
-            :placeholder="$t('plan.selectOperatorType')"
-            allow-clear
-            style="width: 200px"
-          >
-            <a-option v-for="type in operatorTypes" :key="type.value" :value="type.value">
-              {{ $t(`plan.operatorTypes.${type.value}`) }}
-            </a-option>
-          </a-select>
-        </a-form-item>
-        <a-form-item>
-          <a-button type="primary" @click="handleSearch">{{ $t('global.common.search') }}</a-button>
-        </a-form-item>
-      </a-form>
-    </div>
-
-    <!-- Add button -->
-    <div class="operation-section">
-      <a-button type="primary" @click="showNewFeeForm">{{ $t('plan.addFee') }}</a-button>
-    </div>
-
-    <!-- Data table -->
-    <a-table :columns="columns" :data="tableData" :pagination="pagination" @page-change="onPageChange">
-      <template #status="{ record }">
-        <a-tag :color="getStatusColor(record.status)">{{ $t(`plan.status.${record.status}`) }}</a-tag>
-      </template>
-      <template #operation="{ record }">
-        <a-space>
-          <a-button type="text" size="small" @click="handleEdit(record)">{{ $t('global.common.edit') }}</a-button>
-          <a-button type="text" size="small" @click="handleDelete(record)">{{ $t('global.common.delete') }}</a-button>
-        </a-space>
-      </template>
-    </a-table>
-
-    <!-- New/Edit fee form dialog -->
-    <new-fee-form 
-      v-model:visible="newFeeFormVisible"
-      :editMode="editMode"
-      :editData="editData"
-      @submit="handleFeeSubmit"
-    />
-  </div>
-</template>
-
-<script setup>
-import { ref, reactive, computed } from 'vue';
-import { Message } from '@arco-design/web-vue';
-import { useI18n } from 'vue-i18n';
-import NewFeeForm from './NewFeeForm.vue';
-
-const { t } = useI18n();
-
-const searchForm = reactive({
-  feeName: '',
-  operatorType: '',
-});
-
-const operatorTypes = [
-  { value: 'general' },
-  { value: 'specific' },
-];
-
-const columns = computed(() => [
-  { title: t('plan.id'), dataIndex: 'id' },
-  { title: t('plan.feeCode'), dataIndex: 'feeCode' },
-  { title: t('plan.feeName'), dataIndex: 'feeName' },
-  { title: t('plan.supplierName'), dataIndex: 'supplierName' },
-  { title: t('plan.dataType'), dataIndex: 'dataType' },
-  { title: t('plan.billingCategory'), dataIndex: 'billingCategory' },
-  { title: t('plan.billingCycle'), dataIndex: 'billingCycle' },
-  { title: t('plan.packageSize'), dataIndex: 'packageSize' },
-  { title: t('plan.standardPrice'), dataIndex: 'standardPrice' },
-  { title: t('plan.cycleLimitation'), dataIndex: 'cycleLimitation' },
-  { title: t('plan.status'), slotName: 'status' },
-  { title: t('global.common.operations'), slotName: 'operation', width: 150 },
-]);
-
-const tableData = ref([
-  {
-    id: 8,
-    feeCode: 'MR026',
-    feeName: '移动200G',
-    supplierName: '泰国True',
-    dataType: '通用',
-    billingCategory: '流量',
-    billingCycle: '按天',
-    packageSize: '2.00G',
-    standardPrice: '150.00元/月',
-    cycleLimitation: '1-12月',
-    status: '正常',
-  },
-  // 添加更多模拟数据...
-]);
-
-const pagination = reactive({
-  total: 100,
-  current: 1,
-  pageSize: 10,
-});
-
-const newFeeFormVisible = ref(false);
-const editMode = ref(false);
-const editData = ref(null);
-
-const handleSearch = () => {
-  console.log('Search form data:', searchForm);
-  Message.success(t('plan.searchExecuted'));
-};
-
-const showNewFeeForm = () => {
-  editMode.value = false;
-  editData.value = null;
-  newFeeFormVisible.value = true;
-};
-
-const handleEdit = (record) => {
-  editMode.value = true;
-  editData.value = { ...record };
-  newFeeFormVisible.value = true;
-};
-
-const handleDelete = (record) => {
-  Message.success(t('plan.feeDeleted', { name: record.feeName }));
-};
-
-const handleFeeSubmit = (formData) => {
-  if (editMode.value) {
-    console.log('Edited fee submitted:', formData);
-    Message.success(t('plan.feeUpdated', { name: formData.feeName }));
-  } else {
-    console.log('New fee submitted:', formData);
-    Message.success(t('plan.feeAdded', { name: formData.feeName }));
-  }
-};
-
-const onPageChange = (page) => {
-  pagination.current = page;
-};
-
-const getStatusColor = (status) => {
-  const colorMap = {
-    '正常': 'green',
-    '禁用': 'red',
-    '下架': 'gray',
-  };
-  return colorMap[status] || 'blue';
-};
-</script>
-
-<style scoped>
-.fee-management {
-  padding: 20px;
-}
-
-.search-section {
-  margin-bottom: 20px;
-}
-
-.operation-section {
-  margin-bottom: 20px;
-}
-
-.fee-management .arco-table-th {
-  white-space: nowrap;
-}
-</style>

+ 2 - 0
src/views/system/menu/index.vue

@@ -421,8 +421,10 @@ const customRequest = async (option) => {
     key: key,
     body: file
   })
+  
   if (resClient.statusCode === 200) {
     console.log('上传成功')
+    console.log("resClient=",resClient)
   }
 
 };