Переглянути джерело

Merge branch 'main' of http://47.98.54.97:8080/mirendemianbaona/nc-admin into dev-dy

duanyan 5 місяців тому
батько
коміт
0742d8a489

+ 10 - 0
src/api/path/lotCard.api.js

@@ -43,4 +43,14 @@ export function orderCancel(param) {
 // 取消订单订单
 export function orderFlowData(params) {
   return service.get("/admin/sim/orderFlowData", { params });
+}
+
+// 查询订单日志
+export function getOrderLogsList(params) {
+  return service.post("/metadata/getOrderLogsList", params);
+}
+
+// 获取流量包数据
+export function getDataPlanList(params) {
+  return service.post("/metadata/getDataPlanList", params);
 }

+ 88 - 0
src/components/XmSelect/index.vue

@@ -0,0 +1,88 @@
+<template>
+    <a-select :style="{ width: '320px' }" v-model="selectValue" :placeholder="placeholder" @change="selectChange">
+        <a-option v-for="item in selectList" :key="item.value" :value="item[selectOpiton.value]"
+            :label="item[selectOpiton.label]"></a-option>
+    </a-select>
+</template>
+<script setup>
+import { onMounted, ref, computed, watch, h } from "vue";
+import _ from 'lodash'
+
+const props = defineProps({
+    dataList: {
+        type: Array,
+
+    },
+    placeholder: {
+        type: String,
+        default: "请输入"
+    },
+    dictKey: {
+        type: String
+    },
+    modelValue: {
+        type: [String, Number],
+        default: ""
+    },
+    selectType: {
+        type: [String, Number],
+        default: 1
+    },
+    // 下拉框的label及value
+    selectOpiton: {
+        type: Object,
+        default: () => ({
+            label: 'label',
+            value: 'id'
+        })
+    },
+    listRequest: {
+        type: Function,
+    },
+
+});
+
+
+const emits = defineEmits(['update:modelValue', 'change'])
+
+const selectList = computed(() => {
+
+    if (props.selectType == 1) {
+        return props.dataList
+    }
+    if (props.selectType == 2) {
+        props.listRequest.then(res => {
+            const data = res.data
+
+            if (Array.isArray(data) && data.length > 0) {
+                return data
+            }
+            if (data.records && Array.isArray(data.records) && data.records.length > 0) {
+                return data.records
+            }
+        })
+        return []
+    }
+    return []
+
+})
+
+/**
+ * 双向绑定的值
+ */
+const selectValue = computed(() => {
+    return props.modelValue || ""
+})
+
+
+const selectChange = (data) => {
+    const val = props.selectOpiton.value
+    const item = _.find(selectList.value, [val, data])
+    if (val) {
+        emits('update:modelValue', item[val])
+    }
+
+    emits('change', item)
+}
+
+</script>

+ 4 - 2
src/hooks/enum.js

@@ -4,7 +4,7 @@ export const enum_dict = {
     SUBSCRIPTION_RELATIONSHIP_STATUS: "subscription _relationship_status", // 订阅关系状态
     MAIN_CARD_STATUS: "main_card_status", // 主卡状态
     PACKAGE_TRIFF_PLAN_STATUS: "package_tariff_plan_status", // 套餐资费计划判断状态
-    SUPPLIER_SOURCE: "supplier_source", // 来源(订单管理列表)
+    SUPPLIER_SOURCE: "supplier_source", // 来源(订单管理列表-运营商)
     TRAFFI_CTYPE: "TrafficType", // 流量类型
     SOURCE: "source", // 来源(资费列表)
     CARD_TYPE: "card_type", // 卡类型
@@ -14,10 +14,12 @@ export const enum_dict = {
     BILLING_TYPE: "BillingType", // 计费分类
     BILLING_METHOD: "billingMethod", // 计费方式
     SETTLEMENT_CYCLE: "settlementCycle", // 结算周期
-    TRAFFIC_USAGE_TYPE: "trafficPoolType", // 流量池类型
+    TRAFFIC_POOL_TYPE: "trafficPoolType", // 流量池类型
     TRAFFIC_USAGE_TYPE: "traffic_usage_type", // 流量使用限制类型
     CYCLE_TYPE: "cycle_type", // 周期类型
     ACTIVATION_PACKAGE: "activation_package_method", // 激活卡套餐方法
     FLOW_PACKET_TYPE: "flow_packet_type", // 流量包类型
     DEDUCTION_MODEL: "deduction_model", // 套餐收费方式
+    FLOW_PERIOD: "flow_period", // 流量包套餐时长
+    ACTIVATE_METHOD: "activate_method", // 激活方式-激活计费方式
 };

+ 2 - 0
src/i18n/zh/flowPool.js

@@ -19,6 +19,8 @@ export default {
     totalFlow: "已使用流量/总流量",
     warnStatus: "预警状态",
     exceededFlow: "已超流量",
+    poolSize: "池大小",
+    userId: "用户ID",
 
     // 预警
     proportion: "总用量占比",

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

@@ -84,4 +84,7 @@ export default {
     mcc: '国家',
     appName: '应用程序名称',
 
+    // 卡-订单
+    orderType: "订单状态"
+
 }  

+ 8 - 3
src/store/modules/systemStore.js

@@ -13,7 +13,7 @@ const INITIALIZE = {
   stsClientInfo: {},
 };
 try {
-  const  SYSTEM_STORE = getLocalStorage("SYSTEM_STORE")
+  const SYSTEM_STORE = getLocalStorage("SYSTEM_STORE")
   for (const key in SYSTEM_STORE) {
     const value = getLocalStorage(key)
     if (value) INITIALIZE[key] = value
@@ -28,7 +28,7 @@ export const useSystemStore = defineStore({
     ...INITIALIZE,
   }),
   getters: {
-    getLocalLoading(){
+    getLocalLoading() {
       return this.local_loading
     },
     getToken() {
@@ -82,7 +82,7 @@ export const useSystemStore = defineStore({
             return infoData
           }
           getInfoData(info)
-        
+
           const client = new windowVar.OSS({
             ...this.stsClientInfo,
             refreshSTSToken: async () => {
@@ -110,6 +110,11 @@ export const useSystemStore = defineStore({
       };
       return stsFn
     },
+    getRole() {
+      if (this.role) return this.role;
+      this.role = window.localStorage?.role || "";
+      return this.role;
+    },
   },
   actions: {
     localLoading(value = false) {

+ 1 - 1
src/views/flowPool/config.js

@@ -1,12 +1,12 @@
 export const columns = [
     { title: window.$t('flowPool.poolNumber'), dataIndex: 'poolNumber', align: 'center', width: 200 },
     { title: window.$t('flowPool.label'), dataIndex: 'label', align: 'center', width: 200 },
+    { title: window.$t('flowPool.userId'), dataIndex: 'user_id', align: 'center', width: 200 },
     { title: window.$t('flowPool.trafficPoolType'), dataIndex: 'trafficPoolType', align: 'center', width: 200 },
     { title: window.$t('flowPool.trafficPoolStatus'), dataIndex: 'trafficPoolStatus', align: 'center', width: 200 },
     { title: window.$t('flowPool.cardFlow'), dataIndex: 'cardFlow', align: 'center', width: 200 },
     { title: window.$t('flowPool.UsedMonth'), dataIndex: 'UsedMonth', align: 'center', width: 200 },
     { title: window.$t('flowPool.surplusFlow'), dataIndex: 'surplusFlow', align: 'center', width: 200 },
-    // { title: window.$t('flowPool.warnStatus'), dataIndex: 'warnStatus', align: 'center', width: 200 },
     { title: window.$t('flowPool.exceededFlow'), dataIndex: 'exceededFlow', align: 'center', width: 200 },
     { title: window.$t('flowPool.source'), dataIndex: 'sourceName', align: 'center', width: 200 },
     { title: window.$t('flowPool.cardRariffName'), dataIndex: 'cardRariffName', align: 'center', width: 200 },

+ 16 - 0
src/views/flowPool/customerFlowPool/config.js

@@ -0,0 +1,16 @@
+export const columns = [
+    { title: window.$t('flowPool.poolNumber'), dataIndex: 'poolNumber', align: 'center', width: 200 },
+    { title: window.$t('flowPool.label'), dataIndex: 'label', align: 'center', width: 200 },
+    { title: window.$t('flowPool.trafficPoolType'), dataIndex: 'trafficPoolType', align: 'center', width: 200 },
+    { title: window.$t('flowPool.trafficPoolStatus'), dataIndex: 'trafficPoolStatus', align: 'center', width: 200 },
+    { title: window.$t('flowPool.cardFlow'), dataIndex: 'cardFlow', align: 'center', width: 200 },
+    { title: window.$t('flowPool.UsedMonth'), dataIndex: 'UsedMonth', align: 'center', width: 200 },
+    { title: window.$t('flowPool.surplusFlow'), dataIndex: 'surplusFlow', align: 'center', width: 200 },
+    // { title: window.$t('flowPool.warnStatus'), dataIndex: 'warnStatus', align: 'center', width: 200 },
+    { title: window.$t('flowPool.exceededFlow'), dataIndex: 'exceededFlow', align: 'center', width: 200 },
+    { title: window.$t('flowPool.source'), dataIndex: 'sourceName', align: 'center', width: 200 },
+    { title: window.$t('flowPool.cardRariffName'), dataIndex: 'cardRariffName', align: 'center', width: 200 },
+    { title: window.$t('flowPool.cardNum'), dataIndex: 'cardNum', align: 'center', width: 200 },
+    { title: window.$t('flowPool.totalFlow'), dataIndex: 'totalFlow', align: 'center', width: 200 },
+    { title: window.$t('flowPool.updated_at'), dataIndex: 'updated_at', align: 'center', width: 200 },
+]

+ 304 - 0
src/views/flowPool/customerFlowPool/index.vue

@@ -0,0 +1,304 @@
+<!-- 流量池 -->
+<template>
+    <div class="container">
+        <div class="head-title">
+            <span>{{ route.meta.title }} </span>
+            <span class="head-title-right">
+            </span>
+        </div>
+        <!-- 搜索条件区 -->
+        <div class="search-section">
+            <a-form :model="searchForm" ref="formRef" layout="inline">
+                <a-form-item field="label" :label="$t('flowPool.label')">
+                    <a-input v-model="searchForm.label" :placeholder="$t('lotCard.please') + $t('flowPool.label')"
+                        allow-clear />
+                </a-form-item>
+                <a-form-item field="traffic_pool_type" :label="$t('flowPool.trafficPoolType')">
+                    <a-select v-model="searchForm.traffic_pool_type" style="width: 200px;"
+                        :placeholder="$t('form.cardForm.pleaseSelect') + $t('flowPool.trafficPoolType')">
+                        <a-option v-for=" item in typeList" :key="item.id" :value="item.value">{{ item.label
+                            }}</a-option>
+                    </a-select>
+                </a-form-item>
+                <a-form-item>
+                    <a-space>
+                        <a-button type="primary" @click="handleSearch">{{ $t('form.Search') }}</a-button>
+                        <a-button @click="resetSearch">{{ $t('form.Reset') }}</a-button>
+                    </a-space>
+                </a-form-item>
+            </a-form>
+        </div>
+        <a-table row-key="id" :data="dataSource" :columns="columns" :pagination="pagination" :scroll="{ x: 'auto' }"
+            @page-change="evChangePage">
+            <template #id="{ record }">
+            </template>
+
+        </a-table>
+
+
+    </div>
+</template>
+
+<script setup>
+import { onMounted, ref, reactive, getCurrentInstance, nextTick } from "vue";
+import { useRoute } from "vue-router";
+import { columns } from "./config";
+import { Message, Notification } from '@arco-design/web-vue'
+import { deleteTrafficPool, addTrafficPool, updateTrafficPool, trafficPoolList } from "@/api/path/flowPool.api"
+import { tariffList } from "@/api/path/tariffManagement.api"
+import { orderCancel } from "@/api/path/lotCard.api"
+import { enum_dict } from "@/hooks/enum";
+import { useSystemStore } from "@/store/modules/systemStore"
+
+
+const systemStore = useSystemStore()
+const role = ref(systemStore.getRole)
+const { proxy } = getCurrentInstance()
+const formRef = ref()
+const searchForm = ref({
+    "label": "",
+    "traffic_pool_type": ""
+});
+
+const typeList = ref([]);
+const trafficList = ref([]);
+const sourceList = ref([]);
+const dataSource = ref([]);
+const route = useRoute();
+const pagination = ref({
+    total: 0,
+    pageSize: 10,
+    current: 1,
+})
+
+
+
+
+
+const rowSelection = reactive({
+    type: 'checkbox',
+    showCheckedAll: true,
+    onlyCurrent: false,
+});
+const selectedKeys = ref([])
+
+
+
+const intData = async () => {
+    const param = {
+        current: pagination.value.current,
+        size: pagination.value.pageSize,
+        ...searchForm.value,
+    }
+    const { data } = await trafficPoolList(param)
+    dataSource.value = (data.records || []).map((item, index) => {
+        const trafficPoolType = typeList.value.find(val => val.value == item.traffic_pool_type)?.label
+        const trafficPoolStatus = trafficList.value.find(val => val.value == item.status)?.label
+        const sourceName = sourceList.value.find(val => val.value == item.source)?.label
+        return {
+            ...item,
+            sourceName,// 运营商名称
+            trafficPoolType,
+            trafficPoolStatus,
+            poolNumber: "NR0" + (index + 1),
+            cardRariffName: "监控1G月租",
+            cardFlow: "1G/月",
+            cardNum: "11/100",
+            UsedMonth: "1.00G",
+            surplusFlow: "99.0G",
+            totalFlow: "100.0G",
+            exceededFlow: "--",
+        }
+    })
+    pagination.value.total = data.total
+}
+
+
+
+
+const evChangePage = (page) => {
+    pagination.value.current = page
+    intData()
+}
+
+const handleSearch = () => {
+    intData()
+}
+const resetSearch = () => {
+    searchForm.value.label = ''
+    intData()
+}
+
+
+// --------------------------------------------------------
+// 获取字典
+const handleDictValue = () => {
+    const dictList = JSON.parse(window.localStorage.getItem('dictList')) ?? []
+    sourceList.value = dictList.filter((item) => item.type_key == enum_dict.SOURCE)
+    trafficList.value = dictList.filter((item) => item.type_key == enum_dict.TRAFFIC_PACKET_STATUS)
+    typeList.value = dictList.filter((item) => item.type_key == enum_dict.TRAFFIC_POOL_TYPE)
+}
+
+
+
+
+
+onMounted(() => {
+    handleDictValue()
+    intData()
+})
+
+
+
+</script>
+
+<style scoped lang="less">
+.m-r-10 {
+    margin-right: 10px;
+}
+
+.head-title-right {}
+
+.search-section {
+    margin-top: 20px;
+    margin-bottom: 20px;
+}
+
+.container {
+    .head-title {
+        display: flex;
+        justify-content: space-between;
+    }
+
+    .form-row {
+        display: flex;
+
+        .form-row-col {
+            width: 25%;
+            display: flex;
+            align-items: center;
+
+            .form-row-label {
+                width: 120px;
+                text-align: right;
+            }
+        }
+    }
+}
+
+silent-expire-alarm {
+    padding: 20px !important;
+    // background: #fcf;
+}
+
+.search-section {
+    margin-bottom: 20px;
+}
+
+.audit-btn {
+    margin-bottom: 10px;
+}
+
+
+.echarts-box {
+    // width: 100%;
+    display: flex;
+    justify-content: center;
+    overflow: hidden;
+
+    .chart-dom {
+        width: 700px !important;
+        height: 400px !important;
+    }
+}
+
+.form-item-space-item {
+    background-color: #f2f3f5;
+    display: flex;
+    align-items: center;
+    font-size: 14px;
+}
+
+.form-pool-tit {
+    display: flex;
+    align-items: center;
+    margin-bottom: 10px;
+
+    .pool-icon {
+        margin-right: 10px;
+        width: 4px;
+        height: 16px;
+        background: #1B5DF8;
+        font-size: 14px;
+        color: #6C6E70;
+        font-family: PingFang SC;
+
+    }
+}
+
+
+.export-box {
+    .export-box-item {
+        .box-item-title {
+            display: flex;
+            align-items: center;
+            font-family: PingFang SC;
+            font-size: 16px;
+            font-weight: 600;
+            line-height: 24px;
+            color: rgba(0, 0, 0, 0.85);
+            margin-bottom: 10px;
+
+            .title-icon {
+                margin-right: 10px;
+                width: 4px;
+                height: 16px;
+                background: #1B5DF8;
+
+            }
+        }
+
+        .box-item-content {
+            .item-txt {
+                display: flex;
+                align-items: center;
+                margin-bottom: 10px;
+
+                .item-txt-title {
+                    width: 300px;
+                    text-align: right;
+                    margin-right: 10px;
+                }
+
+                .item-txt-text {
+                    font-family: PingFang SC;
+                    font-size: 14px;
+                    font-weight: 400;
+                    line-height: 22px;
+                    text-align: left;
+                    color: #1B5DF8;
+
+                }
+            }
+
+            .export-status {
+                font-family: PingFang SC;
+                font-size: 14px;
+                font-weight: 400;
+                line-height: 22px;
+                text-align: left;
+                color: rgba(51, 51, 51, 1);
+                display: flex;
+                align-items: center;
+
+                .status-icon {
+                    width: 6px;
+                    height: 6px;
+                    border-radius: 50%;
+                    margin-right: 10px;
+                }
+            }
+        }
+    }
+}
+</style>

+ 29 - 27
src/views/flowPool/index.vue

@@ -4,10 +4,10 @@
         <div class="head-title">
             <span>{{ route.meta.title }} </span>
             <span class="head-title-right">
-                <a-popconfirm :content="$t('lotCard.confirmTitleCancelOrder')" :ok-text="$t('form.Confirm')"
+                <!-- <a-popconfirm :content="$t('lotCard.confirmTitleCancelOrder')" :ok-text="$t('form.Confirm')"
                     :cancel-text="$t('form.Cancel')" @ok="handleUnsubscribeDialog(record)">
                     <a-button type="primary">{{ $t('lotCard.titleCancelOrder') }}</a-button>
-                </a-popconfirm>
+                </a-popconfirm> -->
             </span>
         </div>
         <!-- 搜索条件区 -->
@@ -17,14 +17,6 @@
                     <a-input v-model="searchForm.label" :placeholder="$t('lotCard.please') + $t('flowPool.label')"
                         allow-clear />
                 </a-form-item>
-                <a-form-item field="trafficPoolType" :label="$t('flowPool.trafficPoolType')">
-                    <a-select v-model="formState.traffic_pool_type"
-                        :placeholder="$t('form.cardForm.pleaseSelect') + $t('flowPool.trafficPoolType')"
-                        style="width: 170px;">
-                        <a-option v-for=" item in typeList" :key="item.id" :value="item.value">{{ item.label
-                            }}</a-option>
-                    </a-select>
-                </a-form-item>
                 <a-form-item>
                     <a-space>
                         <a-button type="primary" @click="handleSearch">{{ $t('form.Search') }}</a-button>
@@ -35,7 +27,7 @@
         </div>
 
         <div class="audit-btn">
-            <a-button @click="dictShowModel(1, null)" type="text">
+            <a-button @click="dictShowModel(1, null)" type="text" v-if="role == 1">
                 <template #icon>
                     <icon-plus-circle />
                 </template>
@@ -45,27 +37,29 @@
             </a-button>
         </div>
 
-        <a-table row-key="id" :data="dataSource" :columns="columns" :pagination="pagination"
-            :rowSelection="rowSelection" v-model:selected-keys="selectedKeys" :scroll="{ x: 'auto' }">
+        <a-table row-key="id" :data="dataSource" :columns="columns" :pagination="pagination" :scroll="{ x: 'auto' }"
+            @page-change="evChangePage">
             <template #id="{ record }">
                 <!-- 修改 -->
-                <a class="a-link" href="javascript:;" style="margin-right: 1rem" @click="dictShowModel(2, record)">{{
-                    $t('form.Edit') }}</a>
+                <a class="a-link" href="javascript:;" style="margin-right: 1rem" @click="dictShowModel(2, record)"
+                    v-if="role == 1">{{
+                        $t('form.Edit') }}</a>
                 <!-- 取消订单-退订 -->
-                <a-popconfirm :content="$t('lotCard.confirmTitleCancelOrder')" :ok-text="$t('form.Confirm')"
+                <!-- <a-popconfirm :content="$t('lotCard.confirmTitleCancelOrder')" :ok-text="$t('form.Confirm')"
                     :cancel-text="$t('form.Cancel')" @ok="handleUnsubscribeDialog(record)">
                     <a class="a-link" href="javascript:;" style="margin-right: 1rem">{{ $t('lotCard.titleCancelOrder')
                         }}</a>
-                </a-popconfirm>
+                </a-popconfirm> -->
                 <!-- 删除 -->
                 <a-popconfirm :content="$t('form.Delete')" :ok-text="$t('form.Confirm')"
                     :cancel-text="$t('form.Cancel')" @ok="handleDel(record.id)">
-                    <a class="a-link" href="javascript:;" style="margin-right: 1rem">{{ $t('form.Delete')
+                    <a class="a-link" href="javascript:;" style="margin-right: 1rem" v-if="role == 1">{{
+                        $t('form.Delete')
                         }}</a>
                 </a-popconfirm>
                 <!-- 导卡 -->
-                <a class="a-link" href="javascript:;" style="margin-right: 1rem" @click="dictShowModel(3, record)">{{
-                    $t('flowPool.exportCard') }}</a>
+                <!-- <a class="a-link" href="javascript:;" style="margin-right: 1rem" @click="dictShowModel(3, record)">{{
+                    $t('flowPool.exportCard') }}</a> -->
             </template>
 
         </a-table>
@@ -97,13 +91,13 @@
                                     }}</a-option>
                             </a-select>
                         </a-form-item>
-                        <a-form-item :label="$t('flowPool.trafficPoolType')" field="traffic_pool_type">
-                            <a-select v-model="formState.traffic_pool_type"
+                        <!-- <a-form-item :label="$t('flowPool.trafficPoolType')" field="traffic_pool_type">
+                            <a-select v-model="formState.traffic_pool_type" disabled
                                 :placeholder="$t('form.cardForm.pleaseSelect') + $t('flowPool.trafficPoolType')">
                                 <a-option v-for=" item in typeList" :key="item.id" :value="item.value">{{ item.label
                                     }}</a-option>
                             </a-select>
-                        </a-form-item>
+                        </a-form-item> -->
                         <a-form-item :label="$t('flowPool.simRariff')" field="sim_tariff_id">
                             <a-select v-model="formState.sim_tariff_id"
                                 :placeholder="$t('form.cardForm.pleaseSelect') + $t('flowPool.simRariff')">
@@ -118,7 +112,7 @@
                         <a-form-item>
                             <a-button type="primary" html-type="submit" style="margin-right: 10px;">{{
                                 $t('form.Confirm')
-                                }}</a-button>
+                            }}</a-button>
                             <a-button @click="resetForm">{{ $t('form.Cancel') }}</a-button>
                         </a-form-item>
                     </a-form>
@@ -300,12 +294,16 @@ import { deleteTrafficPool, addTrafficPool, updateTrafficPool, trafficPoolList }
 import { tariffList } from "@/api/path/tariffManagement.api"
 import { orderCancel } from "@/api/path/lotCard.api"
 import { enum_dict } from "@/hooks/enum";
+import { useSystemStore } from "@/store/modules/systemStore"
 
 
+const systemStore = useSystemStore()
+const role = ref(systemStore.getRole)
 const { proxy } = getCurrentInstance()
 const formRef = ref()
 const searchForm = ref({
     "label": "",
+    "traffic_pool_type": "1"
 });
 
 const dataSource = ref([]);
@@ -319,6 +317,7 @@ const pagination = ref({
 
 
 
+
 const rowSelection = reactive({
     type: 'checkbox',
     showCheckedAll: true,
@@ -372,13 +371,16 @@ const handleDel = async (id) => {
     }
 };
 
-//
+const evChangePage = (page) => {
+    pagination.value.current = page
+    intData()
+}
 
 const handleSearch = () => {
     intData()
 }
 const resetSearch = () => {
-    proxy.$refs.formRef.resetFields()
+    searchForm.value.label = ''
     intData()
 }
 
@@ -455,7 +457,7 @@ const formState = ref({
     // 流量包名称
     "label": "",
     // 流量池类型: 1: 前流量池 2: 后流量池
-    "traffic_pool_type": "",
+    "traffic_pool_type": "1",
     // 来源
     "source": "",
     // 流量包状态:1:正常(发布计划状态)2:线下暂停销售

+ 830 - 0
src/views/flowPool/rearFlowPool/index.vue

@@ -0,0 +1,830 @@
+<!-- 后流量池 -->
+<template>
+    <div class="container">
+        <div class="head-title">
+            <span>{{ route.meta.title }} </span>
+            <span class="head-title-right">
+                <!-- <a-popconfirm :content="$t('lotCard.confirmTitleCancelOrder')" :ok-text="$t('form.Confirm')"
+                    :cancel-text="$t('form.Cancel')" @ok="handleUnsubscribeDialog(record)">
+                    <a-button type="primary">{{ $t('lotCard.titleCancelOrder') }}</a-button>
+                </a-popconfirm> -->
+            </span>
+        </div>
+        <!-- 搜索条件区 -->
+        <div class="search-section">
+            <a-form :model="searchForm" layout="inline">
+                <a-form-item field="label" :label="$t('flowPool.label')">
+                    <a-input v-model="searchForm.label" :placeholder="$t('lotCard.please') + $t('flowPool.label')"
+                        allow-clear />
+                </a-form-item>
+                <!-- <a-form-item field="trafficPoolType" :label="$t('flowPool.trafficPoolType')">
+                    <a-select v-model="formState.traffic_pool_type"
+                        :placeholder="$t('form.cardForm.pleaseSelect') + $t('flowPool.trafficPoolType')"
+                        style="width: 170px;">
+                        <a-option v-for=" item in typeList" :key="item.id" :value="item.value">{{ item.label
+                            }}</a-option>
+                    </a-select>
+                </a-form-item> -->
+                <a-form-item>
+                    <a-space>
+                        <a-button type="primary" @click="handleSearch">{{ $t('form.Search') }}</a-button>
+                        <a-button @click="resetSearch">{{ $t('form.Reset') }}</a-button>
+                    </a-space>
+                </a-form-item>
+            </a-form>
+        </div>
+
+        <div class="audit-btn">
+            <a-button @click="dictShowModel(1, null)" type="text" v-if="role == 1">
+                <template #icon>
+                    <icon-plus-circle />
+                </template>
+                <template #default>
+                    {{ $t('form.Add') }}
+                </template>
+            </a-button>
+        </div>
+
+        <a-table row-key="id" :data="dataSource" :columns="columns" :pagination="pagination" :scroll="{ x: 'auto' }"
+            @page-change="evChangePage">
+            <template #id="{ record }">
+                <!-- 修改 -->
+                <a class="a-link" href="javascript:;" style="margin-right: 1rem" @click="dictShowModel(2, record)"
+                    v-if="role == 1">{{
+                        $t('form.Edit') }}</a>
+                <!-- 取消订单-退订 -->
+                <!-- <a-popconfirm :content="$t('lotCard.confirmTitleCancelOrder')" :ok-text="$t('form.Confirm')"
+                    :cancel-text="$t('form.Cancel')" @ok="handleUnsubscribeDialog(record)">
+                    <a class="a-link" href="javascript:;" style="margin-right: 1rem" >{{ $t('lotCard.titleCancelOrder')
+                        }}</a>
+                </a-popconfirm> -->
+                <!-- 删除 -->
+                <a-popconfirm :content="$t('form.Delete')" :ok-text="$t('form.Confirm')"
+                    :cancel-text="$t('form.Cancel')" @ok="handleDel(record.id)" v-if="role == 1">
+                    <a class="a-link" href="javascript:;" style="margin-right: 1rem">{{ $t('form.Delete')
+                        }}</a>
+                </a-popconfirm>
+                <!-- 导卡 -->
+                <!-- <a class="a-link" href="javascript:;" style="margin-right: 1rem" @click="dictShowModel(3, record)">{{
+                    $t('flowPool.exportCard') }}</a> -->
+            </template>
+
+        </a-table>
+
+
+        <!-- 新增弹框 -->
+        <a-modal :title="typeCurrent == 1 ? $t('form.Add') : typeCurrent == 2 ? $t('form.Edit') : $t('flowPool.Detail')"
+            v-model:visible="visible" @onCancel="resetForm" centered :maskClosable="false" :footer="null" width="55%">
+
+            <a-tabs v-model:active-key="activeKey">
+                <a-tab-pane key="1" :title="$t('flowPool.infoTabs')">
+                    <a-form ref="formRef" :rules="rules" :model="formState" @submit="handleSubmit"
+                        style="width: 620px;">
+                        <a-form-item :label="$t('flowPool.label')" field="label">
+                            <a-input v-model="formState.label"
+                                :placeholder="$t('form.PleaseEnterThe') + $t('flowPool.label')" />
+                        </a-form-item>
+                        <a-form-item :label="$t('flowPool.source')" field="source">
+                            <a-select v-model="formState.source"
+                                :placeholder="$t('form.cardForm.pleaseSelect') + $t('flowPool.source')">
+                                <a-option v-for=" item in sourceList" :key="item.id" :value="item.value">{{ item.label
+                                    }}</a-option>
+                            </a-select>
+                        </a-form-item>
+                        <a-form-item :label="$t('flowPool.trafficPoolStatus')" field="status">
+                            <a-select v-model="formState.status"
+                                :placeholder="$t('form.cardForm.pleaseSelect') + $t('flowPool.trafficPoolStatus')">
+                                <a-option v-for=" item in trafficList" :key="item.id" :value="item.value">{{ item.label
+                                    }}</a-option>
+                            </a-select>
+                        </a-form-item>
+                        <!-- <a-form-item :label="$t('flowPool.trafficPoolType')" field="traffic_pool_type">
+                            <a-select v-model="formState.traffic_pool_type"
+                                :placeholder="$t('form.cardForm.pleaseSelect') + $t('flowPool.trafficPoolType')">
+                                <a-option v-for=" item in typeList" :key="item.id" :value="item.value">{{ item.label
+                                    }}</a-option>
+                            </a-select>
+                        </a-form-item> -->
+                        <a-form-item :label="$t('flowPool.simRariff')" field="sim_tariff_id">
+                            <a-select v-model="formState.sim_tariff_id"
+                                :placeholder="$t('form.cardForm.pleaseSelect') + $t('flowPool.simRariff')">
+                                <a-option v-for=" item in tariffIdList" :key="item.id" :value="item.value">{{ item.label
+                                    }}</a-option>
+                            </a-select>
+                        </a-form-item>
+                        <a-form-item :label="$t('flowPool.expireTime')" field="expire_time">
+                            <a-date-picker v-model="formState.expire_time" show-time
+                                :time-picker-props="{ defaultValue: '09:09:06' }" format="YYYY-MM-DD HH:mm:ss" />
+                        </a-form-item>
+                        <a-form-item :label="$t('flowPool.poolSize')" field="poolSize">
+                            <a-input v-model="formState.poolSize" :placeholder="$t('flowPool.poolSize')" />
+                            <a-select v-model="formState.poolSizeUnit" style="width: 80px; margin-left: 8px;">
+                                <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>
+                            <a-button type="primary" html-type="submit" style="margin-right: 10px;">{{
+                                $t('form.Confirm')
+                                }}</a-button>
+                            <a-button @click="resetForm">{{ $t('form.Cancel') }}</a-button>
+                        </a-form-item>
+                    </a-form>
+                </a-tab-pane>
+                <a-tab-pane key="2" :title="$t('flowPool.warnTabs')">
+                    <a-form :model="formWarning" direction="inline">
+                        <div class="form-pool-tit">
+                            <div class="pool-icon"></div>
+                            客户端·池预警设置
+                        </div>
+                        <a-form-item field="totalDosage" tooltip="请输入" label="总用量占比">
+                            <a-input-number v-model="formWarning.totalDosage" :style="{ width: '320px' }"
+                                placeholder="请输入" allow-clear hide-button>
+                                <template #suffix>
+                                    %
+                                </template>
+                            </a-input-number>
+                            <a-checkbox value="1" v-model="formWarning.totalDosageCheck">达量预警</a-checkbox>
+                        </a-form-item>
+                        <a-form-item field="stoppagePool" label="达量停机">
+                            <a-select v-model="formWarning.stoppagePool" placeholder="请选择" :style="{ width: '320px' }"
+                                allow-clear>
+                                <a-option v-for="item in earlyList" :key="item.value" :value="item.value"
+                                    :label="item.label" />
+                            </a-select>
+                            <a-checkbox value="1" v-model="formWarning.stoppagePoolCheck">达量停机</a-checkbox>
+                        </a-form-item>
+                        <a-form-item field="stopNetworkPool" label="达量断网">
+                            <a-select v-model="formWarning.stopNetworkPool" placeholder="请选择"
+                                :style="{ width: '320px' }" allow-clear>
+                                <a-option v-for="item in earlyList" :key="item.value" :value="item.value"
+                                    :label="item.label" />
+                            </a-select>
+                            <a-checkbox value="1" v-model="formWarning.stopNetworkPoolCheck">达量断网</a-checkbox>
+                        </a-form-item>
+                        <a-form-item field="remindTotal" label="提醒次数">
+                            <a-input-number v-model="formWarning.remindTotal" :style="{ width: '320px' }"
+                                placeholder="请输入" allow-clear hide-button>
+                                <template #suffix>
+                                    次/月
+                                </template>
+                            </a-input-number>
+                        </a-form-item>
+                        <div class="form-pool-tit">
+                            <div class="pool-icon"></div>
+                            客户端·单卡预警设置
+                        </div>
+                        <a-form-item field="oneCardWarning" tooltip="请输入" label="单卡用量预警">
+                            <a-input-number v-model="formWarning.oneCardWarning" :style="{ width: '320px' }"
+                                placeholder="请输入" allow-clear hide-button>
+                            </a-input-number>
+                            <a-checkbox value="1" v-model="formWarning.outTotalCheck">达量预警</a-checkbox>
+                        </a-form-item>
+                        <a-form-item field="stoppageCard" label="达量停机">
+                            <a-select v-model="formWarning.stoppageCard" placeholder="请选择" :style="{ width: '320px' }"
+                                allow-clear>
+                                <a-option v-for="item in earlyList" :key="item.value" :value="item.value"
+                                    :label="item.label" />
+                            </a-select>
+                            <a-checkbox value="1" v-model="formWarning.stoppageCardCheck">达量停机</a-checkbox>
+                        </a-form-item>
+                        <a-form-item field="stopNetworkCard" label="达量断网">
+                            <a-select v-model="formWarning.stopNetworkCard" placeholder="请选择"
+                                :style="{ width: '320px' }" allow-clear>
+                                <a-option v-for="item in earlyList" :key="item.value" :value="item.value"
+                                    :label="item.label" />
+                            </a-select>
+                            <a-checkbox value="1" v-model="formWarning.stopNetworkCardCheck">达量断网</a-checkbox>
+                        </a-form-item>
+                        <div class="form-pool-tit">
+                            <div class="pool-icon"></div>
+                            管理端预警设置
+                        </div>
+                        <a-form-item field="poolUsedWarning" tooltip="请输入" label="池已用量预警">
+                            <a-input-number v-model="formWarning.poolUsedWarning" :style="{ width: '320px' }"
+                                placeholder="请输入" allow-clear hide-button>
+                                <template #suffix>
+                                    %
+                                </template>
+                            </a-input-number>
+                            <a-checkbox value="1" v-model="formWarning.poolUsedCheck">达量预警</a-checkbox>
+                        </a-form-item>
+                        <a-form-item field="stoppageManagement" label="达量停机">
+                            <a-select v-model="formWarning.stoppageManagement" placeholder="请选择"
+                                :style="{ width: '320px' }" allow-clear>
+                                <a-option v-for="item in earlyList" :key="item.value" :value="item.value"
+                                    :label="item.label" />
+                            </a-select>
+                            <a-checkbox value="1" v-model="formWarning.stoppageManagementCheck">达量停机</a-checkbox>
+                        </a-form-item>
+                        <a-form-item field="stopNetworkManagement" label="达量断网">
+                            <a-select v-model="formWarning.stopNetworkManagement" placeholder="请选择"
+                                :style="{ width: '320px' }" allow-clear>
+                                <a-option v-for="item in earlyList" :key="item.value" :value="item.value"
+                                    :label="item.label" />
+                            </a-select>
+                            <a-checkbox value="1" v-model="formWarning.stopNetworkManagementCheck">达量断网</a-checkbox>
+                        </a-form-item>
+                        <a-form-item>
+                            <a-button type="primary" html-type="submit" @click="resetForm"
+                                style="margin-right: 10px;">{{
+                                    $t('form.Confirm')
+                                }}</a-button>
+                            <a-button @click="resetForm">{{ $t('form.Cancel') }}</a-button>
+                        </a-form-item>
+                    </a-form>
+                </a-tab-pane>
+            </a-tabs>
+
+        </a-modal>
+
+        <a-modal v-model:visible="openExport" @ok="handleOk" @cancel="handleCancel" width="1000px">
+            <template #title>
+                批量导入
+            </template>
+            <div class="export-box">
+                <div class="export-box-item">
+                    <div class="box-item-title">
+                        <div class="title-icon"></div>
+                        批量导入
+                    </div>
+                    <div class="box-item-content">
+                        <div class="item-txt">
+                            <div class="item-txt-title">标题</div>
+                            <div class="item-txt-text">联通流量卡</div>
+                        </div>
+                        <div class="item-txt">
+                            <div class="item-txt-title">标题</div>
+                            <div class="item-txt-text">联通流量卡</div>
+                        </div>
+                        <div class="item-txt">
+                            <div class="item-txt-title"></div>
+                            <div class="item-txt-text"><a-upload action="/">
+                                    <template #upload-button>
+                                        <a-button type="primary">导入</a-button>
+                                    </template>
+                                </a-upload></div>
+                        </div>
+                    </div>
+                </div>
+                <div class="export-box-item" style="margin-top:20px;">
+                    <div class="box-item-title">
+                        <div class="title-icon"></div>
+                        导入结果
+                    </div>
+                    <div class="box-item-content">
+                        <a-table :columns="columnsExport" :data="dataExport">
+                            <template #operate="{ record }">
+                                <a-button @click="openContract(record)" type="text">下载</a-button>
+                            </template>
+                            <template #status="{ record }">
+                                <div class="export-status" v-if="record.status == 1">
+                                    <div class="status-icon" style="background: rgba(82, 196, 27, 1);"></div>
+                                    导入成功
+                                </div>
+                                <div class="export-status" v-if="record.status == 2">
+                                    <div class="status-icon" style="background: rgba(250, 173, 20, 1);"></div>
+                                    部分成功
+                                </div>
+                                <div class="export-status" v-if="record.status == 3">
+                                    <div class="status-icon" style="background: rgba(247, 66, 75, 1);"></div>
+                                    校验失败
+                                </div>
+                            </template>
+                        </a-table>
+                    </div>
+                </div>
+            </div>
+        </a-modal>
+    </div>
+</template>
+
+<script setup>
+import { onMounted, ref, reactive, getCurrentInstance, nextTick } from "vue";
+import { useRoute } from "vue-router";
+import { columns } from "../config";
+import { Message, Notification } from '@arco-design/web-vue'
+import { deleteTrafficPool, addTrafficPool, updateTrafficPool, trafficPoolList } from "@/api/path/flowPool.api"
+import { tariffList } from "@/api/path/tariffManagement.api"
+import { orderCancel } from "@/api/path/lotCard.api"
+import { enum_dict } from "@/hooks/enum";
+import { useSystemStore } from "@/store/modules/systemStore"
+
+
+const systemStore = useSystemStore()
+const role = ref(systemStore.getRole)
+
+
+const { proxy } = getCurrentInstance()
+const formRef = ref()
+const searchForm = ref({
+    "label": "",
+});
+
+const dataSource = ref([]);
+const route = useRoute();
+const pagination = ref({
+    total: 0,
+    pageSize: 10,
+    current: 1,
+})
+
+
+
+
+const rowSelection = reactive({
+    type: 'checkbox',
+    showCheckedAll: true,
+    onlyCurrent: false,
+});
+const selectedKeys = ref([])
+
+
+
+const intData = async () => {
+    const param = {
+        current: pagination.value.current,
+        size: pagination.value.pageSize,
+        traffic_pool_type: "2",
+        ...searchForm.value,
+    }
+    const { data } = await trafficPoolList(param)
+    dataSource.value = (data.records || []).map((item, index) => {
+        const trafficPoolType = typeList.value.find(val => val.value == item.traffic_pool_type)?.label
+        const trafficPoolStatus = trafficList.value.find(val => val.value == item.status)?.label
+        const sourceName = sourceList.value.find(val => val.value == item.source)?.label
+        return {
+            ...item,
+            sourceName,// 运营商名称
+            trafficPoolType,
+            trafficPoolStatus,
+            poolNumber: "NR0" + (index + 1),
+            cardRariffName: "监控1G月租",
+            cardFlow: "1G/月",
+            cardNum: "11/100",
+            UsedMonth: "1.00G",
+            surplusFlow: "99.0G",
+            totalFlow: "100.0G",
+            exceededFlow: "--",
+        }
+    })
+    pagination.value.total = data.total
+}
+
+
+
+
+// 删除
+const handleDel = async (id) => {
+    const { code } = await deleteTrafficPool({ id })
+    if (code == 200) {
+        Message.success({
+            content: "删除成功!",
+            duration: 2000,
+        })
+        intData()
+    }
+};
+
+const evChangePage = (page) => {
+    pagination.value.current = page
+    intData()
+}
+
+const handleSearch = () => {
+    intData()
+}
+const resetSearch = () => {
+    searchForm.value.label = ''
+    intData()
+}
+
+
+
+
+// -------------------弹窗数据------------------------------------
+const activeKey = ref('1');
+const visible = ref(false);
+const typeCurrent = ref(null);
+const sourceList = ref([])
+const trafficList = ref([])
+const typeList = ref([])
+const tariffIdList = ref([])
+
+// 详情---------------------------
+const openExport = ref(false);
+const columnsExport = [
+    { title: '序号', dataIndex: 'index', align: 'center', render: ({ rowIndex }) => rowIndex + 1 },
+    {
+        title: '操作人',
+        dataIndex: 'name',
+    },
+    {
+        title: '导入时间',
+        dataIndex: 'exportTime',
+    },
+    {
+        title: '完成时间',
+        dataIndex: 'successTime',
+    },
+    {
+        title: '状态',
+        slotName: 'status',
+        align: 'center'
+    },
+    { title: '操作', slotName: 'operate', align: 'center' },
+];
+const dataExport = reactive([{
+    key: '1',
+    name: 'Jane Doe',
+    exportTime: '2024-10-13 22:20:01',
+    successTime: '2024-10-13 22:20:01',
+    status: 1
+}, {
+    key: '2',
+    name: 'Alisa Ross',
+    exportTime: '2024-10-13 22:20:01',
+    successTime: '2024-10-13 22:20:01',
+    status: 2
+}, {
+    key: '3',
+    name: 'Kevin Sandra',
+    exportTime: '2024-10-13 22:20:01',
+    successTime: '2024-10-13 22:20:01',
+    status: 3
+}, {
+    key: '4',
+    name: 'Ed Hellen',
+    exportTime: '2024-10-13 22:20:01',
+    successTime: '2024-10-13 22:20:01',
+    status: 2
+}, {
+    key: '5',
+    name: 'William Smith',
+    exportTime: '2024-10-13 22:20:01',
+    successTime: '2024-10-13 22:20:01',
+    status: 3
+}]);
+// -------------------------------
+
+const formState = ref({
+    "id": "",
+    // 流量包名称
+    "label": "",
+    // 流量池类型: 1: 前流量池 2: 后流量池
+    "traffic_pool_type": "2",
+    // 来源
+    "source": "",
+    // 流量包状态:1:正常(发布计划状态)2:线下暂停销售
+    "status": "",
+    // 流量池ID
+    "sim_tariff_id": null,
+    // 过期时间
+    "expire_time": "",
+    // ICCID列表
+    "iccids": ["89852342022040149139", "89852342022060861597"]
+});
+const formWarning = reactive({
+    // 总用量占比
+    totalDosage: null,
+    // 总用量占比达量预警
+    totalDosageCheck: '',
+    // 达量停机
+    stoppagePool: '',
+    stoppagePoolCheck: '',
+    stopNetworkPool: '',
+    stopNetworkPoolCheck: '',
+    remindTotal: null,
+    oneCardWarning: null,
+    outTotalCheck: '',
+    stoppageCard: '',
+    stoppageCardCheck: '',
+    stopNetworkCard: '',
+    stopNetworkCardCheck: '',
+    poolUsedWarning: null,
+    poolUsedCheck: '',
+    stoppageManagement: '',
+    stoppageManagementCheck: '',
+    stopNetworkManagement: '',
+    stopNetworkManagementCheck: '',
+})
+
+const rules = {
+    label: [{ required: true, trigger: 'change', }],
+    sim_data_plan_id: [{ required: true, trigger: 'change', }],
+    user_id: [{ required: true, trigger: 'change', }],
+    source: [{ required: true, trigger: 'change', }],
+    traffic_type: [{ required: true, trigger: 'change', }],
+    billing_type: [{ required: true, trigger: 'change', }],
+    bag_size: [{ required: true, trigger: 'change', }],
+    billing_cycle: [{ required: true, trigger: 'change', }],
+    traffic_pool_type: [{ required: true, trigger: 'change', }],
+    settlement_cycle: [{ required: true, trigger: 'change', }],
+    sim_tariff_id: [{ required: true, trigger: 'change', }],
+    expire_time: [{ required: true, trigger: 'change', }],
+    // pricing: [{ required: true, trigger: 'change', }],
+    // currency: [{ required: true, trigger: 'change', }],
+};
+
+const earlyList = [
+    { value: 1, label: '手工停机' },
+
+];
+
+// 退订
+const handleUnsubscribeDialog = async (record) => {
+    // 订阅关系状态
+    // 1:未激活
+    // 2: 已过期
+    // 3: 已激活99:已退款
+    let param = {}
+    let statusFlag = true
+    if (selectedKeys.value.length > 0) {
+        statusFlag = false
+        param = {
+            ids: selectedKeys.value
+        }
+    }
+    if (record && record.id) {
+        statusFlag = false
+        param = {
+            ids: [record.id]
+        }
+    }
+
+    console.log(param, "param")
+    if (!statusFlag) {
+
+        const { code, data } = await orderCancel(param)
+
+        if (code == 200) {
+            Message.success({
+                content: data,
+                duration: 2000,
+            })
+        }
+    } else {
+        Message.warning({
+            content: $t('lotCard.tipsOrder'),
+            duration: 2000,
+        })
+    }
+};
+
+// 提交
+const handleSubmit = ({ values, errors }) => {
+    formRef.value.validate(async (errors) => {
+        if (!errors) {
+            values.user_id = Number(values.user_id)
+            if (formState.value.id) {
+                const { code, data } = await updateTrafficPool(values)
+
+                if (code == 200) {
+                    Message.success({
+                        content: "修改成功!",
+                        duration: 2000,
+                    })
+                    visible.value = false;
+                    intData()
+                }
+            } else {
+                const { code, data } = await addTrafficPool(values)
+                if (code == 200) {
+                    Message.success({
+                        content: "添加成功!",
+                        duration: 2000,
+                    })
+                    visible.value = false;
+                    intData()
+                }
+            }
+        }
+    });
+
+}
+// 弹框
+const dictShowModel = (type, data) => {
+    if (type == 3) {
+        openExport.value = true;
+        return
+    }
+    handleTariff()
+    formRef.value.resetFields();
+    typeCurrent.value = type;
+    activeKey.value = "1"
+    nextTick(() => {
+        visible.value = true;
+    });
+    // 编辑
+    if (type == 2) {
+        // Object.assign(formState.value, data);
+        Object.keys(formState.value).forEach(key => {
+            if (data[key]) {
+                formState.value[key] = data[key]
+            }
+        });
+    }
+
+}
+
+// 获取资费列表选择id
+const handleTariff = async () => {
+    const { code, data } = await tariffList({
+        "current": 1,
+        "size": 10
+    })
+    if (code == 200) {
+        tariffIdList.value = (data.records || []).map(item => {
+            return {
+                ...item,
+                value: item.id
+            }
+        })
+    }
+}
+
+// 取消
+const resetForm = () => {
+    visible.value = false;
+    formRef.value.resetFields();
+}
+
+// 卡详情
+
+const handleOk = () => {
+}
+const handleCancel = () => {
+}
+// --------------------------------------------------------
+// 获取字典
+const handleDictValue = () => {
+    const dictList = JSON.parse(window.localStorage.getItem('dictList')) ?? []
+    sourceList.value = dictList.filter((item) => item.type_key == enum_dict.SOURCE)
+    trafficList.value = dictList.filter((item) => item.type_key == enum_dict.TRAFFIC_PACKET_STATUS)
+    typeList.value = dictList.filter((item) => item.type_key == enum_dict.TRAFFIC_POOL_TYPE)
+}
+
+
+
+
+
+onMounted(() => {
+    handleDictValue()
+    intData()
+})
+
+
+
+</script>
+
+<style scoped lang="less">
+.m-r-10 {
+    margin-right: 10px;
+}
+
+.head-title-right {}
+
+.search-section {
+    margin-top: 20px;
+    margin-bottom: 20px;
+}
+
+.container {
+    .head-title {
+        display: flex;
+        justify-content: space-between;
+    }
+
+    .form-row {
+        display: flex;
+
+        .form-row-col {
+            width: 25%;
+            display: flex;
+            align-items: center;
+
+            .form-row-label {
+                width: 120px;
+                text-align: right;
+            }
+        }
+    }
+}
+
+silent-expire-alarm {
+    padding: 20px !important;
+    // background: #fcf;
+}
+
+.search-section {
+    margin-bottom: 20px;
+}
+
+.audit-btn {
+    margin-bottom: 10px;
+}
+
+
+.echarts-box {
+    // width: 100%;
+    display: flex;
+    justify-content: center;
+    overflow: hidden;
+
+    .chart-dom {
+        width: 700px !important;
+        height: 400px !important;
+    }
+}
+
+.form-item-space-item {
+    background-color: #f2f3f5;
+    display: flex;
+    align-items: center;
+    font-size: 14px;
+}
+
+.form-pool-tit {
+    display: flex;
+    align-items: center;
+    margin-bottom: 10px;
+
+    .pool-icon {
+        margin-right: 10px;
+        width: 4px;
+        height: 16px;
+        background: #1B5DF8;
+        font-size: 14px;
+        color: #6C6E70;
+        font-family: PingFang SC;
+
+    }
+}
+
+
+.export-box {
+    .export-box-item {
+        .box-item-title {
+            display: flex;
+            align-items: center;
+            font-family: PingFang SC;
+            font-size: 16px;
+            font-weight: 600;
+            line-height: 24px;
+            color: rgba(0, 0, 0, 0.85);
+            margin-bottom: 10px;
+
+            .title-icon {
+                margin-right: 10px;
+                width: 4px;
+                height: 16px;
+                background: #1B5DF8;
+
+            }
+        }
+
+        .box-item-content {
+            .item-txt {
+                display: flex;
+                align-items: center;
+                margin-bottom: 10px;
+
+                .item-txt-title {
+                    width: 300px;
+                    text-align: right;
+                    margin-right: 10px;
+                }
+
+                .item-txt-text {
+                    font-family: PingFang SC;
+                    font-size: 14px;
+                    font-weight: 400;
+                    line-height: 22px;
+                    text-align: left;
+                    color: #1B5DF8;
+
+                }
+            }
+
+            .export-status {
+                font-family: PingFang SC;
+                font-size: 14px;
+                font-weight: 400;
+                line-height: 22px;
+                text-align: left;
+                color: rgba(51, 51, 51, 1);
+                display: flex;
+                align-items: center;
+
+                .status-icon {
+                    width: 6px;
+                    height: 6px;
+                    border-radius: 50%;
+                    margin-right: 10px;
+                }
+            }
+        }
+    }
+}
+</style>

+ 19 - 22
src/views/login/login-form.vue

@@ -2,34 +2,25 @@
   <div class="login-form-wrapper">
     <div class="login-form-title">登陆 Admin</div>
     <div class="login-form-sub-title">Login to ADMIN</div>
-    
-    <a-form ref="loginForm" :model="formData" class="login-form"  @submit-success="handleSubmit">
-      <a-form-item
-        field="username"
-        :rules="[{ required: true, message: '用户名不能为空' }]"
-        :validate-trigger="['change', 'blur']"
-        hide-label
-      >
+
+    <a-form ref="loginForm" :model="formData" class="login-form" @submit-success="handleSubmit">
+      <a-form-item field="username" :rules="[{ required: true, message: '用户名不能为空' }]"
+        :validate-trigger="['change', 'blur']" hide-label>
         <a-input v-model="formData.username" placeholder="用户名:">
           <template #prefix>
             <icon-user />
           </template>
         </a-input>
       </a-form-item>
-      <a-form-item
-        field="password"
-        :rules="[{ required: true, message: '密码不能为空' }]"
-        :validate-trigger="['change', 'blur']"
-        hide-label
-        
-      >
+      <a-form-item field="password" :rules="[{ required: true, message: '密码不能为空' }]"
+        :validate-trigger="['change', 'blur']" hide-label>
         <a-input-password v-model="formData.password" placeholder="密码:" allow-clear>
           <template #prefix>
             <icon-lock />
           </template>
         </a-input-password>
       </a-form-item>
-    
+
 
       <a-space :size="16" direction="vertical">
         <div class="login-form-password-actions">
@@ -48,14 +39,14 @@
 import { ref, reactive } from 'vue'
 import { encryptByDES } from "@/utils"
 import { loginApi } from "@/api/path/login.api"
-import { useSystemStore  } from "@/store/modules/systemStore"
+import { useSystemStore } from "@/store/modules/systemStore"
 import { useRouter } from 'vue-router'
 import { updateRouteByMenu } from '@/router/router.update'
 
 
 const router = useRouter()
 const formData = ref({
-  username:localStorage.remember_user_name
+  username: localStorage.remember_user_name
 })
 const formLoading = ref(false)
 const rememberPassword = ref(true)
@@ -68,7 +59,7 @@ const handleSubmit = async () => {
     password: encryptByDES(formData.value.password)
   })
   window.localStorage.setItem('remember_user_name', formData.value.username)
- 
+
   systemStore.setStateValue({
     key: 'token',
     value: data.token,
@@ -79,6 +70,11 @@ const handleSubmit = async () => {
     value: JSON.stringify(data.userInfo),
     localStorage: true,
   })
+  systemStore.setStateValue({
+    key: 'role',
+    value: data.user_type,
+    localStorage: true,
+  })
   await updateRouteByMenu(router, systemStore)
   router.push({
     path: "/",
@@ -93,18 +89,19 @@ const setRememberPassword = (e) => {
 </script>
 
 <style lang="less" scoped>
-
-.login-form-wrapper{
+.login-form-wrapper {
   margin: 0 1rem;
 }
+
 .login-form {
   margin-top: 32px;
+
   &-wrapper {
     width: 320px;
   }
 
   &-title {
-    color:  @text_color_1;
+    color: @text_color_1;
     font-weight: 500;
     font-size: 24px;
     line-height: 32px;

+ 8 - 8
src/views/lotCard/cardList/config.js

@@ -11,14 +11,14 @@ export const columns = [
   { title: window.$t('lotCard.tariff'), dataIndex: 'tariff', align: 'center', width: 200 },
   { title: window.$t('lotCard.ServiceUsageMode'), dataIndex: 'serviceName', align: 'center', width: 200 },
   { title: window.$t('lotCard.LastModifyTime'), dataIndex: 'last_modify_time', align: 'center', width: 200 },
-  {
-    title: window.$t('global.common.operations'),
-    dataIndex: 'id',
-    slotName: 'id',
-    align: 'center',
-    width: 280,
-    fixed: "right",
-  }
+  // {
+  //   title: window.$t('global.common.operations'),
+  //   dataIndex: 'id',
+  //   slotName: 'id',
+  //   align: 'center',
+  //   width: 280,
+  //   fixed: "right",
+  // }
 ]
 
 export const columnsTrafficUse = [

+ 82 - 8
src/views/lotCard/cardList/index.vue

@@ -6,7 +6,7 @@
       <span class="head-title-right">
         <a-popconfirm :content="$t('form.ImportConfirm')" :ok-text="$t('form.Confirm')" :cancel-text="$t('form.Cancel')"
           @ok="handleImport()">
-          <a-button class="m-r-10" type="primary"> {{ $t('form.Import') }}</a-button>
+          <!-- <a-button class="m-r-10" type="primary"> {{ $t('form.Import') }}</a-button> -->
         </a-popconfirm>
       </span>
 
@@ -27,11 +27,12 @@
     </div>
 
     <a-table row-key="iccid" :data="dataSource" :columns="columns" :pagination="pagination"
-      :row-selection="rowSelection" v-model:selectedKeys="selectedKeys" :scroll="{ x: 'auto' }">
+      :row-selection="rowSelection" v-model:selectedKeys="selectedKeys" :scroll="{ x: 'auto' }" :expandable="expandable"
+      @page-change="evChangePage">
       <template #id="{ record }">
         <!-- 查看流量消耗 -->
-        <!-- <a class="a-link" href="javascript:;" style="margin-right: 1rem" @click="handletrafficUseDialog(record)">{{
-          $t('lotCard.trafficUse') }}</a> -->
+        <a class="a-link" href="javascript:;" style="margin-right: 1rem" @click="handletrafficUseDialog(record)">{{
+          $t('lotCard.trafficUse') }}</a>
       </template>
 
     </a-table>
@@ -41,13 +42,14 @@
 </template>
 
 <script setup>
-import { onMounted, ref, reactive, getCurrentInstance } from "vue";
+import { onMounted, ref, reactive, getCurrentInstance, h } from "vue";
 import { useRoute } from "vue-router";
 import { columns } from "./config";
 import { Message, Notification } from '@arco-design/web-vue'
-import { cardInfoList, cardInfoImport } from "@/api/path/lotCard.api"
+import { cardInfoList, cardInfoImport, orderList, orderFlowData } from "@/api/path/lotCard.api"
 import trafficUseDialog from "./trafficUseDialog.vue";
 import { enum_dict } from "@/hooks/enum";
+import list from "./list.vue";
 
 const { proxy } = getCurrentInstance()
 const formRef = ref()
@@ -83,7 +85,38 @@ const intData = async () => {
     ...searchForm.value,
   }
   const { data } = await cardInfoList(param)
-  dataSource.value = (data.records || []).map(item => {
+
+  dataSource.value = (data.records || []).map((item) => {
+    // 卡下级信息
+    let orderArr = []
+    orderList({ current: 1, size: 999, ICCID: item.iccid }).then(res => {
+
+      res.data.records?.forEach(async (orderItem, index) => {
+        // const dictList = JSON.parse(window.localStorage.getItem('dictList')) ?? []
+        // const orderType = dictList.filter((item) => item.type_key == enum_dict.SOURCE)
+        const params = {
+          iccid: orderItem.ICCID,
+          childOrderId: orderItem.id,
+          subscriptionKey: orderItem.subscription_key,
+        }
+
+        let trafficList = []
+
+        // if (item.iccid == '89852342022040149139' && index < 5 || !(item.iccid == '89852342022040149139')) {
+        //   const { data } = await orderFlowData(params)
+        //   trafficList = data.historyData || []
+        //   orderArr.push({
+        //     ...orderItem,
+        //     trafficList
+        //   })
+        // }
+        orderArr.push({
+          ...orderItem,
+        })
+      })
+    })
+
+    // 处理卡列表信息
     const sourceName = sourceList.value.find(sourceItem => sourceItem.value == item.source)?.label || ''
     const serviceName = serviceList.value.find(serviceItem => serviceItem.value == item.service_usage_mode)?.label || ''
     const statusName = statusList.value.find(statusItem => statusItem.value == item.status)?.label || ''
@@ -92,12 +125,49 @@ const intData = async () => {
       ...item,
       sourceName,
       serviceName,
-      statusName
+      statusName,
+      orderArr
     }
+
   })
   pagination.value.total = data.total
 }
 
+
+// const { data: orderData } = await orderList({ current: 1, size: 999, ICCID: ICCID.value })
+//     orderData.records?.forEach(async (orderItem) => {
+
+//         const params = {
+//             // iccid: orderItem.ICCID,
+//             iccid: '89852342022040149139',
+//             childOrderId: orderItem.id,
+//             subscriptionKey: "1824754463183432097",
+//         }
+
+//         let trafficList = []
+//         const { data } = await orderFlowData(params)
+//         trafficList = data.historyData || []
+
+//         dataSource.value.push({
+//             ...orderItem,
+//             trafficList
+//         })
+//     })
+
+
+const expandable = {
+  expandedRowRender: (record) => {
+    if (record.orderArr && Array.isArray(record.orderArr) && record.orderArr.length > 0) {
+      return h('div', {}, [
+        h(list, { 'data': record.orderArr })
+      ]);
+    }
+    return h('div', {}, '暂无数据')
+
+
+  },
+};
+
 const handleImport = async () => {
   if (!searchForm.value.iccid) {
     Message.warning({
@@ -129,6 +199,10 @@ const handletrafficUseDialog = (data) => {
 }
 
 
+const evChangePage = (page) => {
+  pagination.value.current = page
+  intData()
+}
 const handleSearch = () => {
   formRef.value.validate((errors) => {
     if (!errors) {

+ 94 - 0
src/views/lotCard/cardList/list.vue

@@ -0,0 +1,94 @@
+<template>
+    <!-- 订单列表-查看订单流量明细 -->
+    <div class="trafficUse">
+        <ul class="order_list_box">
+            <li class="list_box_item" v-for="(item, index) in data" key="index">
+                <div class="list_item_left">
+                    <a-progress type="circle" :percent="0.02" />
+                </div>
+                <div class="list_item_right">
+                    <p>
+                        <span class="list_item_right_span">{{ $t('lotCard.orderID') }}:{{ item.id }}</span>
+                        <!-- <span>{{ $t('lotCard.orderType') }}:{{ item.orderType }}</span> -->
+                        <!-- <span>更新时间:{{ item.updated_at }}</span> -->
+                    </p>
+                    <template v-if="item.trafficList">
+                        <p v-for="trafficVal in item.trafficList" :key="trafficVal.id">
+                            <span class="list_item_right_span"> 流量总量:{{ trafficVal.qtaconsumption }}</span>
+                            <span class="list_item_right_span">流量使用时间:{{ trafficVal.time }}</span>
+                            <span>国家:中国</span>
+                        </p>
+                    </template>
+
+                </div>
+            </li>
+        </ul>
+    </div>
+</template>
+<script setup>
+import lotCard from '@/i18n/zh/lotCard';
+
+const props = defineProps({
+    data: Array
+});
+
+
+
+
+</script>
+
+<style scoped lang="less">
+ul,
+li,
+p,
+span {
+    margin: 0;
+    padding: 0;
+    line-height: 1.5;
+}
+
+
+.order_list_box {
+    list-style: none;
+    max-height: 700px;
+    overflow-y: scroll;
+    margin: auto;
+    padding: 0 20px;
+}
+
+.list_box_item {
+    display: flex;
+    align-items: center;
+    margin-bottom: 10px;
+
+    .list_item_left {
+        width: 60px;
+        height: 60px;
+        // background: gainsboro;
+        margin-right: 10px;
+    }
+
+    .list_item_right {
+        p {
+            display: flex;
+            align-items: center;
+            margin: 5px 0;
+        }
+
+        span {
+            display: flex;
+            align-items: center;
+
+        }
+
+        .list_item_right_span::after {
+            content: "";
+            display: inline-block;
+            width: 1px;
+            height: 20px;
+            background-color: gray;
+            margin: 0 10px;
+        }
+    }
+}
+</style>

+ 111 - 22
src/views/lotCard/cardList/trafficUseDialog.vue

@@ -1,8 +1,8 @@
 <template>
-    <a-modal width="70%" :visible="visible" :title="$t('lotCard.trafficUse')" :hide-cancel='true'
+    <a-modal width="800px" :visible="visible" :title="$t('lotCard.trafficUse')" :hide-cancel='true'
         :ok-text="$t('lotCard.close')" @ok="handleSubmit" @cancel="handleCancel">
         <!-- 搜索条件区 -->
-        <div class="search-section">
+        <!-- <div class="search-section">
             <a-form :model="formData" ref="formRef" layout="inline">
                 <a-form-item field="iccid" :label="$t('lotCard.iccid')" :validate-trigger="['change', 'input', 'blur']"
                     :rules="[{ required: true, message: $t('lotCard.please') + $t('lotCard.iccid') }]">
@@ -20,9 +20,33 @@
                     </a-space>
                 </a-form-item>
             </a-form>
+        </div> -->
+        <!-- <a-table :data="dataSource" :columns="columnsTrafficUse" :scroll="{ x: 'auto' }" @page-change="evChangePage">
+        </a-table> -->
+
+        <!-- 订单列表-查看订单流量明细 -->
+        <div class="trafficUse">
+            <ul class="order_list_box">
+                <li class="list_box_item" v-for="(item, index) in dataSource" key="index">
+                    <div class="list_item_left"></div>
+                    <div class="list_item_right">
+                        <p>
+                            <span class="list_item_right_span">订单ID:{{ item.orderId }}</span>
+                            <span class="list_item_right_span">订单状态:正常</span>
+                            <span>更新时间:{{ item.updated_at }}</span>
+                        </p>
+                        <template v-if="item.trafficList">
+                            <p v-for="trafficVal in item.trafficList" :key="trafficVal.id">
+                                <span class="list_item_right_span"> 流量总量:{{ trafficVal.qtaconsumption }}</span>
+                                <span class="list_item_right_span">流量使用时间:{{ trafficVal.time }}</span>
+                                <span>国家:中国</span>
+                            </p>
+                        </template>
+
+                    </div>
+                </li>
+            </ul>
         </div>
-        <a-table :data="dataSource" :columns="columnsTrafficUse" :scroll="{ x: 'auto' }" @page-change="evChangePage">
-        </a-table>
     </a-modal>
 </template>
 <script setup>
@@ -43,7 +67,7 @@ const formData = ref({
     "iccid": "",
     "imsi": "454120387374989",
 });
-const tableMap = ref({})
+const ICCID = ref({})
 
 const dataSource = ref([]);
 const pagination = ref({
@@ -55,29 +79,38 @@ const pagination = ref({
 const visible = ref(false)
 
 const open = (data) => {
-    if (data.length == 0) {
+    if (!data) {
         return
     }
-    visible.value = true
-    tableMap.value = data
-    console.log(data, "“data--------------");
-
+    dataSource.value = []
+    ICCID.value = data
     intData()
+
 }
 
 const intData = async () => {
-    const { data: orderData } = await orderList({ current: 1, size: 999, ICCID: tableMap.value.ICCID })
-    const orderMap = orderData.records[0]
-    const params = {
-        iccid: orderMap.ICCID,
-        childOrderId: orderMap.id,
-        subscriptionKey: "1824754463183432097",
-    }
-    console.log(orderMap, "params----------------");
 
-    const { data } = await orderFlowData(params)
-    dataSource.value = data.historyData || []
-    pagination.value.total = data.historyData.length
+    const { data: orderData } = await orderList({ current: 1, size: 999, ICCID: ICCID.value })
+    orderData.records?.forEach(async (orderItem) => {
+
+        const params = {
+            // iccid: orderItem.ICCID,
+            iccid: '89852342022040149139',
+            childOrderId: orderItem.id,
+            subscriptionKey: "1824754463183432097",
+        }
+
+        let trafficList = []
+        const { data } = await orderFlowData(params)
+        trafficList = data.historyData || []
+
+        dataSource.value.push({
+            ...orderItem,
+            trafficList
+        })
+    })
+    console.log(dataSource.value, "dataSource.value")
+    visible.value = true
 }
 
 const evChangePage = (page) => {
@@ -114,4 +147,60 @@ const handleCancel = () => {
 defineExpose({ open })
 
 
-</script>
+</script>
+
+<style scoped lang="less">
+ul,
+li,
+p,
+span {
+    margin: 0;
+    padding: 0;
+    line-height: 1.5;
+}
+
+
+.order_list_box {
+    list-style: none;
+    height: 700px;
+    overflow-y: scroll;
+    margin: auto;
+    padding: 0 20px;
+}
+
+.list_box_item {
+    display: flex;
+    align-items: center;
+    margin-bottom: 10px;
+
+    .list_item_left {
+        width: 50px;
+        height: 50px;
+        background: gainsboro;
+        margin-right: 10px;
+    }
+
+    .list_item_right {
+        p {
+            display: flex;
+            align-items: center;
+            margin: 5px 0;
+        }
+
+        span {
+            display: flex;
+            align-items: center;
+
+        }
+
+        .list_item_right_span::after {
+            content: "";
+            display: inline-block;
+            width: 1px;
+            height: 20px;
+            background-color: gray;
+            margin: 0 10px;
+        }
+    }
+}
+</style>

+ 10 - 10
src/views/lotCard/orderMange/config.js

@@ -9,17 +9,17 @@ export const columns = [
   { title: window.$t('lotCard.orderID'), dataIndex: 'orderId', align: 'center', width: 200 },
   { title: window.$t('lotCard.price'), dataIndex: 'price', align: 'center', width: 200 },
   { title: window.$t('lotCard.quantity'), dataIndex: 'quantity', align: 'center', width: 200 },
-  { title: window.$t('lotCard.packageStatus'), dataIndex: 'status', align: 'center', width: 200 },
-  { title: window.$t('lotCard.source'), dataIndex: 'source', align: 'center', width: 200 },
+  { title: window.$t('lotCard.packageStatus'), dataIndex: 'statusName', align: 'center', width: 160 },
+  { title: window.$t('lotCard.source'), dataIndex: 'sourceName', align: 'center', width: 100 },
   { title: window.$t('lotCard.UserId'), dataIndex: 'user_id', align: 'center', width: 200 },
-  {
-    title: window.$t('global.common.operations'),
-    dataIndex: 'id',
-    slotName: 'id',
-    align: 'center',
-    width: 180,
-    fixed: "right",
-  }
+  // {
+  //   title: window.$t('global.common.operations'),
+  //   dataIndex: 'id',
+  //   slotName: 'id',
+  //   align: 'center',
+  //   width: 180,
+  //   fixed: "right",
+  // }
 ]
 
 

+ 34 - 19
src/views/lotCard/orderMange/index.vue

@@ -17,10 +17,14 @@
         <!-- 搜索条件区 -->
         <div class="search-section">
             <a-form :model="searchForm" ref="formRef" layout="inline">
-                <a-form-item field="ICCID" :label="$t('lotCard.iccid')" :validate-trigger="['change', 'input', 'blur']"
+                <!-- <a-form-item field="ICCID" :label="$t('lotCard.iccid')" :validate-trigger="['change', 'input', 'blur']"
                     :rules="[{ required: true, message: $t('lotCard.please') + $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.iccid')">
+                    <a-input v-model="searchForm.ICCID" :placeholder="$t('lotCard.please') + $t('lotCard.iccid')"
+                        allow-clear />
                 </a-form-item>
                 <a-form-item field="dataBundleId" :label="$t('lotCard.dataBundleId')">
                     <a-input v-model="searchForm.cardNumber"
@@ -36,18 +40,22 @@
         </div>
 
         <a-table row-key="id" :data="dataSource" :columns="columns" :pagination="pagination"
-            :row-selection="rowSelection" v-model:selectedKeys="selectedKeys" :scroll="{ x: 'auto' }">
+            :row-selection="rowSelection" v-model:selectedKeys="selectedKeys" :scroll="{ x: 'auto' }"
+            @page-change="evChangePage">
             <template #id="{ record }">
-                <!-- 订购生成订单 -->
+                <!-- 获取流量包数据 -->
                 <a-popconfirm :content="$t('lotCard.confirmTitleOrder')" :ok-text="$t('form.Confirm')"
                     :cancel-text="$t('form.Cancel')" @ok="handleOrderDialog(record)">
-                    <a class="a-link" href="javascript:;" style="margin-right: 1rem">{{
-                        $t('lotCard.titleOrder') }}</a>
+                    <a class="a-link" v-if="!(record.status == 1 || record.status == 3)" href="javascript:;"
+                        style="margin-right: 1rem">{{
+                            $t('lotCard.titleOrder') }}</a>
                 </a-popconfirm>
-                <!-- 取消订单-退订 -->
+                <!-- 查看订单日志 -->
+
                 <a-popconfirm :content="$t('lotCard.confirmTitleCancelOrder')" :ok-text="$t('form.Confirm')"
                     :cancel-text="$t('form.Cancel')" @ok="handleUnsubscribeDialog(record)">
-                    <a class="a-link" href="javascript:;" style="margin-right: 1rem">{{ $t('lotCard.titleCancelOrder')
+                    <a class="a-link" v-if="record.status == 1 || record.status == 3" href="javascript:;"
+                        style="margin-right: 1rem">{{ $t('lotCard.titleCancelOrder')
                         }}</a>
                 </a-popconfirm>
             </template>
@@ -61,7 +69,7 @@ import { onMounted, ref, reactive, getCurrentInstance, nextTick } from "vue";
 import { useRoute } from "vue-router";
 import { columns } from "./config";
 import { Message, Notification } from '@arco-design/web-vue'
-import { orderList, setOrderDataPlan, orderCancel } from "@/api/path/lotCard.api"
+import { getOrderLogsList, setOrderDataPlan, orderCancel } from "@/api/path/lotCard.api"
 import { enum_dict } from "@/hooks/enum";
 import { useSystemStore } from '@/store/modules/systemStore'
 
@@ -107,18 +115,22 @@ const intData = async () => {
     const param = {
         current: pagination.value.current,
         size: pagination.value.pageSize,
-        ...searchForm.value,
+        // ...searchForm.value,
     }
-    const { data } = await orderList(param)
-    dataSource.value = data.records || []
+    const { data } = await getOrderLogsList(param)
+    dataSource.value = (data.records || []).map(item => {
+        const dictList = JSON.parse(window.localStorage.getItem('dictList')) ?? []
+        const statusName = (dictList.filter((dicVal) => dicVal.type_key == enum_dict.SUBSCRIPTION_RELATIONSHIP_STATUS) || []).find(val => val.value == item.status)?.label
+        const sourceName = (dictList.filter((dicVal) => dicVal.type_key == enum_dict.SOURCE) || []).find(val => val.value == item.source)?.label
+        return {
+            ...item,
+            sourceName,
+            statusName
+        }
+    })
     pagination.value.total = data.total
 }
 
-// 获取字典值
-const getDictValue = async () => {
-    const dictList = JSON.parse(window.localStorage.getItem('dictList'))
-    const mainList = dictList.filter((item) => item.type_key == enum_dict.MAIN_CARD_STATUS)
-}
 
 
 
@@ -176,13 +188,13 @@ const handleUnsubscribeDialog = async (record) => {
     if (selectedKeys.value.length > 0) {
         const list = dataSource.value.filter(item => selectedKeys.value.some(item2 => item.id === item2))
         list.forEach(item => {
-            if (!(item.status == 2 || item.status == 3)) statusFlag = false
+            if (!(item.status == 1 || item.status == 3)) statusFlag = false
         })
         param = {
             ids: selectedKeys.value
         }
     }
-    if (record && record.id && !(record.status == 2 || record.status == 3)) {
+    if (record && record.id && !(record.status == 1 || record.status == 3)) {
         statusFlag = false
         param = {
             ids: [record.id]
@@ -210,6 +222,10 @@ const handleUnsubscribeDialog = async (record) => {
 
 //
 
+const evChangePage = (current) => {
+    pagination.value.current = current
+    intData()
+}
 const handleSearch = () => {
     formRef.value.validate((errors) => {
         if (!errors) {
@@ -227,7 +243,6 @@ const resetSearch = () => {
 
 onMounted(() => {
     intData()
-    getDictValue()
 })
 </script>
 

+ 4 - 4
src/views/supplier/trafficList/config.js

@@ -3,16 +3,16 @@ export const columns = [
   { title: window.$t('dataPackage.superiorId'), dataIndex: 'superior_id', align: 'center', width: 200 },
   { title: window.$t('dataPackage.typePackage'), dataIndex: 'typePackage', align: 'center', width: 200 },
   { title: window.$t('dataPackage.statusPackage'), dataIndex: 'statusPackage', align: 'center', width: 200 },
-  { title: window.$t('dataPackage.period'), dataIndex: 'period', align: 'center', width: 200 },
-  { title: window.$t('dataPackage.periodType'), dataIndex: 'period_type', align: 'center', width: 200 },
+  { title: window.$t('dataPackage.period'), dataIndex: 'periodName', align: 'center', width: 200 },
+  { title: window.$t('dataPackage.periodType'), dataIndex: 'periodTypeName', align: 'center', width: 200 },
   { title: window.$t('dataPackage.lastModifyTime'), dataIndex: 'last_modify_time', align: 'center', width: 200 },
-  { title: window.$t('dataPackage.activationMode'), dataIndex: 'activation_mode', align: 'center', width: 200 },
+  { title: window.$t('dataPackage.activationMode'), dataIndex: 'activationModeName', align: 'center', width: 300 },
   { title: window.$t('dataPackage.packageCode'), dataIndex: 'packageCode', align: 'center', width: 200 },
   { title: window.$t('dataPackage.packageName'), dataIndex: 'packageName', align: 'center', width: 200 },
   { title: window.$t('dataPackage.operatorName'), dataIndex: 'sourceName', align: 'center', width: 200 },
   { title: window.$t('dataPackage.packageSize'), dataIndex: 'packageSize', align: 'center', width: 200 },
   { title: window.$t('dataPackage.standardPrice'), dataIndex: 'standardPrice', align: 'center', width: 200 },
-  { title: window.$t('dataPackage.statusName'), dataIndex: 'statusName', align: 'center', width: 200 },
+  // { title: window.$t('dataPackage.statusName'), dataIndex: 'statusName', align: 'center', width: 200 },
   {
     title: window.$t('global.common.operations'),
     dataIndex: 'id',

+ 35 - 17
src/views/supplier/trafficList/index.vue

@@ -5,7 +5,7 @@
       <span>{{ route.meta.title }} </span>
     </div>
     <!-- 搜索条件区 -->
-    <div class="search-section">
+    <!-- <div class="search-section">
       <a-form :model="searchForm" ref="formRef" layout="inline">
         <a-form-item field="status" :label="$t('dataPackage.price')">
           <a-input v-model="searchForm.price" :placeholder="$t('form.PleaseEnterThe') + $t('dataPackage.price')"
@@ -22,7 +22,7 @@
           </a-space>
         </a-form-item>
       </a-form>
-    </div>
+    </div> -->
     <div class="audit-btn">
       <a-button @click="showNewDataPackageForm" type="text">
         <template #icon>
@@ -55,9 +55,11 @@ import { onMounted, ref, getCurrentInstance } from "vue";
 import { useRoute } from "vue-router";
 import { columns } from "./config";
 import { Message, Notification } from '@arco-design/web-vue'
-import { dataPlanList } from "@/api/path/lotCard.api"
+import { getDataPlanList } from "@/api/path/lotCard.api"
 import NewDataPackageForm from './NewDataPackageForm.vue';
 import { useI18n } from 'vue-i18n';
+import { enum_dict } from "@/hooks/enum";
+
 
 
 const { t } = useI18n();
@@ -68,6 +70,9 @@ const searchForm = ref({
   "periodType": "",
 });
 
+const sourceList = ref([]);
+const statusList = ref([]);
+const typeList = ref([]);
 const dataSource = ref([]);
 const route = useRoute();
 const pagination = ref({
@@ -84,12 +89,6 @@ const operatorTypeOptions = [
   { value: '4', label: t('dataPackage.operatorTypes.international') },
   { value: '5', label: t('dataPackage.operatorTypes.foreign_local') },
 ];
-// 状态
-const statusList = [
-  { value: '1', label: t('dataPackage.status.offline') },
-  { value: '2', label: t('dataPackage.status.disabled') },
-  { value: '3', label: t('dataPackage.status.normal') },
-]
 
 
 const intData = async () => {
@@ -98,10 +97,17 @@ const intData = async () => {
     size: pagination.value.pageSize,
     ...searchForm.value,
   }
-  const { data } = await dataPlanList(param)
+  const { data } = await getDataPlanList(param)
   dataSource.value = (data?.records || []).map((item, index) => {
-    const sourceName = operatorTypeOptions.find(val => val.value == item.source)?.label
-    const statusName = statusList.find(val => val.value == item.status)?.label
+    const dictList = JSON.parse(window.localStorage.getItem('dictList')) ?? []
+    const periodName = (dictList.filter((dicVal) => dicVal.type_key == enum_dict.FLOW_PERIOD) || []).find(val => val.value == item.period)?.label
+    const periodTypeName = (dictList.filter((dicVal) => dicVal.type_key == enum_dict.CYCLE_TYPE) || []).find(val => val.value == item.period_type)?.label
+    const activationModeName = (dictList.filter((dicVal) => dicVal.type_key == enum_dict.ACTIVATE_METHOD) || []).find(val => val.value == item.activation_mode)?.label
+
+
+    const sourceName = sourceList.value.find(val => val.value == item.source)?.label
+    const typePackage = typeList.value.find(val => val.value == item.type)?.label
+    const statusPackage = statusList.value.find(val => val.value == item.status)?.label
     return {
       ...item,
       packageCode: "NR0" + (index + 1),
@@ -110,11 +116,15 @@ const intData = async () => {
       packageType: '定向',
       billingType: '流量',
       billingPeriod: '按月',
-      packageSize: '1.00',
+      packageSize: '1',
       packageUnit: 'G',
-      standardPrice: '150.00',
-      statusName,
-      sourceName
+      standardPrice: '150',
+      typePackage,
+      sourceName,
+      statusPackage,
+      periodName,
+      activationModeName,
+      periodTypeName
 
     }
   })
@@ -124,6 +134,7 @@ const intData = async () => {
 
 const evChangePage = (page) => {
   pagination.value.current = page
+  intData()
 }
 
 
@@ -176,9 +187,16 @@ const handleNewDataPackageSubmit = (formData) => {
   newDataPackageFormVisible.value = false;
 };
 // -----------------------------------------------------
-
+// 获取字典
+const handleDictValue = () => {
+  const dictList = JSON.parse(window.localStorage.getItem('dictList')) ?? []
+  sourceList.value = dictList.filter((item) => item.type_key == enum_dict.SOURCE)
+  statusList.value = dictList.filter((item) => item.type_key == enum_dict.TRAFFIC_PACKET_STATUS)
+  typeList.value = dictList.filter((item) => item.type_key == enum_dict.TRAFFIC_USAGE_TYPE)
+}
 
 onMounted(() => {
+  handleDictValue()
   intData()
 })
 </script>

+ 17 - 1
src/views/tariffManagement/config.js

@@ -1,4 +1,4 @@
-export const columns = [
+export let columns = [
     { title: window.$t('tariffManagement.id'), dataIndex: 'id', align: 'center', width: 200 },
     { title: window.$t('tariffManagement.feeCode'), dataIndex: 'feeCode', align: 'center', width: 200 },
     { title: window.$t('tariffManagement.label'), dataIndex: 'label', align: 'center', width: 200 },
@@ -21,6 +21,22 @@ export const columns = [
     }
 ]
 
+export const columnsCustomer = [
+    { title: window.$t('tariffManagement.id'), dataIndex: 'id', align: 'center', width: 200 },
+    { title: window.$t('tariffManagement.feeCode'), dataIndex: 'feeCode', align: 'center', width: 200 },
+    { title: window.$t('tariffManagement.label'), dataIndex: 'label', align: 'center', width: 200 },
+    { title: window.$t('tariffManagement.source'), dataIndex: 'sourceName', align: 'center', width: 200 },
+    { title: window.$t('tariffManagement.trafficType'), dataIndex: 'trafficTypeName', align: 'center', width: 200 },
+    { title: window.$t('tariffManagement.billingType'), dataIndex: 'billingTypeName', align: 'center', width: 200 },
+    { title: window.$t('tariffManagement.billingCycle'), dataIndex: 'billingCycleName', align: 'center', width: 200 },
+    { title: window.$t('tariffManagement.bagSize'), dataIndex: 'bag_size', align: 'center', width: 200 },
+    { title: window.$t('tariffManagement.pricing'), dataIndex: 'pricing', align: 'center', width: 200 },
+    // { title: window.$t('tariffManagement.billingMethod'), dataIndex: 'billing_method', align: 'center', width: 200 },
+    { title: window.$t('tariffManagement.settlementCycleLabel'), dataIndex: 'settlement_cycle', align: 'center', width: 200 },
+    { title: window.$t('tariffManagement.feeStatus'), dataIndex: 'status', align: 'center', width: 200 },
+]
+
+
 export const planColumns = [
     { title: window.$t('tariffManagement.feeCode'), dataIndex: 'feeCode', align: 'center', width: 200 },
     { title: window.$t('tariffManagement.label'), dataIndex: 'label', align: 'center', width: 200 },

+ 51 - 44
src/views/tariffManagement/index.vue

@@ -10,9 +10,9 @@
         <!-- 搜索条件区 -->
         <div class="search-section">
             <a-form :model="searchForm" layout="inline">
-                <a-form-item field="sim_data_plan_id" :label="$t('tariffManagement.simDataPlanId')">
-                    <a-input v-model="searchForm.sim_data_plan_id"
-                        :placeholder="$t('lotCard.please') + $t('tariffManagement.simDataPlanId')" allow-clear />
+                <a-form-item field="label" :label="$t('tariffManagement.label')">
+                    <a-input v-model="searchForm.label"
+                        :placeholder="$t('lotCard.please') + $t('tariffManagement.label')" allow-clear />
                 </a-form-item>
                 <a-form-item>
                     <a-space>
@@ -24,7 +24,7 @@
         </div>
 
         <div class="audit-btn">
-            <a-button type="text" @click="dictShowModel(1, null)">
+            <a-button type="text" @click="dictShowModel(1, null)" v-if="role.getRole == 1">
                 <template #icon>
                     <icon-plus-circle />
                 </template>
@@ -32,8 +32,8 @@
             </a-button>
         </div>
 
-        <a-table row-key="id" :data="dataSource" :columns="columns" :pagination="pagination"
-            :row-selection="rowSelection" v-model:selectedKeys="selectedKeys" :scroll="{ x: 'auto' }">
+        <a-table row-key="id" :data="dataSource" :columns="role.getRole == 1 ? columns : columnsCustomer"
+            :pagination="pagination" :scroll="{ x: 'auto' }" @page-change="evChangePage">
             <template #id="{ record }">
                 <!-- 修改 -->
                 <a class="a-link" href="javascript:;" style="margin-right: 1rem" @click="dictShowModel(2, record)">{{
@@ -54,13 +54,21 @@
             @onCancel="resetForm" centered :maskClosable="false" :footer="null">
             <a-form ref="formRef" :rules="rules" :model="formState" @submit="handleSubmit">
                 <div class="formTitle">基本信息</div>
-
-                <a-form-item :label="$t('tariffManagement.simDataPlanId')" field="sim_data_plan_id">
-                    <a-select v-model="formState.sim_data_plan_id">
-                        <a-option v-for=" item in planList" :key="item.superior_id" :value="item.id"> 流量包{{ item.id
+                <a-form-item :label="$t('tariffManagement.source')" field="source">
+                    <a-select v-model="formState.source">
+                        <a-option v-for=" item in sourceList" :key="item.id" :value="item.value">{{ item.label
                             }}</a-option>
                     </a-select>
                 </a-form-item>
+                <template v-if="formState.source">
+                    <a-form-item :label="$t('tariffManagement.simDataPlanId')" field="sim_data_plan_id">
+                        <a-select v-model="formState.sim_data_plan_id">
+                            <a-option v-for=" item in planList" :key="item.superior_id" :value="item.id"> 流量包{{ item.id
+                                }}</a-option>
+                        </a-select>
+                    </a-form-item>
+                </template>
+
                 <a-form-item :label="$t('tariffManagement.feeCode')" field="feeCode" required="">
                     <a-input v-model="formState.feeCode" />
                 </a-form-item>
@@ -73,12 +81,6 @@
                             }}</a-option>
                     </a-select>
                 </a-form-item>
-                <a-form-item :label="$t('tariffManagement.source')" field="source">
-                    <a-select v-model="formState.source">
-                        <a-option v-for=" item in sourceList" :key="item.id" :value="item.value">{{ item.label
-                            }}</a-option>
-                    </a-select>
-                </a-form-item>
                 <a-form-item :label="$t('tariffManagement.trafficType')" field="traffic_type">
                     <a-select v-model="formState.traffic_type">
                         <a-option v-for=" item in trafficList" :key="item.id" :value="item.value">{{ item.label
@@ -215,22 +217,23 @@
 </template>
 
 <script setup>
-import { onMounted, ref, reactive, getCurrentInstance, nextTick } from "vue";
+import { onMounted, ref, reactive, getCurrentInstance, nextTick, watch } from "vue";
 import { useRoute } from "vue-router";
-import { columns, planColumns } from "./config";
+import { columns, columnsCustomer, planColumns } from "./config";
 import { Message, Notification } from '@arco-design/web-vue'
 import { deleteTariff, updateTariff, addTariff, tariffList } from "@/api/path/tariffManagement.api"
-import { dataPlanList } from "@/api/path/lotCard.api"
+import { getDataPlanList } from "@/api/path/lotCard.api"
 import { userList } from '@/api/path/system.api'
 
 import { enum_dict } from "@/hooks/enum";
 import { useSystemStore } from '@/store/modules/systemStore'
+const role = useSystemStore()
 
 
 const { proxy } = getCurrentInstance()
 const formRef = ref()
 const searchForm = ref({
-    "sim_data_plan_id": "",
+    "label": "",
 });
 
 
@@ -296,13 +299,16 @@ const handleDel = async (id) => {
     }
 };
 
-//
+const evChangePage = (page) => {
+    pagination.value.current = page
+    intData()
+}
 
 const handleSearch = () => {
     intData()
 }
 const resetSearch = () => {
-    proxy.$refs.formRef.resetFields()
+    searchForm.value.label = ""
     intData()
 }
 
@@ -458,18 +464,26 @@ const dictShowModel = (type, data) => {
     })
 }
 
+// 获取id数组
 const handleModelId = async () => {
     const param = {
         current: 1,
         size: 999,
     }
-    dataPlanList(param).then(res => {
-        planList.value = res.data.records || []
-    })
     userList(param).then(res => {
         userIdList.value = (res.data.records || []).filter((item) => item.user_type == '2')
     })
 }
+const handleDataPlan = async () => {
+    const param = {
+        current: 1,
+        size: 999,
+        source: formState.value.source
+    }
+    getDataPlanList(param).then(res => {
+        planList.value = res.data.records || []
+    })
+}
 // 取消
 const resetForm = () => {
     visible.value = false;
@@ -489,26 +503,7 @@ const rowSelectionPlan = reactive({
     onlyCurrent: false,
 });
 
-const handlePlan = async () => {
-    planVisible.value = true
-    const param = {
-        current: 1,
-        size: 10,
-        ...formData.value,
-    }
-    const { data } = await dataPlanList(param)
-    planList.value = (data.records || []).map((item, index) => {
-        const sourceName = sourceList.value.find(val => val.value == item.source)?.label
-        return {
-            ...item,
-            sourceName,
-            label: "资费" + (index + 1),
-            feeCode: "NR0" + (index + 1),
-            bag_size: "2.0MB"
-        }
-    })
 
-}
 const resetSearchPlan = () => {
 
 }
@@ -525,6 +520,18 @@ const handleSubmitPlan = () => {
     }
 
 }
+
+watch(
+    () => formState.value.source,
+    (newValue, oldValue) => {
+
+        if (newValue != oldValue) {
+            handleDataPlan()
+        }
+    },
+    { immediate: true }
+);
+
 // -------------------------------------------------------
 // 获取字典
 const handleDictValue = () => {