Bladeren bron

卡跟流量 管理

wanghairong 5 maanden geleden
bovenliggende
commit
85f0bd64aa

+ 4 - 2
src/hooks/enum.js

@@ -4,17 +4,19 @@ 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", // 来源(资费列表)
     BILLING_CYCLE: "Billingcycle", // 计费周期
     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", // 激活方式-激活计费方式
 };

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

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

+ 5 - 12
src/views/flowPool/index.vue

@@ -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>
@@ -97,13 +89,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')">
@@ -306,6 +298,7 @@ const { proxy } = getCurrentInstance()
 const formRef = ref()
 const searchForm = ref({
     "label": "",
+    "traffic_pool_type": "1"
 });
 
 const dataSource = ref([]);
@@ -455,7 +448,7 @@ const formState = ref({
     // 流量包名称
     "label": "",
     // 流量池类型: 1: 前流量池 2: 后流量池
-    "traffic_pool_type": "",
+    "traffic_pool_type": "1",
     // 来源
     "source": "",
     // 流量包状态:1:正常(发布计划状态)2:线下暂停销售

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

@@ -0,0 +1,821 @@
+<!-- 后流量池 -->
+<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">
+                <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"
+            :rowSelection="rowSelection" v-model:selected-keys="selectedKeys" :scroll="{ x: 'auto' }">
+            <template #id="{ record }">
+                <!-- 修改 -->
+                <a class="a-link" href="javascript:;" style="margin-right: 1rem" @click="dictShowModel(2, record)">{{
+                    $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)">
+                    <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";
+
+
+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 handleSearch = () => {
+    intData()
+}
+const resetSearch = () => {
+    proxy.$refs.formRef.resetFields()
+    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>

+ 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 = [

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

@@ -86,12 +86,12 @@ const intData = async () => {
   }
   const { data } = await cardInfoList(param)
 
-  dataSource.value = (data.records || []).map((item, index) => {
+  dataSource.value = (data.records || []).map((item) => {
     // 卡下级信息
     let orderArr = []
     orderList({ current: 1, size: 999, ICCID: item.iccid }).then(res => {
 
-      res.data.records?.forEach(async (orderItem) => {
+      res.data.records?.forEach(async (orderItem, index) => {
 
         const params = {
           // iccid: orderItem.ICCID,
@@ -101,7 +101,8 @@ const intData = async () => {
         }
 
         let trafficList = []
-        if ((item.iccid == '89852342022040149139' && index < 5) || item.iccid !== '89852342022040149139') {
+
+        if (item.iccid == '89852342022040149139' && index < 5 || !(item.iccid == '89852342022040149139')) {
           const { data } = await orderFlowData(params)
           trafficList = data.historyData || []
           orderArr.push({

+ 6 - 4
src/views/lotCard/cardList/list.vue

@@ -3,7 +3,9 @@
     <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"></div>
+                <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">订单ID:{{ item.orderId }}</span>
@@ -58,9 +60,9 @@ span {
     margin-bottom: 10px;
 
     .list_item_left {
-        width: 50px;
-        height: 50px;
-        background: gainsboro;
+        width: 60px;
+        height: 60px;
+        // background: gainsboro;
         margin-right: 10px;
     }
 

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

@@ -9,8 +9,8 @@ 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'),

+ 18 - 12
src/views/lotCard/orderMange/index.vue

@@ -41,13 +41,16 @@
                 <!-- 订购生成订单 -->
                 <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>
@@ -110,15 +113,19 @@ const intData = async () => {
         ...searchForm.value,
     }
     const { data } = await orderList(param)
-    dataSource.value = data.records || []
+    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 +183,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]
@@ -227,7 +234,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',

+ 30 - 13
src/views/supplier/trafficList/index.vue

@@ -58,6 +58,8 @@ import { Message, Notification } from '@arco-design/web-vue'
 import { dataPlanList } 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 () => {
@@ -100,8 +99,15 @@ const intData = async () => {
   }
   const { data } = await dataPlanList(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
 
     }
   })
@@ -176,9 +186,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>