فهرست منبع

Merge branch 'dev'

邵果 3 ماه پیش
والد
کامیت
84087cd2c7

+ 5 - 0
src/api/path/order.js

@@ -48,4 +48,9 @@ export function ReturntheOrderCard(params) {
 // 设置金额
 export function SettingPricing(data) {
     return service.post('/admin/sim/setAmount', data)
+}
+
+// 获取导卡进度
+export function GuideCardProgress(params){
+    return service.get('/admin/sim/assignProgress', { params});
 }

+ 73 - 36
src/components/Search/index.vue

@@ -1,27 +1,35 @@
 <template>
-    <div ref="search">
+    <div class="search">
         <!-- 动态渲染表单项 -->
-        <a-form :model="formState" layout="inline">
-            <a-form-item v-for="(item, index) in SearchForm" :key="index" :label="item.label" :field="item.field">
-                <component :is="'a-' + item.type" v-model="formState[item.field].value" :placeholder="item.placeholder"
-                    allow-clear :style="{ width: item.width ? item.width + 'px' : '' }">
-                    <template v-if="item.type == 'select'">
-                        <a-option v-for="option in item.options" :key="option.value" :value="option.value">
-                            {{ option.label }}
-                        </a-option>
-                    </template>
-                </component>
-            </a-form-item>
-            <a-form-item>
-                <a-button type="primary" @click="handleQuery">查询</a-button>
-                <a-button @click="handleReset" style="margin-left: 10px;">重置</a-button>
-            </a-form-item>
-        </a-form>
+        <div class="Form">
+            <a-form :model="formState" layout="inline">
+                <a-form-item v-for="(item, index) in showIcon ? data : InitialData" :key="index" :label="item.label"
+                    :field="item.field" :wrapper-col-style="{ marginBottom: '20px' }">
+                    <component :is="'a-' + item.type" v-model="formState[item.field].value"
+                        :placeholder="item.type == 'input' ? '请输入' : '请选择' + item.label" allow-clear
+                        :style="{ width: item.width ? item.width + 'px' : '' }">
+                        <template v-if="item.type == 'select'">
+                            <a-option v-for="option in item.options" :key="option.value" :value="option.value">
+                                {{ option.label }}
+                            </a-option>
+                        </template>
+                    </component>
+                </a-form-item>
+                <a-form-item>
+                    <a-button type="primary" @click="handleQuery">查询</a-button>
+                    <a-button @click="handleReset" style="margin-left: 10px;">重置</a-button>
+                </a-form-item>
+            </a-form>
+        </div>
+
+        <div v-if="show" @click="showIcon = !showIcon" class="icon">
+            {{ showIcon ? '折叠' : '展开' }} &nbsp; <icon-down :rotate="showIcon ? 180 : 0" />
+        </div>
     </div>
 </template>
 
 <script setup>
-import { ref, defineProps, toRefs, watch,defineEmits } from 'vue';
+import { ref, defineProps, toRefs, watch, defineEmits } from 'vue';
 import { Getdictionary } from "@/mixins/index.js";
 
 // 接收 props
@@ -33,23 +41,20 @@ const props = defineProps({
                 type: 'input',
                 label: '字典名称',
                 field: 'source',
-                placeholder: '请输入字典名称',
                 value: '', // 双向绑定的值
             },
             {
                 type: 'input',
                 label: '资费ID',
                 field: 'trafficId',
-                placeholder: '请输入资费ID',
                 value: '', // 双向绑定的值
             },
             {
                 type: 'select',
                 label: '卡类型',
                 field: 'simType',
-                placeholder: '选择卡类型',
                 options: [], // 默认空,后面会通过字典加载
-                dict:'CardType',
+                dict: 'CardType',
                 value: '', // 双向绑定的值
                 width: '200'
             },
@@ -59,37 +64,50 @@ const props = defineProps({
 
 const { SearchForm } = toRefs(props);
 
+// 分割完成的数据
+const InitialData = ref()
+const show = ref(false)
+const showIcon = ref(false)
 const formState = ref({});
 
+const data = ref()
+
 const emit = defineEmits(['query'])
 SearchForm.value.forEach(item => {
     formState.value[item.field] = {
-        value: item.value, 
+        value: item.value,
     };
 });
 
 // 字典加载
-const loadedDicts = ref({}); 
+const loadedDicts = ref({});
 const loadDictOptions = async (index, dict) => {
     if (loadedDicts.value[dict]) {
         SearchForm.value[index].options = loadedDicts.value[dict];
         return;
     }
     const dictionary = await Getdictionary(dict);
-    loadedDicts.value[dict] = dictionary || []; 
-    SearchForm.value[index].options = loadedDicts.value[dict]; 
+    loadedDicts.value[dict] = dictionary || [];
+    SearchForm.value[index].options = loadedDicts.value[dict];
 };
 
 watch(
-  () => SearchForm.value, 
-  async () => {
-    for (let index = 0; index < SearchForm.value.length; index++) {
-        const item = SearchForm.value[index];
-        if (item.dict && !loadedDicts.value[item.dict]) {
-            await loadDictOptions(index, item.dict); 
+    () => SearchForm.value,
+    async () => {
+        for (let index = 0; index < SearchForm.value.length; index++) {
+            const item = SearchForm.value[index];
+            if (item.dict && !loadedDicts.value[item.dict]) {
+                await loadDictOptions(index, item.dict);
+            }
         }
-    }
-}, { immediate: true });
+        // 如果当前长度超过5条就需要折叠展开
+        if (SearchForm.value.length >= 6) {
+            show.value = true;
+        }
+        // 初始化切割数组
+        InitialData.value = SearchForm.value.splice(0, 6)
+        data.value = [...InitialData.value, ...SearchForm.value]
+    }, { immediate: true });
 
 // 查询操作
 const handleQuery = () => {
@@ -98,9 +116,28 @@ const handleQuery = () => {
 };
 
 const handleReset = () => {
-    SearchForm.value.forEach(res=>{
+    SearchForm.value.forEach(res => {
         res.value = '';
     })
 }
 
-</script>
+</script>
+
+<style lang="less" scoped>
+.search {
+    display: flex;
+    justify-content: space-between;
+}
+
+.Form{
+    width: 95%;
+}
+
+.icon{
+    display: flex;
+    // align-items: center;
+    color: #3491fa;
+    font-size: 18px;
+    cursor: pointer;
+}
+</style>

+ 1 - 0
src/i18n/zh/lotCard.js

@@ -195,4 +195,5 @@ export default {
      FormationPool:'组池',
      FlowPool:'流量池',
      QuantityCardsPurchased:'购卡数量',
+     DatapackageStatus:'流量包状态'
 }  

+ 69 - 0
src/views/OperationRecord/FlowpoolRecord/index.vue

@@ -0,0 +1,69 @@
+<template>
+  <div>
+    <div class="Search">
+      <Search></Search>
+    </div>
+
+    <div class="table">
+      <a-table :columns="columns" :data="data" :pagination="pageData" @page-change="evChangePage" />
+    </div>
+  </div>
+</template>
+
+<script setup>
+import { ref, onMounted, toRefs } from 'vue';
+import Search from '@/components/Search/index.vue'
+const columns = [
+  {
+    title: 'Name',
+    dataIndex: 'name',
+    ellipsis: true,
+    tooltip: true,
+    align: 'center'
+  },
+  {
+    title: 'Salary',
+    dataIndex: 'salary',
+    ellipsis: true,
+    tooltip: true,
+    align: 'center'
+  },
+  {
+    title: 'Address',
+    dataIndex: 'address',
+    ellipsis: true,
+    tooltip: true,
+    align: 'center'
+  },
+  {
+    title: 'Email',
+    dataIndex: 'email',
+    ellipsis: true,
+    tooltip: true,
+    align: 'center'
+  },
+];
+
+
+const state = ref({
+  pageData: {
+    total: 10,
+    size: 10,
+    current: 1,
+  },
+  data: []
+})
+
+const { pageData, data } = toRefs(state.value)
+
+// 分页
+const evChangePage = (page) => {
+  pageData.value.current = page
+}
+</script>
+<style scoped>
+.Search,
+.table {
+  margin-top: 20px;
+}
+</style>

+ 10 - 0
src/views/OperationRecord/TariffRecord/index.vue

@@ -0,0 +1,10 @@
+<template>
+  <div class=""></div>
+</template>
+
+<script setup>
+import { ref, onMounted, toRefs } from 'vue';
+</script>
+<style scoped>
+
+</style>

+ 265 - 41
src/views/lotCard/cardList/config.js

@@ -1,44 +1,268 @@
 export const columns = [
-    { title: window.$t('lotCard.iccid'), dataIndex: 'iccid', align: 'center', ellipsis: true },
-    { title: window.$t('lotCard.source'), dataIndex: 'source', align: 'center', ellipsis: true },
-    { title: window.$t('lotCard.userName'), dataIndex: 'userName', align: 'center', ellipsis: true },
-    { title: 'IMSI', dataIndex: 'currentImsi', align: 'center', ellipsis: true },
-    { title: window.$t('lotCard.bind'), dataIndex: 'currentImsi', align: 'center', ellipsis: true },
-    // { title: 'SIM货币余额', dataIndex: 'moneyBalances', align: 'center', ellipsis:true  },
-    { title: window.$t('lotCard.GenerationDate'), dataIndex: 'createTime', align: 'center', ellipsis: true },
-    // { title: '支付方式', dataIndex: 'payType', align: 'center', ellipsis: true },
-    { title: window.$t('lotCard.SimStatus'), dataIndex: 'iccidStatus', align: 'center', ellipsis: true },
-    { title: window.$t('lotCard.TotalFlow'), dataIndex: 'dataUsageTotal', slotName: 'dataUsageTotal', align: 'center', ellipsis: true },
-    { title: window.$t('lotCard.MinutesIncomingVoiceCalls'), dataIndex: 'voiceMtTotal', align: 'center', ellipsis: true },
-    { title: window.$t('lotCard.MinutesOutgoingVoiceCalls'), dataIndex: 'voiceMoTotal', align: 'center', ellipsis: true },
-    { title: window.$t('lotCard.TotalVoiceMinutes'), dataIndex: 'voiceTotal', align: 'center', ellipsis: true },
-    { title: window.$t('lotCard.NumberTextMessagesSent'), dataIndex: 'smsTotal', align: 'center', ellipsis: true },
-    { title: window.$t('lotCard.validity')+(window.$t('lotCard.month')), dataIndex: 'validMonth', align: 'center', ellipsis: true },
-    { title: window.$t('lotCard.ClosingDate'), dataIndex: 'closeTime', align: 'center', ellipsis: true },
-    { title: 'SIM'+window.$t('lotCard.ActivationDate'), dataIndex: 'activeTime', align: 'center', ellipsis: true },
-    { title: 'IMSI'+window.$t('lotCard.SupplierName'), dataIndex: 'currentImsiProvider', align: 'center', ellipsis: true },
-    { title: window.$t('lotCard.CardPackage'), dataIndex: 'tariffName', align: 'center', ellipsis: true },
-    { title: window.$t('lotCard.EarlyWarningState'), dataIndex: 'forewarningStatus', align: 'center', width: 200, ellipsis: true },
-    { title: window.$t('lotCard.PoolName_Number'), dataIndex: 'poolNum', slotName: 'poolNum', align: 'center', width: 200, ellipsis: true },
-    { title: window.$t('lotCard.TheExpirationTime'), dataIndex: 'SilenceEndtime', align: 'center', width: 200, ellipsis: true },
-    { title: window.$t('lotCard.UsedPlanData'), dataIndex: 'dataUsage', align: 'center', ellipsis: true },
-    { title: window.$t('lotCard.AvailablePlanData'), dataIndex: 'dataTotal', align: 'center', ellipsis: true },
-    { title: window.$t('lotCard.used'), dataIndex: 'usedBg', align: 'center', ellipsis: true },
-    { title: window.$t('lotCard.available'), dataIndex: 'usableBg', align: 'center', ellipsis: true },
-    { title: window.$t('lotCard.DefaultRate'), dataIndex: 'dataSpeed', align: 'center', ellipsis: true },
-    {
-        title: window.$t('global.common.operations'),
-        dataIndex: 'id',
-        slotName: 'id',
-        align: 'center',
-        width: 200,
-        fixed: "right",
-    }
-]
+  {
+    title: window.$t("lotCard.iccid"),
+    dataIndex: "iccid",
+    align: "center",
+    ellipsis: true,
+  },
+  {
+    title: window.$t("lotCard.source"),
+    dataIndex: "source",
+    align: "center",
+    ellipsis: true,
+  },
+  {
+    title: window.$t("lotCard.userName"),
+    dataIndex: "userName",
+    align: "center",
+    ellipsis: true,
+  },
+  { title: "IMSI", dataIndex: "currentImsi", align: "center", ellipsis: true },
+  {
+    title: window.$t("lotCard.bind"),
+    dataIndex: "currentImsi",
+    align: "center",
+    ellipsis: true,
+  },
+  {
+    title: "SIM货币余额",
+    dataIndex: "moneyBalances",
+    align: "center",
+    ellipsis: true,
+  },
+  {
+    title: window.$t("lotCard.GenerationDate"),
+    dataIndex: "createTime",
+    align: "center",
+    ellipsis: true,
+  },
+  // { title: '支付方式', dataIndex: 'payType', align: 'center', ellipsis: true },
+  {
+    title: window.$t("lotCard.SimStatus"),
+    dataIndex: "iccidStatus",
+    align: "center",
+    ellipsis: true,
+  },
+  {
+    title: window.$t("lotCard.DatapackageStatus"),
+    dataIndex: "DatapackageStatus",
+    align: "center",
+    ellipsis: true,
+  },
+  {
+    title: window.$t("lotCard.TotalFlow"),
+    dataIndex: "dataUsageTotal",
+    slotName: "dataUsageTotal",
+    align: "center",
+    ellipsis: true,
+  },
+  {
+    title: window.$t("lotCard.MinutesIncomingVoiceCalls"),
+    dataIndex: "voiceMtTotal",
+    align: "center",
+    ellipsis: true,
+  },
+  {
+    title: window.$t("lotCard.MinutesOutgoingVoiceCalls"),
+    dataIndex: "voiceMoTotal",
+    align: "center",
+    ellipsis: true,
+  },
+  {
+    title: window.$t("lotCard.TotalVoiceMinutes"),
+    dataIndex: "voiceTotal",
+    align: "center",
+    ellipsis: true,
+  },
+  {
+    title: window.$t("lotCard.NumberTextMessagesSent"),
+    dataIndex: "smsTotal",
+    align: "center",
+    ellipsis: true,
+  },
+  {
+    title: window.$t("lotCard.validity") + window.$t("lotCard.month"),
+    dataIndex: "validMonth",
+    align: "center",
+    ellipsis: true,
+  },
+  {
+    title: window.$t("lotCard.ClosingDate"),
+    dataIndex: "closeTime",
+    align: "center",
+    ellipsis: true,
+  },
+  {
+    title: "SIM" + window.$t("lotCard.ActivationDate"),
+    dataIndex: "activeTime",
+    align: "center",
+    ellipsis: true,
+  },
+  {
+    title: "IMSI" + window.$t("lotCard.SupplierName"),
+    dataIndex: "currentImsiProvider",
+    align: "center",
+    ellipsis: true,
+  },
+  {
+    title: window.$t("lotCard.CardPackage"),
+    dataIndex: "tariffName",
+    align: "center",
+    ellipsis: true,
+  },
+  {
+    title: window.$t("lotCard.EarlyWarningState"),
+    dataIndex: "forewarningStatus",
+    align: "center",
+    width: 200,
+    ellipsis: true,
+  },
+  {
+    title: window.$t("lotCard.PoolName_Number"),
+    dataIndex: "poolNum",
+    slotName: "poolNum",
+    align: "center",
+    width: 200,
+    ellipsis: true,
+  },
+  {
+    title: window.$t("lotCard.TheExpirationTime"),
+    dataIndex: "SilenceEndtime",
+    align: "center",
+    width: 200,
+    ellipsis: true,
+  },
+  {
+    title: window.$t("lotCard.UsedPlanData"),
+    dataIndex: "dataUsage",
+    align: "center",
+    ellipsis: true,
+  },
+  {
+    title: window.$t("lotCard.AvailablePlanData"),
+    dataIndex: "dataTotal",
+    align: "center",
+    ellipsis: true,
+  },
+  {
+    title: window.$t("lotCard.used"),
+    dataIndex: "usedBg",
+    align: "center",
+    ellipsis: true,
+  },
+  {
+    title: window.$t("lotCard.available"),
+    dataIndex: "usableBg",
+    align: "center",
+    ellipsis: true,
+  },
+  {
+    title: window.$t("lotCard.DefaultRate"),
+    dataIndex: "dataSpeed",
+    align: "center",
+    ellipsis: true,
+  },
+  {
+    title: window.$t("global.common.operations"),
+    dataIndex: "id",
+    slotName: "id",
+    align: "center",
+    width: 200,
+    fixed: "right",
+  },
+];
 
 export const columnsTrafficUse = [
-    { title: window.$t('lotCard.appName'), dataIndex: 'appName', align: 'center', },
-    { title: window.$t('lotCard.mcc'), dataIndex: 'mcc', align: 'center', width: 100 },
-    { title: window.$t('lotCard.qtaconsumption'), dataIndex: 'qtaconsumption', align: 'center', },
-    { title: window.$t('lotCard.time'), dataIndex: 'time', align: 'center', },
-]
+  {
+    title: window.$t("lotCard.appName"),
+    dataIndex: "appName",
+    align: "center",
+  },
+  {
+    title: window.$t("lotCard.mcc"),
+    dataIndex: "mcc",
+    align: "center",
+    width: 100,
+  },
+  {
+    title: window.$t("lotCard.qtaconsumption"),
+    dataIndex: "qtaconsumption",
+    align: "center",
+  },
+  { title: window.$t("lotCard.time"), dataIndex: "time", align: "center" },
+];
+
+export const SearchForm = [
+  {
+    type: "input",
+    label: "ICCID",
+    field: "source",
+    value: "", // 双向绑定的值
+  },
+  {
+    type: "select",
+    label: "来源",
+    field: "simType",
+    options: [], // 默认空,后面会通过字典加载
+    dict: "source",
+    value: "", // 双向绑定的值
+    width: "200",
+  },
+  {
+    type: "input",
+    label: "客户名称",
+    field: "source",
+    value: "", // 双向绑定的值
+  },
+  {
+    type: "input",
+    label: "IMSI",
+    field: "source",
+    value: "", // 双向绑定的值
+  },
+  {
+    type: "select",
+    label: "流量包状态",
+    field: "simType",
+    options: [], // 默认空,后面会通过字典加载
+    dict: "source",
+    value: "", // 双向绑定的值
+    width: "200",
+  },
+  {
+    type: "select",
+    label: "SIM状态",
+    field: "simType",
+    options: [], // 默认空,后面会通过字典加载
+    dict: "source",
+    value: "", // 双向绑定的值
+    width: "200",
+  },
+  {
+    type: "date-picker",
+    label: "SIM激活日期",
+    field: "simType",
+    options: [], // 默认空,后面会通过字典加载
+    dict: "source",
+    value: "", // 双向绑定的值
+    width: "200",
+  },
+  {
+    type: "date-picker",
+    label: "SIM关闭日期",
+    field: "simType",
+    options: [], // 默认空,后面会通过字典加载
+    dict: "source",
+    value: "", // 双向绑定的值
+    width: "200",
+  },
+  {
+    type: "input",
+    label: "IMSI所属供应商名称 ",
+    field: "simType",
+    options: [], // 默认空,后面会通过字典加载
+    dict: "source",
+    value: "", // 双向绑定的值
+    width: "200",
+  },
+];

+ 4 - 55
src/views/lotCard/cardList/index.vue

@@ -3,46 +3,9 @@
   <div class="container">
     <!-- 搜索条件区 -->
     <div class="search-section">
-      <a-form :model="searchForm"  layout="inline">
-        <a-form-item field="iccid" :label="$t('lotCard.iccid')">
-          <a-input v-model="searchForm.iccid" :placeholder="$t('lotCard.please') + $t('lotCard.iccid')" allow-clear />
-        </a-form-item>
-        <!--        主卡状态-->
-        <a-form-item field="iccid" :label="$t('lotCard.iccidType')">
-          <a-select v-model="value" :style="{ width: '240px' }" :placeholder="$t('lotCard.iccidTypeName')">
-            <a-option v-for="item of statusList" :value="item.id" :label="item.label" />
-          </a-select>
-        </a-form-item>
-        <!--        来源-->
-        <a-form-item field="iccid" :label="$t('lotCard.sourceCard')">
-          <a-select v-model="value" :style="{ width: '240px' }" :placeholder="$t('lotCard.sourceCardType')">
-            <a-option v-for="item of sourceList" :value="item.id" :label="item.label" />
-          </a-select>
-        </a-form-item>
-        <!--        创建时间-->
-        <a-form-item field="iccid" :label="$t('lotCard.statrt_time')">
-          <a-date-picker style="width: 200px;" ::placeholder="$t('lotCard.statrt_timeType')" />
-        </a-form-item>
-        <!--        更新时间-->
-        <a-form-item field="iccid" :label="$t('lotCard.Renewal_time')">
-          <a-date-picker style="width: 200px;" ::placeholder="$t('lotCard.Renewal_timeType')" />
-        </a-form-item>
-        <a-form-item>
-
-          <a-space>
-            <a-button type="primary">{{ $t('form.Search') }}</a-button>
-            <a-button>{{ $t('form.Reset') }}</a-button>
-          </a-space>
-        </a-form-item>
-      </a-form>
+       <Search :SearchForm="SearchForm"/>
     </div>
 
-    <!-- <div class="top-actions">
-      <a-space>
-        <a-button type="primary" @click="showAdd=true">{{ $t('form.Add') }}</a-button>
-      </a-space>
-    </div> -->
-
     <a-table row-key="iccid" :data="dataSource" :columns="columns" :pagination="false" :scroll="{ x: 'auto' }">
       <template #poolNum="{ record }">
         <span>{{ record.poolName }}</span>
@@ -72,19 +35,16 @@
 
 <script setup>
 import { onMounted, ref, getCurrentInstance, h } from "vue";
-import { columns } from "./config";
+import { columns,SearchForm } from "./config";
 import { cardInfoList } from "@/api/path/lotCard.api"
 import trafficUseDialog from "./trafficUseDialog.vue";
 import { Getdictionary } from '@/mixins/index.js'
 import {sanitizeObject} from '@/utils/utils'
 import Add from './add.vue'
+import Search from '@/components/Search/index.vue'
 const { proxy } = getCurrentInstance()
 import { useI18n } from 'vue-i18n'
 const { t } = useI18n();
-const searchForm = ref({
-  "iccid": "",
-});
-
 const statusList = ref([]);
 const sourceList = ref([]);
 const serviceList = ref([]);
@@ -103,7 +63,6 @@ const intData = async () => {
   const param = {
     current: pagination.value.current,
     size: pagination.value.pageSize,
-    ...searchForm.value,
   }
   const { data } = await cardInfoList(param)
   dataSource.value = (data.records || []).map((item, index) => {
@@ -113,10 +72,10 @@ const intData = async () => {
     return {
       ...sanitizedItem,
       payType: payType,
-      forewarningStatus: '正常',
       SilenceEndtime: '一个月',
       usedBg: '0',
       usableBg: '0',
+      DatapackageStatus:item.dataPackage[0]?.status,
       dataUsage: item.dataPackage[0]?.dataUsage?item.dataPackage[0]?.dataUsage:'0' + '/MB',
       dataTotal: item.dataPackage[0]?.dataTotal?item.dataPackage[0]?.dataTotal:'0' + '/MB',
     }
@@ -140,16 +99,6 @@ const pagesChange = (size) => {
   intData()
 }
 
-
-const handleSearch = () => {
-  formRef.value.validate((errors) => {
-    if (!errors) {
-      intData()
-    }
-  });
-}
-
-
 // 获取字典
 const handleDictValue = async () => {
   // sourceList.value = await Getdictionary('source')

+ 58 - 20
src/views/order/BuyCard/detaile.vue

@@ -48,24 +48,31 @@
             <div class="detail-item-box">
                 <div class="detail-item">
                     <div class="item-label">{{ $t('order.CardNum') }}</div>
-                    <div class="item-content">{{ dataDetail.length<=10?dataDetail.length:tableDataList.length }}
-                        <a-button type="primary" @click="showCard = true" style="margin-left:10px;"
+                    <div class="item-content">{{ tableDataList.length == 0 ? dataDetail.length : tableDataList.length }}
+                        <a-button type="primary" :disabled="show" @click="showCard = true" style="margin-left:10px;"
                             v-if="userType == 1 && FormDataList.moderationStatus == 2">{{
                                 $t('order.AllocationCardNumber') }}</a-button>
                     </div>
                 </div>
             </div>
         </div>
-        <div class="detail-table">
+        <div class="detail-table" v-if="!show">
             <a-table :columns="columnsDetail" @page-change="evChangePage" :data="dataDetail"
                 :pagination="dataDetail.length == 10 ? pagination : false" />
         </div>
 
+        <div class="progress" v-if="show">
+            <div class="cusrte">
+                <a-progress type="circle" :percent="(schedule / 100)" size="large" />
+            </div>
+        </div>
+
         <template #footer>
             <a-button @click="cancel">{{ $t('form.Cancel') }}</a-button>
         </template>
     </a-modal>
 
+
     <!-- 分配卡号 -->
     <a-modal v-model:visible="showCard" :title="$t('order.AllocationCardNumber')"
         @cancel="closeModal(showCard, FormDataList)" @before-ok="showCard = false" :okText="$t('form.Confirm')"
@@ -85,7 +92,7 @@
 
 <script setup>
 import { ref, onMounted, toRefs, toRef, watch } from 'vue';
-import { AcquireOrdertariff, DistributionCard, ReturntheOrderCard } from '@/api/path/order'
+import { AcquireOrdertariff, DistributionCard, ReturntheOrderCard,GuideCardProgress } from '@/api/path/order'
 import { Message } from '@arco-design/web-vue';
 import Upload from "@/components/upload/index.vue";
 import { Getdictionary } from '@/mixins/index.js'
@@ -112,8 +119,10 @@ const state = ref({
     res2: [],
     res3: [],
     userType: JSON.parse(localStorage.getItem('user_login_information'))?.userType, // 1平台 2用户
+    show: false,
+    schedule: 0,// 进度
 })
-const { tariffForm, showCard, res1, res2, res3, userType } = toRefs(state.value)
+const { tariffForm, showCard, res1, res2, res3, userType, show, schedule } = toRefs(state.value)
 const columnsDetail = [{ title: 'ICCID', dataIndex: 'iccid' }, { title: t('order.CardStatus'), dataIndex: 'status' }, { title: t('order.CreationTime'), dataIndex: 'createdAt' }
 ]
 // 初始数据
@@ -126,6 +135,9 @@ const pagination = ref({
     total: 0
 })
 
+// 定时器ID
+let timer;
+
 // 分配卡号
 const customRequest = (options) => {
     const formData = new FormData();
@@ -134,19 +146,8 @@ const customRequest = (options) => {
     DistributionCard(formData).then(res => {
         if (res.code == 200) {
             Message.success(res.message)
-            if (res.data[0].length <= 10) {
-                res.data[0].forEach(val => {
-                    dataDetail.value.push({ iccid: val, status: val.status == 1 ? t('order.normal') : t('order.unsubscribe') })
-                })
-            } else {
-                // 更新完整数据
-                tableDataList.value = res.data[0];
-
-                // 更新总条目数
-                pagination.value.total = res.data[0].length;
-
-                updatePageData();
-            }
+            showCard.value = false
+            CardProgress()
         }
     })
 }
@@ -161,6 +162,8 @@ const closeModal = () => {
 
 watch(() => FormDataList.value, val => {
     if (Object.keys(val).length === 0) return
+    tableDataList.length = []
+    dataDetail.value = []
     pagination.value.total = 0
     pagination.value.current = 1
     pagination.value.pageSize = 10
@@ -173,7 +176,6 @@ watch(() => FormDataList.value, val => {
     })
     dataDetail.value = []
     ReturntheOrderCard({ id: val.id }).then(res => {
-        console.log(res);
         if (res.data.length <= 10) {
             dataDetail.value.push(...res.data.map(val => ({ ...val, status: val.status == 1 ? t('order.normal') : t('order.unsubscribe') })))
         } else {
@@ -186,7 +188,7 @@ watch(() => FormDataList.value, val => {
             updatePageData();
         }
     })
-}, { deep: true })
+}, { immediate: true })
 
 const evChangePage = (page) => {
     pagination.value.current = page
@@ -205,6 +207,36 @@ const DownloadSampleFile = () => {
     downloadFile(['ICCID'], [['8968099000011939']])
 }
 
+// 导卡进度
+const CardProgress = async () => {
+    let res = await GuideCardProgress({ id: FormDataList.value.id })
+    if (res.code === 200) {
+        show.value = res.data !== 0 && res.data !== 100;
+        schedule.value = res.data;
+    }
+}
+// 监听导卡进度
+watch(() => modelValue.value, val => {
+    if (val) {
+        CardProgress()
+    } else {
+        clearInterval(timer);
+    }
+}, { immediate: true })
+
+watch(() => schedule.value, val => {
+     // 清除旧的定时器(如果存在)
+     if (timer) {
+        clearInterval(timer);
+    }
+    timer = setInterval(() => {
+        CardProgress();
+        if (val === 100) {
+            clearInterval(timer);
+        }
+    }, 10000);
+})
+
 onMounted(async () => {
     res1.value = await Getdictionary('Billingcycle')
     res2.value = await Getdictionary('billingMethod')
@@ -212,6 +244,12 @@ onMounted(async () => {
 })
 </script>
 <style scoped lang="less">
+.progress {
+    margin: 30px auto;
+    display: flex;
+    justify-content: center;
+}
+
 .detail-box {
     .detail-item-box {
         display: flex;

+ 7 - 7
src/views/system/menu/index.vue

@@ -49,8 +49,8 @@
             <MonacoEditor v-model="refData.fromData.name" />
           </a-form-item>
 
-          <a-form-item field="menu_id" label="上级路由" :validate-trigger="['change', 'input', 'blur']">
-            <a-tree-select v-model="refData.fromData.menu_id" placeholder="一级菜单" :data="refData.menuTree"
+          <a-form-item field="menuId" label="上级路由" :validate-trigger="['change', 'input', 'blur']">
+            <a-tree-select v-model="refData.fromData.menuId" placeholder="一级菜单" :data="refData.menuTree"
               :allow-clear="true" :field-names="{
                 children: 'children',
                 title: 'name',
@@ -63,7 +63,7 @@
             <a-input v-model="refData.fromData.path" placeholder="请输入路由标识" />
           </a-form-item>
 
-          <a-form-item v-if="!refData.fromData.menu_id" field="icon" label="路由图标"
+          <a-form-item v-if="!refData.fromData.menuId" field="icon" label="路由图标"
             :rules="[{ required: true, message: '请选择路由图标' }]" :validate-trigger="['change', 'input', 'blur']">
             <a-input v-model="refData.fromData.icon" placeholder="请设置菜单图标">
               <template v-if="refData.fromData.icon" #suffix>
@@ -172,7 +172,7 @@ const refData = reactive({
   fromData: {
     name: "",
     parentId: undefined,
-    menu_id: undefined,
+    menuId: undefined,
     type: "0",
     url: "",
     sortNumber: 99,
@@ -186,9 +186,9 @@ const refData = reactive({
 const menuTreeList = ref([])
 
 const isUrlView = computed(() => {
-  // if (refData.fromData.menu_id) {
-  //   const obj =  menuTreeList.value.find(item => item.id == refData.fromData.menu_id)
-  //   return refData.fromData.menu_id && ["1", "2"].includes(obj.type);
+  // if (refData.fromData.menuId) {
+  //   const obj =  menuTreeList.value.find(item => item.id == refData.fromData.menuId)
+  //   return refData.fromData.menuId && ["1", "2"].includes(obj.type);
   // }
   // return false;
   return true;

+ 0 - 16
src/views/tariffManagement/customer/index.vue

@@ -80,16 +80,11 @@ const loading = ref(false);
 
 const columns = computed(() => [
   { title: t('customer.id'), dataIndex: 'id', align: 'center', ellipsis: true },
-  // {title: t('customer.customerCode'), dataIndex: 'customerCode'},
   { title: t('customer.customerName'), dataIndex: 'name', align: 'center', ellipsis: true },
   { title: t('customer.userAdmin'), dataIndex: 'username', align: 'center' },
-  // {title: t('customer.accountBalance'), dataIndex: 'accountBalance'},
-  // {title: t('customer.paymentMethodName'), dataIndex: 'paymentMethod'},
   { title: t('customer.customerStatus'), slotName: 'state', align: 'center', ellipsis: true },
   { title: 'app_key  ', dataIndex: 'appKey', align: 'center', ellipsis: true },
   { title: 'app_secret', dataIndex: 'appSecret', align: 'center', ellipsis: true },
-  // {title: t('customer.validPeriod'), dataIndex: 'validPeriod'},
-  // {title: t('customer.activeCards'), dataIndex: 'activeCards'},
   { title: t('customer.userTypeName'), align: 'center', dataIndex: 'userType', ellipsis: true },
   { title: t('customer.startTime'), dataIndex: 'createdAt', align: 'center', ellipsis: true },
   { title: t('customer.updateTime'), dataIndex: 'updatedAt', align: 'center', ellipsis: true },
@@ -174,13 +169,6 @@ const handleEdit = async (record) => {
   }
 };
 
-const handleRecharge = (record) => {
-  Message.success(`为客户 ${record.customerName} 充值`);
-};
-
-const handlePackageManagement = (record) => {
-  Message.success(`管理客户 ${record.customerName} 的套餐`);
-};
 
 const handleNewCustomerSubmit = (formData) => {
   if (formData) {
@@ -202,10 +190,6 @@ const resetSearch = () => {
   fetchCustomerList();
 };
 
-const handleBatchDelete = () => {
-  Message.warning(t('customer.batchDeleteWarning'));
-};
-
 const getStatusColor = (state) => {
   const stateColors = {
     '1': 'green',    // 正常 - 绿色

+ 3 - 2
vite.config.js

@@ -61,9 +61,10 @@ export default defineConfig({
         hmr: true,
         proxy: {
             "/api": {
-                // target: "http://sim.nanodreamtech.com",
+                target: "http://sim.nanodreamtech.com",
+                // target:"http://192.168.0.78:3001",// 果本地端口
                 // target: "http://127.0.0.1:3001",
-                target: "http://sim.ainets.net",
+                // target: "http://sim.ainets.net",
                 changeOrigin: true,
                 ws: true,
                 secure: true,