فهرست منبع

Merge branch 'main' of http://gogs.ainets.net/mirendemianbaona/nc-admin into chentao

陈景夏 4 ماه پیش
والد
کامیت
5291951b42
60فایلهای تغییر یافته به همراه4661 افزوده شده و 4520 حذف شده
  1. 1 1
      src/api/customer.js
  2. 1 1
      src/api/finance.js
  3. 1 1
      src/api/path/component.api.js
  4. 3 3
      src/api/path/dict.js
  5. 1 1
      src/api/path/dictionary.js
  6. 18 3
      src/api/path/flowPool.api.js
  7. 1 1
      src/api/path/login.api.js
  8. 1 1
      src/api/path/lotCard.api.js
  9. 41 0
      src/api/path/order.js
  10. 2 2
      src/api/path/purchase.js
  11. 1 1
      src/api/path/star.api.js
  12. 1 1
      src/api/path/system.api.js
  13. 23 4
      src/api/path/tariffManagement.api.js
  14. 0 1
      src/components/Layout/components/layout/blendLeft.vue
  15. 38 34
      src/components/Layout/components/layoutHeader/index.vue
  16. 101 0
      src/components/Search/index.vue
  17. 78 68
      src/components/upload/index.vue
  18. 2 2
      src/i18n/zh/tariffManagement.js
  19. 4 5
      src/mixins/index.js
  20. 44 0
      src/store/modules/Login.js
  21. 38 22
      src/store/modules/routerTag.js
  22. 0 1
      src/utils/axios.js
  23. 85 0
      src/utils/cache.js
  24. 8 0
      src/utils/router.js
  25. 238 0
      src/views/flowPool/components/add.vue
  26. 267 0
      src/views/flowPool/components/forewarning.vue
  27. 189 0
      src/views/flowPool/components/openExport.vue
  28. 1 1
      src/views/flowPool/config.js
  29. 15 12
      src/views/flowPool/customerFlowPool/config.js
  30. 12 52
      src/views/flowPool/customerFlowPool/index.vue
  31. 77 602
      src/views/flowPool/index.vue
  32. 168 580
      src/views/flowPool/rearFlowPool/index.vue
  33. 38 26
      src/views/login/login-form.vue
  34. 41 32
      src/views/lotCard/cardList/config.js
  35. 29 83
      src/views/lotCard/cardList/index.vue
  36. 0 94
      src/views/lotCard/cardList/list.vue
  37. 362 352
      src/views/lotCard/cardList/trafficUseDialog.vue
  38. 199 0
      src/views/order/BuyCard/Card.vue
  39. 196 0
      src/views/order/BuyCard/detaile.vue
  40. 0 428
      src/views/order/BuyCard/index copy.vue
  41. 168 476
      src/views/order/BuyCard/index.vue
  42. 50 0
      src/views/order/BuyCard/returnCard.vue
  43. 81 0
      src/views/order/BuyCard/status.vue
  44. 161 0
      src/views/order/CancelOrder/detaile.vue
  45. 149 339
      src/views/order/CancelOrder/index.vue
  46. 81 0
      src/views/order/CancelOrder/status.vue
  47. 161 0
      src/views/order/RenewalOrder/detaile.vue
  48. 152 332
      src/views/order/RenewalOrder/index.vue
  49. 81 0
      src/views/order/RenewalOrder/status.vue
  50. 161 0
      src/views/order/ReturnCard/detaile.vue
  51. 58 280
      src/views/order/ReturnCard/index.vue
  52. 81 0
      src/views/order/ReturnCard/status.vue
  53. 55 70
      src/views/system/dict/index.vue
  54. 349 0
      src/views/tariffManagement/Management/add.vue
  55. 172 0
      src/views/tariffManagement/Management/meal.vue
  56. 39 31
      src/views/tariffManagement/config.js
  57. 152 90
      src/views/tariffManagement/customer/NewCustomerForm.vue
  58. 7 7
      src/views/tariffManagement/customer/index.vue
  59. 115 412
      src/views/tariffManagement/index.vue
  60. 63 68
      vite.config.js

+ 1 - 1
src/api/customer.js

@@ -1,4 +1,4 @@
-import service from './axios'
+import service from '../utils/axios'
 
 export function getCustomerList(data) {
     return service({

+ 1 - 1
src/api/finance.js

@@ -1,4 +1,4 @@
-import service from './axios'
+import service from '../utils/axios'
 
 // 查询充值记录
 export function getTopUpRecordList(data) {

+ 1 - 1
src/api/path/component.api.js

@@ -1,5 +1,5 @@
 
-import service from '../axios'
+import service from '../../utils/axios'
 
 // 保存物料
 export function componentSave(param) {

+ 3 - 3
src/api/path/dict.js

@@ -1,4 +1,4 @@
-import service from '../axios'
+import service from '../../utils/axios'
 
 // 字典列表
 export function dictionaryList(param) {
@@ -7,7 +7,7 @@ export function dictionaryList(param) {
 
 // 获取字典
 export function dictionaryDetail(params) {
-    return service.get('/admin/system/getDic', { params })
+    return service.get('/admin/system/getEnu', { params })
 }
 
 // 添加字典
@@ -27,5 +27,5 @@ export function dictionaryDelete(params) {
 
 // 获取下级分类
 export function dictionaryDeleteAll(params) {
-    return service.get('/admin/system/getDic', { params })
+    return service.get('/admin/system/getEnu', { params })
 }

+ 1 - 1
src/api/path/dictionary.js

@@ -1,4 +1,4 @@
-import service from '../axios'
+import service from '../../utils/axios'
 
 // 获取字典列表
 export function getDictionaryList(param) {

+ 18 - 3
src/api/path/flowPool.api.js

@@ -1,5 +1,5 @@
 
-import service from '../axios'
+import service from '../../utils/axios'
 
 // 分销商
 // 新增
@@ -8,7 +8,7 @@ export function addTrafficPool(param) {
 }
 // list
 export function trafficPoolList(param) {
-    return service.post('/admin/platform/trafficPoolList', param)
+    return service.post('/admin/platform/tariffList', param)
 }
 // 编辑
 export function updateTrafficPool(param) {
@@ -27,4 +27,19 @@ export  function  getCardList (data) {
 // 获取资费下卡列表
 export  function  updateCardList (params) {
     return service.get('admin/platform/getTariffCard',{params})
-}
+}
+
+// 流量池接口
+export function lotCatdList(data){
+    return service.post('/admin/platform/trafficPoolList', data)
+}
+
+// 创建预警
+export  function  createWarning(data){
+    return service.post('/admin/alert/warningCreate',data)
+}
+
+// 修改预警
+export  function  updateWarning(data){
+    return service.post('/admin/alert/warningUpdate',data)
+}

+ 1 - 1
src/api/path/login.api.js

@@ -1,5 +1,5 @@
 
-import service from '../axios'
+import service from '../../utils/axios'
 
 // * 登录
 export function loginApi(data) {

+ 1 - 1
src/api/path/lotCard.api.js

@@ -1,4 +1,4 @@
-import service from "../axios";
+import service from "../../utils/axios";
 
 
 // ----------------------------流量管理---------------------------------

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

@@ -0,0 +1,41 @@
+import service from "../../utils/axios";
+
+// 订单审核
+export function OrderCardStatus(data){
+     return service.post("/admin/sim/applyAudit", data);
+}
+
+// 上传订单合同
+export function UploadOrderCardContract(data){
+     return service.post("/admin/sim/uploadContract", data);
+}
+
+// 购卡
+export function CardPurchase(data){
+    return service.post('/admin/sim/apply',data)
+}
+
+// 分配卡号
+export function DistributionCard(data){
+     return service.post("/admin/sim/assignSim", data);
+}
+
+// 查看订单下的卡
+export function viewOrderCard(params){
+    return service.get("/admin/sim/orderCard", {params});
+}
+
+// 获取资费
+export function AcquireOrdertariff(params){
+     return service.get("/admin/platform/getTariffById", {params});
+}
+
+// 获取资费下的卡
+export function TariffOrderCard(params){
+     return service.get("/admin/platform/getTariffCard", {params});
+}
+
+// 退卡
+export function ReturntheCard(data){
+     return service.post("/admin/sim/returnCard", data);
+}

+ 2 - 2
src/api/path/purchase.js

@@ -1,4 +1,4 @@
-import service from '../axios'
+import service from '../../utils/axios'
 
 // 采购订单分页查询
 export function purchaseOrderList(param) {
@@ -23,5 +23,5 @@ export function platformUpdate(params) {
 
 // 退卡
 export function cancelOrderList(params) {
-    return service.post("/admin/sim/cancelOrderList", params);
+    return service.post("/admin/sim/returnCardList", params);
 }

+ 1 - 1
src/api/path/star.api.js

@@ -1,5 +1,5 @@
 
-import service from '../axios'
+import service from '../../utils/axios'
 
 // 分销商
 // 新增

+ 1 - 1
src/api/path/system.api.js

@@ -1,5 +1,5 @@
 
-import service from '../axios'
+import service from '../../utils/axios'
 
 // 获取菜单
 

+ 23 - 4
src/api/path/tariffManagement.api.js

@@ -1,5 +1,4 @@
-
-import service from '../axios'
+import service from '../../utils/axios'
 
 // 查询资费计划
 export function tariffList(param) {
@@ -21,7 +20,27 @@ export function deleteTariff(params) {
     return service.get('/admin/platform/deleteTariff', { params })
 }
 
-// 资费计划详情
-export function getTariffList(params) {
+// 添加资费套餐
+export function addTariffPackage(data) {
+    return service.post('/admin/platform/addTariffProduct', data)
+}
+
+// 查询资费商品
+export function CheckTariffPackages(params) {
+    return service.get('/admin/platform/tariffProductList', { params })
+}
+
+// 更新资费商品
+export function UpdateTariffTtems(data) {
+    return service.post('/admin/platform/updateTariffProduct', data)
+}
+
+// 删除资费商品
+export function DeleteTariffItems(params) {
+    return service.get('/admin/platform/deleteTariffProduct', { params })
+}
 
+// 查询客户下的流量池
+export function ExampleQueryTrafficPool() {
+    return service.get('/admin/platform/customerTrafficPool')
 }

+ 0 - 1
src/components/Layout/components/layout/blendLeft.vue

@@ -91,7 +91,6 @@ const evMenuSecondLongShow = () => {
   });
 };
 const evMouseleaveMenu = (e) => {
-
   if (
     e.relatedTarget?.offsetParent?.id &&
     e.relatedTarget?.offsetParent?.id == "layout-sider"

+ 38 - 34
src/components/Layout/components/layoutHeader/index.vue

@@ -2,72 +2,70 @@
   <div class="header">
     <!--    标签-->
     <div class="flex-left-tag">
-<!--      <a-space wrap>-->
-<!--        <a-tag-->
-<!--            v-for="(tag, index) in tags"-->
-<!--            :key="tag.name"-->
-<!--            :closable="index !== 0"-->
-<!--            @close="settingStore.handleRemove(tag)"-->
-<!--        >-->
-<!--          {{ tag.meta.title }}-->
-<!--        </a-tag>-->
-<!--      </a-space>-->
+      <!--      <a-space wrap>-->
+      <!--        <a-tag-->
+      <!--            v-for="(tag, index) in tags"-->
+      <!--            :key="tag.name"-->
+      <!--            :closable="index !== 0"-->
+      <!--            @close="settingStore.handleRemove(tag)"-->
+      <!--        >-->
+      <!--          {{ tag.meta.title }}-->
+      <!--        </a-tag>-->
+      <!--      </a-space>-->
     </div>
     <!--    个人信息和操作-->
     <div class="flex-right-user">
-      <a-select :style="{width:'100px'}" v-model="langStore.lang" :bordered="false" @change="toggleLang">
+      <a-select :style="{ width: '100px' }" v-model="langStore.lang" :bordered="false" @change="toggleLang">
         <a-option v-for="item in langList" :key="item.key" :value="item.key">{{ item.label }}</a-option>
       </a-select>
 
       <div class="toggle-theme-box">
-        <icon-sun-fill v-if="designStore.getDarkTheme" @click="toggleTheme(false)" :size="18"/>
-        <icon-moon-fill v-else @click="toggleTheme(true)" :size="18"/>
+        <icon-sun-fill v-if="designStore.getDarkTheme" @click="toggleTheme(false)" :size="18" />
+        <icon-moon-fill v-else @click="toggleTheme(true)" :size="18" />
       </div>
 
       <a-dropdown trigger="click">
         <a-avatar :size="38" class="avatar-body">
-          <img
-              class="avatar-image"
-              alt="avatar"
-              src="https://avatars.githubusercontent.com/u/39849555?v=4"
-          />
+          <img class="avatar-image" alt="avatar" src="https://avatars.githubusercontent.com/u/39849555?v=4" />
         </a-avatar>
         <template #content>
           <a-doption>
             <a-space @click="evHandleLogout">
-              <icon-export/>
+              <icon-export />
               <span>{{ $t('global.logOut') }}</span>
             </a-space>
           </a-doption>
         </template>
       </a-dropdown>
+
+      <div class="userName">{{ userInfor?.username }}</div>
     </div>
   </div>
 </template>
 
 <script setup>
-import {ref, inject, onMounted, watch, reactive} from 'vue'
-import {useRouter} from 'vue-router'
-import {useSystemStore} from '@/store/modules/systemStore'
-import {Notification} from '@arco-design/web-vue'
-import {useDesignStore} from '@/store/modules/designStore'
-import {useLangStore} from '@/store/modules/langStore'
-import {useI18n} from 'vue-i18n'
-import {langList} from '@/i18n'
-import {fn_logout} from '@/utils'
-import {RouterTagData} from '@/store/modules/routerTag.js'
+import { ref, inject, onMounted, watch, reactive } from 'vue'
+import { useRouter } from 'vue-router'
+import { useSystemStore } from '@/store/modules/systemStore'
+import { Notification } from '@arco-design/web-vue'
+import { useDesignStore } from '@/store/modules/designStore'
+import { useLangStore } from '@/store/modules/langStore'
+import { useI18n } from 'vue-i18n'
+import { langList } from '@/i18n'
+import { fn_logout } from '@/utils'
+import { RouterTagData } from '@/store/modules/routerTag.js'
 import { setLocalStorage, getLocalStorage } from "@/utils";
 // 标签页仓库
 const settingStore = RouterTagData()
-import {updateRouteByMenu} from "@/router/router.update.js"
+import { updateRouteByMenu } from "@/router/router.update.js"
 
 
 const router = useRouter()
-const {locale} = useI18n()
+const { locale } = useI18n()
 const systemStore = useSystemStore()
 const designStore = useDesignStore()
 const langStore = useLangStore()
-
+const userInfor = ref(null)
 
 // const reload  = inject('reloadRoutePage')
 
@@ -95,8 +93,9 @@ const evHandleLogout = () => {
     name: "login",
   })
 }
-
-
+onMounted(() => {
+  userInfor.value = JSON.parse(localStorage.getItem('user_login_information'))
+})
 
 </script>
 
@@ -136,4 +135,9 @@ const evHandleLogout = () => {
 :deep(.arco-select-view-suffix) {
   padding: 0;
 }
+
+.userName {
+  margin-left: 10px;
+  font-size: 16px;
+}
 </style>

+ 101 - 0
src/components/Search/index.vue

@@ -0,0 +1,101 @@
+<template>
+    <div ref="search">
+        <!-- 动态渲染表单项 -->
+        <a-form :model="formState" layout="inline">
+            <a-form-item v-for="(item, index) in SearchForm" :key="index" :label="item.label" :field="item.field">
+                <component :is="'a-' + item.type" v-model="formState[item.field].value" :placeholder="item.placeholder"
+                    allow-clear :style="{ width: item.width ? item.width + 'px' : '' }">
+                    <template v-if="item.type == 'select'">
+                        <a-option v-for="option in item.options" :key="option.value" :value="option.value">
+                            {{ option.label }}
+                        </a-option>
+                    </template>
+                </component>
+            </a-form-item>
+            <a-form-item>
+                <a-button type="primary" @click="handleQuery">查询</a-button>
+                <a-button @click="handleReset" style="margin-left: 10px;">重置</a-button>
+            </a-form-item>
+        </a-form>
+    </div>
+</template>
+
+<script setup>
+import { ref, defineProps, toRefs, onMounted, watch, watchEffect } from 'vue';
+import { Getdictionary } from "@/mixins/index.js";
+
+// 接收 props
+const props = defineProps({
+    SearchForm: {
+        type: Array,
+        default: () => [
+            {
+                type: 'input',
+                label: '字典名称',
+                field: 'source',
+                placeholder: '请输入字典名称',
+                value: '', // 双向绑定的值
+            },
+            {
+                type: 'input',
+                label: '资费ID',
+                field: 'trafficId',
+                placeholder: '请输入资费ID',
+                value: '', // 双向绑定的值
+            },
+            {
+                type: 'select',
+                label: '卡类型',
+                field: 'simType',
+                placeholder: '选择卡类型',
+                options: [], // 默认空,后面会通过字典加载
+                dict:'CardType',
+                value: '', // 双向绑定的值
+                width: '200'
+            },
+        ],
+    },
+});
+
+const { SearchForm } = toRefs(props);
+
+// 初始化 formState,确保每个字段都是对象,包含 `value` 属性
+const formState = ref({});
+SearchForm.value.forEach(item => {
+    formState.value[item.field] = {
+        value: item.value, // 初始化为字段的默认值
+    };
+});
+
+// 字典加载
+const loadedDicts = ref({}); // 存储已加载的字典
+const loadDictOptions = async (index, dict) => {
+    if (loadedDicts.value[dict]) {
+        // 如果字典已加载,则直接使用缓存的字典数据
+        SearchForm.value[index].options = loadedDicts.value[dict];
+        return;
+    }
+    const dictionary = await Getdictionary(dict);
+    loadedDicts.value[dict] = dictionary || []; // 更新缓存
+    SearchForm.value[index].options = loadedDicts.value[dict]; // 更新 options
+};
+
+// 监听 SearchForm 更新,加载字典
+watch(
+  () => SearchForm.value, // 只监听 SearchForm 的变化
+  async () => {
+    for (let index = 0; index < SearchForm.value.length; index++) {
+        const item = SearchForm.value[index];
+        if (item.dict && !loadedDicts.value[item.dict]) {
+            await loadDictOptions(index, item.dict); // 加载字典
+        }
+    }
+}, { immediate: true });
+
+// 查询操作
+const handleQuery = () => {
+    // 将表单数据通过事件传递给父组件
+    emit('query', formState.value);
+};
+
+</script>

+ 78 - 68
src/components/upload/index.vue

@@ -1,26 +1,45 @@
 <template>
-  <a-upload
-    :show-file-list="true"
-    :custom-request="customRequest"
-    list-type="picture-card"
-    :file-list="fileList"
-    :limit="minx"
-    @before-remove="beforeRemove"
-    image-preview
-    @before-upload="beforeUpload"
-  />
+  <a-upload :show-file-list="true" :custom-request="handelUpload == null ? customRequest : handelUpload"
+    :list-type="listType" :file-list="fileList" :limit="minx" @before-remove="beforeRemove" :show-remove-button="showRemoveButton" :show-cancel-button="false"
+    :image-preview="imagePreview" :accept="accept" @before-upload="beforeUpload" />
 </template>
 
 <script setup>
-import { toRef, ref, watch, watchEffect } from "vue";
-import { useSystemStore } from "@/store/modules/systemStore";
+import { toRef, ref, watch, watchEffect, onMounted } from 'vue';
+import { useSystemStore } from '@/store/modules/systemStore';
 import { Modal } from "@arco-design/web-vue";
-import { useI18n } from "vue-i18n";
+import { useI18n } from 'vue-i18n';
 import { Message } from "@arco-design/web-vue";
 
 const systemStore = useSystemStore();
 const { t } = useI18n();
 
+// 自定义请求:上传文件的处理逻辑
+const customRequest = async (option) => {
+  const { file } = option.fileItem;
+  const fileName = `thumbnail_${file.name}`;
+  const key = `test/${fileName}`;
+
+  // 获取上传客户端(假设 systemStore 已经定义了上传接口)
+  const client = await systemStore.getSTSClient();
+  const resClient = await client.putObject({
+    key: key,
+    body: file
+  });
+
+
+  // 上传成功后,更新 fileList 和 modelValue
+  if (resClient.statusCode === 200) {
+    const uploadedFileUrl = resClient.url;
+    fileList.value.push({ url: uploadedFileUrl, name: fileName, status: resClient.statusCode, uid: '0' });
+    // 更新父组件的 modelValue
+    if (minx.value === 1) {
+      emit('update:modelValue', uploadedFileUrl);
+    } else {
+      emit('update:modelValue', fileList.value.map(res => res.url).join(','));
+    }
+  }
+};
 // 接收外部传入的 props:modelValue 和 minx
 const props = defineProps({
   modelValue: {
@@ -29,7 +48,27 @@ const props = defineProps({
   },
   minx: {
     type: Number,
-    default: 1,
+    default: 1
+  },
+  listType: {
+    type: String,
+    default: 'picture-card'
+  },// 上传样式
+  imagePreview: {
+    type: Boolean,
+    default: true
+  }, // 是否支持预览
+  accept: {
+    type: String,
+    default: ''
+  }, // 上传文件类型
+  handelUpload: {
+    type: Function,
+    default: null  // 外部传入的自定义上传方法
+  },
+  showRemoveButton:{
+    type: Boolean,
+    default: true  // 是否显示删除按钮
   },
   beforeUpload: {
     type: Boolean,
@@ -38,66 +77,17 @@ const props = defineProps({
 });
 
 // 使用 toRef 确保对 props 的访问是响应式的
-const minx = toRef(props, "minx");
-const modelValue = toRef(props, "modelValue");
-
+const minx = toRef(props, 'minx');
+const modelValue = toRef(props, 'modelValue');
+const listType = toRef(props, 'listType');
+const imagePreview = toRef(props, 'imagePreview');
+const handelUpload = toRef(props, 'handelUpload');
 // 定义 emit,用于向外抛出事件
 const emit = defineEmits(["update:modelValue"]);
 
 // 用于存储文件列表,初始化时显示传递给子组件的值
 const fileList = ref([]);
 
-// 初始化:根据外部传入的 modelValue 进行文件列表的设置
-watchEffect(() => {
-  if (modelValue.value) {
-    if (Array.isArray(modelValue.value)) {
-      // 如果传递的是数组,则直接使用
-      fileList.value = modelValue.value.map((item) => ({ url: item }));
-    } else if (typeof modelValue.value === "string") {
-      // 如果传递的是字符串,则将字符串按逗号分割成数组
-      const urlList = modelValue.value
-        .split(",")
-        .map((url) => ({ url: url.trim() }));
-      fileList.value = urlList;
-    }
-  } else {
-    fileList.value = [];
-  }
-});
-
-// 自定义请求:上传文件的处理逻辑
-const customRequest = async (option) => {
-  const { file } = option.fileItem;
-  const fileName = `thumbnail_${file.name}`;
-  const key = `test/${fileName}`;
-
-  try {
-    // 获取上传客户端(假设 systemStore 已经定义了上传接口)
-    const client = await systemStore.getSTSClient();
-    const resClient = await client.putObject({
-      key: key,
-      body: file,
-    });
-
-    // 上传成功后,更新 fileList 和 modelValue
-    if (resClient.statusCode === 200) {
-      const uploadedFileUrl = resClient.url;
-      fileList.value.push({ url: uploadedFileUrl });
-
-      // 更新父组件的 modelValue
-      if (minx.value === 1) {
-        emit("update:modelValue", uploadedFileUrl);
-      } else {
-        emit(
-          "update:modelValue",
-          fileList.value.map((res) => res.url).join(",")
-        );
-      }
-    }
-  } catch (error) {
-    console.error("上传失败", error);
-  }
-};
 
 // 删除文件处理逻辑
 const beforeRemove = (file) => {
@@ -125,6 +115,25 @@ const beforeRemove = (file) => {
   });
 };
 
+watchEffect(() => {
+  if (modelValue.value) {
+    if (Array.isArray(modelValue.value)) {
+      // 如果传递的是数组,则直接使用
+      fileList.value = modelValue.value.map(item => ({ url: item, status: item.status, name: item.name }));
+    } else if (typeof modelValue.value === 'string') {
+      // 如果传递的是字符串,则将字符串按逗号分割成数组
+      const urlList = modelValue.value.split(',').map(url => ({ url: url.trim() }));
+      fileList.value = urlList;
+    }
+  } else {
+    fileList.value = [];
+  }
+})
+
+onMounted(() => {
+
+})
+
 // 上传前校验
 const beforeUpload = (rawFile) => {
   if(!props.beforeUpload) return true
@@ -141,6 +150,7 @@ const beforeUpload = (rawFile) => {
   }
   return true;
 };
+
 </script>
 
 <style scoped>

+ 2 - 2
src/i18n/zh/tariffManagement.js

@@ -8,7 +8,7 @@ export default {
     billingType: "计费分类",//计费方式
     billingCycle: "计费周期",
     bagSize: "资费包大小",
-    pricing: "标准价格",
+    pricing: "结算价格",
     settlementCycle: "周期限制",// 结算周期
     settlementCycleLabel: "周期限制(月)",// 结算周期
 
@@ -35,5 +35,5 @@ export default {
     userName:'客户名称',
     MRCName:'MRC费(月租)',
     networkName:'网络接入费',
-    ActivatedNames:'流量总数'
+    ActivatedNames:'流量大小'
 }

+ 4 - 5
src/mixins/index.js

@@ -1,10 +1,9 @@
-import {dictionaryDeleteAll} from '@/api/path/dict.js'
-
-
+import { dictionaryDeleteAll } from "@/api/path/dict.js";
+import { ref } from "vue";
 // 获取字典
 export function Getdictionary(params) {
     // 返回 Promise
-    return dictionaryDeleteAll({ typeKey: params }).then(res => {
+    return dictionaryDeleteAll({ typeKey: params }).then((res) => {
         return res.data; // 将响应数据返回
     });
-}
+}

+ 44 - 0
src/store/modules/Login.js

@@ -0,0 +1,44 @@
+import { defineStore } from "pinia";
+import CryptoJS from "crypto-js";
+
+// 登录
+export const FormLoginUser = defineStore({
+  id: "FormLoginUser",
+  state: () => ({
+    encryptedUsername: "",
+    encryptedPassword: "",
+    SECRET_KEY: "your-secret-key",
+  }),
+  getters: {
+    // 使用 RC4 加密
+  },
+  actions: {
+    // 登录时加密并保存
+    loginYester(data) {
+      const encryptedData = this.encryptData(data);
+      localStorage.setItem("USER_KEY_ACCOUT", encryptedData);
+    },
+
+    // 加载加密后的账户信息
+    loadCredentials() {
+        const encryptedData = localStorage.getItem("USER_KEY_ACCOUT") || false;
+      if (encryptedData) {
+        return this.decryptData(encryptedData);
+      }
+      return null;
+    },
+    encryptData(data) {
+      const jsonString = JSON.stringify(data);
+      // 使用 RC4 加密
+      return CryptoJS.RC4.encrypt(jsonString, this.SECRET_KEY).toString();
+    },
+    // 解密数据
+    decryptData(encryptedData) {
+      // 解密 RC4 数据
+      const bytes = CryptoJS.RC4.decrypt(encryptedData, this.SECRET_KEY);
+      // 将解密后的结果转换为字符串并解析为对象
+      const decryptedData = bytes.toString(CryptoJS.enc.Utf8);
+      return JSON.parse(decryptedData); // 解析为对象
+    },
+  },
+});

+ 38 - 22
src/store/modules/routerTag.js

@@ -1,25 +1,41 @@
-import { defineStore } from 'pinia'
+import { defineStore } from "pinia";
 import { setLocalStorage, getLocalStorage } from "@/utils";
-
 export const RouterTagData = defineStore({
-    id: 'RouterTagData',
-    state: () => ({
-        tagData:  []
-    }),
-    getters: {
-
+  id: "RouterTagData",
+  state: () => ({
+    tagData: [],
+    getMenuTabSate:localStorage.getItem('menuTabSate') || ''
+  }),
+  getters: {},
+  actions: {
+    tagsPushData(data) {
+      // 先将已有的相同 name 的标签移除
+      this.tagData = this.tagData.filter((res) => res.name !== data.name);
+      // 再将新的标签加入
+      this.tagData.push(data);
+      this.localStorageTagsData(this.tagData);
+    },
+    // 初始化标签
+    tagsPushFilter(data) {
+      if (data.length !== 0) {
+        this.tagData = JSON.parse(data);
+      } else {
+        this.tagData = data;
+      }
+    },
+    // 删除标签
+    handleRemove(data) {
+      // 去重
+      this.tagData = this.tagData.filter((item) => item.name !== data.name);
+      this.localStorageTagsData(this.tagData);
     },
-    actions: {
-        tagsPushData(items) {
-            if (!this.tagData.some((res) => res.name === items.name)) {
-                this.tagData.push(items);
-            }
-            setLocalStorage('LAOUT_TAG', this.tagData);
-        },
-        // 删除标签
-        handleRemove(items){
-            this.tagData = this.tagData.filter((res) => res.name!== items.name);
-            setLocalStorage('LAOUT_TAG', this.tagData);
-        }
-    }
-})
+    localStorageTagsData(data) {
+      localStorage.setItem("RouterTagData", JSON.stringify(data));
+    },
+    // 默认选中菜单
+    getDefault(data){
+        this.getMenuTabSate = data
+    },
+
+  },
+});

+ 0 - 1
src/api/axios.js → src/utils/axios.js

@@ -5,7 +5,6 @@ import { useSystemStore } from "@/store/modules/systemStore";
 
 import { fn_logout } from "@/utils";
 
-console.log(import.meta.env.BASE_URL)
 const axiosInstance = axios.create({
   // baseURL: `${import.meta.env.PROD ? import.meta.env.VITE_PRO_PATH : ''}/api`,
   baseURL: import.meta.env.BASE_URL + "api",

+ 85 - 0
src/utils/cache.js

@@ -0,0 +1,85 @@
+// localStorage.js
+const Storage = {
+    // 设置缓存
+    set(key, value) {
+      if (key && value !== undefined) {
+        // 如果 value 是对象或数组,转成 JSON 字符串
+        if (typeof value === 'object') {
+          value = JSON.stringify(value);
+        }
+        localStorage.setItem(key, value);
+      } else {
+        console.warn("Invalid key or value");
+      }
+    },
+  
+    // 获取缓存
+    get(key) {
+      if (key) {
+        const value = localStorage.getItem(key);
+        if (value) {
+          try {
+            // 尝试解析 JSON 格式的数据
+            return JSON.parse(value);
+          } catch (e) {
+            // 如果解析失败,直接返回原始字符串
+            return value;
+          }
+        }
+        return null; // 如果没有找到缓存项
+      }
+      return null;
+    },
+  
+    // 删除缓存
+    remove(key) {
+      if (key) {
+        localStorage.removeItem(key);
+      }
+    },
+  
+    // 清空所有缓存
+    clear() {
+      localStorage.clear();
+    },
+  
+    // 判断缓存是否存在
+    exists(key) {
+      return localStorage.getItem(key) !== null;
+    },
+  
+    // 获取缓存的所有键
+    getAllKeys() {
+      return Object.keys(localStorage);
+    },
+  
+    // 设置过期时间,单位:秒
+    setWithExpire(key, value, expireTimeInSec) {
+      if (expireTimeInSec && expireTimeInSec > 0) {
+        const expireDate = new Date().getTime() + expireTimeInSec * 1000;
+        const data = {
+          value: value,
+          expireDate: expireDate,
+        };
+        this.set(key, data);
+      } else {
+        console.warn("Invalid expire time");
+      }
+    },
+  
+    // 获取带过期时间的缓存
+    getWithExpire(key) {
+      const data = this.get(key);
+      if (data && data.expireDate && new Date().getTime() < data.expireDate) {
+        return data.value;
+      } else {
+        // 如果缓存过期或数据不存在,则返回 null
+        this.remove(key);
+        return null;
+      }
+    },
+  };
+  
+  // 导出 Storage 对象
+  export default Storage;
+  

+ 8 - 0
src/utils/router.js

@@ -1,14 +1,22 @@
 import router from '@/router' 
 
+import { useSystemStore } from '@/store/modules/systemStore'
+
+
 
 /**
  * * 退出
  */
 export const fn_logout = (router) => {
+  const systemStore = useSystemStore()
+  systemStore.$reset()
   localStorage.removeItem("user_login_information");
   localStorage.removeItem("routeItem");
   localStorage.removeItem("menus");
   localStorage.removeItem("token");
+  localStorage.removeItem("menuTabSate")
+  localStorage.removeItem("menuSecondLongShow")
+  
   if(router){
     router.push({
       name: "login"

+ 238 - 0
src/views/flowPool/components/add.vue

@@ -0,0 +1,238 @@
+<script setup>
+import {ref, onMounted, toRefs, toRef, watch} from 'vue';
+import {Message} from "@arco-design/web-vue";
+import {
+  addTrafficPool,
+  updateTrafficPool,
+  updateCardList
+} from "@/api/path/flowPool.api"
+import {tariffList} from "@/api/path/tariffManagement.api"
+import {Getdictionary} from '@/mixins/index.js'
+
+const props = defineProps({
+  modelValue: {
+    type: Boolean,
+    default: false
+  },
+  status: {
+    type: [String, Number],
+    default: ''
+  },
+  typeCurrent: {
+    type: [String, Number],
+    default: ''
+  },
+  record: {
+    type: [Array, Object],
+    default: () => {
+    }
+  }
+})
+
+const modelValue = toRef(props, 'modelValue')
+const status = toRef(props, 'status')
+const typeCurrent = toRef(props, 'typeCurrent')
+const record = toRef(props, 'record')
+const emit = defineEmits(['update:modelValue', 'submit'])
+const rules = {
+  label: [{required: true, trigger: 'change',}],
+  source: [{required: true, trigger: 'change',}],
+  status: [{required: true, trigger: 'change',}],
+  simTariffId: [{required: true, trigger: 'change',}],
+  expireTime: [{required: true, trigger: 'change',}],
+  size: [{required: true, trigger: 'change',}],
+  sizeType: [{required: true, trigger: 'change',}],
+};
+const state = ref({
+  typeList: [],
+  tariffIdList: [],
+  formState: {
+    "label": "",
+    "trafficPoolType": props.status,
+    "source": "",
+    "status": "",
+    "simTariffId": null,
+    "expireTime": "",
+    "iccids": [],
+    "size": null,
+    "sizeType": ""
+  },
+  card: [],
+  formRef: null,
+  sourceList: [],
+  trafficList: [],
+})
+
+const {typeList, tariffIdList, formState, card, formRef, sourceList, trafficList} = toRefs(state.value)
+
+// 提交
+const handleSubmit = ({values, errors}) => {
+  formRef.value.validate(async (errors) => {
+    if (!errors) {
+      values.size = Number(values.size)
+      if (formState.value.id) {
+        const {code, data} = await updateTrafficPool(formState.value)
+
+        if (code == 200) {
+          Message.success({
+            content: "修改成功!",
+            duration: 2000,
+          })
+          resetForm()
+          emit('submit', true)
+        }
+      } else {
+        const {code, data} = await addTrafficPool(formState.value)
+        if (code == 200) {
+          Message.success({
+            content: "添加成功!",
+            duration: 2000,
+          })
+          resetForm()
+          emit('submit', true)
+        }
+      }
+    }
+  });
+}
+
+// 获取资费列表选择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,
+        label:item.label +'---'+item.userName
+      }
+    })
+  }
+}
+
+// 取消
+const resetForm = () => {
+  emit('update:modelValue', false)
+  formState.value = {
+    "label": "",
+    "trafficPoolType": "2",
+    "source": "",
+    "status": "",
+    "simTariffId": null,
+    "expireTime": "",
+    "iccids": [],
+    "size": null,
+    "sizeType": ""
+  }
+}
+
+// 获取字典
+const handleDictValue = async () => {
+  sourceList.value = await Getdictionary('source')
+  trafficList.value = await Getdictionary('trafficPacketStatus')
+  typeList.value = await Getdictionary('trafficPoolType')
+}
+
+
+const selectChange = (val)=>{
+  updateCardList({id: val}).then(res => {
+    if (res.code === 200) {
+      card.value = res.data
+    }
+  })
+}
+
+watch(() => record.value, val => {
+  if(props.typeCurrent==2){
+    formState.value = val
+  }
+}, {deep: true})
+
+
+onMounted(()=>{
+  handleDictValue()
+  handleTariff()
+})
+
+</script>
+
+<template>
+  <a-modal :render-to-body="false"
+           :title="typeCurrent == 1 ? $t('form.Add') : typeCurrent == 2 ? $t('form.Edit') : $t('flowPool.Detail')"
+           v-model:visible="modelValue" @cancel="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.simRariff')" field="simTariffId">
+            <a-select v-model="formState.simTariffId" @change="selectChange"
+                      :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.ICCIDlabel')" v-if="formState?.simTariffId!==null"> -->
+            <a-select v-model="formState.iccids" multiple
+                      :placeholder="$t('flowPool.ICCIDName')">
+              <a-option v-for=" item in card" :key="item.iccid" :value="item.iccid">{{
+                  item.iccid
+                }}
+              </a-option>
+            </a-select>
+          <!-- </a-form-item> -->
+          <a-form-item :label="$t('flowPool.expireTime')" field="expireTime">
+            <a-date-picker v-model="formState.expireTime" 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="size" v-if="status==2">
+            <a-input v-model="formState.size" :placeholder="$t('flowPool.poolSize')"/>
+            <a-select v-model="formState.sizeType" 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-tabs>
+
+  </a-modal>
+</template>
+
+<style scoped lang="less">
+
+</style>

+ 267 - 0
src/views/flowPool/components/forewarning.vue

@@ -0,0 +1,267 @@
+<script setup>
+import { ref, onMounted, toRefs, toRef, watch, watchEffect } from 'vue';
+import { Message } from "@arco-design/web-vue";
+import { Getdictionary } from '@/mixins/index.js'
+import { createWarning, updateWarning } from '@/api/path/flowPool.api.js'
+
+const props = defineProps({
+  modelValue: {
+    type: Boolean,
+    default: false
+  },
+  FormDataList: {
+    type: Object,
+    default: () => ({})
+  }
+})
+const modelValue = toRef(props, 'modelValue')
+const FormDataList = toRef(props, 'FormDataList')
+const emit = defineEmits(['update:modelValue', 'submit'])
+const state = ref({
+  formWarning: {
+    "userId": null, // 用户ID
+    "poolId": null, // 流量池ID
+    "clientPooPc": null, // 客户端-池预警设置:端流量池预计
+    "clientPooPcWarnSwitch": false, // 客户端-池预警设置:达量预警
+    "clientPooPcStop": "", // 客户端-池预警设置:达量停机
+    "clientPooPcStopSwitch": false, // 客户端-池预警设置:达量停机开关
+    "clientPooPcStopNetwork": "", // 客户端-池预警设置:达量断网
+    "clientPooPcStopNetworkSwitch": false, // 客户端-池预警设置:达量断网开关
+    "clientNotifyNumber": null, // 客户端-池预警设置:通知次数 次/月
+    "clientSingleCardWarn": "", // 客户端-单卡预警设置:单卡预警 M
+    "clientSingleCardWarnSwitch": false, // 客户端-单卡预警设置:单卡预警 M 开关
+    "clientSingleCardWarnStop": "", // 客户端-单卡预警设置:达量停机
+    "clientSingleCardWarnStopSwitch": false, // 客户端-单卡预警设置:达量停机开关
+    "clientSingleCardWarnStopNetwork": "", // 客户端-单卡预警设置:达量断网
+    "clientSingleCardWarnStopNetworkSwitch": false, // 客户端-单卡预警设置:达量断网开关
+    "manageWarn": null, // 管理端-预警设置:单卡预警 M
+    "manageWarnSwitch": false, // 管理端-预警设置:单卡预警 M 开关
+    "manageWarnSwitchStop": "", // 管理端-预警设置:达量停机
+    "manageWarnSwitchStopSwitch": false, // 管理端-预警设置:达量停机开关
+    "manageWarnStopNetwork": "", // 管理端-预警设置:达量断网
+    "manageWarnStopNetworkSwitch": false // 管理端-预警设置:达量断网开关
+  },
+  formRef: null,
+  earlyList: []
+})
+
+const { formWarning, formRef, earlyList } = toRefs(state.value)
+
+const rules = {
+  clientPooPc: [{ required: true, trigger: 'change', }],
+  clientPooPcStop: [{ required: true, trigger: 'change', }],
+  clientPooPcStopNetwork: [{ required: true, trigger: 'change', }],
+  clientNotifyNumber: [{ required: true, trigger: 'change', }],
+  clientSingleCardWarn: [{ required: true, trigger: 'change', }],
+  clientSingleCardWarnStop: [{ required: true, trigger: 'change', }],
+  clientSingleCardWarnStopNetwork: [{ required: true, trigger: 'change', }],
+  manageWarn: [{ required: true, trigger: 'change', }],
+  manageWarnSwitchStop: [{ required: true, trigger: 'change', }],
+  manageWarnStopNetwork: [{ required: true, trigger: 'change', }],
+};
+
+// 取消
+const resetForm = () => {
+  emit('update:modelValue', false)
+  formWarning.value = {
+    "userId": null, // 用户ID
+    "clientPooPc": null, // 客户端-池预警设置:端流量池预计
+    "clientPooPcWarnSwitch": false, // 客户端-池预警设置:达量预警
+    "clientPooPcStop": "", // 客户端-池预警设置:达量停机
+    "clientPooPcStopSwitch": false, // 客户端-池预警设置:达量停机开关
+    "clientPooPcStopNetwork": "", // 客户端-池预警设置:达量断网
+    "clientPooPcStopNetworkSwitch": false, // 客户端-池预警设置:达量断网开关
+    "clientNotifyNumber": null, // 客户端-池预警设置:通知次数 次/月
+    "clientSingleCardWarn": "", // 客户端-单卡预警设置:单卡预警 M
+    "clientSingleCardWarnSwitch": false, // 客户端-单卡预警设置:单卡预警 M 开关
+    "clientSingleCardWarnStop": "", // 客户端-单卡预警设置:达量停机
+    "clientSingleCardWarnStopSwitch": false, // 客户端-单卡预警设置:达量停机开关
+    "clientSingleCardWarnStopNetwork": "", // 客户端-单卡预警设置:达量断网
+    "clientSingleCardWarnStopNetworkSwitch": false, // 客户端-单卡预警设置:达量断网开关
+    "manageWarn": null, // 管理端-预警设置:单卡预警 M
+    "manageWarnSwitch": false, // 管理端-预警设置:单卡预警 M 开关
+    "manageWarnSwitchStop": "", // 管理端-预警设置:达量停机
+    "manageWarnSwitchStopSwitch": false, // 管理端-预警设置:达量停机开关
+    "manageWarnStopNetwork": "", // 管理端-预警设置:达量断网
+    "manageWarnStopNetworkSwitch": false // 管理端-预警设置:达量断网开关
+  }
+  FormDataList.value = {}
+}
+
+const handleSubmit = ({ values, error }) => {
+  formRef.value.validate(async (errors) => {
+    if (!errors) {
+      Object.keys(formWarning.value).forEach(key => {
+        if (typeof formWarning.value[key] === 'boolean') {
+          formWarning.value[key] = formWarning.value[key] ? "1" : "2";
+        }
+      });
+      formWarning.value.clientPooPc = Number(formWarning.value.clientPooPc)
+      formWarning.value.clientNotifyNumber = Number(formWarning.value.clientNotifyNumber)
+      formWarning.value.manageWarn = Number(formWarning.value.manageWarn)
+      formWarning.value.clientSingleCardWarn = String(formWarning.value.clientSingleCardWarn)
+
+      let res = formWarning.value.id ? await updateWarning(formWarning.value) : await createWarning(formWarning.value)
+      if (res.code === 200) {
+        Message.success('操作成功')
+        emit('update:modelValue', false)
+        emit('submit', true)
+        resetForm()
+      }
+    } else {
+      console.error('Validation failed', errors);
+    }
+  })
+}
+
+const handleDictValue = async () => {
+  earlyList.value = await Getdictionary('forewarning')
+}
+
+watch(() => FormDataList.value, val => {
+  if (!val.id) return;
+
+  formWarning.value.userId = val.userId;
+  formWarning.value.poolId = val.id;
+
+  if (val.alert && val.alert.id !== '') {
+    Object.keys(formWarning.value).forEach(key => {
+      if (typeof formWarning.value[key] === 'boolean') {
+        formWarning.value[key] = val.alert[key] == 1;
+      } else {
+        formWarning.value[key] = val.alert[key];
+      }
+    });
+    formWarning.value.clientSingleCardWarn = Number(formWarning.value.clientSingleCardWarn)
+  }
+
+})
+
+
+onMounted(() => {
+  handleDictValue()
+})
+</script>
+
+<template>
+  <a-modal title="预警池" v-model:visible="modelValue" @cancel="resetForm" centered :maskClosable="false" :footer="null"
+    width="55%">
+    <a-tabs>
+      <a-tab-pane key="1" :title="$t('flowPool.warnTabs')">
+        <a-form :model="formWarning" direction="inline" ref="formRef" :rules="rules">
+          <div class="form-pool-tit">
+            <div class="pool-icon"></div>
+            客户端·池预警设置
+          </div>
+          <a-form-item field="clientPooPc" tooltip="请输入" label="总用量占比">
+            <a-input-number v-model="formWarning.clientPooPc" :style="{ width: '320px' }" placeholder="请输入" allow-clear
+              hide-button>
+              <template #suffix>
+                %
+              </template>
+            </a-input-number>
+            <a-checkbox v-model="formWarning.clientPooPcWarnSwitch">达量预警</a-checkbox>
+          </a-form-item>
+          <a-form-item field="clientPooPcStop" label="达量停机">
+            <a-select v-model="formWarning.clientPooPcStop" 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 v-model="formWarning.clientPooPcStopSwitch">达量停机</a-checkbox>
+          </a-form-item>
+          <a-form-item field="clientArriveStopNetwork" label="达量断网">
+            <a-select v-model="formWarning.clientPooPcStopNetwork" 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 v-model="formWarning.clientPooPcStopNetworkSwitch">达量断网</a-checkbox>
+          </a-form-item>
+          <a-form-item field="clientNotifyNumber" label="提醒次数">
+            <a-input-number v-model="formWarning.clientNotifyNumber" :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="clientSingleCardWarn" tooltip="请输入" label="单卡用量预警">
+            <a-input-number v-model="formWarning.clientSingleCardWarn" :style="{ width: '320px' }" placeholder="请输入"
+              allow-clear hide-button>
+            </a-input-number>
+            <a-checkbox v-model="formWarning.clientSingleCardWarnSwitch">达量预警</a-checkbox>
+          </a-form-item>
+          <a-form-item field="clientSingleCardWarnStop" label="达量停机">
+            <a-select v-model="formWarning.clientSingleCardWarnStop" 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 v-model="formWarning.clientSingleCardWarnStopSwitch">达量停机</a-checkbox>
+          </a-form-item>
+          <a-form-item field="clientSingleCardWarnStopNetwork" label="达量断网">
+            <a-select v-model="formWarning.clientSingleCardWarnStopNetwork" 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 v-model="formWarning.clientSingleCardWarnStopNetworkSwitch">达量断网</a-checkbox>
+          </a-form-item>
+          <div class="form-pool-tit">
+            <div class="pool-icon"></div>
+            管理端预警设置
+          </div>
+          <a-form-item field="manageWarn" tooltip="请输入" label="池已用量预警">
+            <a-input-number v-model="formWarning.manageWarn" :style="{ width: '320px' }" placeholder="请输入" allow-clear
+              hide-button>
+              <template #suffix>
+                %
+              </template>
+            </a-input-number>
+            <a-checkbox v-model="formWarning.manageWarnSwitch">达量预警</a-checkbox>
+          </a-form-item>
+          <a-form-item field="manageWarnSwitchstop" label="达量停机">
+            <a-select v-model="formWarning.manageWarnSwitchStop" 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 v-model="formWarning.manageWarnSwitchStopSwitch">达量停机</a-checkbox>
+          </a-form-item>
+          <a-form-item field="manageWarnStopNetwork" label="达量断网">
+            <a-select v-model="formWarning.manageWarnStopNetwork" 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 v-model="formWarning.manageWarnStopNetworkSwitch">达量断网</a-checkbox>
+          </a-form-item>
+          <a-form-item>
+            <a-button type="primary" @click="handleSubmit" 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>
+</template>
+
+<style scoped lang="less">
+.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;
+
+  }
+}
+</style>

+ 189 - 0
src/views/flowPool/components/openExport.vue

@@ -0,0 +1,189 @@
+<template>
+    <a-modal v-model:visible="modelValue" @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">
+                    <a-form :model="searchForm">
+                        <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="label" :label="$t('flowPool.status')">
+                            <a-select v-model="value" :style="{ width: '240px' }"
+                                :placeholder="$t('flowPool.flowPoolStatus')">
+                                <a-option v-for="item of trafficList" :value="item.id" :label="item.label" />
+                            </a-select>
+                        </a-form-item>
+                        <a-form-item field="label" :label="$t('flowPool.operator')">
+                            <a-select v-model="value" :style="{ width: '240px' }"
+                                :placeholder="$t('flowPool.operatorName')">
+                                <a-option v-for="item of sourceList" :value="item.id" :label="item.label" />
+                            </a-select>
+                        </a-form-item>
+                        <a-form-item field="label" :label="$t('flowPool.start_time')">
+                            <a-date-picker style="width: 200px;" :placeholder="$t('flowPool.start_timeName')" />
+                        </a-form-item>
+                    </a-form>
+                </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" :pagination="paginationCard"
+                        :scroll="{ x: 'auto' }" @page-change="evChangePageCard">
+                        <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>
+</template>
+
+<script setup>
+import { ref, onMounted, toRefs, toRef, watch } from 'vue';
+const props = defineProps({
+    modelValue: {
+        type: Boolean,
+        default: false
+    },
+})
+
+const modelValue = toRef(props, 'modelValue')
+const emit = defineEmits(['update:modelValue', 'submit'])
+
+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 state = ref({
+    dataExport: [],
+    paginationCard: {
+        total: 0,
+        pageSize: 10,
+        current: 1,
+    },
+    searchForm: {
+        "label": "",
+        "trafficPoolType": "1"
+    }
+})
+
+const { dataExport, paginationCard,searchForm } = toRefs(state.value)
+
+
+// 卡信息
+const evChangePageCard = (page) => {
+    paginationCard.value.current = page
+    intData()
+}
+</script>
+<style scoped lang="less">
+.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>

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

@@ -3,7 +3,7 @@ export const columns = [
     { 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.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 },

+ 15 - 12
src/views/flowPool/customerFlowPool/config.js

@@ -1,16 +1,19 @@
 export const columns = [
-    { title: window.$t('flowPool.poolNumber'), dataIndex: 'poolNumber', align: 'center', width: 200 },
+    { title: window.$t('flowPool.poolNumber'), dataIndex: 'id', 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.exceededFlow'), dataIndex: 'exceededFlow', 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.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 },
-]
+    { title: window.$t('flowPool.tariffName'), dataIndex: 'simTariffName', align: 'center', width: 200 },
+    { title: window.$t('flowPool.ActivatedName'), dataIndex: 'Activated', align: 'center', width: 200 },
+    { title: window.$t('flowPool.HaveBeenUsedName'), dataIndex: 'HaveBeenUsed', 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: 'updatedAt', align: 'center', width: 200 },
+]

+ 12 - 52
src/views/flowPool/customerFlowPool/index.vue

@@ -34,8 +34,6 @@
             </template>
 
         </a-table>
-
-
     </div>
 </template>
 
@@ -43,17 +41,12 @@
 import { onMounted, ref, reactive, getCurrentInstance } from "vue";
 import { useRoute } from "vue-router";
 import { columns } from "./config";
-import { trafficPoolList } from "@/api/path/flowPool.api"
-import { useSystemStore } from "@/store/modules/systemStore"
+import { lotCatdList } from "@/api/path/flowPool.api"
+import { Getdictionary } from '@/mixins/index.js'
 
-import {Getdictionary} from '@/mixins/index.js'
-const systemStore = useSystemStore()
-const role = ref(systemStore.getRole)
-const { proxy } = getCurrentInstance()
 const formRef = ref()
 const searchForm = ref({
     "label": "",
-    "trafficPoolType": ""
 });
 
 const typeList = ref([]);
@@ -68,52 +61,29 @@ const pagination = ref({
 })
 
 
-
-
-
-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)
+    const { data } = await lotCatdList(param)
     dataSource.value = (data.records || []).map((item, index) => {
-        const trafficPoolType = typeList.value.find(val => val.value == item.trafficPoolType)?.label
         const trafficPoolStatus = trafficList.value.find(val => val.value == item.status)?.label
         const sourceName = sourceList.value.find(val => val.value == item.source)?.label
-        console.log(item, "item-------------------------");
-
+        const Activated = 0 + '/' + item.iccids?.length
+        const HaveBeenUsed = 0 + '/' + item.size + item.sizeType
         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: "--",
+            Activated: Activated,
+            HaveBeenUsed: HaveBeenUsed,
         }
     })
     pagination.value.total = data.total
 }
 
-
-
-
 const evChangePage = (page) => {
     pagination.value.current = page
     intData()
@@ -127,26 +97,16 @@ const resetSearch = () => {
     intData()
 }
 
-
-// --------------------------------------------------------
-// 获取字典
 const handleDictValue = async () => {
-  sourceList.value = await Getdictionary('source')
-  trafficList.value = await Getdictionary('trafficPacketStatus')
-  typeList.value = await Getdictionary('trafficPoolType')
+    sourceList.value = await Getdictionary('source')
+    trafficList.value = await Getdictionary('trafficPacketStatus')
 }
 
 
-
-
-
-onMounted(() => {
-    handleDictValue()
-    intData()
+onMounted(async () => {
+    await handleDictValue()
+    await intData()
 })
-
-
-
 </script>
 
 <style scoped lang="less">

+ 77 - 602
src/views/flowPool/index.vue

@@ -1,34 +1,24 @@
 <!-- 流量池 -->
 <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-input v-model="searchForm.label" :placeholder="$t('lotCard.please') + $t('flowPool.label')" allow-clear />
         </a-form-item>
         <a-form-item field="label" :label="$t('flowPool.status')">
-          <a-select v-model="value" :style="{width:'240px'}" :placeholder="$t('flowPool.flowPoolStatus')">
-            <a-option v-for="item of trafficList" :value="item.id" :label="item.label"/>
+          <a-select v-model="value" :style="{ width: '240px' }" :placeholder="$t('flowPool.flowPoolStatus')">
+            <a-option v-for="item of trafficList" :value="item.id" :label="item.label" />
           </a-select>
         </a-form-item>
         <a-form-item field="label" :label="$t('flowPool.operator')">
-          <a-select v-model="value" :style="{width:'240px'}" :placeholder="$t('flowPool.operatorName')">
-            <a-option v-for="item of sourceList" :value="item.id" :label="item.label"/>
+          <a-select v-model="value" :style="{ width: '240px' }" :placeholder="$t('flowPool.operatorName')">
+            <a-option v-for="item of sourceList" :value="item.id" :label="item.label" />
           </a-select>
         </a-form-item>
         <a-form-item field="label" :label="$t('flowPool.start_time')">
-          <a-date-picker style="width: 200px;" :placeholder="$t('flowPool.start_timeName')"/>
+          <a-date-picker style="width: 200px;" :placeholder="$t('flowPool.start_timeName')" />
         </a-form-item>
         <a-form-item>
           <a-space>
@@ -42,7 +32,7 @@
     <div class="audit-btn">
       <a-button @click="dictShowModel(1, null)" type="text" v-if="role == 1">
         <template #icon>
-          <icon-plus-circle/>
+          <icon-plus-circle />
         </template>
         <template #default>
           {{ $t('form.Add') }}
@@ -51,317 +41,88 @@
     </div>
 
     <a-table row-key="id" :data="dataSource" :columns="columns" :pagination="pagination" :scroll="{ x: 'auto' }"
-             @page-change="evChangePage">
+      @page-change="evChangePage">
       <template #id="{ record }">
         <!-- 修改 -->
         <a class="a-link" href="javascript:;" style="margin-right: 1rem" @click="dictShowModel(2, record)"
-           v-if="role == 1">{{
+          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 class="a-link" href="javascript:;" style="margin-right: 1rem" @click="handelForewring(record)"
+          v-if="role == 1">预警</a>
         <!-- 删除 -->
-        <a-popconfirm :content="$t('form.Delete')" :ok-text="$t('form.Confirm')"
-                      :cancel-text="$t('form.Cancel')" @ok="handleDel(record.id)">
+        <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" v-if="role == 1">{{
-              $t('form.Delete')
-            }}</a>
+            $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="trafficPoolType">
-                <a-select v-model="formState.trafficPoolType" 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 :label="$t('flowPool.simRariff')" field="simTariffId">
-              <a-select v-model="formState.simTariffId"
-                        :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.ICCIDlabel')" v-if="formState.simTariffId!==null">
-              <a-select v-model="formState.iccids" multiple
-                        :placeholder="$t('flowPool.ICCIDName')">
-                <a-option v-for=" item in card" :key="item.iccid" :value="item.iccid">{{
-                    item.iccid
-                  }}
-                </a-option>
-              </a-select>
-            </a-form-item>
-            <a-form-item :label="$t('flowPool.TimeName')" field="expireTime">
-              <a-date-picker v-model="formState.expireTime" show-time
-                             :time-picker-props="{ defaultValue: '09:09:06' }" format="YYYY-MM-DD HH:mm:ss"/>
-            </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>
+    <add v-model:model-value="showAdd" status="1" :typeCurrent="typeCurrent" :record="record" @submit="intData()"></add>
+    <Forewarning v-model:modelValue="visibleForewarning" :FormDataList="FormDataList" @submit="intData()" />
+    <openExport v-model:model-value="ShowOpenExport" />
 
-    <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">
-            <a-form :model="searchForm">
-              <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="label" :label="$t('flowPool.status')">
-                <a-select v-model="value" :style="{width:'240px'}" :placeholder="$t('flowPool.flowPoolStatus')">
-                  <a-option v-for="item of trafficList" :value="item.id" :label="item.label"/>
-                </a-select>
-              </a-form-item>
-              <a-form-item field="label" :label="$t('flowPool.operator')">
-                <a-select v-model="value" :style="{width:'240px'}" :placeholder="$t('flowPool.operatorName')">
-                  <a-option v-for="item of sourceList" :value="item.id" :label="item.label"/>
-                </a-select>
-              </a-form-item>
-              <a-form-item field="label" :label="$t('flowPool.start_time')">
-                <a-date-picker style="width: 200px;" :placeholder="$t('flowPool.start_timeName')"/>
-              </a-form-item>
-            </a-form>
-          </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" :pagination="paginationCard" :scroll="{ x: 'auto' }"
-                     @page-change="evChangePageCard">
-              <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, watch} from "vue";
-import {useRoute} from "vue-router";
-import {columns} from "./config";
-import {Message, Notification} from '@arco-design/web-vue'
+import { onMounted, ref, getCurrentInstance, nextTick, watch, toRefs } from "vue";
+import { columns } from "./config";
+import { Message } from '@arco-design/web-vue'
 import {
   deleteTrafficPool,
-  addTrafficPool,
-  updateTrafficPool,
-  trafficPoolList,
-  getCardList,
-  updateCardList
+  lotCatdList,
 } from "@/api/path/flowPool.api"
-import {tariffList} from "@/api/path/tariffManagement.api"
-import {useSystemStore} from "@/store/modules/systemStore"
-
-
+import { useSystemStore } from "@/store/modules/systemStore"
 import {Getdictionary} from '@/mixins/index.js'
-
+import Forewarning from "./components/forewarning.vue";
+import add from './components/add.vue'
+import openExport from "./components/openExport.vue"
 const systemStore = useSystemStore()
-const role = ref(systemStore.getRole)
-const {proxy} = getCurrentInstance()
-const formRef = ref()
-const searchForm = ref({
-  "label": "",
-  "trafficPoolType": "1"
-});
-
-const dataSource = ref([]);
-const route = useRoute();
-const pagination = ref({
-  total: 0,
-  pageSize: 10,
-  current: 1,
-})
-// 卡信息列表
-const paginationCard = ref({
-  total: 0,
-  pageSize: 10,
-  current: 1,
+const state = ref({
+  role: systemStore.getRole,
+  formRef: null,
+  searchForm: {
+    "label": "",
+    "trafficPoolType": "1"
+  },
+  pagination: {
+    total: 0,
+    pageSize: 10,
+    current: 1,
+  },
+  sourceList: [],
+  trafficList: [],
+  typeList: [],
+  tariffIdList: [],
+  ShowOpenExport: false,
+  visibleForewarning: false,
+  showAdd: false,
+  typeCurrent: 1,
+  record: {},
+  dataSource: [],
+  FormDataList: {}
 })
-
+const {
+  role,
+  searchForm,
+  pagination,
+  typeCurrent,
+  sourceList,
+  trafficList,
+  ShowOpenExport,
+  visibleForewarning,
+  showAdd,
+  record,
+  dataSource,
+  FormDataList
+} = toRefs(state.value)
+const { proxy } = getCurrentInstance()
 
 const intData = async () => {
   const param = {
@@ -370,29 +131,27 @@ const intData = async () => {
     ...searchForm.value,
     type: 1
   }
-  const {data} = await trafficPoolList(param)
+  const { data } = await lotCatdList(param)
   dataSource.value = (data.records || []).map((item, index) => {
     // const trafficPoolType = typeList.value.find(val => val.value == item.trafficPoolType)?.label
     const trafficPoolStatus = trafficList.value.find(val => val.value == item.status)?.label
     const sourceName = sourceList.value.find(val => val.value == item.source)?.label
-    const Activated = 0 + '/' + item.iccids.length
-    const HaveBeenUsed = 0+ '/' + item.size+item.sizeType
+    const Activated = 0 + '/' + item.iccids?.length
+    const HaveBeenUsed = 0 + '/' + item.size + item.sizeType
     return {
       ...item,
       sourceName,// 运营商名称
       trafficPoolStatus,
       Activated: Activated,
-      HaveBeenUsed:HaveBeenUsed,
-      poolNumber: "NR0" + (index + 1),
+      HaveBeenUsed: HaveBeenUsed,
     }
   })
+
   pagination.value.total = data.total
 }
-
-
 // 删除
 const handleDel = async (id) => {
-  const {code} = await deleteTrafficPool({id})
+  const { code } = await deleteTrafficPool({ id })
   if (code == 200) {
     Message.success({
       content: "删除成功!",
@@ -406,13 +165,6 @@ const evChangePage = (page) => {
   pagination.value.current = page
   intData()
 }
-
-// 卡信息
-const evChangePageCard = (page) => {
-  paginationCard.value.current = page
-  intData()
-}
-
 const handleSearch = () => {
   intData()
 }
@@ -421,200 +173,29 @@ const resetSearch = () => {
   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 card = 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();
-// -------------------------------
-
-const formState = ref({
-  "id": "",
-  // 流量包名称
-  "label": "",
-  // 流量池类型: 1: 前流量池 2: 后流量池
-  "trafficPoolType": "1",
-  // 来源
-  "source": "",
-  // 流量包状态:1:正常(发布计划状态)2:线下暂停销售
-  "status": "",
-  // 流量池ID
-  "simTariffId": null,
-  // 过期时间
-  "expireTime": "",
-  // ICCID列表
-  "iccids": []
-});
-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',}],
-  source: [{required: true, trigger: 'change',}],
-  status: [{required: true, trigger: 'change',}],
-  simTariffId: [{required: true, trigger: 'change',}],
-  expireTime: [{required: true, trigger: 'change',}],
-};
-
-// 提交
-const handleSubmit = ({values, errors}) => {
-  formRef.value.validate(async (errors) => {
-    if (!errors) {
-      if (formState.value.id) {
-        const {code, data} = await updateTrafficPool(formState.value)
-
-        if (code == 200) {
-          Message.success({
-            content: "修改成功!",
-            duration: 2000,
-          })
-          resetForm()
-          intData()
-        }
-      } else {
-        const {code, data} = await addTrafficPool(formState.value)
-        if (code == 200) {
-          Message.success({
-            content: "添加成功!",
-            duration: 2000,
-          })
-          resetForm()
-          intData()
-        }
-      }
-    }
-  });
-
-}
 // 弹框
 const dictShowModel = (type, data) => {
-  if (type == 3) {
-    openExport.value = true;
-    getCardList({iccid: data.id, current: 1, size: 10}).then((res) => {
-      dataExport.value = res.data.records || []
-      paginationCard.value.total = res.data.total
-    })
-    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]
-      }
-    });
-    formState.value.id = data.id
-  }
+  typeCurrent.value = type
+  record.value = data
+  showAdd.value = true
 }
 
-// 获取资费列表选择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 handelForewring = (item) => {
+  FormDataList.value = item
+  visibleForewarning.value = true
 }
 
-// 取消
-const resetForm = () => {
-  visible.value = false;
-  Object.keys(formState.value).forEach(key => {
-    if (key != 'trafficPoolType') {
-      formState.value[key] = ''
-    }
-  })
-  delete formState.value.id
-}
-// --------------------------------------------------------
-// 获取字典
 const handleDictValue = async () => {
   sourceList.value = await Getdictionary('source')
   trafficList.value = await Getdictionary('trafficPacketStatus')
-  typeList.value = await Getdictionary('trafficPoolType')
 }
 
-
-watch(() => formState.value.simTariffId, val => {
-  if (!val) return
-  updateCardList({id: val}).then(res => {
-    if (res.code === 200) {
-      card.value = res.data
-    }
-  })
-})
 onMounted(async () => {
   await handleDictValue()
+
   await intData()
 })
 
-
 </script>
 
 <style scoped lang="less">
@@ -622,9 +203,6 @@ onMounted(async () => {
   margin-right: 10px;
 }
 
-.head-title-right {
-}
-
 .search-section {
   margin-top: 20px;
   margin-bottom: 20px;
@@ -664,107 +242,4 @@ silent-expire-alarm {
 .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>

+ 168 - 580
src/views/flowPool/rearFlowPool/index.vue

@@ -1,39 +1,54 @@
 <!-- 后流量池 -->
 <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-input
+            v-model="searchForm.label"
+            :placeholder="$t('lotCard.please') + $t('flowPool.label')"
+            allow-clear
+          />
         </a-form-item>
         <a-form-item field="label" :label="$t('flowPool.status')">
-          <a-select v-model="value" :style="{width:'240px'}" :placeholder="$t('flowPool.flowPoolStatus')">
-            <a-option v-for="item of trafficList" :value="item.id" :label="item.label"/>
+          <a-select
+            v-model="value"
+            :style="{ width: '240px' }"
+            :placeholder="$t('flowPool.flowPoolStatus')"
+          >
+            <a-option
+              v-for="item of trafficList"
+              :value="item.id"
+              :label="item.label"
+            />
           </a-select>
         </a-form-item>
         <a-form-item field="label" :label="$t('flowPool.operator')">
-          <a-select v-model="value" :style="{width:'240px'}" :placeholder="$t('flowPool.operatorName')">
-            <a-option v-for="item of sourceList" :value="item.id" :label="item.label"/>
+          <a-select
+            v-model="value"
+            :style="{ width: '240px' }"
+            :placeholder="$t('flowPool.operatorName')"
+          >
+            <a-option
+              v-for="item of sourceList"
+              :value="item.id"
+              :label="item.label"
+            />
           </a-select>
         </a-form-item>
         <a-form-item field="label" :label="$t('flowPool.start_time')">
-          <a-date-picker style="width: 200px;" :placeholder="$t('flowPool.start_timeName')"/>
+          <a-date-picker
+            style="width: 200px"
+            :placeholder="$t('flowPool.start_timeName')"
+          />
         </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-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>
@@ -42,618 +57,196 @@
     <div class="audit-btn">
       <a-button @click="dictShowModel(1, null)" type="text" v-if="role == 1">
         <template #icon>
-          <icon-plus-circle/>
+          <icon-plus-circle />
         </template>
         <template #default>
-          {{ $t('form.Add') }}
+          {{ $t("form.Add") }}
         </template>
       </a-button>
     </div>
 
-    <a-table row-key="id" :data="dataSource" :columns="columns" :pagination="pagination" :scroll="{ x: 'auto' }"
-             @page-change="evChangePage">
+    <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
+          class="a-link"
+          href="javascript:;"
+          style="margin-right: 1rem"
+          @click="dictShowModel(2, record)"
+          v-if="role == 1"
+          >{{ $t("form.Edit") }}</a
+        >
+        <a
+          class="a-link"
+          href="javascript:;"
+          style="margin-right: 1rem"
+          @click="handelForewring(record)"
+          v-if="role == 1"
+          >预警</a
+        >
         <!-- 删除 -->
-        <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-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>
+            $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>
-
-
-    <!-- 新增弹框 -->
-    <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="trafficPoolType">
-                <a-select v-model="formState.trafficPoolType"
-                    :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="simTariffId">
-              <a-select v-model="formState.simTariffId"
-                        :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.ICCIDlabel')" v-if="formState.simTariffId!==null">
-              <a-select v-model="formState.iccids" multiple
-                        :placeholder="$t('flowPool.ICCIDName')">
-                <a-option v-for=" item in card" :key="item.iccid" :value="item.iccid">{{
-                    item.iccid
-                  }}
-                </a-option>
-              </a-select>
-            </a-form-item>
-            <a-form-item :label="$t('flowPool.expireTime')" field="expireTime">
-              <a-date-picker v-model="formState.expireTime" 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="size">
-              <a-input v-model="formState.size" :placeholder="$t('flowPool.poolSize')"/>
-              <a-select v-model="formState.sizeType" 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>
+    <add
+      v-model:modelValue="showAdd"
+      status="2"
+      :typeCurrent="typeCurrent"
+      :record="record"
+      @submit="intData()"
+    ></add>
+    <Forewarning
+      v-model:modelValue="visibleForewarning"
+      :FormDataList="FormDataList"
+      @submit="intData()"
+    />
   </div>
 </template>
 
 <script setup>
-import {onMounted, ref, reactive, getCurrentInstance, nextTick, watch} from "vue";
-import {useRoute} from "vue-router";
-import {columns} from "../config";
-import {Message, Notification} from '@arco-design/web-vue'
-import {
-  deleteTrafficPool,
-  addTrafficPool,
-  updateTrafficPool,
-  trafficPoolList,
-  updateCardList
-} 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"
-import {Getdictionary} from '@/mixins/index.js'
-
-const systemStore = useSystemStore()
-const role = ref(systemStore.getRole)
-const card = ref([])
-
-const {proxy} = getCurrentInstance()
-const formRef = ref()
-const searchForm = ref({
-  "label": "",
+import { onMounted, reactive, toRefs } from "vue";
+import { columns } from "../config";
+import { Message } from "@arco-design/web-vue";
+import { deleteTrafficPool, lotCatdList } from "@/api/path/flowPool.api";
+import { useSystemStore } from "@/store/modules/systemStore";
+import add from "../components/add.vue";
+import Forewarning from "../components/forewarning.vue";
+import { Getdictionary } from "@/mixins/index.js";
+const systemStore = useSystemStore();
+const state = reactive({
+  dataSource: [],
+  pagination: {
+    total: 0,
+    pageSize: 10,
+    current: 1,
+  },
+  searchForm: {
+    label: "",
+  },
+  role: systemStore.getRole,
+  typeCurrent: 1,
+  visibleForewarning: false,
+  FormDataList: {},
+  record: {},
+  sourceList: [],
+  trafficList: [],
+  showAdd: false,
 });
 
-const dataSource = ref([]);
-const route = useRoute();
-const pagination = ref({
-  total: 0,
-  pageSize: 10,
-  current: 1,
-})
-
+const {
+  dataSource,
+  pagination,
+  searchForm,
+  role,
+  typeCurrent,
+  visibleForewarning,
+  FormDataList,
+  record,
+  sourceList,
+  trafficList,
+  showAdd,
+} = toRefs(state);
 
 const intData = async () => {
   const param = {
     current: pagination.value.current,
     size: pagination.value.pageSize,
     ...searchForm.value,
-    trafficPoolType: '2',
-    type:2
-  }
-  const {data} = await trafficPoolList(param)
+    trafficPoolType: "2",
+    type: 2,
+  };
+  const { data } = await lotCatdList(param);
   dataSource.value = (data.records || []).map((item, index) => {
     // const trafficPoolType = typeList.value.find(val => val.value == item.trafficPoolType)?.label
-    const trafficPoolStatus = trafficList.value.find(val => val.value == item.status)?.label
-    const sourceName = sourceList.value.find(val => val.value == item.source)?.label
-    const Activated = 0 + '/' + item.iccids.length
-    const HaveBeenUsed = 0+ '/' + item.size+item.sizeType
+    const trafficPoolStatus = trafficList.value.find(
+      (val) => val.value == item.status
+    )?.label;
+    const sourceName = sourceList.value.find(
+      (val) => val.value == item.source
+    )?.label;
+    const Activated = 0 + "/" + item.iccids?.length;
+    const HaveBeenUsed = 0 + "/" + item.size + item.sizeType;
     return {
       ...item,
-      sourceName,// 运营商名称
+      sourceName, // 运营商名称
       // trafficPoolType,
-      Activated:Activated,
-      HaveBeenUsed:HaveBeenUsed,
+      Activated: Activated,
+      HaveBeenUsed: HaveBeenUsed,
       trafficPoolStatus,
-    }
-  })
-  pagination.value.total = data.total
-}
-
+    };
+  });
+  pagination.value.total = data.total;
+};
 
 // 删除
 const handleDel = async (id) => {
-  const {code} = await deleteTrafficPool({id})
+  const { code } = await deleteTrafficPool({ id });
   if (code == 200) {
     Message.success({
       content: "删除成功!",
       duration: 2000,
-    })
-    intData()
+    });
+    intData();
   }
 };
 
 const evChangePage = (page) => {
-  pagination.value.current = page
-  intData()
-}
+  pagination.value.current = page;
+  intData();
+};
 
 const handleSearch = () => {
-  intData()
-}
+  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({
-  // 流量包名称
-  "label": "",
-  // 流量池类型: 1: 前流量池 2: 后流量池
-  "trafficPoolType": "2",
-  // 来源
-  "source": "",
-  // 流量包状态:1:正常(发布计划状态)2:线下暂停销售
-  "status": "",
-  // 流量池ID
-  "simTariffId": null,
-  // 过期时间
-  "expireTime": "",
-  // ICCID列表
-  "iccids": [],
-
-  "size": null,
-  "sizeType": ''
-});
-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',}],
-  source: [{required: true, trigger: 'change',}],
-  status: [{required: true, trigger: 'change',}],
-  simTariffId: [{required: true, trigger: 'change',}],
-  expireTime: [{required: true, trigger: 'change',}],
-  // iccids: [{required: true, trigger: 'change',}],
-  size: [{required: true, trigger: 'change',}],
-  sizeType: [{required: true, trigger: 'change',}],
+  searchForm.value.label = "";
+  intData();
 };
 
-
-// 提交
-const handleSubmit = ({values, errors}) => {
-  formRef.value.validate(async (errors) => {
-    if (!errors) {
-      values.size = Number(values.size)
-      if (formState.value.id) {
-        const {code, data} = await updateTrafficPool(formState.value)
-
-        if (code == 200) {
-          Message.success({
-            content: "修改成功!",
-            duration: 2000,
-          })
-          resetForm()
-          intData()
-        }
-      } else {
-        const {code, data} = await addTrafficPool(formState.value)
-        if (code == 200) {
-          Message.success({
-            content: "添加成功!",
-            duration: 2000,
-          })
-          resetForm()
-          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.keys(formState.value).forEach(key => {
-      if (data[key]) {
-        formState.value[key] = data[key]
-      }
-    })
-    formState.value.id = data.id
-  }
-}
-
-// 获取资费列表选择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
-      }
-    })
-  }
-}
+  record.value = data;
+  showAdd.value = true;
+};
 
-// 取消
-const resetForm = () => {
-  visible.value = false;
-  Object.keys(formState.value).forEach(key => {
-    if (key != 'trafficPoolType') {
-      formState.value[key] = ''
-    }
-  })
-  delete formState.value.id
-}
+const handelForewring = (item) => {
+  FormDataList.value = item;
+  visibleForewarning.value = true;
+};
 
-// --------------------------------------------------------
-// 获取字典
 const handleDictValue = async () => {
-  sourceList.value = await Getdictionary('source')
-  trafficList.value = await Getdictionary('trafficPacketStatus')
-  typeList.value = await Getdictionary('trafficPoolType')
-}
-
-watch(() => formState.value.simTariffId, val => {
-  if (!val) return
-  updateCardList({id: val}).then(res => {
-    if (res.code === 200) {
-      card.value = res.data
-    }
-  })
-})
-
+  sourceList.value = await Getdictionary("source");
+};
 
 onMounted(async () => {
-  await handleDictValue()
-  await intData()
-})
-
-
+  await handleDictValue();
+  await intData();
+});
 </script>
 
 <style scoped lang="less">
-.m-r-10 {
-  margin-right: 10px;
-}
-
-.head-title-right {
-}
-
 .search-section {
   margin-top: 20px;
   margin-bottom: 20px;
@@ -694,7 +287,6 @@ silent-expire-alarm {
   margin-bottom: 10px;
 }
 
-
 .echarts-box {
   // width: 100%;
   display: flex;
@@ -723,15 +315,13 @@ silent-expire-alarm {
     margin-right: 10px;
     width: 4px;
     height: 16px;
-    background: #1B5DF8;
+    background: #1b5df8;
     font-size: 14px;
-    color: #6C6E70;
+    color: #6c6e70;
     font-family: PingFang SC;
-
   }
 }
 
-
 .export-box {
   .export-box-item {
     .box-item-title {
@@ -748,8 +338,7 @@ silent-expire-alarm {
         margin-right: 10px;
         width: 4px;
         height: 16px;
-        background: #1B5DF8;
-
+        background: #1b5df8;
       }
     }
 
@@ -771,8 +360,7 @@ silent-expire-alarm {
           font-weight: 400;
           line-height: 22px;
           text-align: left;
-          color: #1B5DF8;
-
+          color: #1b5df8;
         }
       }
 

+ 38 - 26
src/views/login/login-form.vue

@@ -5,18 +5,18 @@
 
     <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>
+        :validate-trigger="['change', 'blur']" hide-label>
         <a-input v-model="formData.username" placeholder="用户名:">
           <template #prefix>
-            <icon-user/>
+            <icon-user />
           </template>
         </a-input>
       </a-form-item>
       <a-form-item field="password" :rules="[{ required: true, message: '密码不能为空' }]"
-                   :validate-trigger="['change', 'blur']" hide-label>
+        :validate-trigger="['change', 'blur']" hide-label>
         <a-input-password v-model="formData.password" placeholder="密码:" allow-clear>
           <template #prefix>
-            <icon-lock/>
+            <icon-lock />
           </template>
         </a-input-password>
       </a-form-item>
@@ -24,7 +24,7 @@
 
       <a-space :size="16" direction="vertical">
         <div class="login-form-password-actions">
-          <a-checkbox checked="rememberPassword" :default-checked="true" @change="setRememberPassword">
+          <a-checkbox v-model="rememberPassword">
             记住账号
           </a-checkbox>
           <!-- <a-link>忘记密码</a-link> -->
@@ -36,29 +36,41 @@
 </template>
 
 <script setup>
-import {ref, reactive} from 'vue'
-import {encryptByDES} from "@/utils"
-import {loginApi} from "@/api/path/login.api"
-import {useSystemStore} from "@/store/modules/systemStore"
-import {useRouter} from 'vue-router'
-import {updateRouteByMenu} from '@/router/router.update'
-import {dictionaryDeleteAll, dictionaryList} from "@/api/path/dict"
-
+import { ref, reactive, toRefs, onMounted } from 'vue'
+import { encryptByDES } from "@/utils"
+import { loginApi } from "@/api/path/login.api"
+import { useSystemStore } from "@/store/modules/systemStore"
+import { useRouter } from 'vue-router'
+import { updateRouteByMenu } from '@/router/router.update'
+import { FormLoginUser } from '@/store/modules/Login'
 const router = useRouter()
-const formData = ref({
-  username: localStorage.remember_user_name
+const systemStore = useSystemStore()
+const LoginSet = FormLoginUser()
+const state = ref({
+  formData: {
+    username: '',
+    password: ''
+  },
+  formLoading: false,
+  rememberPassword: false,
 })
-const formLoading = ref(false)
-const rememberPassword = ref(true)
 
-const systemStore = useSystemStore()
+const { formData, formLoading, rememberPassword } = toRefs(state.value)
 
 const handleSubmit = async () => {
-  const {data} = await loginApi({
+  const { data } = await loginApi({
     username: formData.value.username,
     password: encryptByDES(formData.value.password)
   })
-  window.localStorage.setItem('remember_user_name', formData.value.username)
+
+  if (rememberPassword.value) {
+    LoginSet.loginYester(formData.value)
+  } else {
+    const nste = localStorage.getItem("USER_KEY_ACCOUT") || false;
+    if (nste) {
+      localStorage.removeItem('USER_KEY_ACCOUT')
+    }
+  }
 
   systemStore.setStateValue({
     key: 'token',
@@ -72,21 +84,21 @@ const handleSubmit = async () => {
   })
   systemStore.setStateValue({
     key: 'role',
-    value: data.user_type,
+    value: data.userType,
     localStorage: true,
   })
   await updateRouteByMenu(router, systemStore)
   router.push({
     path: "/",
   })
-  
 }
 
-const setRememberPassword = (e) => {
-  if (!e) {
-    window.localStorage.removeItem('remember_user_name')
+onMounted(() => {
+  if (LoginSet.loadCredentials()) {
+    formData.value.username = LoginSet.loadCredentials()?.username
+    formData.value.password = LoginSet.loadCredentials()?.password
   }
-}
+})
 
 
 </script>

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

@@ -1,36 +1,45 @@
 export const columns = [
-  { title: window.$t('lotCard.iccid'), dataIndex: 'iccid', align: 'center',  ellipsis:true },
-  { title: window.$t('lotCard.source'), dataIndex: 'sourceName', align: 'center',  ellipsis:true },
-  { title: 'IMSI', dataIndex: 'account', align: 'center', ellipsis:true},
-  { title: 'SIM绑定的IMSI', dataIndex: 'currentImsi', align: 'center', ellipsis:true  },
-  { title: 'SIM货币余额', dataIndex: 'moneyBalances', align: 'center', ellipsis:true  },
-  { title: 'SIM生成日期', dataIndex: 'createTime', align: 'center',  ellipsis:true },
-  { title: '支付方式', dataIndex: 'payType', align: 'center', ellipsis:true  },
-  { title: 'SIM状态', dataIndex: 'accountStatus', align: 'center', ellipsis:true  },
-  { title: '已使用总流量', dataIndex: 'dataUsageTotal', align: 'center',  ellipsis:true },
-  { title: '语音呼入分钟数', dataIndex: 'voiceMtTotal', align: 'center', ellipsis:true  },
-  { title: '语音呼出分钟数', dataIndex: 'voiceMoTotal', align: 'center', ellipsis:true  },
-  { title: '总语音分钟数', dataIndex: 'voiceTotal', align: 'center',  ellipsis:true },
-  { title: '发短信数', dataIndex: 'smsTotal', align: 'center',  ellipsis:true },
-  { title: 'SIM有效期(月)', dataIndex: 'validMonth', align: 'center', ellipsis:true  },
-  { title: 'SIM关闭日期', dataIndex: 'closeTime', align: 'center', ellipsis:true  },
-  { title: 'SIM激活日期', dataIndex: 'activeTime', align: 'center',  ellipsis:true },
-  { title: 'IMSI所属供应商名称', dataIndex: 'currentImsiProvider', align: 'center',  ellipsis:true },
-  { title: '流量包', dataIndex: 'dataPackageName', align: 'center',  ellipsis:true },
-  {
-    title: window.$t('global.common.operations'),
-    dataIndex: 'id',
-    slotName: 'id',
-    align: 'center',
-    width: 280,
-    fixed: "right",
-  }
+    { title: window.$t('lotCard.iccid'), dataIndex: 'iccid', align: 'center', ellipsis: true },
+    { title: window.$t('lotCard.source'), dataIndex: 'sourceName', align: 'center', ellipsis: true },
+    { title: '客户名称', dataIndex: 'userName', align: 'center', ellipsis: true },
+    { title: 'IMSI', dataIndex: 'currentImsi', align: 'center', ellipsis: true },
+    { title: 'SIM绑定的IMSI', dataIndex: 'currentImsi', align: 'center', ellipsis: true },
+    // { title: 'SIM货币余额', dataIndex: 'moneyBalances', align: 'center', ellipsis:true  },
+    { title: 'SIM生成日期', dataIndex: 'createTime', align: 'center', ellipsis: true },
+    // { title: '支付方式', dataIndex: 'payType', align: 'center', ellipsis: true },
+    { title: 'SIM状态', dataIndex: 'iccidStatus', align: 'center', ellipsis: true },
+    { title: '预警状态', dataIndex: '', align: 'center', ellipsis: true },
+    { title: '已使用总流量', dataIndex: 'dataUsageTotal', slotName: 'dataUsageTotal', align: 'center', ellipsis: true },
+    { title: '语音呼入分钟数', dataIndex: 'voiceMtTotal', align: 'center', ellipsis: true },
+    { title: '语音呼出分钟数', dataIndex: 'voiceMoTotal', align: 'center', ellipsis: true },
+    { title: '总语音分钟数', dataIndex: 'voiceTotal', align: 'center', ellipsis: true },
+    { title: '发短信数', dataIndex: 'smsTotal', align: 'center', ellipsis: true },
+    { title: 'SIM有效期(月)', dataIndex: 'validMonth', align: 'center', ellipsis: true },
+    { title: 'SIM关闭日期', dataIndex: 'closeTime', align: 'center', ellipsis: true },
+    { title: 'SIM激活日期', dataIndex: 'activeTime', align: 'center', ellipsis: true },
+    { title: 'IMSI所属供应商名称', dataIndex: 'currentImsiProvider', align: 'center', ellipsis: true },
+    { title: '卡套餐', dataIndex: 'tariffName', align: 'center', ellipsis: true },
+    { title: '预警状态', dataIndex: 'forewarningStatus', align: 'center', width: 200, ellipsis: true },
+    { title: '历史用量', dataIndex: 'HistoricalUsage', align: 'center', width: 200, ellipsis: true },
+    { title: '池名称/编号', dataIndex: 'poolNum', slotName: 'poolNum', align: 'center', width: 200, ellipsis: true },
+    { title: '沉默期到期时间', dataIndex: 'SilenceEndtime', align: 'center', width: 200, ellipsis: true },
+    { title: '已用(套餐流量)', dataIndex: 'dataUsage', align: 'center', width: 200, ellipsis: true },
+    { title: '可用(套餐流量)', dataIndex: 'dataTotal', align: 'center', width: 200, ellipsis: true },
+    { title: '已用(加油包流量)', dataIndex: 'usedBg', align: 'center', width: 200, ellipsis: true },
+    { title: '可用(加油包流量)', dataIndex: 'usableBg', align: 'center', width: 200, ellipsis: true },
+    {
+        title: window.$t('global.common.operations'),
+        dataIndex: 'id',
+        slotName: 'id',
+        align: 'center',
+        width: 200,
+        fixed: "right",
+    }
 ]
 
 export const columnsTrafficUse = [
-  { title: window.$t('lotCard.appName'), dataIndex: 'appName', align: 'center',   },
-  { title: window.$t('lotCard.mcc'), dataIndex: 'mcc', align: 'center', width: 100 },
-  { title: window.$t('lotCard.qtaconsumption'), dataIndex: 'qtaconsumption', align: 'center',   },
-  { title: window.$t('lotCard.time'), dataIndex: 'time', align: 'center',   },
-]
-
+    { title: window.$t('lotCard.appName'), dataIndex: 'appName', align: 'center', },
+    { title: window.$t('lotCard.mcc'), dataIndex: 'mcc', align: 'center', width: 100 },
+    { title: window.$t('lotCard.qtaconsumption'), dataIndex: 'qtaconsumption', align: 'center', },
+    { title: window.$t('lotCard.time'), dataIndex: 'time', align: 'center', },
+]

+ 29 - 83
src/views/lotCard/cardList/index.vue

@@ -1,16 +1,6 @@
 <template>
   <!-- 卡清单管理 -->
   <div class="container">
-    <div class="head-title">
-      <span>{{ route.meta.title }} </span>
-      <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-popconfirm>
-      </span>
-
-    </div>
     <!-- 搜索条件区 -->
     <div class="search-section">
       <a-form :model="searchForm" ref="formRef" layout="inline">
@@ -48,7 +38,15 @@
     </div>
 
     <a-table row-key="iccid" :data="dataSource" :columns="columns" :pagination="pagination" :scroll="{ x: 'auto' }"
-      :expandable="expandable" @page-change="evChangePage">
+      @page-change="evChangePage">
+      <template #poolNum="{ record }">
+        <span>{{ record.poolName }}</span>
+        <br/>
+        <span>{{ record.poolId }}</span>
+      </template>
+      <template #dataUsageTotal="{ record }">
+        <span>{{ record.dataUsageTotal }}MB</span>
+      </template>
       <template #id="{ record }">
         <!-- 查看流量消耗 -->
         <a class="a-link" href="javascript:;" style="margin-right: 1rem" @click="handletrafficUseDialog(record)">详情</a>
@@ -56,20 +54,17 @@
 
     </a-table>
     <!-- 查看流量消耗 -->
-    <trafficUseDialog ref="trafficUseDialogRef" @submit="intData()"/>
+    <trafficUseDialog ref="trafficUseDialogRef" @submit="intData()" />
+
 
-    
   </div>
 </template>
 
 <script setup>
-import { onMounted, ref, reactive, getCurrentInstance, h } from "vue";
-import { useRoute } from "vue-router";
+import { onMounted, ref, getCurrentInstance, h } from "vue";
 import { columns } from "./config";
-import { Message, Notification } from '@arco-design/web-vue'
-import { cardInfoList, cardInfoImport, orderList, orderFlowData } from "@/api/path/lotCard.api"
+import { cardInfoList } from "@/api/path/lotCard.api"
 import trafficUseDialog from "./trafficUseDialog.vue";
-import list from "./list.vue";
 import { Getdictionary } from '@/mixins/index.js'
 const { proxy } = getCurrentInstance()
 const formRef = ref()
@@ -81,7 +76,6 @@ const statusList = ref([]);
 const sourceList = ref([]);
 const serviceList = ref([]);
 const dataSource = ref([]);
-const route = useRoute();
 const pagination = ref({
   total: 0,
   pageSize: 10,
@@ -98,81 +92,31 @@ const intData = async () => {
     ...searchForm.value,
   }
   const soureName = await Getdictionary('source')
+  const accountStatusName = await Getdictionary('account')
   const { data } = await cardInfoList(param)
-  dataSource.value = (data.records || []).map((item) => {
+  dataSource.value = (data.records || []).map((item,index) => {
     const payType = item.payType == 0 ? 'Prepay' : 'Postpay';
-    const dataPackage = item.Info.dataPackage.map(res => res.productName).join(',');
     const soure = soureName.find(val => val.value == item.source)?.label
+    // const accountStatus = accountStatusName.find(val => val.value == item.Info.accountStatus)?.label
+    const iccidStatus = accountStatusName.find(val => val.value == item.iccidStatus)?.label
     return {
       ...item,
       ...item.Info,
       payType: payType,
-      dataPackageName: dataPackage,
-      sourceName: soure
+      sourceName: soure,
+      iccidStatus,
+      forewarningStatus:'正常',
+      HistoricalUsage:'10/G',
+      SilenceEndtime:'一个月',
+      usedBg:'0',
+      usableBg:'0',
+      ...item.dataPackage[0]
     }
   })
   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({
-      content: '请先输入ICCID,可输入多个以逗号分隔,然后再点击导入!',
-      duration: 2000,
-    })
-    return
-  }
-  const iccids = searchForm.value.iccid.split(',')
-  const iccidList = iccids.map(item => {
-    return {
-      iccid: item
-    }
-  })
-  const { code, data } = await cardInfoImport({ iccidList })
-  if (code == 200) {
-    Message.success({
-      content: data,
-      duration: 2000,
-    })
-    intData()
-  }
-
-};
-
-// 查看当前流量消耗详情
+// 详情
 const handletrafficUseDialog = (data) => {
   trafficUseDialogRef.value.open(data)
 }
@@ -182,6 +126,8 @@ const evChangePage = (page) => {
   pagination.value.current = page
   intData()
 }
+
+
 const handleSearch = () => {
   formRef.value.validate((errors) => {
     if (!errors) {
@@ -243,4 +189,4 @@ onMounted(() => {
     }
   }
 }
-</style>
+</style>

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

@@ -1,94 +0,0 @@
-<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.2" />
-                </div>
-                <div class="list_item_right">
-                    <p>
-                        <span>{{ $t('lotCard.orderID') }}:{{ item.id }}</span>
-                        <!-- <span class="list_item_right_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>

+ 362 - 352
src/views/lotCard/cardList/trafficUseDialog.vue

@@ -1,156 +1,158 @@
 <template>
-    <a-modal width="70%" :visible="visible" :title="'卡详情' + Card_info.iccid" :hide-cancel='true'
-        :ok-text="$t('lotCard.close')" @ok="handleSubmit" @cancel="handleCancel" draggable>
-        <!-- 卡片信息 -->
-        <a-row class="grid-demo" :gutter="24">
+  <a-modal width="70%" :visible="visible" :title="'卡详情' + Card_info.iccid" :hide-cancel='true'
+           :ok-text="$t('lotCard.close')" @ok="handleSubmit" @cancel="handleCancel" draggable>
+    <!-- 卡片信息 -->
+    <a-row class="grid-demo" :gutter="24">
+      <a-col :span="12">
+        <a-form :model="Card_info" auto-label-width label-align="left" class="toal_Form">
+          <a-row :gutter="10">
             <a-col :span="12">
-                <a-form :model="Card_info" auto-label-width label-align="left" class="toal_Form">
-                    <a-row :gutter="10">
-                        <a-col :span="12">
-                            <a-form-item label="ICCID">
-                                {{ Card_info.iccid }}
-                            </a-form-item>
-                        </a-col>
+              <a-form-item label="ICCID">
+                {{ Card_info.iccid }}
+              </a-form-item>
+            </a-col>
 
-                        <a-col :span="12">
-                            <a-form-item label="IMSI">
-                                {{ Card_info.account }}
-                            </a-form-item>
-                        </a-col>
-                        <a-col :span="12">
-                            <a-form-item label="SIM绑定的IMSI">
-                                {{ Card_info.currentImsi }}
-                            </a-form-item>
-                        </a-col>
-                        <a-col :span="12">
-                            <a-form-item label="SIM货币余额">
-                                {{ Card_info.moneyBalances }}
-                            </a-form-item>
-                        </a-col>
-                        <a-col :span="12">
-                            <a-form-item label="激活日期">
-                                {{ Card_info.activeTime }}
-                            </a-form-item>
-                        </a-col>
-                        <a-col :span="12">
-                            <a-form-item label="到期日期">
-                                {{ Card_info.closeTime }}
-                            </a-form-item>
-                        </a-col>
-                        <a-col :span="12">
-                            <a-form-item label="有效期">
-                                {{ Card_info.validMonth }}月
-                            </a-form-item>
-                        </a-col>
-                        <a-col :span="12">
-                            <a-form-item label="供应商">
-                                {{ Card_info.currentImsiProvider }}
-                            </a-form-item>
-                        </a-col>
-                    </a-row>
-                </a-form>
-                <p>当前套餐信息</p>
-                <a-form :model="dataPackage" auto-label-width label-align="left">
-                    <a-row :gutter="10" wrap>
-                        <a-col :span="12">
-                            <a-form-item label="套餐名称">
-                                {{ dataPackage?.productName }}
-                            </a-form-item>
-                        </a-col>
-                        <a-col :span="12">
-                            <a-form-item label="套餐状态">
-                                {{ dataPackage?.status == 1 ? '已激活' : (dataPackage?.status == 2 ? '关闭' :
-                                    dataPackage?.status == 3 ? '已过期' : '未使用') }}
-                            </a-form-item>
-                        </a-col>
-                        <a-col :span="12">
-                            <a-form-item label="有效期">
-                                {{ dataPackage?.validMonth }}月
-                            </a-form-item>
-                        </a-col>
-                        <a-col :span="12">
-                            <a-form-item label="是否赠送套餐">
-                                {{ dataPackage?.present == 0 ? '否' : '是' }}
-                            </a-form-item>
-                        </a-col>
-                        <a-col :span="12">
-                            <a-form-item label="套餐激活日期">
-                                {{ dataPackage?.activeTime }}
-                            </a-form-item>
-                        </a-col>
-                        <a-col :span="12">
-                            <a-form-item label="套餐过期日期">
-                                {{ dataPackage?.expiryTime }}
-                            </a-form-item>
-                        </a-col>
-                        <div class="line"></div>
-                        <a-col :span="12">
-                            <a-form-item label="套餐可用流量">
-                                {{ dataPackage?.dataTotal == -1 ? '无限流量' : dataPackage?.dataTotal }}MB
-                            </a-form-item>
-                        </a-col>
-                        <a-col :span="12">
-                            <a-form-item label="套餐已使用流量">
-                                {{ dataPackage?.dataUsage }}MB
-                            </a-form-item>
-                        </a-col>
-                        <a-col :span="12">
-                            <a-form-item label="套餐今日使用流量">
-                                {{ dataPackage?.dataToday }}MB
-                            </a-form-item>
-                        </a-col>
-                        <a-col :span="12">
-                            <a-form-item label="套餐有效天数">
-                                {{ dataPackage?.validDays }}
-                            </a-form-item>
-                        </a-col>
-                    </a-row>
-                </a-form>
+            <a-col :span="12">
+              <a-form-item label="IMSI">
+                {{ Card_info.account }}
+              </a-form-item>
+            </a-col>
+            <a-col :span="12">
+              <a-form-item label="IMSI">
+                {{ Card_info.currentImsi }}
+              </a-form-item>
+            </a-col>
+            <a-col :span="12">
+              <a-form-item label="SIM货币余额">
+                {{ Card_info.moneyBalances }}
+              </a-form-item>
+            </a-col>
+            <a-col :span="12">
+              <a-form-item label="激活日期">
+                {{ Card_info.activeTime }}
+              </a-form-item>
+            </a-col>
+            <a-col :span="12">
+              <a-form-item label="到期日期">
+                {{ Card_info.closeTime }}
+              </a-form-item>
+            </a-col>
+            <a-col :span="12">
+              <a-form-item label="有效期">
+                {{ Card_info.validMonth }}月
+              </a-form-item>
+            </a-col>
+            <a-col :span="12">
+              <a-form-item label="供应商">
+                {{ Card_info.currentImsiProvider }}
+              </a-form-item>
+            </a-col>
+          </a-row>
+        </a-form>
+        <p>当前套餐信息</p>
+        <a-form :model="dataPackage" auto-label-width label-align="left">
+          <a-row :gutter="10" wrap>
+            <a-col :span="12">
+              <a-form-item label="套餐名称">
+                {{ dataPackage?.productName }}
+              </a-form-item>
+            </a-col>
+            <a-col :span="12">
+              <a-form-item label="套餐状态">
+                {{
+                  dataPackage?.status == 1 ? '已激活' : (dataPackage?.status == 2 ? '关闭' :
+                      dataPackage?.status == 3 ? '已过期' : '未使用')
+                }}
+              </a-form-item>
+            </a-col>
+            <a-col :span="12">
+              <a-form-item label="有效期">
+                {{ dataPackage?.validMonth }}月
+              </a-form-item>
+            </a-col>
+            <a-col :span="12">
+              <a-form-item label="是否赠送套餐">
+                {{ dataPackage?.present == 0 ? '否' : '是' }}
+              </a-form-item>
+            </a-col>
+            <a-col :span="12">
+              <a-form-item label="套餐激活日期">
+                {{ dataPackage?.activeTime }}
+              </a-form-item>
+            </a-col>
+            <a-col :span="12">
+              <a-form-item label="套餐过期日期">
+                {{ dataPackage?.expiryTime }}
+              </a-form-item>
             </a-col>
+            <div class="line"></div>
             <a-col :span="12">
-                <a-tabs>
-                    <a-tab-pane key="1" title="月用量">
-                        <div class="chart" style="width:100%" id="chartContainer" />
-                    </a-tab-pane>
-                    <a-tab-pane key="2" title="卡套餐信息">
-                        <a-table :columns="columnsCard" :data="dataCard" :scroll="{ x: 'auto' }" :pagination="false" />
-                    </a-tab-pane>
-                    <a-tab-pane key="3" title="预警信息">
-                        Content of Tab Panel 3
-                    </a-tab-pane>
-                    <a-tab-pane key="4" title="充值记录">
-                        <a-table :columns="columnsTopup" :data="dataTopup" />
-                    </a-tab-pane>
-                    <a-tab-pane key="5" title="使用量">
-                        <a-table :columns="columnsAmount" :data="dataAmount" :scroll="{ x: 'auto' }"
-                            :pagination="false" />
-                    </a-tab-pane>
-                    <a-tab-pane key="6" title="操作记录">
-                        Content of Tab Panel 3
-                    </a-tab-pane>
-                </a-tabs>
+              <a-form-item label="套餐可用流量">
+                {{ dataPackage?.dataTotal == -1 ? '无限流量' : dataPackage?.dataTotal }}MB
+              </a-form-item>
             </a-col>
-        </a-row>
+            <a-col :span="12">
+              <a-form-item label="套餐已使用流量">
+                {{ dataPackage?.dataUsage }}MB
+              </a-form-item>
+            </a-col>
+            <a-col :span="12">
+              <a-form-item label="套餐今日使用流量">
+                {{ dataPackage?.dataToday }}MB
+              </a-form-item>
+            </a-col>
+            <a-col :span="12">
+              <a-form-item label="套餐有效天数">
+                {{ dataPackage?.validDays }}
+              </a-form-item>
+            </a-col>
+          </a-row>
+        </a-form>
+      </a-col>
+      <a-col :span="12">
+        <a-tabs>
+          <a-tab-pane key="1" title="月用量">
+            <div class="chart" style="width:100%" id="chartContainer"/>
+          </a-tab-pane>
+          <a-tab-pane key="2" title="卡套餐信息">
+            <a-table :columns="columnsCard" :data="dataCard" :scroll="{ x: 'auto' }" :pagination="false"/>
+          </a-tab-pane>
+          <a-tab-pane key="3" title="预警信息">
+            Content of Tab Panel 3
+          </a-tab-pane>
+          <a-tab-pane key="4" title="充值记录">
+            <a-table :columns="columnsTopup" :data="dataTopup" :scroll="{ x: 'auto' }"/>
+          </a-tab-pane>
+          <a-tab-pane key="5" title="使用量">
+            <a-table :columns="columnsAmount" :data="dataAmount" :scroll="{ x: 'auto' }"
+                     :pagination="false"/>
+          </a-tab-pane>
+          <a-tab-pane key="6" title="操作记录">
+            Content of Tab Panel 3
+          </a-tab-pane>
+        </a-tabs>
+      </a-col>
+    </a-row>
 
-        <template #footer>
-            <div class="footer_button">
-                <!-- <a-button type="primary" status="warning">同步卡信息 V</a-button> -->
-                <a-button type="primary" status="warning" @click="SIMCardService(0)">暂停SIM卡服务</a-button>
-                <a-button type="primary" status="warning" @click="SIMCardService(1)">恢复SIM卡服务</a-button>
-                <a-button type="primary" status="warning">关闭SIM卡</a-button>
-            </div>
-        </template>
-    </a-modal>
+    <template #footer>
+      <div class="footer_button">
+        <!-- <a-button type="primary" status="warning">同步卡信息 V</a-button> -->
+        <a-button type="primary" status="warning" @click="SIMCardService(0)">暂停SIM卡服务</a-button>
+        <a-button type="primary" status="warning" @click="SIMCardService(1)">恢复SIM卡服务</a-button>
+        <a-button type="primary" status="warning">关闭SIM卡</a-button>
+      </div>
+    </template>
+  </a-modal>
 </template>
 <script setup>
-import { onMounted, ref } from "vue";
-import { getDataCDR, PauseSIMService, RecoverSIMService, OffSIMCard } from '@/api/path/lotCard.api'
-import { Getdictionary } from '@/mixins/index'
-import { Message } from '@arco-design/web-vue'
+import {onMounted, ref} from "vue";
+import {getDataCDR, PauseSIMService, RecoverSIMService, OffSIMCard} from '@/api/path/lotCard.api'
+import {Getdictionary} from '@/mixins/index'
+import {Message} from '@arco-design/web-vue'
 // 图表插件
 import * as echarts from "echarts";
-const props = defineProps({
-});
+
+const props = defineProps({});
 
 const emit = defineEmits(['submit']);
 const visible = ref(false)
@@ -160,247 +162,255 @@ const dataSource = ref([]);
 
 // 图表插件
 const option = ref({
-    xAxis: {
-        type: 'category',
-        data: ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月']
-    },
-    yAxis: {
-        type: 'value'
-    },
-    series: [
-        {
-            data: [120, 200, 150, 80, 70, 110, 130],
-            type: 'bar',
-        }
-    ],
+  xAxis: {
+    type: 'category',
+    data: ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月']
+  },
+  yAxis: {
+    type: 'value'
+  },
+  series: [
+    {
+      data: [],
+      type: 'bar',
+    }
+  ],
 })
 
 // 卡套餐信息
 const columnsCard = [
-    {
-        title: '套餐名称',
-        dataIndex: 'productName',
-        align: 'center', ellipsis: true
-    }, {
-        title: '套餐状态',
-        dataIndex: 'status',
-        align: 'center', ellipsis: true
-    },
-    {
-        title: '有效期(月)',
-        dataIndex: 'validMonth',
-        align: 'center', ellipsis: true
-    },
-    {
-        title: '可用流量',
-        dataIndex: 'dataTotal',
-        align: 'center', ellipsis: true
-    },
-    {
-        title: '已使用流量',
-        dataIndex: 'dataUsage',
-        align: 'center', ellipsis: true
-    },
-    {
-        title: '今日使用流量',
-        dataIndex: 'dataToday',
-        align: 'center', ellipsis: true
-    },
-    {
-        title: '套餐有效期(天数)',
-        dataIndex: 'validDays',
-        align: 'center', ellipsis: true
-    },
-    {
-        title: '激活日期',
-        dataIndex: 'activeTime',
-        align: 'center', ellipsis: true
-    },
-    {
-        title: '过期日期',
-        dataIndex: 'expiryTime',
-        align: 'center', ellipsis: true
-    },
+  {
+    title: '套餐名称',
+    dataIndex: 'productName',
+    align: 'center', ellipsis: true
+  }, {
+    title: '套餐状态',
+    dataIndex: 'status',
+    align: 'center', ellipsis: true
+  },
+  {
+    title: '有效期(月)',
+    dataIndex: 'validMonth',
+    align: 'center', ellipsis: true
+  },
+  {
+    title: '可用流量',
+    dataIndex: 'dataTotal',
+    align: 'center', ellipsis: true
+  },
+  {
+    title: '已使用流量',
+    dataIndex: 'dataUsage',
+    align: 'center', ellipsis: true
+  },
+  {
+    title: '今日使用流量',
+    dataIndex: 'dataToday',
+    align: 'center', ellipsis: true
+  },
+  {
+    title: '套餐有效期(天数)',
+    dataIndex: 'validDays',
+    align: 'center', ellipsis: true
+  },
+  {
+    title: '激活日期',
+    dataIndex: 'activeTime',
+    align: 'center', ellipsis: true
+  },
+  {
+    title: '过期日期',
+    dataIndex: 'expiryTime',
+    align: 'center', ellipsis: true
+  },
 ]
 const dataCard = ref([])
 
 // 充值信息
 const columnsTopup = [
-    {
-        title: '订单号',
-        dataIndex: 'productName',
-    },
-    {
-        title: 'ICCID',
-        dataIndex: 'productName',
-    },
-    {
-        title: '购买套餐',
-        dataIndex: 'productName',
-    },
-    {
-        title: '订单类型',
-        dataIndex: 'productName',
-    },
-    {
-        title: '套餐价格',
-        dataIndex: 'productName',
-    },
-    {
-        title: '运营商',
-        dataIndex: 'productName',
-    },
-    {
-        title: '支付状态',
-        dataIndex: 'productName',
-    },
-    {
-        title: '下单日期',
-        dataIndex: 'productName',
-    },
+  {
+    title: '订单号',
+    dataIndex: 'productName',
+    ellipsis: true
+  },
+  {
+    title: 'ICCID',
+    dataIndex: 'productName',
+    ellipsis: true
+  },
+  {
+    title: '购买套餐',
+    dataIndex: 'productName',
+    ellipsis: true
+  },
+  {
+    title: '订单类型',
+    dataIndex: 'productName',
+    ellipsis: true
+  },
+  {
+    title: '套餐价格',
+    dataIndex: 'productName',
+    ellipsis: true
+  },
+  {
+    title: '运营商',
+    dataIndex: 'productName',
+    ellipsis: true
+  },
+  {
+    title: '支付状态',
+    dataIndex: 'productName',
+    ellipsis: true
+  },
+  {
+    title: '下单日期',
+    dataIndex: 'productName',
+    ellipsis: true
+  },
 ]
 const dataTopup = ref([])
 // 使用量
 const columnsAmount = [
-    {
-        title: '编号',
-        dataIndex: 'productId',
-        align: 'center', ellipsis: true
-    },
-    {
-        title: 'IMIS',
-        dataIndex: 'imsi',
-        align: 'center', ellipsis: true
-    },
+  {
+    title: '编号',
+    dataIndex: 'productId',
+    align: 'center', ellipsis: true
+  },
+  {
+    title: 'IMIS',
+    dataIndex: 'imsi',
+    align: 'center', ellipsis: true
+  },
 
-    {
-        title: 'SIM账户(卡号)',
-        dataIndex: 'account',
-        align: 'center', ellipsis: true
-    },
-    {
-        title: '流量(MB)',
-        dataIndex: 'usage',
-        align: 'center', ellipsis: true
-    },
-    {
-        title: '流量产生国家货地区编号',
-        dataIndex: 'countryNo',
-        align: 'center', ellipsis: true
-    },
-    {
-        title: '详单日期',
-        dataIndex: 'date',
-        align: 'center', ellipsis: true
-    },
+  {
+    title: 'SIM账户(卡号)',
+    dataIndex: 'account',
+    align: 'center', ellipsis: true
+  },
+  {
+    title: '流量(MB)',
+    dataIndex: 'usage',
+    align: 'center', ellipsis: true
+  },
+  {
+    title: '流量产生国家货地区编号',
+    dataIndex: 'countryNo',
+    align: 'center', ellipsis: true
+  },
+  {
+    title: '详单日期',
+    dataIndex: 'date',
+    align: 'center', ellipsis: true
+  },
 ]
 const dataAmount = ref([])
 const open = (data) => {
-    if (!data) {
-        return
+  if (!data) {
+    return
+  }
+  dataSource.value = []
+  Card_info.value = data
+  dataPackage.value = data.dataPackage[0]
+  // 卡套餐信息
+  dataCard.value = (data.dataPackage || []).map(val => {
+    const status = val.status == 1 ? '已激活' : (val.status == 2 ? '关闭' :
+        val.status == 3 ? '已过期' : '未使用')
+    const tatal = val.dataTotal == -1 ? '无限流量' : val.dataTotal
+    return {
+      ...val,
+      status: status,
+      dataTotal: tatal
     }
-    dataSource.value = []
-    Card_info.value = data
-    dataPackage.value = data.dataPackage[0]
-    // 卡套餐信息
-    dataCard.value = (data.dataPackage || []).map(val => {
-        const status = val.status == 1 ? '已激活' : (val.status == 2 ? '关闭' :
-            val.status == 3 ? '已过期' : '未使用')
-        const tatal = val.dataTotal == -1 ? '无限流量' : val.dataTotal
-        return {
-            ...val,
-            status: status,
-            dataTotal: tatal
-        }
-    })
-    intData()
-    visible.value = true
+  })
+  intData()
+  visible.value = true
 }
 
 // 使用量
 const intData = async () => {
-    // 获取今天的日期
-    const today = new Date();
-    const toDay = today.toISOString().split('T')[0];
+  // 获取今天的日期
+  const today = new Date();
+  const toDay = today.toISOString().split('T')[0];
 
-    // 获取三个月前的日期
-    const pastDate = new Date(today);
-    pastDate.setMonth(today.getMonth() - 3); // 减去三个月
-    const formattedDate = pastDate.toISOString().split('T')[0];
+  // 获取三个月前的日期
+  const pastDate = new Date(today);
+  pastDate.setMonth(today.getMonth() - 3); // 减去三个月
+  const formattedDate = pastDate.toISOString().split('T')[0];
 
-    // 获取 CDR 数据
-    let res = await getDataCDR({
-        iccid: Card_info.value.iccid,
-        source: Card_info.value.source,
-        startDate: formattedDate,
-        endDate: toDay
-    });
+  // 获取 CDR 数据
+  let res = await getDataCDR({
+    iccid: Card_info.value.iccid,
+    source: Card_info.value.source,
+    startDate: formattedDate,
+    endDate: toDay
+  });
 
-    dataAmount.value = res.data
+  dataAmount.value = res.data
 
 
-    // 定义季度时间段
-    const time = ['1-3', '4-6', '7-9', '9-12'];
+  // 定义季度时间段
+  const time = ['1-3', '4-6', '7-9', '9-12'];
 
-    // 获取当前年份
-    const year = today.getFullYear();
-    for (let val of time) {
-        // 拆分每个时间段,获取开始月和结束月
-        const [startMonth, endMonth] = val.split('-');
-        const startDate = `${year}-${startMonth}-01`; // 格式化开始日期
-        const endDate = `${year}-${endMonth}-01`; // 格式化结束日期
+  // 获取当前年份
+  const year = today.getFullYear();
+  for (let val of time) {
+    // 拆分每个时间段,获取开始月和结束月
+    const [startMonth, endMonth] = val.split('-');
+    const startDate = `${year}-${startMonth}-01`; // 格式化开始日期
+    const endDate = `${year}-${endMonth}-01`; // 格式化结束日期
 
-        // 获取每个时间段的数据
-        let res = await getDataCDR({
-            iccid: Card_info.value.iccid,
-            source: Card_info.value.source,
-            startDate: startDate,
-            endDate: endDate
-        });
+    // 获取每个时间段的数据
+    let res = await getDataCDR({
+      iccid: Card_info.value.iccid,
+      source: Card_info.value.source,
+      startDate: startDate,
+      endDate: endDate
+    });
 
-        // 将当前时间段的数据中的 'usage' 字段合并到 series[0].data 数组中
-        const usageData = (res.data || [])
-            .filter(val => val.usage !== undefined)
-            .map(val => val.usage);
-        option.value.series[0].data.push(...usageData);
-        initChart()
-    }
+    // 将当前时间段的数据中的 'usage' 字段合并到 series[0].data 数组中
+    const usageData = (res.data || [])
+        .filter(val => val.usage !== undefined)
+        .map(val => val.usage);
+    option.value.series[0].data.push(...usageData);
+    initChart()
+  }
 }
 
 // SIM卡操作
 const SIMCardService = async (index) => {
-    const Inform = {
-        iccid: Card_info.value.iccid, source: Card_info.value.source
-    }
-    // 暂停SIM卡
-    let res = index == 0 ? await PauseSIMService(Inform) : (index == 1 ? await RecoverSIMService(Inform) : '')
-    if (res.code === 200) {
-        Message.success({
-            content: res.message,
-            duration: 2000,
-        })
-        handleSubmit()
-    }
+  const Inform = {
+    iccid: Card_info.value.iccid, source: Card_info.value.source
+  }
+  // 暂停SIM卡
+  let res = index == 0 ? await PauseSIMService(Inform) : (index == 1 ? await RecoverSIMService(Inform) : '')
+  if (res.code === 200) {
+    Message.success({
+      content: res.message,
+      duration: 2000,
+    })
+    handleSubmit()
+  }
 }
 const handleSubmit = () => {
-    emit('submit', true);
-    visible.value = false
+  emit('submit', true);
+  visible.value = false
 };
 
 const handleCancel = () => {
-    visible.value = false
+  visible.value = false
 };
 
 // 图表
 const initChart = () => {
-    const dom = echarts.init(document.getElementById("chartContainer"));
-    dom.setOption(option.value);
-    window.addEventListener("resize",()=>{
-        dom.resize();
-    })
+  const dom = echarts.init(document.getElementById("chartContainer"));
+  dom.setOption(option.value);
+  window.addEventListener("resize", () => {
+    dom.resize();
+  })
 }
 
-defineExpose({ open })
+defineExpose({open})
 
 
 onMounted(() => {
@@ -409,32 +419,32 @@ onMounted(() => {
 
 <style scoped lang="less">
 .toal_Form {
-    padding-bottom: 10px;
-    border-bottom: 1px solid #ccc;
+  padding-bottom: 10px;
+  border-bottom: 1px solid #ccc;
 }
 
 p {
-    font-size: 20px;
-    color: black;
+  font-size: 20px;
+  color: black;
 }
 
 .line {
-    margin: 15px 0;
-    border-bottom: 1px solid #ccc;
-    width: 100%;
+  margin: 15px 0;
+  border-bottom: 1px solid #ccc;
+  width: 100%;
 }
 
 .footer_button {
-    display: flex;
-    justify-content: start;
+  display: flex;
+  justify-content: start;
 
-    button {
-        margin-right: 15px;
-    }
+  button {
+    margin-right: 15px;
+  }
 }
 
 .chart {
-    height: 310px;
-    width: 100%;
+  height: 310px;
+  width: 100%;
 }
 </style>

+ 199 - 0
src/views/order/BuyCard/Card.vue

@@ -0,0 +1,199 @@
+<template>
+    <!-- 创建 -->
+    <a-modal v-model:visible="modelValue" title="购卡" width="600px" @cancel="closeModal(showAudit, formState)" centered
+        :maskClosable="false" okText="确定" cancelText="关闭" :footer="null">
+        <a-form ref="formRef" :rules="rules" :model="formState" @submit="submitPurchase">
+            <a-form-item field="customerName" label="客户名称">
+                <div class="audit-txt">{{ userName }}</div>
+            </a-form-item>
+            <a-form-item label="运营商" field="source">
+                <a-select v-model="formState.source" :style="{ width: '380px' }" placeholder="请选择运营商">
+                    <a-option v-for="item of sourceList" :value="item.value" :label="item.label" />
+                </a-select>
+            </a-form-item>
+            <a-form-item label="资费名称" field="tariffId">
+                <a-select v-model="formState.trafficId" :style="{ width: '380px' }" placeholder="请选择资费ID">
+                    <a-option v-for="item of tariffData" :value="item.value" :label="item.label" />
+                </a-select>
+            </a-form-item>
+            <a-form-item label="卡类型" field="cardType">
+                <a-select v-model="formState.simType" :style="{ width: '380px' }" placeholder="请选择卡类型">
+                    <a-option v-for="item of orderType" :value="item.value" :label="item.label" />
+                </a-select>
+            </a-form-item>
+            <a-form-item label="沉默期">
+                <a-select v-model="formState.periodOfSilence" :style="{ width: '380px' }" placeholder="请选择沉默期">
+                    <a-option v-for="item of silenceOptions" :value="item.value" :label="item.label" />
+                </a-select>
+            </a-form-item>
+            <a-form-item label="组池" field="flowPool">
+                <a-radio-group v-model="formState.isTrafficPool" :options="flowPoolData">
+                    <template #label="{ data }">
+                        <a-tag>{{ data.label }}</a-tag>
+                    </template>
+                </a-radio-group>
+            </a-form-item>
+            <a-form-item label="流量池" v-if="formState.isTrafficPool == 1">
+                <a-select v-model="formState.poolId" :style="{ width: '380px' }" placeholder="请选择流量池">
+                    <a-option v-for="item of FlowPool" :value="item.id" :label="item.label" />
+                </a-select>
+            </a-form-item>
+            <a-form-item label="购卡数量" field="num">
+                <a-input v-model="formState.quantity" placeholder="请输入购卡数量" />
+            </a-form-item>
+            <a-form-item>
+                <a-button type="primary" html-type="submit" style="margin-right: 10px;">确定</a-button>
+                <a-button @click="closeModal(formState)">取消</a-button>
+            </a-form-item>
+        </a-form>
+    </a-modal>
+</template>
+
+<script setup>
+import { ref, toRefs, defineProps, watch, toRef } from 'vue';
+import { tariffList, ExampleQueryTrafficPool } from "@/api/path/tariffManagement.api";
+import { Getdictionary } from '@/mixins/index.js'
+import { CardPurchase } from '@/api/path/order'
+import { Message } from '@arco-design/web-vue';
+const props = defineProps({
+    modelValue: {
+        type: Boolean,
+        default: false
+    }
+})
+
+const modelValue = toRef(props, 'modelValue')
+const emit = defineEmits(['update:modelValue', 'submit'])
+const state = ref({
+    userName: JSON.parse(localStorage.getItem('user_login_information'))?.username,
+    userType: JSON.parse(localStorage.getItem('user_login_information'))?.userType, // 1平台 2用户
+    showAudit: false,
+    formRef: null,
+    formState: {
+        source: null, // 来源
+        trafficId: "", // 资费Id
+        periodOfSilence: "", // 静默期
+        isTrafficPool: "", // 是否是流量池 1:是 2:否
+        quantity: null, // 采购数量
+        simType: "" ,// 卡类型
+        poolId: null,
+    },
+    sourceList: [],
+    silenceOptions: [], // 沉默期
+    orderType: [], // 卡类型
+    flowPoolData: [], // 组池
+    tariffData: [],
+    FlowPool: [], // 流量池
+})
+
+const { showAudit, formState, sourceList, silenceOptions, orderType, flowPoolData, userName, userType, tariffData, formRef, FlowPool } = toRefs(state.value)
+
+const rules = {
+    source: [{ required: true, trigger: 'change', }],
+    trafficId: [
+        {
+            required: true,
+            trigger: 'change',
+        },
+    ],
+    simType: [
+        {
+            required: true,
+            trigger: 'change',
+        },
+    ],
+    periodOfSilence: [
+        {
+            required: true,
+            trigger: 'change',
+        },
+    ],
+    isTrafficPool: [
+        {
+            required: true,
+            trigger: 'change',
+        },
+    ],
+    quantity: [
+        {
+            required: true,
+            trigger: 'change',
+        },
+    ],
+    poolId: [
+        {
+            required: true,
+            trigger: 'change',
+        },
+    ],
+};
+
+const handleDictValue = async () => {
+    // 使用 Promise.all 并行获取字典数据
+    const [sourceRes, cardTypeRes, silenceOfRes, groupPoolRes] = await Promise.all([
+        Getdictionary('source'),
+        Getdictionary('cardType'),
+        Getdictionary('silenceOf'),
+        Getdictionary('groupPool')
+    ]);
+
+    // 分别将返回的数据保存到响应的 ref 变量中
+    sourceList.value = sourceRes;
+    orderType.value = cardTypeRes;
+    silenceOptions.value = silenceOfRes;
+    flowPoolData.value = groupPoolRes;
+    const param = {
+        current: 1,
+        size: 999,
+    }
+    tariffList(param).then(res => {
+        tariffData.value = res.data.records.map(item => ({
+            label: item.label,
+            value: item.id,
+            ...item
+        }));
+    })
+}
+// 确认购卡
+const submitPurchase = ({ values, errors }) => {
+    formRef.value.validate(async (errors) => {
+        if (!errors) {
+            const data = {
+                source: String(formState.value.source),
+                trafficId: formState.value.trafficId,
+                quantity: Number(formState.value.quantity),
+                simType: formState.value.simType,
+                periodOfSilence: String(formState.value.periodOfSilence),
+                isTrafficPool: formState.value.isTrafficPool,
+                poolId: formState.value.poolId,
+            }
+            CardPurchase(data).then(res => {
+                Message.success(res.message)
+                emit('update:modelValue', false)
+                emit('submit', true)
+            })
+        }
+    })
+}
+
+const closeModal = (val) => {
+    emit('update:modelValue', false)
+    Object.keys(formState.value).forEach(key => {
+        formState.value[key] = ''
+    })
+}
+// 流量池
+watch(() => formState.value?.isTrafficPool, val => {
+    if (val == 1) {
+        ExampleQueryTrafficPool().then(res => {
+            FlowPool.value = res.data
+        })
+    }
+})
+watch(() => modelValue.value, val => {
+    if (val) {
+        handleDictValue()
+    }
+})
+</script>
+<style scoped></style>

+ 196 - 0
src/views/order/BuyCard/detaile.vue

@@ -0,0 +1,196 @@
+<template>
+    <a-modal v-model:visible="modelValue" width="800px" title="订单详情" >
+        <div class="detail-box">
+            <div class="detail-item-box">
+                <div class="detail-item">
+                    <div class="item-label">订单编号</div>
+                    <div class="item-content">{{ FormDataList.id }}</div>
+                </div>
+                <div class="detail-item">
+                    <div class="item-label">订单状态</div>
+                    <div class="item-content">
+                        <a-tag color="#168cff" v-if="FormDataList.tmsStatus == 1">未发货</a-tag>
+                        <a-tag color="#00b42a" v-if="FormDataList.tmsStatus == 2">已发货</a-tag>
+                    </div>
+                </div>
+            </div>
+            <div class="detail-item-box">
+                <div class="detail-item">
+                    <div class="item-label">运营商</div>
+                    <div class="item-content">{{ FormDataList.sourceName }}</div>
+                </div>
+                <div class="detail-item">
+                    <div class="item-label">资费信息</div>
+                    <div class="item-content">{{ TariffInfomr }}</div>
+                </div>
+            </div>
+            <div class="detail-item-box">
+                <div class="detail-item">
+                    <div class="item-label">最短订阅周期</div>
+                    <div class="item-content">{{ tariffForm.settlementCycle?.split('~')[0] }}个月</div>
+                </div>
+                <div class="detail-item">
+                    <div class="item-label">最长订阅周期</div>
+                    <div class="item-content">{{ tariffForm.settlementCycle?.split('~')[1] }}个月</div>
+                </div>
+            </div>
+            <div class="detail-item-box">
+                <div class="detail-item">
+                    <div class="item-label">计费方式</div>
+                    <div class="item-content">{{ tariffForm.billingMethodName }}</div>
+                </div>
+                <div class="detail-item">
+                    <div class="item-label">结算周期</div>
+                    <div class="item-content">{{ tariffForm.billingcycleName }}</div>
+                </div>
+            </div>
+            <div class="detail-item-box">
+                <div class="detail-item">
+                    <div class="item-label">卡类型</div>
+                    <div class="item-content">{{ FormDataList.CardType }}</div>
+                </div>
+                <div class="detail-item">
+                    <div class="item-label">标准价格</div>
+                    <div class="item-content">{{ tariffForm.pricingName }}</div>
+                </div>
+            </div>
+            <div class="detail-item-box">
+                <div class="detail-item">
+                    <div class="item-label">流量池</div>
+                    <div class="item-content">{{ FormDataList.isTrafficPool == 1 ? '是' : '否' }}</div>
+                </div>
+            </div>
+            <div class="detail-item-box">
+                <div class="detail-item">
+                    <div class="item-label">卡数量</div>
+                    <div class="item-content">{{ dataDetail.length }}
+                        <a-button type="primary" @click="showCard = true" style="margin-left:10px;"
+                            v-if="userType == 1 && FormDataList.moderationStatus == 2">分配卡号</a-button>
+                    </div>
+                </div>
+            </div>
+        </div>
+        <div class="detail-table">
+            <a-table :columns="columnsDetail" :data="dataDetail" />
+        </div>
+
+        <template #footer>
+            <a-button @click="cancel">取消</a-button>
+        </template>
+    </a-modal>
+
+    <!-- 分配卡号 -->
+    <a-modal v-model:visible="showCard" title="分配卡号" @cancel="closeModal(showCard, FormDataList)"
+        @before-ok="showCard = false" okText="确认" cancelText="取消">
+        <Upload listType="" minx="1" accept=".xlsx" :handelUpload="customRequest" :showRemoveButton="false">
+        </Upload>
+    </a-modal>
+</template>
+
+<script setup>
+import { ref, onMounted, toRefs, toRef ,watch} from 'vue';
+import { AcquireOrdertariff, DistributionCard,TariffOrderCard } from '@/api/path/order'
+import { Message } from '@arco-design/web-vue';
+import Upload from "@/components/upload/index.vue";
+import { Getdictionary } from '@/mixins/index.js'
+const props = defineProps({
+    modelValue: {
+        type: Boolean,
+        default: false
+    },
+    FormDataList: {
+        type: Object,
+        default: () => ({})
+    }
+})
+const modelValue = toRef(props, 'modelValue')
+const FormDataList = toRef(props, 'FormDataList')
+const emit = defineEmits(['update:modelValue', 'submit'])
+const state = ref({
+    tariffForm: {},
+    showCard: false,
+    res1:[],
+    res2:[],
+    res3:[],
+    userType: JSON.parse(localStorage.getItem('user_login_information'))?.userType, // 1平台 2用户
+})
+const { tariffForm, showCard,res1,res2,res3,userType } = toRefs(state.value)
+const columnsDetail = [{ title: 'ICCID', dataIndex: 'iccid' },{ title: '卡状态', dataIndex: 'status' },{ title: '创建时间', dataIndex: 'expireTime' }
+]
+const dataDetail = ref([])
+
+// 分配卡号
+const customRequest = (options) => {
+    const formData = new FormData();
+    formData.append('file', options.fileItem.file);  // 这里将文件添加到 FormDataList 中
+    formData.append('orderId', FormDataList.value.id);
+    DistributionCard(formData).then(res => {
+        Message.success(res.message)
+        res.data[0].forEach(val=>[
+            dataDetail.value.push({iccid:val})
+        ])
+    })
+}
+
+const cancel = () => {
+    emit('update:modelValue', false)
+}
+
+const closeModal = ()=>{
+    showCard.value = false
+}
+
+watch(() => FormDataList.value, val => {
+    if (Object.keys(val).length === 0) return
+    AcquireOrdertariff({ id: val.trafficId }).then(res => {
+        tariffForm.value = res.data
+        tariffForm.value.billingcycleName = res1.value.filter(val => val.value == res.data.billingCycle)[0]?.label;
+        tariffForm.value.billingMethodName = res2.value.filter(val => val.value == res.data.billingMethod)[0]?.label;
+        tariffForm.value.TariffInfomr = res.data.trafficBilling + '/' + res.data.trafficBillingType
+        tariffForm.value.pricingName = tariffForm.value.pricing !== '' ? tariffForm.value.pricing + '/' + res3.value.filter(val => val.value == res.data.currency)[0]?.label : '';
+    })
+    dataDetail.value = []
+    TariffOrderCard({id:val.trafficId}).then(res=>{
+        dataDetail.value = res.data
+    })
+},{deep: true})
+
+onMounted(async () => {
+    res1.value = await Getdictionary('Billingcycle')
+    res2.value = await Getdictionary('billingMethod')
+    res3.value = await Getdictionary('currencyType')
+})
+</script>
+<style scoped lang="less">
+.detail-box {
+    .detail-item-box {
+        display: flex;
+        justify-content: space-between;
+        align-items: center;
+        margin-bottom: 10px;
+
+        .detail-item {
+            //styleName: Body/Medium;
+            font-family: PingFang SC;
+            font-size: 14px;
+            font-weight: 400;
+            line-height: 22px;
+            text-align: left;
+            display: flex;
+            align-items: center;
+            min-width: 350px;
+
+            .item-label {
+                color: rgba(0, 0, 0, 0.4);
+                width: 120px;
+                text-align: right;
+                margin-right: 10px;
+            }
+
+            .item-content {
+                color: rgba(51, 51, 51, 1);
+            }
+        }
+    }
+}
+</style>

+ 0 - 428
src/views/order/BuyCard/index copy.vue

@@ -1,428 +0,0 @@
-<!-- 购卡订单 -->
-<template>
-  <div class="silent-expire-alarm">
-    <!-- 搜索条件区 -->
-    <div class="search-section">
-      <a-form :model="searchForm" layout="inline">
-        <a-form-item field="cardNumber" label="订单编号">
-          <a-input v-model="searchForm.orderNumber" placeholder="请输入订单编号" allow-clear />
-        </a-form-item>
-        <a-form-item field="customerName" label="客户">
-          <a-input v-model="searchForm.customerName" placeholder="请输入客户名称" allow-clear />
-        </a-form-item>
-        <a-form-item>
-          <a-space>
-            <a-button type="primary" @click="handleSearch">搜索</a-button>
-            <a-button @click="resetSearch">重置</a-button>
-          </a-space>
-        </a-form-item>
-      </a-form>
-    </div>
-    <div class="audit-btn">
-      <a-button @click="openAudit" type="text">
-        <template #icon>
-          <icon-plus-circle />
-        </template>
-        <template #default>审核</template>
-      </a-button>
-    </div>
-    <!-- 数据表格 -->
-    <a-table row-key="customerName" v-model:selectedKeys="selectedKeys" :row-selection="rowSelection" :columns="columns"
-      :data="tableData" :pagination="pagination" :scroll="{ x: '100%', y: '400px' }">
-      <template #operate="{ record }">
-        <a-button @click="openContract(record)" type="text">上传合同</a-button>
-      </template>
-      <template #detail="{ record }">
-        <a-button @click="openDetail(record)" type="text">订单详情</a-button>
-      </template>
-    </a-table>
-    <a-modal v-model:visible="uploadContract" title="上传合同" @cancel="handleCancel" @before-ok="handleBeforeOk"
-      okText="保存" cancelText="关闭">
-      <a-form :model="formContract" auto-label-width>
-        <a-form-item field="orderNumber" label="单号">
-          <!-- <a-input v-model="formContract.orderNumber" disabled placeholder="请输入单号" /> -->
-          <div class="audit-txt">{{ formContract.orderNumber }}</div>
-        </a-form-item>
-        <a-form-item field="customerName" label="客户">
-          <!-- <a-input v-model="formContract.customerName" disabled placeholder="请输入客户" /> -->
-          <div class="audit-txt" style="color:#418035;">{{ formContract.customerName }}</div>
-        </a-form-item>
-        <a-form-item field="fileList" label="销售合同">
-          <a-upload action="/" :default-file-list="formContract.fileList" />
-        </a-form-item>
-      </a-form>
-    </a-modal>
-    <a-modal v-model:visible="showAudit" title="审核" @cancel="showAudit = false" @before-ok="submitAudit" okText="确定审核"
-      cancelText="关闭">
-      <a-form :model="formAudit" auto-label-width>
-        <a-form-item field="customerName" label="客户">
-          <!-- <a-input v-model="formAudit.customerName" placeholder="请输入客户" /> -->
-          <div class="audit-txt" style="color:#418035;">演示账号02</div>
-        </a-form-item>
-        <a-form-item field="cardType" label="卡类型">
-          <!-- <a-input v-model="formAudit.cardType" placeholder="请输入单号" /> -->
-          <div class="audit-txt">普通卡切卡普通卡MP1,1元/涨<div class="audit-tag">共1张卡</div>
-          </div>
-        </a-form-item>
-        <a-form-item field="money" label="资费">
-          <!-- <a-input v-model="formAudit.money" placeholder="请输入单号" /> -->
-          <div class="audit-txt">“移动100M月包” <div class="audit-tag">订购12个月</div>
-          </div>
-        </a-form-item>
-        <a-form-item field="orderStatus" label="订单状态">
-          <!-- <a-input v-model="formAudit.orderStatus" placeholder="请输入单号" /> -->
-          <a-radio-group v-model="formAudit.orderStatus" :options="options" />
-        </a-form-item>
-        <a-form-item field="auditOpinion" label="审核意见">
-          <!-- <a-input v-model="formAudit.auditOpinion" placeholder="请输入单号" /> -->
-          <a-textarea placeholder="您填写的审核意见会直接投送给用户,请认真填写!" v-model="formAudit.auditOpinion" allow-clear />
-        </a-form-item>
-        <a-form-item field="fileList" label="销售合同">
-          <a-upload action="/" :default-file-list="formAudit.fileList" />
-        </a-form-item>
-      </a-form>
-    </a-modal>
-    <a-modal v-model:visible="showDetail" width="800px" title="订单详情" :hide-cancel="true" @cancel="detailCancel">
-      <div class="detail-box">
-        <div class="detail-item-box">
-          <div class="detail-item">
-            <div class="item-label">订单编号</div>
-            <div class="item-content">53357981207</div>
-          </div>
-          <div class="detail-item">
-            <div class="item-label">订单状态</div>
-            <div class="item-content">已发货</div>
-          </div>
-        </div>
-        <div class="detail-item-box">
-          <div class="detail-item">
-            <div class="item-label">发货日期</div>
-            <div class="item-content">2024-10-24 17:46:33</div>
-          </div>
-        </div>
-        <div class="detail-item-box">
-          <div class="detail-item">
-            <div class="item-label">运营商</div>
-            <div class="item-content">泰国AIS</div>
-          </div>
-          <div class="detail-item">
-            <div class="item-label">资费信息</div>
-            <div class="item-content">1.0G/月</div>
-          </div>
-        </div>
-        <div class="detail-item-box">
-          <div class="detail-item">
-            <div class="item-label">最短订阅周期</div>
-            <div class="item-content">3个月</div>
-          </div>
-          <div class="detail-item">
-            <div class="item-label">最长订阅周期</div>
-            <div class="item-content">--</div>
-          </div>
-        </div>
-        <div class="detail-item-box">
-          <div class="detail-item">
-            <div class="item-label">计费方式</div>
-            <div class="item-content">按单流量消耗计费</div>
-          </div>
-          <div class="detail-item">
-            <div class="item-label">结算周期</div>
-            <div class="item-content">月</div>
-          </div>
-        </div>
-        <div class="detail-item-box">
-          <div class="detail-item">
-            <div class="item-label">流量资费计费</div>
-            <div class="item-content">0.8美金/G;MRC:0元;网络接入0元</div>
-          </div>
-        </div>
-        <div class="detail-item-box">
-          <div class="detail-item">
-            <div class="item-label">卡类型</div>
-            <div class="item-content">工业级PlugIn</div>
-          </div>
-          <div class="detail-item">
-            <div class="item-label">卡板费</div>
-            <div class="item-content">1美金</div>
-          </div>
-        </div>
-        <div class="detail-item-box">
-          <div class="detail-item">
-            <div class="item-label">流量池</div>
-            <div class="item-content">组池</div>
-          </div>
-          <div class="detail-item">
-            <div class="item-label">沉默期</div>
-            <div class="item-content">6个月</div>
-          </div>
-        </div>
-        <div class="detail-item-box">
-          <div class="detail-item">
-            <div class="item-label">卡数量</div>
-            <div class="item-content">10000;已分配0,已退回0,已转移0
-              <a-button type="primary" @click="showCard = true" style="margin-left:10px;">分配卡号</a-button>
-            </div>
-          </div>
-        </div>
-      </div>
-      <div class="detail-table">
-        <a-table :columns="columnsDetail" :data="dataDetail" />
-      </div>
-    </a-modal>
-    <a-modal v-model:visible="showCard" width="800px" title="分配卡号" @cancel="showCard = false" @before-ok="submitCard"
-      okText="确认" cancelText="取消">
-      <a-textarea :auto-size="{
-        minRows: 15,
-        maxRows: 15
-      }" v-model="cardNumber" max-length="1000" :show-word-limit="true" placeholder="请输入iccid,一行一个或者逗号分隔;不支持两种混合号码。"
-        allow-clear />
-    </a-modal>
-  </div>
-</template>
-
-<script setup>
-import { ref, reactive } from 'vue';
-import { Message } from '@arco-design/web-vue';
-const selectedKeys = ref([]);
-const rowSelection = reactive({
-  type: 'checkbox',
-  showCheckedAll: true,
-  onlyCurrent: false,
-});
-const searchForm = reactive({
-  cardNumber: '',
-  customerName: '',
-});
-
-const columns = [
-  { title: '序号', dataIndex: 'index', align: 'center', render: ({ rowIndex }) => rowIndex + 1 },
-  { title: '订单编号', dataIndex: 'cardNumber' },
-  { title: '客户名称', dataIndex: 'customerName' },
-  { title: '审核状态', dataIndex: 'auditStatus' },
-  { title: '订单状态', dataIndex: 'orderStatus' },
-  { title: '开卡张数', dataIndex: 'cardQuantity' },
-  { title: '通道', dataIndex: 'source' },
-  { title: '资费', dataIndex: 'money' },
-  { title: '结算价/原价(元)', dataIndex: 'outMoney' },
-  { title: '下单时间', dataIndex: 'orderTime' },
-  { title: '操作', slotName: 'operate', align: 'center' },
-  { title: '详情', slotName: 'detail', align: 'center' },
-];
-const columnsDetail = [{ title: 'ICCID', dataIndex: 'iccid' },
-{ title: '池名称及编号', dataIndex: 'nameAndId' },
-{ title: '卡状态', dataIndex: 'status' },
-]
-const dataDetail = ref([{
-  iccid: '8986061800002054589N',
-  nameAndId: '泰国监控40G共享/53357981207',
-  status: '沉默期'
-},
-{
-  iccid: '8986061800002054588N',
-  nameAndId: '泰国监控40G共享/53357981207',
-  status: '沉默期'
-}, {
-  iccid: '8986061800002054587N',
-  nameAndId: '泰国监控40G共享/53357981207',
-  status: '沉默期'
-}, {
-  iccid: '8986061800002054586N',
-  nameAndId: '泰国监控40G共享/53357981207',
-  status: '沉默期'
-},])
-const tableData = ref([
-  {
-    cardNumber: '13800138000',
-    customerName: '张三',
-    auditStatus: '1',
-    orderStatus: '1',
-    cardQuantity: 24,
-    source: '联通',
-    money: '100',
-    outMoney: '10',
-    orderTime: '2024-10-11'
-    // operate:'上传合同'
-  },
-  {
-    cardNumber: '13800138000',
-    customerName: '李四',
-    auditStatus: '1',
-    orderStatus: '1',
-    cardQuantity: 24,
-    source: '联通',
-    money: '100',
-    outMoney: '10',
-    orderTime: '2024-10-11'
-    // operate:'上传合同'
-  }, {
-    cardNumber: '13800138000',
-    customerName: '王五',
-    auditStatus: '1',
-    orderStatus: '1',
-    cardQuantity: 24,
-    source: '联通',
-    money: '100',
-    outMoney: '10',
-    orderTime: '2024-10-11'
-    // operate:'上传合同'
-  },
-  // 可以添加更多模拟数据...
-]);
-// 上传合同的弹框
-const uploadContract = ref(false);
-const pagination = reactive({
-  total: tableData.value.length,
-  current: 1,
-  pageSize: 10,
-});
-const openContract = (item) => {
-  console.log(item, '???')
-  uploadContract.value = true;
-  formContract.customerName = item.customerName;
-  formContract.orderNumber = item.cardNumber;
-};
-//订单详情的弹框
-const showDetail = ref(false);
-// 查看订单详情
-const openDetail = (item) => {
-  showDetail.value = true;
-}
-const handleBeforeOk = (done) => {
-  console.log(formContract)
-  window.setTimeout(() => {
-    done()
-    // prevent close
-    // done(false)
-  }, 3000)
-};
-const handleCancel = () => {
-  uploadContract.value = false;
-}
-const handleSearch = () => {
-  console.log('Search form data:', searchForm);
-  Message.success('执行搜索操作');
-};
-
-const resetSearch = () => {
-  Object.keys(searchForm).forEach(key => {
-    if (Array.isArray(searchForm[key])) {
-      searchForm[key] = [];
-    } else {
-      searchForm[key] = null;
-    }
-  });
-  Message.success('搜索条件已重置');
-};
-// 文件上传的列表
-const formContract = reactive({
-  orderNumber: '',
-  customerName: '',
-  fileList: []
-})
-// 订单状态
-const options = [
-  { label: '发货', value: '1' },
-  { label: '退回', value: '2' },
-];
-// 审核
-const showAudit = ref(false);
-const formAudit = reactive({
-  customerName: '',
-  cardType: '',
-  money: '',
-  orderStatus: '',
-  auditOpinion: '',
-  fileList: []
-})
-// 触发审核的弹框
-const openAudit = () => {
-  showAudit.value = true;
-}
-// 确认审核
-const submitAudit = () => {
-  console.log(formAudit, 'lll')
-  window.setTimeout(() => {
-    showAudit.value = false;
-  }, 1000)
-}
-// 分配卡号的值
-const cardNumber = ref('');
-const showCard = ref(false);
-
-const submitCard = () => {
-}
-</script>
-
-<style scoped lang="less">
-.silent-expire-alarm {
-  padding: 20px !important;
-  // background: #fcf;
-}
-
-.search-section {
-  margin-bottom: 20px;
-}
-
-.arco-table-th {
-  white-space: nowrap;
-}
-
-.audit-txt {
-  display: flex;
-  justify-content: center;
-  align-items: center;
-
-  .audit-tag {
-    margin-left: 20px;
-    background: #63c2c6;
-    color: #fff;
-    font-size: 12px;
-    display: flex;
-    justify-content: center;
-    align-items: center;
-    padding: 0 10px;
-    box-sizing: border-box;
-    border-radius: 50px;
-  }
-}
-
-.audit-btn {
-  margin-bottom: 10px;
-}
-
-.detail-box {
-  .detail-item-box {
-    display: flex;
-    justify-content: space-between;
-    align-items: center;
-    margin-bottom: 10px;
-
-    .detail-item {
-      //styleName: Body/Medium;
-      font-family: PingFang SC;
-      font-size: 14px;
-      font-weight: 400;
-      line-height: 22px;
-      text-align: left;
-      display: flex;
-      align-items: center;
-      min-width: 350px;
-
-      .item-label {
-        color: rgba(0, 0, 0, 0.4);
-        width: 120px;
-        text-align: right;
-        margin-right: 10px;
-      }
-
-      .item-content {
-        color: rgba(51, 51, 51, 1);
-      }
-    }
-  }
-}
-
-.detail-table {
-  margin-top: 20px;
-}
-</style>

+ 168 - 476
src/views/order/BuyCard/index.vue

@@ -2,24 +2,11 @@
 <template>
   <div class="silent-expire-alarm">
     <!-- 搜索条件区 -->
-    <!-- <div class="search-section">
-      <a-form :model="searchForm" layout="inline">
-        <a-form-item field="cardNumber" label="订单编号">
-          <a-input v-model="searchForm.orderNumber" placeholder="请输入订单编号" allow-clear />
-        </a-form-item>
-        <a-form-item field="customerName" label="客户">
-          <a-input v-model="searchForm.customerName" placeholder="请输入客户名称" allow-clear />
-        </a-form-item>
-        <a-form-item>
-          <a-space>
-            <a-button type="primary" @click="handleSearch">搜索</a-button>
-            <a-button @click="resetSearch">重置</a-button>
-          </a-space>
-        </a-form-item>
-      </a-form>
-    </div> -->
+    <div class="search-section">
+      <Search />
+    </div>
     <div class="audit-btn" v-if="userType == 2">
-      <a-button @click="openAudit" type="text">
+      <a-button @click="showAudit = true" type="text">
         <template #icon>
           <icon-plus-circle />
         </template>
@@ -28,498 +15,217 @@
     </div>
     <!-- 数据表格 -->
     <a-table :data="tableData" :pagination="pageData" :columns="columns" @page-change="evChangePage"
-             :scroll="{ x: 'auto' }">
-      <!-- <template #status="{ record }">
-        {{ record.status }}
+      :scroll="{ x: 'auto' }">
+      <template #image="{ record }">
+        <a-image width="60" height="60" :src="record.contractImg" :preview-props="{
+          actionsLayout: ['rotateRight', 'zoomIn', 'zoomOut'],
+        }">
+        </a-image>
+      </template>
+      <template #id="{ record }">
+        <div class="line_heis" @click="openDetail(record)">{{ record.id }}</div>
+      </template>
+      <template #statusType="{ record }">
+        <a-tag color="#ff7d00" v-if="record.moderationStatus == 1">待审核</a-tag>
+        <a-tag color="#00b42a" v-if="record.moderationStatus == 2">审核通过</a-tag>
+        <a-tag color="#f53f3f" v-if="record.moderationStatus == 3">已驳回</a-tag>
+      </template>
+      <template #LogisticsStatus="{ record }">
+        <a-tag color="#168cff" v-if="record.tmsStatus == 1">未发货</a-tag>
+        <a-tag color="#00b42a" v-if="record.tmsStatus == 2">已发货</a-tag>
       </template>
-      <template #moderation_status="{ record }">
-        {{ record.moderation_status }}
-      </template> -->
       <template #operate="{ record }">
-        <div v-if="userType == 1">
-          <a-popconfirm content="审核" ok-text="通过" cancel-text="驳回" type="warning" @ok="platformCancel(record, 2)" @cancel="platformCancel(record, 3)">
-            <a-button type="text">审核</a-button>
-          </a-popconfirm>
-          <a-button @click="uploadModal(record)" type="text">上传合同</a-button>
-        </div>
-        <div v-if="userType == 2">
-          <a-popconfirm :content="`是否确认退订?`" type="warning" @ok="adminCancel(record)">
-            <a-button type="text">退订</a-button>
-          </a-popconfirm>
-          <a-button @click="openDetail(record, 2)" type="text">查看</a-button>
+        <div class="setting">
+          <div v-if="userType == 1">
+            <a-button type="text" v-if="record.moderationStatus == 1 && record.status == 1"
+              @click="statusOrder(record)">审核</a-button>
+            <a-button @click="uploadModal(record)" type="text">{{ record.contractImg == '' ? '上传合同' : '查看合同'
+              }}</a-button>
+          </div>
+          <div v-if="userType == 2">
+            <a-button type="text" @click="adminCancel(record)"
+              v-if="record.moderationStatus == 2 && userType !== 1">退订</a-button>
+          </div>
+          <a-button @click="openDetail(record)" type="text">查看</a-button>
         </div>
-
       </template>
     </a-table>
-    <a-modal v-model:visible="uploadContract" title="上传合同" @cancel="handleCancel" @before-ok="handleBeforeOk"
-      okText="保存" cancelText="关闭">
+
+
+    <a-modal v-model:visible="uploadContract" width="600px" title="上传合同"
+      @cancel="closeModal(uploadContract, formContract)" @ok="handleBeforeOk" okText="保存" cancelText="关闭">
       <a-form :model="formContract" auto-label-width>
         <a-form-item field="customerName" label="客户名称">
-          <!-- <a-input v-model="formContract.customerName" disabled placeholder="请输入客户" /> -->
-          <div class="audit-txt" style="color:#418035;">{{ formContract.customerName }}</div>
+          <div class="audit-txt" style="color:#418035;">{{ FormDataList.userName }}</div>
         </a-form-item>
         <a-form-item field="orderNumber" label="订单编号">
-          <!-- <a-input v-model="formContract.orderNumber" disabled placeholder="请输入单号" /> -->
-          <div class="audit-txt">{{ formContract.orderNumber }}</div>
-        </a-form-item>
-        <a-form-item field="fileList" label="销售合同">
-          <Upload v-model:modelValue="formContract.fileList"/>
-        </a-form-item>
-      </a-form>
-    </a-modal>
-
-    <!-- 创建 -->
-    <a-modal v-model:visible="showAudit" title="购卡" width="600px" @cancel="cancelPurchase" centered
-      :maskClosable="false" okText="确定" cancelText="关闭" :footer="null">
-      <a-form ref="formRef" :rules="rules" :model="formState" @submit="submitPurchase">
-        <a-form-item field="customerName" label="客户名称">
-          <!-- <a-input v-model="formAudit.customerName" placeholder="请输入客户" /> -->
-          <div class="audit-txt">{{ userName }}</div>
-        </a-form-item>
-        <a-form-item label="运营商" field="source">
-          <a-select v-model="formState.source" :style="{ width: '380px' }" placeholder="请选择运营商">
-            <a-option v-for="item of sourceList" :value="item.id" :label="item.label" />
-          </a-select>
-        </a-form-item>
-        <a-form-item label="资费名称" field="tariffId">
-          <a-select v-model="formState.tariffId" :style="{ width: '380px' }" @change="tariffChange"
-            placeholder="请选择资费ID">
-            <a-option v-for="item of tariffData" :value="item.value" :label="item.label" />
-          </a-select>
-        </a-form-item>
-        <!-- <a-form-item label="资费详情" v-if="formState.tariffId">
-          <div class="audit-txt">
-            <div class="audit-tag">套餐类型<span>流量</span></div>
-            <div class="audit-tag">资费编码<span>流量</span></div>
-            <div class="audit-tag">资费编码<span>流量</span></div>
-            <div class="audit-tag">资费编码<span>流量</span></div>
-          </div>
-        </a-form-item>
-        <a-form-item label="资费计费详情" v-if="formState.tariffId">
-          <div class="audit-txt">
-            <div class="audit-tag">套餐类型<span>流量</span></div>
-            <div class="audit-tag">资费编码<span>流量</span></div>
-            <div class="audit-tag">资费编码<span>流量</span></div>
-            <div class="audit-tag">资费编码<span>流量</span></div>
-          </div>
-        </a-form-item> -->
-        <a-form-item label="卡类型" field="cardType">
-          <a-select v-model="formState.cardType" :style="{ width: '380px' }" placeholder="请选择卡类型">
-            <a-option v-for="item of orderType" :value="item.value" :label="item.label" />
-          </a-select>
-        </a-form-item>
-
-
-        <a-form-item label="沉默期">
-          <a-select v-model="formState.silencePeriod" :style="{ width: '380px' }" placeholder="请选择沉默期">
-            <a-option v-for="item of silenceOptions" :value="item.value" :label="item.label" />
-          </a-select>
-        </a-form-item>
-        <a-form-item label="流量池" field="flowPool">
-          <a-radio-group v-model="formState.flowPool" :options="flowPoolData">
-            <template #label="{ data }">
-              <a-tag>{{ data.label }}</a-tag>
-            </template>
-          </a-radio-group>
+          <div class="audit-txt">{{ FormDataList.id }}</div>
         </a-form-item>
-        <a-form-item label="购卡数量" field="num">
-          <a-input v-model="formState.num" placeholder="请输入购卡数量" />
-        </a-form-item>
-        <a-form-item>
-          <a-button type="primary" html-type="submit" style="margin-right: 10px;">确定</a-button>
-          <a-button @click="cancelPurchase">取消</a-button>
+        <a-form-item field="contractImg" label="销售合同">
+          <Upload v-model:model-value="formContract.contractImg" />
         </a-form-item>
       </a-form>
     </a-modal>
 
-    <!-- 详情 -->
-    <a-modal v-model:visible="showDetail" width="800px" :title="currentIndex == 1 ? '退卡详情' : '查看'"
-      @cancel="showDetail = false" :footer="null">
-      <div class="detail-box">
-        <div class="detail-item-box">
-          <div class="detail-item">
-            <div class="item-label">订单编号</div>
-            <div class="item-content">53357981207</div>
-          </div>
-          <div class="detail-item">
-            <div class="item-label">订单状态</div>
-            <div class="item-content">已发货</div>
-          </div>
-        </div>
-        <div class="detail-item-box">
-          <div class="detail-item">
-            <div class="item-label">发货日期</div>
-            <div class="item-content">2024-10-24 17:46:33</div>
-          </div>
-        </div>
-        <div class="detail-item-box">
-          <div class="detail-item">
-            <div class="item-label">运营商</div>
-            <div class="item-content">泰国AIS</div>
-          </div>
-          <div class="detail-item">
-            <div class="item-label">资费信息</div>
-            <div class="item-content">1.0G/月</div>
-          </div>
-        </div>
-        <div class="detail-item-box">
-          <div class="detail-item">
-            <div class="item-label">最短订阅周期</div>
-            <div class="item-content">3个月</div>
-          </div>
-          <div class="detail-item">
-            <div class="item-label">最长订阅周期</div>
-            <div class="item-content">--</div>
-          </div>
-        </div>
-        <div class="detail-item-box">
-          <div class="detail-item">
-            <div class="item-label">计费方式</div>
-            <div class="item-content">按单流量消耗计费</div>
-          </div>
-          <div class="detail-item">
-            <div class="item-label">结算周期</div>
-            <div class="item-content">月</div>
-          </div>
-        </div>
-        <div class="detail-item-box">
-          <div class="detail-item">
-            <div class="item-label">流量资费计费</div>
-            <div class="item-content">0.8美金/G;MRC:0元;网络接入0元</div>
-          </div>
-        </div>
-        <div class="detail-item-box">
-          <div class="detail-item">
-            <div class="item-label">卡类型</div>
-            <div class="item-content">工业级PlugIn</div>
-          </div>
-          <div class="detail-item">
-            <div class="item-label">卡板费</div>
-            <div class="item-content">1美金</div>
-          </div>
-        </div>
-        <div class="detail-item-box">
-          <div class="detail-item">
-            <div class="item-label">流量池</div>
-            <div class="item-content">组池</div>
-          </div>
-          <div class="detail-item">
-            <div class="item-label">沉默期</div>
-            <div class="item-content">6个月</div>
-          </div>
-        </div>
-        <div class="detail-item-box">
-          <div class="detail-item">
-            <div class="item-label">卡数量</div>
-            <div class="item-content">10000;已分配0,已退回0,已转移0
-              <!-- <a-button type="primary" @click="showCard = true" style="margin-left:10px;">分配卡号</a-button> -->
-            </div>
-          </div>
-        </div>
-      </div>
-      <div class="detail-table">
-        <a-table :columns="columnsDetail" :data="dataDetail" />
-      </div>
-      <div style="text-align: right;margin-top: 20px;">
-        <a-button type="primary" html-type="submit" style="margin-right: 10px;" @click="operateHandle">确定</a-button>
-      </div>
-    </a-modal>
-    <!-- <a-modal v-model:visible="showCard" width="800px" title="分配卡号" @cancel="showCard = false" @before-ok="submitCard"
-      okText="确认" cancelText="取消">
-      <a-textarea :auto-size="{
-        minRows: 15,
-        maxRows: 15
-      }" v-model="cardNumber" max-length="1000" :show-word-limit="true" placeholder="请输入iccid,一行一个或者逗号分隔;不支持两种混合号码。"
-        allow-clear />
-    </a-modal> -->
+    <Card v-model:modelValue="showAudit" @submit="intData()" />
+    <Status v-model:modelValue="showStatus" @submit="intData()" :FormDataList="FormDataList" />
+    <Detaile v-model:modelValue="showDetail" @submit="intData()" :FormDataList="FormDataList" />
+    <returnCard v-model:modelValue="showReturn" :ReturnData="ReturnData" :id="id" @submit="intData()"></returnCard>
   </div>
 </template>
 
 <script setup>
-import { ref, reactive, onMounted } from 'vue';
+import { ref, onMounted, toRefs } from 'vue';
 import { Message } from '@arco-design/web-vue';
-import { tariffList } from "@/api/path/tariffManagement.api";
-import { purchaseOrderList, addPurchaseOrder, platformUpdate, adminUpdate } from '@/api/path/purchase';
+import { purchaseOrderList, platformUpdate, adminUpdate } from '@/api/path/purchase';
+import { UploadOrderCardContract, TariffOrderCard } from '@/api/path/order'
 import { Getdictionary } from '@/mixins/index.js'
 import Upload from "@/components/upload/index.vue";
-const selectedKeys = ref([]);
-const rowSelection = reactive({
-  type: 'checkbox',
-  showCheckedAll: true,
-  onlyCurrent: false,
-});
-const searchForm = reactive({
-  cardNumber: '',
-  customerName: '',
+import Card from './Card.vue'
+import Status from './status.vue'
+import Detaile from './detaile.vue'
+import Search from '@/components/Search/index.vue'
+import returnCard from './returnCard.vue'
+// 数据层
+const state = ref({
+  userName: localStorage.getItem('user_login_information')?.username,
+  userType: JSON.parse(localStorage.getItem('user_login_information'))?.userType, // 1平台 2用户
+  tableData: [],
+  currentIndex: null,
+  FormDataList: {},
+  pageData: {
+    total: 0,
+    size: 10,
+    current: 1,
+  },
+  showAudit: false,
+  showStatus: false,
+  formContract: {
+    id: null,
+    contractImg: []
+  }, // 文件上传列表
+  showDetail: false,
+  uploadContract: false,
+  showReturn: false,
+  ReturnData: [],
+  id: null
 });
 
+const {
+  userType,
+  tableData,
+  FormDataList,
+  pageData,
+  showAudit,
+  showStatus,
+  formContract,
+  showDetail,
+  uploadContract,
+  showReturn,
+  ReturnData,
+  id
+} = toRefs(state.value);
+
 const columns = [
-  { title: '序号', dataIndex: 'index', align: 'center',ellipsis:true },
-  { title: '订单编号', dataIndex: 'id', align: 'center', ellipsis:true },
-  { title: '审核状态', dataIndex: 'orderTypeName', align: 'center' ,ellipsis:true},
-  { title: '订单状态', dataIndex: 'statusName', align: 'center' ,ellipsis:true},
-  { title: '客户名称', dataIndex: 'userName', align: 'center',ellipsis:true },
-  { title: '采购数量', dataIndex: 'quantity', align: 'center' ,ellipsis:true},
-  { title: '运营商名称', dataIndex: 'quantity', align: 'center',ellipsis:true },
-  { title: '资费', dataIndex: 'quantity', align: 'center',ellipsis:true },
-  { title: '支付金额', dataIndex: 'paymentAmount', align: 'center',ellipsis:true },
-  { title: '下单时间', dataIndex: 'createdAt', align: 'center',ellipsis:true },
-  { title: '操作', slotName: 'operate', align: 'center',ellipsis:true}
+  { title: '序号', dataIndex: 'index', align: 'center', ellipsis: true },
+  { title: '订单编号', slotName: 'id', align: 'center', ellipsis: true },
+  { title: '审核状态', slotName: 'statusType', align: 'center', ellipsis: true },
+  { title: '物流状态', slotName: 'LogisticsStatus', align: 'center', ellipsis: true },
+  { title: '客户名称', dataIndex: 'userName', align: 'center', ellipsis: true },
+  { title: '购卡数', dataIndex: 'quantity', align: 'center', ellipsis: true },
+  { title: '静默期(月)', dataIndex: 'periodOfSilence', align: 'center', ellipsis: true },
+  { title: '卡类型', dataIndex: 'cardType', align: 'center', ellipsis: true },
+  { title: '运营商名称', dataIndex: 'sourceName', align: 'center', ellipsis: true },
+  { title: '资费', dataIndex: 'trafficName', align: 'center', ellipsis: true },
+  { title: '支付金额', dataIndex: 'priceing', align: 'center', ellipsis: true },
+  { title: '合同照片', slotName: 'image', align: 'center', ellipsis: true },
+  { title: '下单时间', dataIndex: 'createdAt', align: 'center', ellipsis: true },
+  { title: '操作', slotName: 'operate', align: 'center', ellipsis: true }
 ];
-const columnsDetail = [{ title: 'ICCID', dataIndex: 'iccid' },
-{ title: '池名称及编号', dataIndex: 'nameAndId' },
-{ title: '卡状态', dataIndex: 'status' },
-]
-const dataDetail = ref([{
-  iccid: '8986061800002054589N',
-  nameAndId: '泰国监控40G共享/53357981207',
-  status: '沉默期'
-},
-{
-  iccid: '8986061800002054588N',
-  nameAndId: '泰国监控40G共享/53357981207',
-  status: '沉默期'
-}, {
-  iccid: '8986061800002054587N',
-  nameAndId: '泰国监控40G共享/53357981207',
-  status: '沉默期'
-}, {
-  iccid: '8986061800002054586N',
-  nameAndId: '泰国监控40G共享/53357981207',
-  status: '沉默期'
-},])
-const userName = ref(localStorage.getItem('remember_user_name'))
-const userType = ref(JSON.parse(localStorage.getItem('user_login_information'))?.userType);// 1平台 2用户
-const tableData = ref([]);
-const formRef = ref(null);
-const currentIndex = ref(null);
-const rules = {
-  source: [{ required: true, trigger: 'change', }],
-  tariffId: [
-    {
-      required: true,
-      trigger: 'change',
-    },
-  ],
-  cardType: [
-    {
-      required: true,
-      trigger: 'change',
-    },
-  ],
-  flowPool: [
-    {
-      required: true,
-      trigger: 'change',
-    },
-  ],
-  num: [
-    {
-      required: true,
-      trigger: 'change',
-    },
-  ],
-};
-const pageData = ref({
-  total: 0,
-  size: 10,
-  current: 1,
-})
-const formState = ref({
-  source: null,
-  tariffId: null,
-  cardType: null,
-  silencePeriod: null,
-  flowPool: null,
-  num: null
-})
-const sourceList = ref([]) // 来源
-const tariffData = ref([]) // 自费
-const silenceOptions = ref([]); // 沉默期
-const orderType = ref([]); // 卡类型
-const flowPoolData = ref([]); // 组池
-const showAudit = ref(false);
 
-const handleDictValue = async () => {
-  sourceList.value = await Getdictionary('source')
-  orderType.value = await Getdictionary('cardType')
-  silenceOptions.value  = await Getdictionary('silenceOf')
-  flowPoolData.value = await Getdictionary('groupPool')
-  const param = {
-    current: 1,
-    size: 999,
-  }
-  tariffList(param).then(res => {
-    tariffData.value = res.data.records.map(item => ({
-      label: item.label,
-      value: item.id,
-      ...item
-    }));
-  })
-}
 // 订单列表
 const intData = async () => {
   const param = {
     current: pageData.value.current,
     size: pageData.value.size,
   }
-  let res1 = await Getdictionary('subscriptionRelationshipStatus')
-  let res2 = await Getdictionary('orderAuditStatus')
+  const simTypeList = await Getdictionary('cardType')
+  let sourceList = await Getdictionary('source')
   purchaseOrderList(param).then(res => {
-    tableData.value = (res.data.records || []).map((item,key) => {
-      const statusName = res1.filter((item) => item.typeKey == 'subscriptionRelationshipStatus')?.find(val => item.status == val.value)?.label
-      const orderTypeName = res2.filter((item) => item.typeKey == 'orderAuditStatus')?.find(val => item.status == val.value)?.label
-
+    tableData.value = (res.data.records || []).map((item, key) => {
+      const sourceName = sourceList.find(val => val.value == item.source)?.label
+      const cardType = simTypeList.find(val => val.value == item.simType)?.label
       return {
         ...item,
         index: key + 1,
-        orderTypeName,
-        statusName,
+        sourceName,
+        cardType
       }
     });
     pageData.value.total = res.data.total;
   })
 
 }
-// 确认购卡
-const submitPurchase = ({ values, errors }) => {
-  formRef.value.validate(async (errors) => {
-    if (!errors) {
-      const data = {
-        source: String(formState.value.source),
-        tariffId: formState.value.tariffId,
-        quantity: Number(formState.value.num),
-        cardType: formState.value.cardType,
-        periodOfSilence: String(formState.value.silencePeriod),
-        isTrafficPool: formState.value.flowPool
-      }
-      addPurchaseOrder(data).then(res => {
-        intData();
-        showAudit.value = false;
-      })
-    }
-  })
-
-}
-// 取消
-const cancelPurchase = () => {
-  showAudit.value = false;
-  formRef.value.resetFields();
-  Object.assign(formState, {
-    source: null,
-    tariffId: null,
-    cardType: null,
-    silencePeriod: null,
-    flowPool: 0,
-    num: null
-  });
-}
-// 平台退订
-const platformCancel = (data, type) => {
-  const param = {
-    id: data.id,
-    status: type
-  }
-  platformUpdate(param).then(res => {
-    intData();
-  })
-}
 // 用户退订
 const adminCancel = (data) => {
-  const param = {
-    id: data.id,
-    status: data.status
-  }
-  adminUpdate(param).then(res => {
-    intData();
+  TariffOrderCard({ id: data.trafficId }).then(res => {
+    ReturnData.value = res.data || []
   })
+  id.value = data.id
+  showReturn.value = true
 }
-
-//
-const tariffChange = (e) => {
-  formState.value.tariffId = e;
-  // tariffObj.value = res.data.records.map(item=>{
-
-  // })
-}
-
-//
-const operateHandle = () => {
-  if (currentIndex.value == 1) {
-
-  } else {
-    showDetail.value = false;
-  }
-}
-
 // 分页
 const evChangePage = (page) => {
   pageData.value.current = page
   intData()
 }
 
-onMounted(() => {
-  intData();
-})
+// 订单审核
+const statusOrder = (items) => {
+  FormDataList.value = items
+  showStatus.value = true
+}
 
-// 上传合同的弹框
-const uploadContract = ref(false);
+// 上传合同
 const uploadModal = (item) => {
   uploadContract.value = true;
-  formContract.customerName = item.customerName;
-  formContract.orderNumber = item.sourceOrderId;
+  FormDataList.value = item
+  formContract.value = {
+    id: item.id,
+    contractImg: item.contractImg
+  }
 };
-//订单详情的弹框
-const showDetail = ref(false);
 // 查看订单详情
-const openDetail = (item, current) => {
-  currentIndex.value = current;
-  uploadContract.value = true;
+const openDetail = async (item) => {
+  FormDataList.value = item
+  showDetail.value = true;
 }
-const handleBeforeOk = (done) => {
-  window.setTimeout(() => {
-    done()
-    // prevent close
-    // done(false)
-  }, 3000)
-};
-const handleCancel = () => {
-  uploadContract.value = false;
-}
-const handleSearch = () => {
-  console.log('Search form data:', searchForm);
-  Message.success('执行搜索操作');
+// 上传合同
+const handleBeforeOk = () => {
+  new Promise((resolve, reject) => {
+    formContract.value.id = FormDataList.value.id;
+    UploadOrderCardContract(formContract.value).then(res => {
+      resolve(res)
+      Message.success(res.message)
+      intData();
+    }).catch(error => {
+      reject(error)
+    })
+  })
 };
-
-const resetSearch = () => {
-  Object.keys(searchForm).forEach(key => {
-    if (Array.isArray(searchForm[key])) {
-      searchForm[key] = [];
-    } else {
-      searchForm[key] = null;
+// 模态框取消
+const closeModal = (items, obj) => {
+  items = false
+  Object.keys(obj).forEach(key => {
+    if (obj.key) {
+      obj[key] = '';
     }
-  });
-  Message.success('搜索条件已重置');
-};
-// 文件上传的列表
-const formContract = reactive({
-  orderNumber: '',
-  customerName: '',
-  fileList: []
-})
-
-// 触发购卡弹框
-const openAudit = () => {
-  showAudit.value = true;
-  handleDictValue();
+  })
 }
 
-// 分配卡号的值
-const cardNumber = ref('');
-const showCard = ref(false);
-
-const submitCard = () => {
-}
+onMounted(() => {
+  intData();
+})
 </script>
 
 <style scoped lang="less">
@@ -528,6 +234,12 @@ const submitCard = () => {
   // background: #fcf;
 }
 
+.setting {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+}
+
 .search-section {
   margin-bottom: 20px;
 }
@@ -556,39 +268,19 @@ const submitCard = () => {
   margin-bottom: 10px;
 }
 
-.detail-box {
-  .detail-item-box {
-    display: flex;
-    justify-content: space-between;
-    align-items: center;
-    margin-bottom: 10px;
 
-    .detail-item {
-      //styleName: Body/Medium;
-      font-family: PingFang SC;
-      font-size: 14px;
-      font-weight: 400;
-      line-height: 22px;
-      text-align: left;
-      display: flex;
-      align-items: center;
-      min-width: 350px;
 
-      .item-label {
-        color: rgba(0, 0, 0, 0.4);
-        width: 120px;
-        text-align: right;
-        margin-right: 10px;
-      }
+.detail-table {
+  margin-top: 20px;
+}
 
-      .item-content {
-        color: rgba(51, 51, 51, 1);
-      }
-    }
-  }
+.line_heis {
+  color: #FF8839;
+  cursor: pointer;
+  display: inline-block;
 }
 
-.detail-table {
-  margin-top: 20px;
+.line_heis:hover {
+  color: #168cff;
 }
 </style>

+ 50 - 0
src/views/order/BuyCard/returnCard.vue

@@ -0,0 +1,50 @@
+<template>
+    <a-modal v-model:visible="modelValue" width="800px" title="退卡" @cancel="cancel" @ok="submitStatus" okText="确认"
+        cancelText="取消">
+        <a-table row-key="iccid" :columns="columns" :data="data" :row-selection="rowSelection"
+             v-model:selectedKeys="selectedKeys" :pagination="pagination" />
+    </a-modal>
+</template>
+
+<script setup>
+import { ref, defineProps, toRef, defineEmits,watch} from 'vue';
+import { Message } from '@arco-design/web-vue';
+import {ReturntheCard} from '@/api/path/order'
+const props = defineProps({
+    modelValue: {
+        type: Boolean,
+        default: false
+    },
+    ReturnData:Array,
+    id:String,
+})
+const modelValue = toRef(props, 'modelValue')
+const emit = defineEmits(['update:modelValue', 'submit'])
+const selectedKeys = ref([])
+const columns = [{ title: 'ICCID', dataIndex: 'iccid' },{ title: '卡状态', dataIndex: 'status' },{ title: '创建时间', dataIndex: 'expireTime' }]
+const data = ref()
+const rowSelection = ref({
+      type: 'checkbox',
+      showCheckedAll: true,
+      onlyCurrent: false,
+    });
+const cancel = ()=>{
+    emit('update:modelValue', false)
+    data.value = []
+}
+const submitStatus = async () => {
+    if(selectedKeys.value.length === 0){
+        Message.warning('请选择ICCID')
+        return
+    }
+    await ReturntheCard({iccids:selectedKeys.value,id:props.id})
+    emit('update:modelValue', false)
+    emit('submit',true)
+    data.value = []
+}
+watch(()=>props.ReturnData,val=>{
+  data.value = val
+},{deep: true})
+</script>
+<style scoped>
+</style>

+ 81 - 0
src/views/order/BuyCard/status.vue

@@ -0,0 +1,81 @@
+<template>
+    <a-modal v-model:visible="modelValue" width="800px" title="审核" @cancel="cancel" @ok="submitStatus"
+        okText="确认" cancelText="取消">
+        <a-form :model="formStatus" :style="{ width: '600px' }">
+            <a-form-item label="客户名称">
+                {{ FormDataList.userName }}
+            </a-form-item>
+            <a-form-item label="订单编号">
+                {{ FormDataList.id }}
+            </a-form-item>
+            <a-form-item label="资费名称">
+                {{ FormDataList.trafficName }}
+            </a-form-item>
+            <a-form-item label="审核意见">
+                <a-radio-group v-model="formStatus.moderationStatus" :options="optionsStatus">
+                    <template #label="{ data }">
+                        <a-tag>{{ data.label }}</a-tag>
+                    </template>
+                </a-radio-group>
+            </a-form-item>
+            <a-form-item label="备注">
+                <a-textarea placeholder="请输入备注" v-model:model-value="formStatus.moderationNotes" allow-clear />
+            </a-form-item>
+        </a-form>
+    </a-modal>
+</template>
+
+<script setup>
+import { ref, onMounted, toRefs, defineProps, toRef, defineEmits } from 'vue';
+import { OrderCardStatus } from '@/api/path/order'
+import { Message } from '@arco-design/web-vue';
+const props = defineProps({
+    modelValue: {
+        type: Boolean,
+        default: false
+    },
+    FormDataList: {
+        type: Object,
+        default: () => ({})
+    }
+})
+const modelValue = toRef(props, 'modelValue')
+const FormDataList = toRef(props, 'FormDataList')
+const emit = defineEmits(['update:modelValue', 'submit'])
+
+const state = ref({
+    formStatus: {
+        id: null,
+        moderationStatus: '', // 审核状态
+        moderationNotes: '', // 审核备注
+    },
+    optionsStatus: [
+        { label: '审核通过', value: '2' },
+        { label: '驳回', value: '3' },
+    ],
+})
+
+const { formStatus ,optionsStatus} = toRefs(state.value)
+
+// 订单审核
+const submitStatus = async () => {
+    new Promise((resolve, reject) => {
+        formStatus.value.id = FormDataList.value.id
+        OrderCardStatus(formStatus.value).then(res => {
+            Message.success(res.message)
+            emit('update:modelValue', false)
+            emit('submit', true)
+        }).catch(error => [
+            reject(error)
+        ])
+    })
+}
+
+const cancel = ()=>{
+    emit('update:modelValue', false)
+    Object.keys(formStatus.value).forEach(key => {
+        formStatus.value[key] = ''
+    })
+}
+</script>
+<style scoped></style>

+ 161 - 0
src/views/order/CancelOrder/detaile.vue

@@ -0,0 +1,161 @@
+<template>
+    <a-modal v-model:visible="modelValue" width="800px" title="订单详情" @cancel="cancel" @ok="showDetail = false">
+        <div class="detail-box">
+            <div class="detail-item-box">
+                <div class="detail-item">
+                    <div class="item-label">订单编号</div>
+                    <div class="item-content">{{ FormDataList.id }}</div>
+                </div>
+                <div class="detail-item">
+                    <div class="item-label">订单状态</div>
+                    <div class="item-content">
+                        <a-tag color="#168cff" v-if="FormDataList.tmsStatus == 1">未发货</a-tag>
+                        <a-tag color="#00b42a" v-if="FormDataList.tmsStatus == 2">已发货</a-tag>
+                    </div>
+                </div>
+            </div>
+            <div class="detail-item-box">
+                <div class="detail-item">
+                    <div class="item-label">运营商</div>
+                    <div class="item-content">{{ FormDataList.sourceName }}</div>
+                </div>
+                <div class="detail-item">
+                    <div class="item-label">资费信息</div>
+                    <div class="item-content">{{ TariffInfomr }}</div>
+                </div>
+            </div>
+            <div class="detail-item-box">
+                <div class="detail-item">
+                    <div class="item-label">最短订阅周期</div>
+                    <div class="item-content">{{ tariffForm.settlementCycle?.split('~')[0] }}个月</div>
+                </div>
+                <div class="detail-item">
+                    <div class="item-label">最长订阅周期</div>
+                    <div class="item-content">{{ tariffForm.settlementCycle?.split('~')[1] }}个月</div>
+                </div>
+            </div>
+            <div class="detail-item-box">
+                <div class="detail-item">
+                    <div class="item-label">计费方式</div>
+                    <div class="item-content">{{ tariffForm.billingMethodName }}</div>
+                </div>
+                <div class="detail-item">
+                    <div class="item-label">结算周期</div>
+                    <div class="item-content">{{ tariffForm.billingcycleName }}</div>
+                </div>
+            </div>
+            <div class="detail-item-box">
+                <div class="detail-item">
+                    <div class="item-label">卡类型</div>
+                    <div class="item-content">{{ FormDataList.CardType }}</div>
+                </div>
+                <div class="detail-item">
+                    <div class="item-label">标准价格</div>
+                    <div class="item-content">{{ tariffForm.pricingName }}</div>
+                </div>
+            </div>
+            <div class="detail-item-box">
+                <div class="detail-item">
+                    <div class="item-label">流量池</div>
+                    <div class="item-content">{{ FormDataList.isTrafficPool == 1 ? '是' : '否' }}</div>
+                </div>
+            </div>
+            <div class="detail-item-box">
+                <div class="detail-item">
+                    <div class="item-label">卡数量</div>
+                    <div class="item-content">{{ dataDetail.length }}
+                    </div>
+                </div>
+            </div>
+        </div>
+        <div class="detail-table">
+            <a-table :columns="columnsDetail" :data="dataDetail" />
+        </div>
+    </a-modal>
+</template>
+
+<script setup>
+import { ref, onMounted, toRefs, toRef ,watch} from 'vue';
+import { AcquireOrdertariff,TariffOrderCard } from '@/api/path/order'
+import { Getdictionary } from '@/mixins/index.js'
+const props = defineProps({
+    modelValue: {
+        type: Boolean,
+        default: false
+    },
+    FormDataList: {
+        type: Object,
+        default: () => ({})
+    }
+})
+const modelValue = toRef(props, 'modelValue')
+const FormDataList = toRef(props, 'FormDataList')
+const emit = defineEmits(['update:modelValue', 'submit'])
+const state = ref({
+    tariffForm: {},
+    res1:[],
+    res2:[],
+    res3:[],
+})
+const { tariffForm,res1,res2,res3 } = toRefs(state.value)
+const columnsDetail = [{ title: 'ICCID', dataIndex: 'iccid' }
+]
+const dataDetail = ref([])
+
+const cancel = () => {
+    emit('update:modelValue', false)
+}
+
+watch(() => FormDataList.value, val => {
+    if (Object.keys(val).length === 0) return
+    AcquireOrdertariff({ id: val.trafficId }).then(res => {
+        tariffForm.value = res.data
+        tariffForm.value.billingcycleName = res1.value.filter(val => val.value == res.data.billingCycle)[0]?.label;
+        tariffForm.value.billingMethodName = res2.value.filter(val => val.value == res.data.billingMethod)[0]?.label;
+        tariffForm.value.TariffInfomr = res.data.trafficBilling + '/' + res.data.trafficBillingType
+        tariffForm.value.pricingName = tariffForm.value.pricing !== '' ? tariffForm.value.pricing + '/' + res3.value.filter(val => val.value == res.data.currency)[0]?.label : '';
+    })
+    TariffOrderCard({id:val.trafficId}).then(res=>{
+        dataDetail.value = res.data
+    })
+},{deep: true})
+
+onMounted(async () => {
+    res1.value = await Getdictionary('Billingcycle')
+    res2.value = await Getdictionary('billingMethod')
+    res3.value = await Getdictionary('currencyType')
+})
+</script>
+<style scoped lang="less">
+.detail-box {
+    .detail-item-box {
+        display: flex;
+        justify-content: space-between;
+        align-items: center;
+        margin-bottom: 10px;
+
+        .detail-item {
+            //styleName: Body/Medium;
+            font-family: PingFang SC;
+            font-size: 14px;
+            font-weight: 400;
+            line-height: 22px;
+            text-align: left;
+            display: flex;
+            align-items: center;
+            min-width: 350px;
+
+            .item-label {
+                color: rgba(0, 0, 0, 0.4);
+                width: 120px;
+                text-align: right;
+                margin-right: 10px;
+            }
+
+            .item-content {
+                color: rgba(51, 51, 51, 1);
+            }
+        }
+    }
+}
+</style>

+ 149 - 339
src/views/order/CancelOrder/index.vue

@@ -1,384 +1,194 @@
-<!-- 注销订单 -->
+<!-- 退卡订单 -->
 <template>
-    <div class="silent-expire-alarm">
-        <!-- 搜索条件区 -->
-        <div class="search-section">
-            <a-form :model="searchForm" layout="inline">
-                <a-form-item field="orderNumber" label="订单编号">
-                    <a-input v-model="searchForm.orderNumber" placeholder="请输入订单编号" allow-clear />
-                </a-form-item>
-                <a-form-item field="customerName" label="客户">
-                    <a-input v-model="searchForm.customerName" placeholder="请输入客户名称" allow-clear />
-                </a-form-item>
-                <a-form-item field="customerName" label="卡号">
-                    <a-input v-model="searchForm.cardNumber" placeholder="请输入卡号" allow-clear />
-                </a-form-item>
-                <a-form-item>
-                    <a-space>
-                        <a-button type="primary" @click="handleSearch">搜索</a-button>
-                        <a-button @click="resetSearch">重置</a-button>
-                    </a-space>
-                </a-form-item>
-            </a-form>
-        </div>
-        <div class="audit-btn">
-            <a-button @click="openAudit" type="text">
-                <template #icon>
-                    <icon-plus-circle />
-                </template>
-                <template #default>审核</template>
-            </a-button>
-        </div>
-        <!-- 数据表格 -->
-        <a-table row-key="customerName" v-model:selectedKeys="selectedKeys" :row-selection="rowSelection"
-            :columns="columns" :data="tableData" :pagination="pagination" :scroll="{ x: '100%', y: '400px' }">
-            <template #detail="{ record }">
-                <a-button @click="openDetail(record)" type="text">订单详情</a-button>
-            </template>
-        </a-table>
-        <a-modal v-model:visible="showAudit" title="审核" @cancel="showAudit = false" @before-ok="submitAudit"
-            okText="确定审核" cancelText="关闭">
-            <a-form :model="formAudit" auto-label-width>
-                <a-form-item field="customerName" label="客户">
-                    <!-- <a-input v-model="formAudit.customerName" placeholder="请输入客户" /> -->
-                    <div class="audit-txt" style="color:#418035;">演示账号02</div>
-                </a-form-item>
-                <a-form-item field="cardType" label="卡类型">
-                    <!-- <a-input v-model="formAudit.cardType" placeholder="请输入单号" /> -->
-                    <div class="audit-txt">普通卡切卡普通卡MP1,1元/涨<div class="audit-tag">共1张卡</div>
-                    </div>
-                </a-form-item>
-                <a-form-item field="money" label="资费">
-                    <!-- <a-input v-model="formAudit.money" placeholder="请输入单号" /> -->
-                    <div class="audit-txt">“移动100M月包” <div class="audit-tag">订购12个月</div>
-                    </div>
-                </a-form-item>
-                <a-form-item field="orderStatus" label="订单状态">
-                    <!-- <a-input v-model="formAudit.orderStatus" placeholder="请输入单号" /> -->
-                    <a-radio-group v-model="formAudit.orderStatus" :options="options" />
-                </a-form-item>
-                <a-form-item field="auditOpinion" label="审核意见">
-                    <!-- <a-input v-model="formAudit.auditOpinion" placeholder="请输入单号" /> -->
-                    <a-textarea placeholder="您填写的审核意见会直接投送给用户,请认真填写!" v-model="formAudit.auditOpinion" allow-clear />
-                </a-form-item>
-                <a-form-item field="fileList" label="销售合同">
-                    <a-upload action="/" :default-file-list="formAudit.fileList" />
-                </a-form-item>
-            </a-form>
-        </a-modal>
-        <a-modal v-model:visible="showDetail" width="800px" title="卡注销" :hide-cancel="true" @cancel="detailCancel">
-            <div class="detail-box">
-                <div class="detail-item-box">
-                    <div class="detail-item">
-                        <div class="item-label">订单编号</div>
-                        <div class="item-content">53357981207</div>
-                    </div>
-                    <div class="detail-item">
-                        <div class="item-label">订单状态</div>
-                        <div class="item-content">已审核</div>
-                    </div>
-                </div>
-                <div class="detail-item-box">
-                    <div class="detail-item">
-                        <div class="item-label">运营商</div>
-                        <div class="item-content">泰国AIS</div>
-                    </div>
-                    <div class="detail-item">
-                        <div class="item-label">下单时间</div>
-                        <div class="item-content">2024-10-24 10:00:23</div>
-                    </div>
-                </div>
-                <div class="detail-item-box">
-                    <div class="detail-item">
-                        <div class="item-label">原资费信息</div>
-                        <div class="item-content">1.0G/月</div>
-                    </div>
-                    <div class="detail-item">
-                        <div class="item-label">原资费编码</div>
-                        <div class="item-content">MR206</div>
-                    </div>
-                </div>
-                <div class="detail-item-box">
-                    <div class="detail-item">
-                        <div class="item-label">新资费信息</div>
-                        <div class="item-content">5.0G/月</div>
-                    </div>
-                    <div class="detail-item">
-                        <div class="item-label">新资费编码</div>
-                        <div class="item-content">MR207</div>
-                    </div>
-                </div>
-                <div class="detail-item-box">
-                    <div class="detail-item">
-                        <div class="item-label">计费方式</div>
-                        <div class="item-content">按单流量消耗计费</div>
-                    </div>
-                    <div class="detail-item">
-                        <div class="item-label">结算周期</div>
-                        <div class="item-content">月</div>
-                    </div>
-                </div>
-                <div class="detail-item-box">
-                    <div class="detail-item">
-                        <div class="item-label">流量资费计费</div>
-                        <div class="item-content">0.8美金/G;MRC:0元;网络接入0元</div>
-                    </div>
-                </div>
-                <div class="detail-item-box">
-                    <div class="detail-item">
-                        <div class="item-label">变更数量</div>
-                        <div class="item-content">50
-                        </div>
-                    </div>
-                </div>
-            </div>
-            <div class="detail-table">
-                <a-table :columns="columnsDetail" :data="dataDetail" />
-            </div>
-        </a-modal>
+  <div class="silent-expire-alarm">
+    <!-- 搜索条件区 -->
+    <div class="search-section">
+      <Search/>
     </div>
+    <!-- 数据表格 -->
+    <a-table :columns="columns" :data="tableData" :pagination="pagination" :scroll="{ x: '100%', y: '400px' }">
+      <template #detail="{ record }">
+        <a-button @click="openDetail(record)" type="text">订单详情</a-button>
+      </template>
+      <template #orderStatus="{ record }">
+        <a-tag color="orangered" v-if="record.moderationStatus == 1">待审核</a-tag>
+        <a-tag color="arcoblue" v-if="record.moderationStatus == 2">审核通过</a-tag>
+        <a-tag color="#f53f3f" v-if="record.moderationStatus == 3">已驳回</a-tag>
+      </template>
+      <template #id="{ record }">
+        <div class="line_heis" @click="openDetail(record)">{{ record.id }}</div>
+      </template>
+      <template #operate="{ record }">
+        <a-button type="primary" @click="showAudit = true">审核</a-button>
+      </template>
+    </a-table>
+
+
+    <Status v-model:modelValue="showAudit" @submit="intData()" />
+    <<Detaile v-model:modelValue="showDetail" @submit="intData()" :FormDataList="FormDataList" />
+  </div>
 </template>
 
 <script setup>
-import { ref, reactive } from 'vue';
-import { Message } from '@arco-design/web-vue';
-const selectedKeys = ref([]);
-const rowSelection = reactive({
-    type: 'checkbox',
-    showCheckedAll: true,
-    onlyCurrent: false,
-});
-const searchForm = reactive({
-    cardNumber: '',
-    customerName: '',
-    orderNumber: ''
-});
+import { ref, onMounted, toRefs } from 'vue';
+import Status from './status.vue'
+import Search from '@/components/Search/index.vue'
+const state = ref({
+  tableData: [],
+  pagination: {
+    total: 0,
+    current: 1,
+    size: 10,
+  },
+  showDetail: false,
+  showAudit: false,
+  FormDataList: {}
+})
+
+const { tableData, pagination, showDetail, showAudit, FormDataList } = toRefs(state.value)
 
 const columns = [
-    { title: '序号', dataIndex: 'index', align: 'center', render: ({ rowIndex }) => rowIndex + 1 },
-    {
-        title: '订单编号', dataIndex: 'orderNumber', ellipsis: true,
-        tooltip: true,
-        width: 100
-    },
-    { title: '客户名称', dataIndex: 'customerName' },
-    { title: '订单状态', dataIndex: 'auditStatus' },
-    { title: '注销张数', dataIndex: 'moneyNew' },
-    { title: '资费', dataIndex: 'moneyOld' },
-    { title: '卡号', dataIndex: 'cardNumber' },
-    { title: '下单时间', dataIndex: 'orderTime' },
+  { title: '序号', dataIndex: 'index', align: 'center', render: ({ rowIndex }) => rowIndex + 1 },
+  {
+    title: '订单编号', slotName: 'id', ellipsis: true,
+    tooltip: true,
+  },
+  {
+    title: '客户名称', dataIndex: 'userName', ellipsis: true,
+    tooltip: true,
+  },
+  { title: '审核状态', slotName: 'orderStatus', ellipsis: true },
+  {
+    title: '供应商名称', dataIndex: 'sourceName', ellipsis: true,
+    tooltip: true,
+  },
+  { title: '卡数量', dataIndex: 'quantity', ellipsis: true },
+  { title: '注销日期', dataIndex: 'period_of_silence', ellipsis: true },
+  { title: '操作', slotName: 'operate', align: 'center', ellipsis: true }
 ];
-const columnsDetail = [{ title: 'ICCID', dataIndex: 'iccid' },
-{ title: '池名称及编号', dataIndex: 'nameAndId' },
-{ title: '卡状态', dataIndex: 'status' },
-]
-const dataDetail = ref([{
-    iccid: '8986061800002054589N',
-    nameAndId: '泰国监控40G共享/53357981207',
-    status: '沉默期'
-},
-{
-    iccid: '8986061800002054588N',
-    nameAndId: '泰国监控40G共享/53357981207',
-    status: '沉默期'
-}, {
-    iccid: '8986061800002054587N',
-    nameAndId: '泰国监控40G共享/53357981207',
-    status: '沉默期'
-}, {
-    iccid: '8986061800002054586N',
-    nameAndId: '泰国监控40G共享/53357981207',
-    status: '沉默期'
-},])
-const tableData = ref([
-    {
-        orderNumber: '13800138000',
-        customerName: '张三',
-        orderStatus: '1',
-        auditStatus: '待审核',
-        originName: '移动-广州分公司',
-        moneyNew: '100',
-        moneyOld: '100',
-        cardNumber: '1124224q',
-        orderMoney: '11美元',
-        finallyMoney: '1美元',
-        returnMoney: '10美元',
-        orderTime: '2024-10-11'
-        // operate:'上传合同'
-    },
-    {
-        orderNumber: '13800138000',
-        customerName: '李四',
-        orderStatus: '1',
-        auditStatus: '待审核',
-        originName: '移动-广州分公司',
-        moneyNew: '100',
-        moneyOld: '100',
-        cardNumber: '1124224q',
-        orderMoney: '11美元',
-        finallyMoney: '1美元',
-        returnMoney: '10美元',
-        orderTime: '2024-10-11'
-        // operate:'上传合同'
-    },
-    {
-        orderNumber: '13800138000',
-        customerName: '王五',
-        orderStatus: '1',
-        auditStatus: '待审核',
-        originName: '移动-广州分公司',
-        moneyNew: '100',
-        moneyOld: '100',
-        cardNumber: '1124224q',
-        orderMoney: '11美元',
-        finallyMoney: '1美元',
-        returnMoney: '10美元',
-        orderTime: '2024-10-11'
-        // operate:'上传合同'
-    },
-    {
-        orderNumber: '13800138000',
-        customerName: '赵六',
-        orderStatus: '1',
-        auditStatus: '待审核',
-        originName: '移动-广州分公司',
-        moneyNew: '100',
-        moneyOld: '100',
-        cardNumber: '1124224q',
-        orderMoney: '11美元',
-        finallyMoney: '1美元',
-        returnMoney: '10美元',
-        orderTime: '2024-10-11'
-        // operate:'上传合同'
-    },
 
-]);
-const pagination = reactive({
-    total: tableData.value.length,
-    current: 1,
-    pageSize: 10,
-});
-//订单详情的弹框
-const showDetail = ref(false);
 // 查看订单详情
 const openDetail = (item) => {
-    showDetail.value = true;
+  showDetail.value = true;
+  FormDataList.value = item;
 }
-const handleSearch = () => {
-    console.log('Search form data:', searchForm);
-    Message.success('执行搜索操作');
-};
 
-const resetSearch = () => {
-    Object.keys(searchForm).forEach(key => {
-        if (Array.isArray(searchForm[key])) {
-            searchForm[key] = [];
-        } else {
-            searchForm[key] = null;
-        }
-    });
-    Message.success('搜索条件已重置');
-};
-// 订单状态
-const options = [
-    { label: '发货', value: '1' },
-    { label: '退回', value: '2' },
-];
-// 审核
-const showAudit = ref(false);
-const formAudit = reactive({
-    customerName: '',
-    cardType: '',
-    money: '',
-    orderStatus: '',
-    auditOpinion: '',
-    fileList: []
+// 列表-------------------------------------
+// 订单列表
+// const intData = async () => {
+//   const param = {
+//     current: pagination.value.current,
+//     size: pagination.value.size,
+//   }
+//   const one = await Getdictionary('source')
+//   const two = await Getdictionary('cardType')
+//   const tree = await Getdictionary('subscriptionRelationshipStatus')
+//   const tive = await Getdictionary('orderAuditStatus')
+//   cancelOrderList(param).then(res => {
+//     tableData.value = (res.data.records || []).map(item => {
+
+//       const sourceName = one.filter((item) => item.typeKey == enum_dict.SOURCE)?.find(val => item.source == val.value)?.label
+//       const cardTypeName = two.filter((item) => item.typeKey == enum_dict.CARD_TYPE)?.find(val => item.card_type == val.value)?.label
+//       const statusName = tree.filter((item) => item.typeKey == enum_dict.SUBSCRIPTION_RELATIONSHIP_STATUS)?.find(val => item.status == val.value)?.label
+//       const moderationStatusName = tive.filter((item) => item.typeKey == enum_dict.ORDER_AUDIT_STATUS)?.find(val => item.moderation_status == val.value)?.label
+
+//       return {
+//         ...item,
+//         moderationStatusName,
+//         statusName,
+//         cardTypeName,
+//         sourceName
+//       }
+//     });
+//     pagination.value.total = res.data.total;
+//   })
+
+// }
+onMounted(() => {
+  // intData();
 })
-// 触发审核的弹框
-const openAudit = () => {
-    showAudit.value = true;
-}
-// 确认审核
-const submitAudit = () => {
-    console.log(formAudit, 'lll')
-    window.setTimeout(() => {
-        showAudit.value = false;
-    }, 1000)
-}
-const detailCancel = () => {
-}
 </script>
 
 <style scoped lang="less">
 .silent-expire-alarm {
-    padding: 20px !important;
-    // background: #fcf;
+  padding: 20px !important;
+  // background: #fcf;
 }
 
 .search-section {
-    margin-bottom: 20px;
+  margin-bottom: 20px;
 }
 
 .arco-table-th {
-    white-space: nowrap;
+  white-space: nowrap;
 }
 
 .audit-txt {
+  display: flex;
+  justify-content: center;
+  align-items: center;
+
+  .audit-tag {
+    margin-left: 20px;
+    background: #63c2c6;
+    color: #fff;
+    font-size: 12px;
     display: flex;
     justify-content: center;
     align-items: center;
-
-    .audit-tag {
-        margin-left: 20px;
-        background: #63c2c6;
-        color: #fff;
-        font-size: 12px;
-        display: flex;
-        justify-content: center;
-        align-items: center;
-        padding: 0 10px;
-        box-sizing: border-box;
-        border-radius: 50px;
-    }
+    padding: 0 10px;
+    box-sizing: border-box;
+    border-radius: 50px;
+  }
 }
 
 .audit-btn {
-    margin-bottom: 10px;
+  margin-bottom: 10px;
 }
 
 .detail-box {
-    .detail-item-box {
-        display: flex;
-        justify-content: space-between;
-        align-items: center;
-        margin-bottom: 10px;
+  .detail-item-box {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    margin-bottom: 10px;
 
-        .detail-item {
-            //styleName: Body/Medium;
-            font-family: PingFang SC;
-            font-size: 14px;
-            font-weight: 400;
-            line-height: 22px;
-            text-align: left;
-            display: flex;
-            align-items: center;
-            min-width: 350px;
+    .detail-item {
+      //styleName: Body/Medium;
+      font-family: PingFang SC;
+      font-size: 14px;
+      font-weight: 400;
+      line-height: 22px;
+      text-align: left;
+      display: flex;
+      align-items: center;
+      min-width: 350px;
 
-            .item-label {
-                color: rgba(0, 0, 0, 0.4);
-                width: 120px;
-                text-align: right;
-                margin-right: 10px;
-            }
+      .item-label {
+        color: rgba(0, 0, 0, 0.4);
+        width: 120px;
+        text-align: right;
+        margin-right: 10px;
+      }
 
-            .item-content {
-                color: rgba(51, 51, 51, 1);
-            }
-        }
+      .item-content {
+        color: rgba(51, 51, 51, 1);
+      }
     }
+  }
 }
 
 .detail-table {
-    margin-top: 20px;
+  margin-top: 20px;
+}
+
+.line_heis {
+  color: #FF8839;
+  cursor: pointer;
+  display: inline-block;
+}
+
+.line_heis:hover {
+  color: #168cff;
 }
 </style>

+ 81 - 0
src/views/order/CancelOrder/status.vue

@@ -0,0 +1,81 @@
+<template>
+    <div class="">
+        <a-modal v-model:visible="modelValue" title="审核" @cancel="cancel" @before-ok="submitAudit" okText="确定审核"
+            cancelText="关闭">
+            <a-form :model="formAudit" auto-label-width>
+                <a-form-item field="customerName" label="客户">
+                    <!-- <a-input v-model="formAudit.customerName" placeholder="请输入客户" /> -->
+                    <div class="audit-txt" style="color:#418035;">演示账号02</div>
+                </a-form-item>
+                <a-form-item field="cardType" label="卡类型">
+                    <!-- <a-input v-model="formAudit.cardType" placeholder="请输入单号" /> -->
+                    <div class="audit-txt">普通卡切卡普通卡MP1,1元/涨
+                        <div class="audit-tag">共1张卡</div>
+                    </div>
+                </a-form-item>
+                <a-form-item field="money" label="资费">
+                    <!-- <a-input v-model="formAudit.money" placeholder="请输入单号" /> -->
+                    <div class="audit-txt">“移动100M月包”
+                        <div class="audit-tag">订购12个月</div>
+                    </div>
+                </a-form-item>
+                <a-form-item field="orderStatus" label="订单状态">
+                    <!-- <a-input v-model="formAudit.orderStatus" placeholder="请输入单号" /> -->
+                    <a-radio-group v-model="formAudit.orderStatus" :options="options" />
+                </a-form-item>
+                <a-form-item field="auditOpinion" label="审核意见">
+                    <!-- <a-input v-model="formAudit.auditOpinion" placeholder="请输入单号" /> -->
+                    <a-textarea placeholder="您填写的审核意见会直接投送给用户,请认真填写!" v-model="formAudit.auditOpinion" allow-clear />
+                </a-form-item>
+                <a-form-item field="fileList" label="销售合同">
+                    <a-upload action="/" :default-file-list="formAudit.fileList" />
+                </a-form-item>
+            </a-form>
+        </a-modal>
+    </div>
+</template>
+
+<script setup>
+import { ref, onMounted, toRefs, toRef, watch } from 'vue';
+const props = defineProps({
+    modelValue: {
+        type: Boolean,
+        default: false
+    },
+    FormDataList: {
+        type: Object,
+        default: () => ({})
+    }
+})
+const modelValue = toRef(props, 'modelValue')
+const FormDataList = toRef(props, 'FormDataList')
+const emit = defineEmits(['update:modelValue', 'submit'])
+
+const state = ref({
+    options: [
+        { label: '发货', value: '1' },
+        { label: '退回', value: '2' },
+    ],
+    formAudit: {
+        customerName: '',
+        cardType: '',
+        money: '',
+        orderStatus: '',
+        auditOpinion: '',
+        fileList: []
+    },
+    
+})
+
+const { options, formAudit } = toRefs(state.value)
+
+const cancel = () => {
+    emit('update:modelValue', false)
+}
+
+// 确认审核
+const submitAudit = () => {
+   emit('submit',true)
+}
+</script>
+<style scoped></style>

+ 161 - 0
src/views/order/RenewalOrder/detaile.vue

@@ -0,0 +1,161 @@
+<template>
+    <a-modal v-model:visible="modelValue" width="800px" title="订单详情" @cancel="cancel" @ok="showDetail = false">
+        <div class="detail-box">
+            <div class="detail-item-box">
+                <div class="detail-item">
+                    <div class="item-label">订单编号</div>
+                    <div class="item-content">{{ FormDataList.id }}</div>
+                </div>
+                <div class="detail-item">
+                    <div class="item-label">订单状态</div>
+                    <div class="item-content">
+                        <a-tag color="#168cff" v-if="FormDataList.tmsStatus == 1">未发货</a-tag>
+                        <a-tag color="#00b42a" v-if="FormDataList.tmsStatus == 2">已发货</a-tag>
+                    </div>
+                </div>
+            </div>
+            <div class="detail-item-box">
+                <div class="detail-item">
+                    <div class="item-label">运营商</div>
+                    <div class="item-content">{{ FormDataList.sourceName }}</div>
+                </div>
+                <div class="detail-item">
+                    <div class="item-label">资费信息</div>
+                    <div class="item-content">{{ TariffInfomr }}</div>
+                </div>
+            </div>
+            <div class="detail-item-box">
+                <div class="detail-item">
+                    <div class="item-label">最短订阅周期</div>
+                    <div class="item-content">{{ tariffForm.settlementCycle?.split('~')[0] }}个月</div>
+                </div>
+                <div class="detail-item">
+                    <div class="item-label">最长订阅周期</div>
+                    <div class="item-content">{{ tariffForm.settlementCycle?.split('~')[1] }}个月</div>
+                </div>
+            </div>
+            <div class="detail-item-box">
+                <div class="detail-item">
+                    <div class="item-label">计费方式</div>
+                    <div class="item-content">{{ tariffForm.billingMethodName }}</div>
+                </div>
+                <div class="detail-item">
+                    <div class="item-label">结算周期</div>
+                    <div class="item-content">{{ tariffForm.billingcycleName }}</div>
+                </div>
+            </div>
+            <div class="detail-item-box">
+                <div class="detail-item">
+                    <div class="item-label">卡类型</div>
+                    <div class="item-content">{{ FormDataList.CardType }}</div>
+                </div>
+                <div class="detail-item">
+                    <div class="item-label">标准价格</div>
+                    <div class="item-content">{{ tariffForm.pricingName }}</div>
+                </div>
+            </div>
+            <div class="detail-item-box">
+                <div class="detail-item">
+                    <div class="item-label">流量池</div>
+                    <div class="item-content">{{ FormDataList.isTrafficPool == 1 ? '是' : '否' }}</div>
+                </div>
+            </div>
+            <div class="detail-item-box">
+                <div class="detail-item">
+                    <div class="item-label">卡数量</div>
+                    <div class="item-content">{{ dataDetail.length }}
+                    </div>
+                </div>
+            </div>
+        </div>
+        <div class="detail-table">
+            <a-table :columns="columnsDetail" :data="dataDetail" />
+        </div>
+    </a-modal>
+</template>
+
+<script setup>
+import { ref, onMounted, toRefs, toRef ,watch} from 'vue';
+import { AcquireOrdertariff,TariffOrderCard } from '@/api/path/order'
+import { Getdictionary } from '@/mixins/index.js'
+const props = defineProps({
+    modelValue: {
+        type: Boolean,
+        default: false
+    },
+    FormDataList: {
+        type: Object,
+        default: () => ({})
+    }
+})
+const modelValue = toRef(props, 'modelValue')
+const FormDataList = toRef(props, 'FormDataList')
+const emit = defineEmits(['update:modelValue', 'submit'])
+const state = ref({
+    tariffForm: {},
+    res1:[],
+    res2:[],
+    res3:[],
+})
+const { tariffForm,res1,res2,res3 } = toRefs(state.value)
+const columnsDetail = [{ title: 'ICCID', dataIndex: 'iccid' }
+]
+const dataDetail = ref([])
+
+const cancel = () => {
+    emit('update:modelValue', false)
+}
+
+watch(() => FormDataList.value, val => {
+    if (Object.keys(val).length === 0) return
+    AcquireOrdertariff({ id: val.trafficId }).then(res => {
+        tariffForm.value = res.data
+        tariffForm.value.billingcycleName = res1.value.filter(val => val.value == res.data.billingCycle)[0]?.label;
+        tariffForm.value.billingMethodName = res2.value.filter(val => val.value == res.data.billingMethod)[0]?.label;
+        tariffForm.value.TariffInfomr = res.data.trafficBilling + '/' + res.data.trafficBillingType
+        tariffForm.value.pricingName = tariffForm.value.pricing !== '' ? tariffForm.value.pricing + '/' + res3.value.filter(val => val.value == res.data.currency)[0]?.label : '';
+    })
+    TariffOrderCard({id:val.trafficId}).then(res=>{
+        dataDetail.value = res.data
+    })
+},{deep: true})
+
+onMounted(async () => {
+    res1.value = await Getdictionary('Billingcycle')
+    res2.value = await Getdictionary('billingMethod')
+    res3.value = await Getdictionary('currencyType')
+})
+</script>
+<style scoped lang="less">
+.detail-box {
+    .detail-item-box {
+        display: flex;
+        justify-content: space-between;
+        align-items: center;
+        margin-bottom: 10px;
+
+        .detail-item {
+            //styleName: Body/Medium;
+            font-family: PingFang SC;
+            font-size: 14px;
+            font-weight: 400;
+            line-height: 22px;
+            text-align: left;
+            display: flex;
+            align-items: center;
+            min-width: 350px;
+
+            .item-label {
+                color: rgba(0, 0, 0, 0.4);
+                width: 120px;
+                text-align: right;
+                margin-right: 10px;
+            }
+
+            .item-content {
+                color: rgba(51, 51, 51, 1);
+            }
+        }
+    }
+}
+</style>

+ 152 - 332
src/views/order/RenewalOrder/index.vue

@@ -1,379 +1,199 @@
-<!-- 续费订单 -->
+<!-- 退卡订单 -->
 <template>
-    <div class="silent-expire-alarm">
-        <!-- 搜索条件区 -->
-        <div class="search-section">
-            <a-form :model="searchForm" layout="inline">
-                <a-form-item field="orderNumber" label="订单编号">
-                    <a-input v-model="searchForm.orderNumber" placeholder="请输入订单编号" allow-clear />
-                </a-form-item>
-                <a-form-item field="customerName" label="客户">
-                    <a-input v-model="searchForm.customerName" placeholder="请输入客户名称" allow-clear />
-                </a-form-item>
-                <a-form-item field="customerName" label="卡号">
-                    <a-input v-model="searchForm.cardNumber" placeholder="请输入卡号" allow-clear />
-                </a-form-item>
-                <a-form-item>
-                    <a-space>
-                        <a-button type="primary" @click="handleSearch">搜索</a-button>
-                        <a-button @click="resetSearch">重置</a-button>
-                    </a-space>
-                </a-form-item>
-            </a-form>
-        </div>
-        <div class="audit-btn">
-            <a-button @click="openAudit" type="text">
-                <template #icon>
-                    <icon-plus-circle />
-                </template>
-                <template #default>审核</template>
-            </a-button>
-        </div>
-        <!-- 数据表格 -->
-        <a-table row-key="customerName" v-model:selectedKeys="selectedKeys" :row-selection="rowSelection"
-            :columns="columns" :data="tableData" :pagination="pagination" :scroll="{ x: '100%', y: '400px' }">
-            <template #detail="{ record }">
-                <a-button @click="openDetail(record)" type="text">订单详情</a-button>
-            </template>
-        </a-table>
-        <a-modal v-model:visible="showAudit" title="审核" @cancel="showAudit = false" @before-ok="submitAudit"
-            okText="确定审核" cancelText="关闭">
-            <a-form :model="formAudit" auto-label-width>
-                <a-form-item field="customerName" label="客户">
-                    <!-- <a-input v-model="formAudit.customerName" placeholder="请输入客户" /> -->
-                    <div class="audit-txt" style="color:#418035;">演示账号02</div>
-                </a-form-item>
-                <a-form-item field="cardType" label="卡类型">
-                    <!-- <a-input v-model="formAudit.cardType" placeholder="请输入单号" /> -->
-                    <div class="audit-txt">普通卡切卡普通卡MP1,1元/涨<div class="audit-tag">共1张卡</div>
-                    </div>
-                </a-form-item>
-                <a-form-item field="money" label="资费">
-                    <!-- <a-input v-model="formAudit.money" placeholder="请输入单号" /> -->
-                    <div class="audit-txt">“移动100M月包” <div class="audit-tag">订购12个月</div>
-                    </div>
-                </a-form-item>
-                <a-form-item field="orderStatus" label="订单状态">
-                    <!-- <a-input v-model="formAudit.orderStatus" placeholder="请输入单号" /> -->
-                    <a-radio-group v-model="formAudit.orderStatus" :options="options" />
-                </a-form-item>
-                <a-form-item field="auditOpinion" label="审核意见">
-                    <!-- <a-input v-model="formAudit.auditOpinion" placeholder="请输入单号" /> -->
-                    <a-textarea placeholder="您填写的审核意见会直接投送给用户,请认真填写!" v-model="formAudit.auditOpinion" allow-clear />
-                </a-form-item>
-                <a-form-item field="fileList" label="销售合同">
-                    <a-upload action="/" :default-file-list="formAudit.fileList" />
-                </a-form-item>
-            </a-form>
-        </a-modal>
-        <a-modal v-model:visible="showDetail" width="800px" title="续费订单" :hide-cancel="true" @cancel="detailCancel">
-            <div class="detail-box">
-                <div class="detail-item-box">
-                    <div class="detail-item">
-                        <div class="item-label">订单编号</div>
-                        <div class="item-content">53357981207</div>
-                    </div>
-                    <div class="detail-item">
-                        <div class="item-label">订单状态</div>
-                        <div class="item-content">已审核</div>
-                    </div>
-                </div>
-                <div class="detail-item-box">
-                    <div class="detail-item">
-                        <div class="item-label">运营商</div>
-                        <div class="item-content">泰国AIS</div>
-                    </div>
-                    <div class="detail-item">
-                        <div class="item-label">下单时间</div>
-                        <div class="item-content">2024-10-24 10:00:23</div>
-                    </div>
-                </div>
-                <div class="detail-item-box">
-                    <div class="detail-item">
-                        <div class="item-label">资费信息</div>
-                        <div class="item-content">1.0G/月</div>
-                    </div>
-                    <div class="detail-item">
-                        <div class="item-label">资费编码</div>
-                        <div class="item-content">MR206</div>
-                    </div>
-                </div>
-                <div class="detail-item-box">
-                    <div class="detail-item">
-                        <div class="item-label">计费方式</div>
-                        <div class="item-content">按单流量消耗计费</div>
-                    </div>
-                    <div class="detail-item">
-                        <div class="item-label">结算周期</div>
-                        <div class="item-content">月</div>
-                    </div>
-                </div>
-                <div class="detail-item-box">
-                    <div class="detail-item">
-                        <div class="item-label">流量资费计费</div>
-                        <div class="item-content">0.8美金/G;MRC:0元;网络接入0元</div>
-                    </div>
-                </div>
-                <div class="detail-item-box">
-                    <div class="detail-item">
-                        <div class="item-label">续期数量</div>
-                        <div class="item-content">50
-                        </div>
-                    </div>
-                </div>
-            </div>
-            <div class="detail-table">
-                <a-table :columns="columnsDetail" :data="dataDetail" />
-            </div>
-        </a-modal>
+  <div class="silent-expire-alarm">
+    <!-- 搜索条件区 -->
+    <div class="search-section">
+      <Search/>
     </div>
+    <!-- 数据表格 -->
+    <a-table :columns="columns" :data="tableData" :pagination="pagination" :scroll="{ x: '100%', y: '400px' }">
+      <template #detail="{ record }">
+        <a-button @click="openDetail(record)" type="text">订单详情</a-button>
+      </template>
+      <template #orderStatus="{ record }">
+        <a-tag color="orangered" v-if="record.moderationStatus == 1">待审核</a-tag>
+        <a-tag color="arcoblue" v-if="record.moderationStatus == 2">审核通过</a-tag>
+        <a-tag color="#f53f3f" v-if="record.moderationStatus == 3">已驳回</a-tag>
+      </template>
+      <template #id="{ record }">
+        <div class="line_heis" @click="openDetail(record)">{{ record.id }}</div>
+      </template>
+      <template #operate="{ record }">
+        <a-button type="primary" @click="showAudit = true">审核</a-button>
+      </template>
+    </a-table>
+
+
+    <Status v-model:modelValue="showAudit" @submit="intData()" />
+    <<Detaile v-model:modelValue="showDetail" @submit="intData()" :FormDataList="FormDataList" />
+  </div>
 </template>
 
 <script setup>
-import { ref, reactive } from 'vue';
-import { Message } from '@arco-design/web-vue';
-const selectedKeys = ref([]);
-const rowSelection = reactive({
-    type: 'checkbox',
-    showCheckedAll: true,
-    onlyCurrent: false,
-});
-const searchForm = reactive({
+import { ref, onMounted, toRefs } from 'vue';
+import Status from './status.vue'
+import Search from '@/components/Search/index.vue'
+const state = ref({
+  searchForm: {
     cardNumber: '',
     customerName: '',
-    orderNumber: ''
-});
+  },
+  tableData: [],
+  pagination: {
+    total: 0,
+    current: 1,
+    size: 10,
+  },
+  showDetail: false,
+  showAudit: false,
+  FormDataList: {}
+})
+
+const { searchForm, tableData, pagination, showDetail, showAudit, FormDataList } = toRefs(state.value)
 
 const columns = [
-    { title: '序号', dataIndex: 'index', align: 'center', render: ({ rowIndex }) => rowIndex + 1 },
-    {
-        title: '订单编号', dataIndex: 'orderNumber', ellipsis: true,
-        tooltip: true,
-        width: 100
-    },
-    { title: '客户名称', dataIndex: 'customerName' },
-    { title: '审核状态', dataIndex: 'auditStatus' },
-    {
-        title: '供应商名称', dataIndex: 'originName', ellipsis: true,
-        tooltip: true,
-        width: 150
-    },
-    { title: '资费', dataIndex: 'money' },
-    { title: '卡号', dataIndex: 'cardNumber' },
-    { title: '订单金额(元)', dataIndex: 'orderMoney' },
-    { title: '下单时间', dataIndex: 'orderTime' },
-    { title: '详情', slotName: 'detail', align: 'center' },
+  { title: '序号', dataIndex: 'index', align: 'center', render: ({ rowIndex }) => rowIndex + 1 },
+  {
+    title: '订单编号', slotName: 'id', ellipsis: true,
+    tooltip: true,
+  },
+  {
+    title: '客户名称', dataIndex: 'userName', ellipsis: true,
+    tooltip: true,
+  },
+  { title: '审核状态', slotName: 'orderStatus', ellipsis: true },
+  {
+    title: '供应商名称', dataIndex: 'sourceName', ellipsis: true,
+    tooltip: true,
+  },
+  { title: '资费', dataIndex: 'quantity', ellipsis: true },
+  { title: '卡号', dataIndex: 'period_of_silence', ellipsis: true },
+  { title: '订单金额', dataIndex: 'payment_amount', ellipsis: true },
+  { title: '操作', slotName: 'operate', align: 'center', ellipsis: true }
 ];
-const columnsDetail = [{ title: 'ICCID', dataIndex: 'iccid' },
-{ title: '池名称及编号', dataIndex: 'nameAndId' },
-{ title: '卡状态', dataIndex: 'status' },
-]
-const dataDetail = ref([{
-    iccid: '8986061800002054589N',
-    nameAndId: '泰国监控40G共享/53357981207',
-    status: '沉默期'
-},
-{
-    iccid: '8986061800002054588N',
-    nameAndId: '泰国监控40G共享/53357981207',
-    status: '沉默期'
-}, {
-    iccid: '8986061800002054587N',
-    nameAndId: '泰国监控40G共享/53357981207',
-    status: '沉默期'
-}, {
-    iccid: '8986061800002054586N',
-    nameAndId: '泰国监控40G共享/53357981207',
-    status: '沉默期'
-},])
-const tableData = ref([
-    {
-        orderNumber: '13800138000',
-        customerName: '张三',
-        orderStatus: '1',
-        auditStatus: '待审核',
-        originName: '移动-广州分公司',
-        money: '100',
-        cardNumber: '1124224q',
-        orderMoney: '11美元',
-        finallyMoney: '1美元',
-        returnMoney: '10美元',
-        orderTime: '2024-10-11'
-        // operate:'上传合同'
-    },
-    {
-        orderNumber: '13800138000',
-        customerName: '李四',
-        orderStatus: '1',
-        auditStatus: '待审核',
-        originName: '移动-广州分公司',
-        money: '100',
-        moneyOld: '100',
-        cardNumber: '1124224q',
-        orderMoney: '11美元',
-        finallyMoney: '1美元',
-        returnMoney: '10美元',
-        orderTime: '2024-10-11'
-        // operate:'上传合同'
-    },
-    {
-        orderNumber: '13800138000',
-        customerName: '王五',
-        orderStatus: '1',
-        auditStatus: '待审核',
-        originName: '移动-广州分公司',
-        money: '100',
-        moneyOld: '100',
-        cardNumber: '1124224q',
-        orderMoney: '11美元',
-        finallyMoney: '1美元',
-        returnMoney: '10美元',
-        orderTime: '2024-10-11'
-        // operate:'上传合同'
-    },
-    {
-        orderNumber: '13800138000',
-        customerName: '赵六',
-        orderStatus: '1',
-        auditStatus: '待审核',
-        originName: '移动-广州分公司',
-        money: '100',
-        moneyOld: '100',
-        cardNumber: '1124224q',
-        orderMoney: '11美元',
-        finallyMoney: '1美元',
-        returnMoney: '10美元',
-        orderTime: '2024-10-11'
-        // operate:'上传合同'
-    },
 
-]);
-const pagination = reactive({
-    total: tableData.value.length,
-    current: 1,
-    pageSize: 10,
-});
-//订单详情的弹框
-const showDetail = ref(false);
 // 查看订单详情
 const openDetail = (item) => {
-    showDetail.value = true;
+  showDetail.value = true;
+  FormDataList.value = item;
 }
-const handleSearch = () => {
-    console.log('Search form data:', searchForm);
-    Message.success('执行搜索操作');
-};
 
-const resetSearch = () => {
-    Object.keys(searchForm).forEach(key => {
-        if (Array.isArray(searchForm[key])) {
-            searchForm[key] = [];
-        } else {
-            searchForm[key] = null;
-        }
-    });
-    Message.success('搜索条件已重置');
-};
-// 订单状态
-const options = [
-    { label: '发货', value: '1' },
-    { label: '退回', value: '2' },
-];
-// 审核
-const showAudit = ref(false);
-const formAudit = reactive({
-    customerName: '',
-    cardType: '',
-    money: '',
-    orderStatus: '',
-    auditOpinion: '',
-    fileList: []
+// 列表-------------------------------------
+// 订单列表
+// const intData = async () => {
+//   const param = {
+//     current: pagination.value.current,
+//     size: pagination.value.size,
+//   }
+//   const one = await Getdictionary('source')
+//   const two = await Getdictionary('cardType')
+//   const tree = await Getdictionary('subscriptionRelationshipStatus')
+//   const tive = await Getdictionary('orderAuditStatus')
+//   cancelOrderList(param).then(res => {
+//     tableData.value = (res.data.records || []).map(item => {
+
+//       const sourceName = one.filter((item) => item.typeKey == enum_dict.SOURCE)?.find(val => item.source == val.value)?.label
+//       const cardTypeName = two.filter((item) => item.typeKey == enum_dict.CARD_TYPE)?.find(val => item.card_type == val.value)?.label
+//       const statusName = tree.filter((item) => item.typeKey == enum_dict.SUBSCRIPTION_RELATIONSHIP_STATUS)?.find(val => item.status == val.value)?.label
+//       const moderationStatusName = tive.filter((item) => item.typeKey == enum_dict.ORDER_AUDIT_STATUS)?.find(val => item.moderation_status == val.value)?.label
+
+//       return {
+//         ...item,
+//         moderationStatusName,
+//         statusName,
+//         cardTypeName,
+//         sourceName
+//       }
+//     });
+//     pagination.value.total = res.data.total;
+//   })
+
+// }
+onMounted(() => {
+  // intData();
 })
-// 触发审核的弹框
-const openAudit = () => {
-    showAudit.value = true;
-}
-// 确认审核
-const submitAudit = () => {
-    console.log(formAudit, 'lll')
-    window.setTimeout(() => {
-        showAudit.value = false;
-    }, 1000)
-}
-const detailCancel = () => {
-}
 </script>
 
 <style scoped lang="less">
 .silent-expire-alarm {
-    padding: 20px !important;
-    // background: #fcf;
+  padding: 20px !important;
+  // background: #fcf;
 }
 
 .search-section {
-    margin-bottom: 20px;
+  margin-bottom: 20px;
 }
 
 .arco-table-th {
-    white-space: nowrap;
+  white-space: nowrap;
 }
 
 .audit-txt {
+  display: flex;
+  justify-content: center;
+  align-items: center;
+
+  .audit-tag {
+    margin-left: 20px;
+    background: #63c2c6;
+    color: #fff;
+    font-size: 12px;
     display: flex;
     justify-content: center;
     align-items: center;
-
-    .audit-tag {
-        margin-left: 20px;
-        background: #63c2c6;
-        color: #fff;
-        font-size: 12px;
-        display: flex;
-        justify-content: center;
-        align-items: center;
-        padding: 0 10px;
-        box-sizing: border-box;
-        border-radius: 50px;
-    }
+    padding: 0 10px;
+    box-sizing: border-box;
+    border-radius: 50px;
+  }
 }
 
 .audit-btn {
-    margin-bottom: 10px;
+  margin-bottom: 10px;
 }
 
 .detail-box {
-    .detail-item-box {
-        display: flex;
-        justify-content: space-between;
-        align-items: center;
-        margin-bottom: 10px;
+  .detail-item-box {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    margin-bottom: 10px;
 
-        .detail-item {
-            //styleName: Body/Medium;
-            font-family: PingFang SC;
-            font-size: 14px;
-            font-weight: 400;
-            line-height: 22px;
-            text-align: left;
-            display: flex;
-            align-items: center;
-            min-width: 350px;
+    .detail-item {
+      //styleName: Body/Medium;
+      font-family: PingFang SC;
+      font-size: 14px;
+      font-weight: 400;
+      line-height: 22px;
+      text-align: left;
+      display: flex;
+      align-items: center;
+      min-width: 350px;
 
-            .item-label {
-                color: rgba(0, 0, 0, 0.4);
-                width: 120px;
-                text-align: right;
-                margin-right: 10px;
-            }
+      .item-label {
+        color: rgba(0, 0, 0, 0.4);
+        width: 120px;
+        text-align: right;
+        margin-right: 10px;
+      }
 
-            .item-content {
-                color: rgba(51, 51, 51, 1);
-            }
-        }
+      .item-content {
+        color: rgba(51, 51, 51, 1);
+      }
     }
+  }
 }
 
 .detail-table {
-    margin-top: 20px;
+  margin-top: 20px;
+}
+
+.line_heis {
+  color: #FF8839;
+  cursor: pointer;
+  display: inline-block;
+}
+
+.line_heis:hover {
+  color: #168cff;
 }
 </style>

+ 81 - 0
src/views/order/RenewalOrder/status.vue

@@ -0,0 +1,81 @@
+<template>
+    <div class="">
+        <a-modal v-model:visible="modelValue" title="审核" @cancel="cancel" @before-ok="submitAudit" okText="确定审核"
+            cancelText="关闭">
+            <a-form :model="formAudit" auto-label-width>
+                <a-form-item field="customerName" label="客户">
+                    <!-- <a-input v-model="formAudit.customerName" placeholder="请输入客户" /> -->
+                    <div class="audit-txt" style="color:#418035;">演示账号02</div>
+                </a-form-item>
+                <a-form-item field="cardType" label="卡类型">
+                    <!-- <a-input v-model="formAudit.cardType" placeholder="请输入单号" /> -->
+                    <div class="audit-txt">普通卡切卡普通卡MP1,1元/涨
+                        <div class="audit-tag">共1张卡</div>
+                    </div>
+                </a-form-item>
+                <a-form-item field="money" label="资费">
+                    <!-- <a-input v-model="formAudit.money" placeholder="请输入单号" /> -->
+                    <div class="audit-txt">“移动100M月包”
+                        <div class="audit-tag">订购12个月</div>
+                    </div>
+                </a-form-item>
+                <a-form-item field="orderStatus" label="订单状态">
+                    <!-- <a-input v-model="formAudit.orderStatus" placeholder="请输入单号" /> -->
+                    <a-radio-group v-model="formAudit.orderStatus" :options="options" />
+                </a-form-item>
+                <a-form-item field="auditOpinion" label="审核意见">
+                    <!-- <a-input v-model="formAudit.auditOpinion" placeholder="请输入单号" /> -->
+                    <a-textarea placeholder="您填写的审核意见会直接投送给用户,请认真填写!" v-model="formAudit.auditOpinion" allow-clear />
+                </a-form-item>
+                <a-form-item field="fileList" label="销售合同">
+                    <a-upload action="/" :default-file-list="formAudit.fileList" />
+                </a-form-item>
+            </a-form>
+        </a-modal>
+    </div>
+</template>
+
+<script setup>
+import { ref, onMounted, toRefs, toRef, watch } from 'vue';
+const props = defineProps({
+    modelValue: {
+        type: Boolean,
+        default: false
+    },
+    FormDataList: {
+        type: Object,
+        default: () => ({})
+    }
+})
+const modelValue = toRef(props, 'modelValue')
+const FormDataList = toRef(props, 'FormDataList')
+const emit = defineEmits(['update:modelValue', 'submit'])
+
+const state = ref({
+    options: [
+        { label: '发货', value: '1' },
+        { label: '退回', value: '2' },
+    ],
+    formAudit: {
+        customerName: '',
+        cardType: '',
+        money: '',
+        orderStatus: '',
+        auditOpinion: '',
+        fileList: []
+    },
+    
+})
+
+const { options, formAudit } = toRefs(state.value)
+
+const cancel = () => {
+    emit('update:modelValue', false)
+}
+
+// 确认审核
+const submitAudit = () => {
+   emit('submit',true)
+}
+</script>
+<style scoped></style>

+ 161 - 0
src/views/order/ReturnCard/detaile.vue

@@ -0,0 +1,161 @@
+<template>
+    <a-modal v-model:visible="modelValue" width="800px" title="订单详情" @cancel="cancel" @ok="showDetail = false">
+        <div class="detail-box">
+            <div class="detail-item-box">
+                <div class="detail-item">
+                    <div class="item-label">订单编号</div>
+                    <div class="item-content">{{ FormDataList.id }}</div>
+                </div>
+                <div class="detail-item">
+                    <div class="item-label">订单状态</div>
+                    <div class="item-content">
+                        <a-tag color="#168cff" v-if="FormDataList.tmsStatus == 1">未发货</a-tag>
+                        <a-tag color="#00b42a" v-if="FormDataList.tmsStatus == 2">已发货</a-tag>
+                    </div>
+                </div>
+            </div>
+            <div class="detail-item-box">
+                <div class="detail-item">
+                    <div class="item-label">运营商</div>
+                    <div class="item-content">{{ FormDataList.sourceName }}</div>
+                </div>
+                <div class="detail-item">
+                    <div class="item-label">资费信息</div>
+                    <div class="item-content">{{ TariffInfomr }}</div>
+                </div>
+            </div>
+            <div class="detail-item-box">
+                <div class="detail-item">
+                    <div class="item-label">最短订阅周期</div>
+                    <div class="item-content">{{ tariffForm.settlementCycle?.split('~')[0] }}个月</div>
+                </div>
+                <div class="detail-item">
+                    <div class="item-label">最长订阅周期</div>
+                    <div class="item-content">{{ tariffForm.settlementCycle?.split('~')[1] }}个月</div>
+                </div>
+            </div>
+            <div class="detail-item-box">
+                <div class="detail-item">
+                    <div class="item-label">计费方式</div>
+                    <div class="item-content">{{ tariffForm.billingMethodName }}</div>
+                </div>
+                <div class="detail-item">
+                    <div class="item-label">结算周期</div>
+                    <div class="item-content">{{ tariffForm.billingcycleName }}</div>
+                </div>
+            </div>
+            <div class="detail-item-box">
+                <div class="detail-item">
+                    <div class="item-label">卡类型</div>
+                    <div class="item-content">{{ FormDataList.CardType }}</div>
+                </div>
+                <div class="detail-item">
+                    <div class="item-label">标准价格</div>
+                    <div class="item-content">{{ tariffForm.pricingName }}</div>
+                </div>
+            </div>
+            <div class="detail-item-box">
+                <div class="detail-item">
+                    <div class="item-label">流量池</div>
+                    <div class="item-content">{{ FormDataList.isTrafficPool == 1 ? '是' : '否' }}</div>
+                </div>
+            </div>
+            <div class="detail-item-box">
+                <div class="detail-item">
+                    <div class="item-label">退卡数量</div>
+                    <div class="item-content">{{ dataDetail.length }}
+                    </div>
+                </div>
+            </div>
+        </div>
+        <div class="detail-table">
+            <a-table :columns="columnsDetail" :data="dataDetail" />
+        </div>
+    </a-modal>
+</template>
+
+<script setup>
+import { ref, onMounted, toRefs, toRef ,watch} from 'vue';
+import { AcquireOrdertariff,TariffOrderCard } from '@/api/path/order'
+import { Getdictionary } from '@/mixins/index.js'
+const props = defineProps({
+    modelValue: {
+        type: Boolean,
+        default: false
+    },
+    FormDataList: {
+        type: Object,
+        default: () => ({})
+    }
+})
+const modelValue = toRef(props, 'modelValue')
+const FormDataList = toRef(props, 'FormDataList')
+const emit = defineEmits(['update:modelValue', 'submit'])
+const state = ref({
+    tariffForm: {},
+    res1:[],
+    res2:[],
+    res3:[],
+})
+const { tariffForm,res1,res2,res3 } = toRefs(state.value)
+const columnsDetail = [{ title: 'ICCID', dataIndex: 'iccid' },{ title: '卡状态', dataIndex: 'status' },{ title: '创建时间', dataIndex: 'expireTime' }
+]
+const dataDetail = ref([])
+
+const cancel = () => {
+    emit('update:modelValue', false)
+}
+
+watch(() => FormDataList.value, val => {
+    if (Object.keys(val).length === 0) return
+    AcquireOrdertariff({ id: val.trafficId }).then(res => {
+        tariffForm.value = res.data
+        tariffForm.value.billingcycleName = res1.value.filter(val => val.value == res.data.billingCycle)[0]?.label;
+        tariffForm.value.billingMethodName = res2.value.filter(val => val.value == res.data.billingMethod)[0]?.label;
+        tariffForm.value.TariffInfomr = res.data.trafficBilling + '/' + res.data.trafficBillingType
+        tariffForm.value.pricingName = tariffForm.value.pricing !== '' ? tariffForm.value.pricing + '/' + res3.value.filter(val => val.value == res.data.currency)[0]?.label : '';
+    })
+    TariffOrderCard({id:val.trafficId}).then(res=>{
+        dataDetail.value = res.data
+    })
+},{deep: true})
+
+onMounted(async () => {
+    res1.value = await Getdictionary('Billingcycle')
+    res2.value = await Getdictionary('billingMethod')
+    res3.value = await Getdictionary('currencyType')
+})
+</script>
+<style scoped lang="less">
+.detail-box {
+    .detail-item-box {
+        display: flex;
+        justify-content: space-between;
+        align-items: center;
+        margin-bottom: 10px;
+
+        .detail-item {
+            //styleName: Body/Medium;
+            font-family: PingFang SC;
+            font-size: 14px;
+            font-weight: 400;
+            line-height: 22px;
+            text-align: left;
+            display: flex;
+            align-items: center;
+            min-width: 350px;
+
+            .item-label {
+                color: rgba(0, 0, 0, 0.4);
+                width: 120px;
+                text-align: right;
+                margin-right: 10px;
+            }
+
+            .item-content {
+                color: rgba(51, 51, 51, 1);
+            }
+        }
+    }
+}
+</style>

+ 58 - 280
src/views/order/ReturnCard/index.vue

@@ -3,285 +3,84 @@
   <div class="silent-expire-alarm">
     <!-- 搜索条件区 -->
     <div class="search-section">
-      <a-form :model="searchForm" layout="inline">
-        <a-form-item field="cardNumber" label="订单编号">
-          <a-input v-model="searchForm.orderNumber" placeholder="请输入订单编号" allow-clear/>
-        </a-form-item>
-        <a-form-item field="customerName" label="客户">
-          <a-input v-model="searchForm.customerName" placeholder="请输入客户名称" allow-clear/>
-        </a-form-item>
-        <a-form-item>
-          <a-space>
-            <a-button type="primary" @click="handleSearch">搜索</a-button>
-            <a-button @click="resetSearch">重置</a-button>
-          </a-space>
-        </a-form-item>
-      </a-form>
-    </div>
-    <div class="audit-btn">
-      <a-button @click="openAudit" type="text">
-        <template #icon>
-          <icon-plus-circle/>
-        </template>
-        <template #default>审核</template>
-      </a-button>
+      <Search/>
     </div>
     <!-- 数据表格 -->
     <a-table :columns="columns" :data="tableData" :pagination="pagination" :scroll="{ x: '100%', y: '400px' }">
       <template #detail="{ record }">
         <a-button @click="openDetail(record)" type="text">订单详情</a-button>
       </template>
+      <template #orderStatus="{ record }">
+        <a-tag color="orangered" v-if="record.moderationStatus == 1">待审核</a-tag>
+        <a-tag color="arcoblue" v-if="record.moderationStatus == 2">审核通过</a-tag>
+        <a-tag color="#f53f3f" v-if="record.moderationStatus == 3">已驳回</a-tag>
+      </template>
+      <template #id="{ record }">
+        <div class="line_heis" @click="openDetail(record)">{{ record.id }}</div>
+      </template>
+      <template #operate="{ record }">
+        <a-button type="primary" @click="showAudit = true" v-if="record.moderationStatus==1 && record.status==2">审核</a-button>
+      </template>
     </a-table>
-    <a-modal v-model:visible="showAudit" title="审核" @cancel="showAudit = false" @before-ok="submitAudit"
-             okText="确定审核"
-             cancelText="关闭">
-      <a-form :model="formAudit" auto-label-width>
-        <a-form-item field="customerName" label="客户">
-          <!-- <a-input v-model="formAudit.customerName" placeholder="请输入客户" /> -->
-          <div class="audit-txt" style="color:#418035;">演示账号02</div>
-        </a-form-item>
-        <a-form-item field="cardType" label="卡类型">
-          <!-- <a-input v-model="formAudit.cardType" placeholder="请输入单号" /> -->
-          <div class="audit-txt">普通卡切卡普通卡MP1,1元/涨
-            <div class="audit-tag">共1张卡</div>
-          </div>
-        </a-form-item>
-        <a-form-item field="money" label="资费">
-          <!-- <a-input v-model="formAudit.money" placeholder="请输入单号" /> -->
-          <div class="audit-txt">“移动100M月包”
-            <div class="audit-tag">订购12个月</div>
-          </div>
-        </a-form-item>
-        <a-form-item field="orderStatus" label="订单状态">
-          <!-- <a-input v-model="formAudit.orderStatus" placeholder="请输入单号" /> -->
-          <a-radio-group v-model="formAudit.orderStatus" :options="options"/>
-        </a-form-item>
-        <a-form-item field="auditOpinion" label="审核意见">
-          <!-- <a-input v-model="formAudit.auditOpinion" placeholder="请输入单号" /> -->
-          <a-textarea placeholder="您填写的审核意见会直接投送给用户,请认真填写!" v-model="formAudit.auditOpinion"
-                      allow-clear/>
-        </a-form-item>
-        <a-form-item field="fileList" label="销售合同">
-          <a-upload action="/" :default-file-list="formAudit.fileList"/>
-        </a-form-item>
-      </a-form>
-    </a-modal>
-    <a-modal v-model:visible="showDetail" width="800px" title="退卡详情" :hide-cancel="true" @cancel="detailCancel">
-      <div class="detail-box">
-        <div class="detail-item-box">
-          <div class="detail-item">
-            <div class="item-label">订单编号</div>
-            <div class="item-content">53357981207</div>
-          </div>
-          <div class="detail-item">
-            <div class="item-label">订单状态</div>
-            <div class="item-content">已审核</div>
-          </div>
-        </div>
-        <div class="detail-item-box">
-          <div class="detail-item">
-            <div class="item-label">运营商</div>
-            <div class="item-content">泰国AIS</div>
-          </div>
-          <div class="detail-item">
-            <div class="item-label">资费信息</div>
-            <div class="item-content">1.0G/月</div>
-          </div>
-        </div>
-        <div class="detail-item-box">
-          <div class="detail-item">
-            <div class="item-label">最短订阅周期</div>
-            <div class="item-content">3个月</div>
-          </div>
-          <div class="detail-item">
-            <div class="item-label">剩余时长</div>
-            <div class="item-content">2个月</div>
-          </div>
-        </div>
-        <div class="detail-item-box">
-          <div class="detail-item">
-            <div class="item-label">计费方式</div>
-            <div class="item-content">按单流量消耗计费</div>
-          </div>
-          <div class="detail-item">
-            <div class="item-label">结算周期</div>
-            <div class="item-content">月</div>
-          </div>
-        </div>
-        <div class="detail-item-box">
-          <div class="detail-item">
-            <div class="item-label">流量资费计费</div>
-            <div class="item-content">0.8美金/G;MRC:0元;网络接入0元</div>
-          </div>
-        </div>
-        <div class="detail-item-box">
-          <div class="detail-item">
-            <div class="item-label">卡类型</div>
-            <div class="item-content">工业级PlugIn</div>
-          </div>
-          <div class="detail-item">
-            <div class="item-label">卡板费</div>
-            <div class="item-content">1美金</div>
-          </div>
-        </div>
-        <div class="detail-item-box">
-          <div class="detail-item">
-            <div class="item-label">流量池</div>
-            <div class="item-content">组池</div>
-          </div>
-          <div class="detail-item">
-            <div class="item-label">沉默期</div>
-            <div class="item-content">6个月</div>
-          </div>
-        </div>
-        <div class="detail-item-box">
-          <div class="detail-item">
-            <div class="item-label">退卡数量</div>
-            <div class="item-content">50
-            </div>
-          </div>
-        </div>
-      </div>
-      <div class="detail-table">
-        <a-table :columns="columnsDetail" :data="dataDetail"/>
-      </div>
-    </a-modal>
+
+
+    <Status v-model:modelValue="showAudit" @submit="intData()" />
+    <<Detaile v-model:modelValue="showDetail" @submit="intData()" :FormDataList="FormDataList" />
   </div>
 </template>
 
 <script setup>
-import {ref, reactive, onMounted} from 'vue';
-import {Message} from '@arco-design/web-vue';
-import {cancelOrderList} from '@/api/path/purchase';
-import {enum_dict} from "@/hooks/enum";
-import {Getdictionary} from "@/mixins/index.js";
+import { ref, reactive, onMounted, toRefs } from 'vue';
+import { Message } from '@arco-design/web-vue';
+import { cancelOrderList } from '@/api/path/purchase';
+import { enum_dict } from "@/hooks/enum";
+import { Getdictionary } from "@/mixins/index.js";
+import Status from './status.vue'
+import Search from '@/components/Search/index.vue'
+const state = ref({
+  searchForm: {
+    cardNumber: '',
+    customerName: '',
+  },
+  tableData: [],
+  pagination: {
+    total: 0,
+    current: 1,
+    size: 10,
+  },
+  showDetail: false,
+  showAudit: false,
+  FormDataList: {}
+})
 
-const selectedKeys = ref([]);
-const rowSelection = reactive({
-  type: 'checkbox',
-  showCheckedAll: true,
-  onlyCurrent: false,
-});
-const searchForm = reactive({
-  cardNumber: '',
-  customerName: '',
-});
+const { searchForm, tableData, pagination, showDetail, showAudit, FormDataList } = toRefs(state.value)
 
 const columns = [
-  {title: '序号', dataIndex: 'index', align: 'center', render: ({rowIndex}) => rowIndex + 1},
+  { title: '序号', dataIndex: 'index', align: 'center', render: ({ rowIndex }) => rowIndex + 1 },
   {
-    title: '订单ID', dataIndex: 'source_order_id', ellipsis: true,
+    title: '订单编号', slotName: 'id', ellipsis: true,
     tooltip: true,
-    width: 200
   },
   {
-    title: '资费ID', dataIndex: 'tariff_id', ellipsis: true,
+    title: '客户名称', dataIndex: 'userName', ellipsis: true,
     tooltip: true,
-    width: 100
   },
-  {title: '订单审核状态', dataIndex: 'moderationStatusName'},
-  {title: '订阅关系状态', dataIndex: 'statusName'},
-  {title: '卡类型', dataIndex: 'cardTypeName'},
+  { title: '订单状态', slotName: 'orderStatus', ellipsis: true },
   {
     title: '供应商名称', dataIndex: 'sourceName', ellipsis: true,
     tooltip: true,
-    width: 150
   },
-  {title: '退卡张数', dataIndex: 'quantity'},
-  {title: '剩余时长', dataIndex: 'period_of_silence'},
-  {title: '返回金额', dataIndex: 'payment_amount'},
+  { title: '退卡张数', dataIndex: 'quantity', ellipsis: true },
+  { title: '剩余时长', dataIndex: 'period_of_silence', ellipsis: true },
+  { title: '退回金额', dataIndex: 'payment_amount', ellipsis: true },
+  { title: '操作', slotName: 'operate', align: 'center', ellipsis: true }
 ];
-const columnsDetail = [{title: 'ICCID', dataIndex: 'iccid'},
-  {title: '池名称及编号', dataIndex: 'nameAndId'},
-  {title: '卡状态', dataIndex: 'status'},
-]
-const dataDetail = ref([{
-  iccid: '8986061800002054589N',
-  nameAndId: '泰国监控40G共享/53357981207',
-  status: '沉默期'
-},
-  {
-    iccid: '8986061800002054588N',
-    nameAndId: '泰国监控40G共享/53357981207',
-    status: '沉默期'
-  }, {
-    iccid: '8986061800002054587N',
-    nameAndId: '泰国监控40G共享/53357981207',
-    status: '沉默期'
-  }, {
-    iccid: '8986061800002054586N',
-    nameAndId: '泰国监控40G共享/53357981207',
-    status: '沉默期'
-  },])
-const tableData = ref([
-  {
-    cardNumber: '13800138000',
-    customerName: '张三',
-    orderStatus: '1',
-    cardQuantity: 24,
-    money: '100',
-    outTime: '11',
-    returnMoney: '11美元',
-    orderTime: '2024-10-11'
-    // operate:'上传合同'
-  },
-  {
-    cardNumber: '13800138000',
-    customerName: '李四',
-    orderStatus: '1',
-    cardQuantity: 24,
-    money: '100',
-    outTime: '11',
-    returnMoney: '11美元',
-    orderTime: '2024-10-11'
-    // operate:'上传合同'
-  }, {
-    cardNumber: '13800138000',
-    customerName: '王五',
-    orderStatus: '1',
-    cardQuantity: 24,
-    money: '100',
-    outTime: '11',
-    returnMoney: '11美元',
-    orderTime: '2024-10-11'
-    // operate:'上传合同'
-  }, {
-    cardNumber: '13800138000',
-    customerName: '赵六',
-    orderStatus: '1',
-    cardQuantity: 24,
-    money: '100',
-    outTime: '11',
-    returnMoney: '11美元',
-    orderTime: '2024-10-11'
-    // operate:'上传合同'
-  }, {
-    cardNumber: '13800138000',
-    customerName: '田七',
-    orderStatus: '1',
-    cardQuantity: 24,
-    money: '100',
-    outTime: '11',
-    returnMoney: '11美元',
-    orderTime: '2024-10-11'
-    // operate:'上传合同'
-  },
 
-]);
-const pagination = ref({
-  total: 0,
-  current: 1,
-  pageSize: 10,
-});
-//订单详情的弹框
-const showDetail = ref(false);
 // 查看订单详情
 const openDetail = (item) => {
   showDetail.value = true;
+  FormDataList.value = item;
 }
-const handleSearch = () => {
-  intData()
-};
 
 const resetSearch = () => {
   Object.keys(searchForm).forEach(key => {
@@ -294,35 +93,6 @@ const resetSearch = () => {
   });
   Message.success('搜索条件已重置');
 };
-// 订单状态
-const options = [
-  {label: '发货', value: '1'},
-  {label: '退回', value: '2'},
-];
-// 审核
-const showAudit = ref(false);
-const formAudit = reactive({
-  customerName: '',
-  cardType: '',
-  money: '',
-  orderStatus: '',
-  auditOpinion: '',
-  fileList: []
-})
-// 触发审核的弹框
-const openAudit = () => {
-  showAudit.value = true;
-}
-// 确认审核
-const submitAudit = () => {
-  console.log(formAudit, 'lll')
-  window.setTimeout(() => {
-    showAudit.value = false;
-  }, 1000)
-}
-const detailCancel = () => {
-}
-
 
 // 列表-------------------------------------
 // 订单列表
@@ -357,8 +127,6 @@ const intData = async () => {
 }
 onMounted(() => {
   intData();
-  // userName.value = localStorage.getItem('remember_user_name');
-  // userType.value = localStorage.getItem('role');
 })
 </script>
 
@@ -434,4 +202,14 @@ onMounted(() => {
 .detail-table {
   margin-top: 20px;
 }
+
+.line_heis {
+  color: #FF8839;
+  cursor: pointer;
+  display: inline-block;
+}
+
+.line_heis:hover {
+  color: #168cff;
+}
 </style>

+ 81 - 0
src/views/order/ReturnCard/status.vue

@@ -0,0 +1,81 @@
+<template>
+    <div class="">
+        <a-modal v-model:visible="modelValue" title="审核" @cancel="cancel" @before-ok="submitAudit" okText="确定审核"
+            cancelText="关闭">
+            <a-form :model="formAudit" auto-label-width>
+                <a-form-item field="customerName" label="客户">
+                    <!-- <a-input v-model="formAudit.customerName" placeholder="请输入客户" /> -->
+                    <div class="audit-txt" style="color:#418035;">演示账号02</div>
+                </a-form-item>
+                <a-form-item field="cardType" label="卡类型">
+                    <!-- <a-input v-model="formAudit.cardType" placeholder="请输入单号" /> -->
+                    <div class="audit-txt">普通卡切卡普通卡MP1,1元/涨
+                        <div class="audit-tag">共1张卡</div>
+                    </div>
+                </a-form-item>
+                <a-form-item field="money" label="资费">
+                    <!-- <a-input v-model="formAudit.money" placeholder="请输入单号" /> -->
+                    <div class="audit-txt">“移动100M月包”
+                        <div class="audit-tag">订购12个月</div>
+                    </div>
+                </a-form-item>
+                <a-form-item field="orderStatus" label="订单状态">
+                    <!-- <a-input v-model="formAudit.orderStatus" placeholder="请输入单号" /> -->
+                    <a-radio-group v-model="formAudit.orderStatus" :options="options" />
+                </a-form-item>
+                <a-form-item field="auditOpinion" label="审核意见">
+                    <!-- <a-input v-model="formAudit.auditOpinion" placeholder="请输入单号" /> -->
+                    <a-textarea placeholder="您填写的审核意见会直接投送给用户,请认真填写!" v-model="formAudit.auditOpinion" allow-clear />
+                </a-form-item>
+                <a-form-item field="fileList" label="销售合同">
+                    <a-upload action="/" :default-file-list="formAudit.fileList" />
+                </a-form-item>
+            </a-form>
+        </a-modal>
+    </div>
+</template>
+
+<script setup>
+import { ref, onMounted, toRefs, toRef, watch } from 'vue';
+const props = defineProps({
+    modelValue: {
+        type: Boolean,
+        default: false
+    },
+    FormDataList: {
+        type: Object,
+        default: () => ({})
+    }
+})
+const modelValue = toRef(props, 'modelValue')
+const FormDataList = toRef(props, 'FormDataList')
+const emit = defineEmits(['update:modelValue', 'submit'])
+
+const state = ref({
+    options: [
+        { label: '发货', value: '1' },
+        { label: '退回', value: '2' },
+    ],
+    formAudit: {
+        customerName: '',
+        cardType: '',
+        money: '',
+        orderStatus: '',
+        auditOpinion: '',
+        fileList: []
+    },
+    
+})
+
+const { options, formAudit } = toRefs(state.value)
+
+const cancel = () => {
+    emit('update:modelValue', false)
+}
+
+// 确认审核
+const submitAudit = () => {
+   emit('submit',true)
+}
+</script>
+<style scoped></style>

+ 55 - 70
src/views/system/dict/index.vue

@@ -3,43 +3,48 @@
     <div class="head-title">
       <span> 字典管理 </span>
       <div class="form-row">
-        <a-input v-model="formData.typeLabel" style="margin: 0 0.6rem" placeholder="请输入字典名称" />
-        <a-input v-model="formData.typeKey" style="margin: 0 0.6rem" placeholder="请输入字典类型" />
+        <a-input v-model="formData.typeLabel" style="margin: 0 0.6rem" placeholder="请输入字典名称"/>
+        <a-input v-model="formData.typeKey" style="margin: 0 0.6rem" placeholder="请输入字典类型"/>
         <a-button type="primary" style="margin: 0 0.6rem" @click="intData">查询</a-button>
         <a-button style="margin: 0 0.6rem 0 0" @click="resetSelectData">重置</a-button>
         <a-button type="primary" @click="dictShowModel(1, null)">添加字典</a-button>
       </div>
     </div>
 
-    <a-table :data="dataSource" row-key="typeKey" :columns="columns" :scroll="{ x: 'auto' }" :pagination="pageData"
-      @page-change="evChangePage" @expanded-change="expandTableIds">
+    <a-table :data="dataSource" row-key="typeKey" :columns="columns" :scroll="{ x: 'auto' }" :pagination="false">
       <template #operation="{ record }">
-        <a class="a-link" href="javascript:;" style="margin: 0 1rem;" @click="dictShowModel(2, record)">修改</a>
-        <a-popconfirm :content="`是否确认删除字典编号为 ${record.id} 的数据项?`" @ok="deleteChange(record.id)" type="warning">
-          <a class="a-link" href="javascript:;" style="color: red;">删除</a>
+        <a class="a-link" href="javascript:;" style="margin: 0 0.4rem;" @click="dictShowModel(2, record)"
+           v-if="!record.typeKey">修改</a>
+        <a class="a-link" href="javascript:;" style="margin: 0 0.4rem;" @click="dictShowModel(3, record)"
+           v-if="record.typeKey">添加</a>
+
+        <a-popconfirm :content="`是否确认删除字典编号为 ${record.id} 的数据项?`" @ok="deleteChange(record.id)"
+                      type="warning">
+          <a class="a-link" href="javascript:;" style="color: red;margin: 0 0.4rem;">删除</a>
         </a-popconfirm>
 
       </template>
     </a-table>
 
     <!-- 弹框 -->
-    <a-modal :title="typeCurrent == 1 ? '添加字典' : '修改字典'" v-model:visible="visible" @onCancel="resetForm" centered
-      :maskClosable="false" :footer="null">
+    <a-modal :title="typeCurrent !== 2 ? '添加字典' : '修改字典'" v-model:visible="visible" @onCancel="resetForm"
+             centered
+             :maskClosable="false" :footer="null">
       <a-form ref="formRef" :rules="rules" :model="formState" @submit="handleSubmit">
-        <a-form-item label="字典名称" field="typeLabel">
-          <a-input v-model="formState.typeLabel" />
+        <a-form-item label="标签名称" field="typeLabel" v-if="typeCurrent == 1">
+          <a-input v-model="formState.typeLabel"/>
         </a-form-item>
-        <a-form-item label="字典类型" field="typeKey">
-          <a-input v-model="formState.typeKey" />
+        <a-form-item label="标签类型" field="typeKey" v-if="typeCurrent == 1">
+          <a-input v-model="formState.typeKey"/>
         </a-form-item>
-        <a-form-item label="数据标签" field="label">
-          <a-input v-model="formState.label" />
+        <a-form-item label="字典名称" field="label">
+          <a-input v-model="formState.label"/>
         </a-form-item>
         <a-form-item label="数据键值" field="value">
-          <a-input v-model="formState.value" />
+          <a-input v-model="formState.value"/>
         </a-form-item>
         <a-form-item label="备注" field="remark">
-          <a-textarea v-model="formState.remark" />
+          <a-textarea v-model="formState.remark"/>
         </a-form-item>
         <a-form-item>
           <a-button type="primary" html-type="submit" style="margin-right: 10px;">确定</a-button>
@@ -51,8 +56,8 @@
 </template>
 
 <script setup>
-import { onMounted, ref, reactive } from "vue";
-import { dictionaryList, dictionaryAdd, dictionaryDelete, dictionaryUpdate, dictionaryDeleteAll } from '@/api/path/dict';
+import {onMounted, ref, reactive, h} from "vue";
+import {dictionaryList, dictionaryAdd, dictionaryDelete, dictionaryUpdate, dictionaryDeleteAll} from '@/api/path/dict';
 
 const visible = ref(false);
 const typeCurrent = ref(null);
@@ -63,18 +68,10 @@ const formData = ref({
   typeLabel: '',
 });
 const columns = ref([
-
-  // {title: '数据标签', dataIndex: 'label', align: 'center', width: 120},
-  { title: '字典名称', dataIndex: 'typeLabel', align: 'center', width: 120 },
-  { title: '字典类型', dataIndex: 'typeKey', align: 'center', width: 150 },
-  { title: '数据键值', dataIndex: 'value', align: 'center', width: 120 },
-  // {
-  //   title: '备注',
-  //   dataIndex: 'remark',
-  //   align: 'center',
-  //   width: 180
-  // },
-  // {title: '创建时间', dataIndex: 'created_at', align: 'center', width: 200},
+  {title: '标签名称', dataIndex: 'typeLabel', align: 'center', width: 120},
+  {title: '标签类型', dataIndex: 'typeKey', align: 'center', width: 150},
+  {title: '字典名称', dataIndex: 'label', align: 'center', width: 120},
+  {title: '数据键值', dataIndex: 'value', align: 'center', width: 120},
   {
     title: '操作',
     dataIndex: 'id',
@@ -85,7 +82,7 @@ const columns = ref([
   }
 ])
 const rules = {
-  label: [{ required: true, trigger: 'change', }],
+  label: [{required: true, trigger: 'change',}],
   value: [
     {
       required: true,
@@ -113,11 +110,11 @@ const rules = {
 };
 
 const formState = reactive({
-  // label: '',
+  label: '',
   value: '',
   typeKey: '',
   typeLabel: '',
-  // remark: '',
+  remark: '',
 });
 
 const pageData = ref({
@@ -135,24 +132,21 @@ const intData = async () => {
     ...formData.value
   }
   const res = await dictionaryList(param)
-  dataSource.value = res.data.map(res => ({
-    ...res,
-    children: []
-  }))
+  dataSource.value = res.data
   pageData.value.total = res.total;
-  
+
 }
 // 提交
-const handleSubmit = async ({ values, errors }) => {
+const handleSubmit = async ({values, errors}) => {
   const submitData = {
     label: formState.label,
     value: formState.value,
     typeKey: formState.typeKey,
     typeLabel: formState.typeLabel,
     remark: formState.remark,
-    id: typeCurrent.value == 1 ? undefined : dicId.value
+    id: typeCurrent.value !== 2 ? undefined : dicId.value
   }
-  let res = typeCurrent.value === 1 ? await dictionaryAdd(submitData) : await dictionaryUpdate(submitData)
+  let res = typeCurrent.value !== 2 ? await dictionaryAdd(submitData) : await dictionaryUpdate(submitData)
   if (res.code === 200) {
     intData();
     resetForm();
@@ -160,7 +154,7 @@ const handleSubmit = async ({ values, errors }) => {
 }
 // 删除
 const deleteChange = (e) => {
-  dictionaryDelete({ id: e }).then(res => {
+  dictionaryDelete({id: e}).then(res => {
     intData();
   })
 }
@@ -168,15 +162,27 @@ const deleteChange = (e) => {
 const dictShowModel = (type, data) => {
   typeCurrent.value = type;
   visible.value = true;
+  console.log(type)
   if (type == 2) {
-    dicId.value = data.id;
-    formState.label = data.label;
-    formState.value = data.value;
-    formState.typeKey = data.typeKey;
-    formState.typeLabel = data.typeLabel;
-    formState.remark = data.remark;
+    dataSource.value.forEach(res => {
+      res.children.forEach(val => {
+        if (val.id == data.id) {
+          dicId.value = data.id
+          formState.typeKey = res.typeKey
+          formState.typeLabel = res.typeLabel
+          formState.remark = res.remark
+          formState.value = data.value
+          formState.label = data.label
+        }
+      })
+    })
+  } else if (type == 3) {
+    formState.typeKey = data.typeKey
+    formState.typeLabel = data.typeLabel
   }
+
 }
+
 // 取消
 const resetForm = () => {
   visible.value = false;
@@ -191,11 +197,6 @@ const resetForm = () => {
   });
 }
 
-const evChangePage = (page) => {
-  pageData.value.current = page
-  intData()
-}
-
 // 重置
 const resetSelectData = () => {
   formData.value.typeKey = "";
@@ -203,22 +204,6 @@ const resetSelectData = () => {
   intData();
 }
 
-const expandTableIds = async (e) => {
-  if (e.length === 0) return
-  let res = await dictionaryDeleteAll({ typeKey: e[0] });
-  if (res.code === 200) {
-    dataSource.value.forEach((item) => {
-      // 检查 item.typeKey 是否包含 e 中的任意一个值
-      if (e.some((key) => item.typeKey.includes(key))) {
-        // 判断 children 是否为空,为空则添加数据
-        if (item.children.length === 0) {
-          item.children = [...res.data];
-        }
-      }
-    });
-  }
-};
-
 
 onMounted(() => {
   intData();

+ 349 - 0
src/views/tariffManagement/Management/add.vue

@@ -0,0 +1,349 @@
+<template>
+    <!--资费 弹框 -->
+    <a-modal :title="typeIndex == 1 ? $t('form.Add') : $t('form.Edit')" v-model:visible="modelValue"
+        @onCancel="resetForm" centered :maskClosable="false" :footer="null" width="700px">
+        <a-form ref="formRef" :rules="rules" :model="formState" @submit="handleSubmit">
+            <div class="formTitle">基本信息</div>
+            <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="simDataPlanId">
+                    <a-select v-model="formState.simDataPlanId">
+                        <a-option v-for=" (item, index) in planList" :key="item.id" :value="item.id"> 流量包{{
+                            item.productName
+                        }}
+                        </a-option>
+                    </a-select>
+                </a-form-item>
+            </template>
+            <a-form-item :label="$t('tariffManagement.label')" field="label">
+                <a-input v-model="formState.label" />
+            </a-form-item>
+            <a-form-item :label="$t('tariffManagement.userId')" field="userId">
+                <a-select v-model="formState.userId">
+                    <a-option v-for=" item in userIdList" :key="item.id" :value="item.id">{{
+                        item.name
+                    }}
+                    </a-option>
+                </a-select>
+            </a-form-item>
+            <a-form-item :label="$t('tariffManagement.billingMethod')" field="billingMethod">
+                <a-select v-model="formState.billingMethod">
+                    <a-option v-for=" item in methodList" :key="item.id" :value="item.value">{{
+                        item.label
+                    }}
+                    </a-option>
+                </a-select>
+            </a-form-item>
+            <a-form-item :label="$t('tariffManagement.currency')" field="currency">
+                <a-select v-model="formState.currency">
+                    <a-option v-for=" item in currency" :key="item.id" :value="item.value">{{
+                        item.label
+                    }}
+                    </a-option>
+                </a-select>
+            </a-form-item>
+            <div class="formTitle">计费信息</div>
+            <a-form-item field="billingCycle" :label="$t('tariffManagement.billingCycle')" required>
+                <a-radio-group v-model="formState.billingCycle" :options="billingCycleData">
+                </a-radio-group>
+            </a-form-item>
+            <a-form-item field="" :label="$t('tariffManagement.pricing')" required>
+                <a-input v-model="formState.pricing" v-if="formState.billingMethod == 2">
+                    <template #append>
+                        {{ formState.currency === '0' ? '元' : '美金' }}
+                    </template>
+                </a-input>
+                <a-input v-model="formState.trafficBilling" v-if="formState.billingMethod == 1"></a-input>
+                <a-select v-model="formState.trafficBillingType" style="width: 80px; margin:0 8px;"
+                    v-if="formState.billingMethod == 1">
+                    <a-option value="KB">KB</a-option>
+                    <a-option value="MB">MB</a-option>
+                    <a-option value="GB">GB</a-option>
+                </a-select>
+                <a-input v-model="formState.trafficBillingAmount" v-if="formState.billingMethod == 1">
+                    <template #append>
+                        {{ formState.currency === '0' ? '元' : '美金' }}
+                    </template>
+                </a-input>
+            </a-form-item>
+            <a-form-item field="settlementCycle" :label="$t('tariffManagement.cycleBuy')">
+                <a-input v-model="formState.settlementCycleMap.starTime">
+                    <template #prepend>
+                        最短
+                    </template>
+                    <template #append>
+                        个月,最长
+                    </template>
+                </a-input>
+                <a-input v-model="formState.settlementCycleMap.endTime" style="width: 50%;">
+                    <template #append>
+                        个月
+                    </template>
+                </a-input>
+            </a-form-item>
+            <a-form-item :label="$t('tariffManagement.MRCName')" field="mrcAmount">
+                <a-input v-model="formState.mrcAmount">
+                    <template #append>
+                        {{ formState.currency === '0' ? '元' : '美金' }}
+                    </template>
+                </a-input>
+            </a-form-item>
+            <a-form-item :label="$t('tariffManagement.networkName')" field="networkAccessFee">
+                <a-input v-model="formState.networkAccessFee">
+                    <template #append>
+                        {{ formState.currency === '0' ? '元' : '美金' }}
+                    </template>
+                </a-input>
+            </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-modal>
+</template>
+
+<script setup>
+import { ref, onMounted, toRefs, toRef, watch } from 'vue';
+import { getDataPlanList } from "@/api/path/lotCard.api"
+import { getSTSInfoList } from '@/api/path/system.api'
+import { updateTariff, addTariff } from "@/api/path/tariffManagement.api"
+import { Getdictionary } from '@/mixins/index.js'
+import { Message } from '@arco-design/web-vue'
+
+const props = defineProps({
+    modelValue: {
+        type: Boolean,
+        default: false
+    },
+    typeIndex: {
+        type: Number,
+        default: null
+    },
+    FormDataList: {
+        type: Object,
+        default: () => { }
+    }
+})
+
+const modelValue = toRef(props, 'modelValue')
+const typeIndex = toRef(props, 'typeIndex')
+const FormDataList = toRef(props, 'FormDataList')
+const emit = defineEmits(['update:modelValue', 'submit'])
+
+const state = ref({
+    formState: {
+        // 资费名称(必填)
+        "label": "",
+        // 流量包ID(必填)
+        "simDataPlanId": null,
+        // 用户ID(必填)
+        "userId": null,
+        // 来源(必填)
+        "source": "",
+        // 计费周期(必填)
+        "billingCycle": "",
+        // 计费方式(必填)
+        "billingMethod": "1",
+        // 结算周期(必填)
+        "settlementCycle": "",
+        // 价格(必填)
+        "pricing": "",
+        // 币种(必填)
+        "currency": "0",
+        // 流量资费计费
+        "trafficBilling": '',
+        // 流量资费计费类型
+        "trafficBillingType": '',
+        // 流量资费计费金
+        "trafficBillingAmount": '',
+        // MRC金额
+        "mrcAmount": '',
+        // 网络接入费
+        "networkAccessFee": '',
+
+        "settlementCycleMap": {
+            "starTime": '',
+            "endTime": ''
+        }
+    },
+    sourceList: [],
+    userIdList: [],
+    methodList: [],
+    currency: [],
+    billingCycleData: [],
+    planList: [],
+    formRef: null
+
+})
+
+const { formState, sourceList, userIdList, methodList, currency, billingCycleData, planList, formRef } = toRefs(state.value)
+
+const rules = {
+    label: [{ required: true, trigger: 'change', }],
+    simDataPlanId: [{ required: true, trigger: 'change', }],
+    userId: [{ required: true, trigger: 'change', }],
+    source: [{ required: true, trigger: 'change', }],
+    billingCycle: [{ required: true, trigger: 'change', }],
+    billingMethod: [{ required: true, trigger: 'change', }],
+    currency: [{ required: true, trigger: 'change', }],
+    trafficBilling: [{ required: true, trigger: 'change', }],
+    trafficBillingType: [{ required: true, trigger: 'change', }],
+    trafficBillingAmount: [{ required: true, trigger: 'change', }],
+    mrcAmount: [{ required: true, trigger: 'change', }],
+    networkAccessFee: [{ required: true, trigger: 'change', }],
+};
+
+
+// 提交
+const handleSubmit = ({ values, errors }) => {
+    formRef.value.validate(async (errors) => {
+        if (!errors) {
+            const formVal = JSON.parse(JSON.stringify(values))
+            delete formVal.settlementCycleMap
+            formVal.userId = Number(values.userId)
+            formVal.simDataPlanId = String(values.simDataPlanId)
+            formVal.simDataPlanId = String(values.simDataPlanId)
+            formVal.pricing = Number(values.pricing)
+            if (values.settlementCycleMap.starTime && values.settlementCycleMap.starTime) {
+                formVal.settlementCycle = values.settlementCycleMap.starTime + '~' + values.settlementCycleMap.endTime
+            } else {
+                Message.warning({
+                    content: "请选择订购周期!",
+                    duration: 2000,
+                })
+            }
+
+            if (typeIndex.value === 2) {
+                const { code, data } = await updateTariff(formVal)
+
+                if (code == 200) {
+                    Message.success({
+                        content: "修改成功!",
+                        duration: 2000,
+                    })
+                    emit('update:modelValue', false)
+                    emit('submit', true)
+                    resetForm()
+                }
+            } else {
+                const { code, data } = await addTariff(formVal)
+                if (code == 200) {
+                    Message.success({
+                        content: "添加成功!",
+                        duration: 2000,
+                    })
+                    emit('update:modelValue', false)
+                    emit('submit', true)
+                    resetForm()
+                }
+            }
+        }
+    });
+}
+
+// 取消
+const resetForm = () => {
+    emit('update:modelValue', false)
+    Object.keys(formState.value).forEach(key => {
+        formState.value[key] = ''
+    })
+    delete formState.value.id
+    formState.value.settlementCycleMap = {
+        starTime: '',
+        endTime: ''
+    }
+    FormDataList.value = {}
+}
+
+const handleDataPlan = async () => {
+    const param = {
+        current: 1,
+        size: 999,
+        source: formState.value.source
+    }
+    getDataPlanList(param).then(res => {
+        planList.value = res.data.records || []
+    })
+}
+
+// 获取id数组
+const handleModelId = async () => {
+    const param = {
+        current: 1,
+        size: 999,
+    }
+    getSTSInfoList(param).then(res => {
+        userIdList.value = (res.data.records || [])
+    })
+}
+
+const handleDictValue = async () => {
+    sourceList.value = await Getdictionary('source')
+    methodList.value = await Getdictionary('billingMethod')
+    currency.value = await Getdictionary('currencyType')
+    billingCycleData.value = await Getdictionary('Billingcycle')
+}
+
+watch(() => modelValue.value, val => {
+    if (val) {
+        handleDictValue()
+        handleModelId()
+    }
+})
+
+watch(() => formState.value.billingMethod, val => {
+    if (val == 2) {
+        formState.value.trafficBillingType = ''
+        formState.value.trafficBilling = ''
+        formState.value.trafficBillingAmount = ''
+    }else{
+        formState.value.pricing = ''
+    }
+})
+
+watch(
+    () => formState.value.source,
+    (newValue, oldValue) => {
+
+        if (newValue != oldValue) {
+            handleDataPlan()
+        }
+    },
+    { immediate: true }
+);
+
+
+watch(() => FormDataList.value, val => {
+    if (!val.id) return
+    if (formState.value.settlementCycleMap) {
+        formState.value.settlementCycleMap.starTime = ''
+        formState.value.settlementCycleMap.endTime = ''
+    }
+    Object.keys(formState.value).forEach(key => {
+        if (val[key]) {
+            formState.value[key] = val[key]
+        }
+    })
+    formState.value.userId = Number(formState.value.userId)
+    // if (val.pricing !== '') {
+    //     formState.value.pricing = val.pricing.match(/\d+/)[0] || ''
+    // }
+    if (val.settlementCycle) {
+        formState.value.settlementCycleMap.starTime = val.settlementCycle.split('~')[0] || ''
+        formState.value.settlementCycleMap.endTime = val.settlementCycle.split('~')[1] || ''
+    }
+    formState.value.id = val.id
+},{deep:true})
+</script>
+<style scoped></style>

+ 172 - 0
src/views/tariffManagement/Management/meal.vue

@@ -0,0 +1,172 @@
+<template>
+    <a-modal width="55%" v-model:visible="modelValue" @ok="handleOk" @cancel="handleCancel" title="套餐">
+        <div class="add"><a-button type="primary" @click="addMeal" v-if="role.getRole == 1">添加套餐</a-button></div>
+        <div class="item_warp">
+            <a-table :columns="columns" :data="wanberFloter" style="margin-top: 20px" :pagination="false"
+                :scroll="{ y: 'auto' }">
+                <template #period="{ record, rowIndex }">
+                    <a-input v-model="record.period" :disabled="role.getRole !== 1" />
+                </template>
+                <template #price="{ record, rowIndex }">
+                    <a-input v-model="record.price" />
+                </template>
+                <template #currency="{ record, rowIndex }">
+                    <a-select v-model="record.currency" :style="{ width: '300px' }" placeholder="请选择币种"
+                        :disabled="role.getRole !== 1">
+                        <a-option v-for="res of Pricing" :value="res.value" :label="res.label" />
+                    </a-select>
+                </template>
+                <template #label="{ record, rowIndex }">
+                    <a-input v-model="record.label" v-if="role.getRole !== 1" />
+                </template>
+                <template #setting="{ record }">
+                    <a class="a-link" href="javascript:;" style="margin-right: 1rem" @click="addUpate(record)">{{
+                        record.id == '' ? '添加' : '修改' }}</a>
+                    <a-popconfirm :content="$t('form.Delete')" :ok-text="$t('form.Confirm')"
+                        :cancel-text="$t('form.Cancel')" @ok="deletaMeal(record.id)">
+                        <a class="a-link" href="javascript:;" v-if="role.getRole == 1">{{
+                            $t('form.Delete')
+                        }}</a>
+                    </a-popconfirm>
+                </template>
+            </a-table>
+        </div>
+    </a-modal>
+</template>
+
+<script setup>
+import { ref, onMounted, toRefs, toRef, watch } from 'vue';
+import { Getdictionary } from '@/mixins/index.js'
+import { useSystemStore } from '@/store/modules/systemStore'
+import { Message } from '@arco-design/web-vue'
+import { addTariffPackage, CheckTariffPackages, UpdateTariffTtems, DeleteTariffItems } from '@/api/path/tariffManagement.api'
+const props = defineProps({
+    modelValue: {
+        type: Boolean,
+        default: false
+    },
+    traffIds: {
+        type: [String, Number],
+        default: undefined
+    }
+})
+const role = useSystemStore()
+const modelValue = toRef(props, 'modelValue')
+const traffIds = toRef(props, 'traffIds')
+const indexSet = ref(0)
+
+const emit = defineEmits(['update:modelValue', 'submit'])
+const columns = [{
+    title: '套餐期限(月)',
+    dataIndex: 'period',
+    slotName: 'period',
+    ellipsis: true,
+    align: 'center',
+}, {
+    title: '套餐价格',
+    dataIndex: 'price',
+    slotName: 'price',
+    ellipsis: true,
+    align: 'center',
+}, {
+    title: '币种',
+    dataIndex: 'currency',
+    slotName: 'currency',
+    ellipsis: true,
+    align: 'center',
+}, {
+    title: '套餐名称',
+    slotName: 'label',
+    ellipsis: true,
+    align: 'center',
+}, {
+    title: '操作',
+    slotName: 'setting',
+    ellipsis: true,
+    align: 'center',
+}];
+const state = ref({
+    wanberFloter: [
+        { id: '', period: '', price: '', currency: '', label: '' }
+    ],
+    formRef: null,
+    Pricing: []
+})
+const { wanberFloter, formRef, Pricing } = toRefs(state.value)
+// 添加套餐
+const handleOk = () => {
+    emit('update:modelValue', false)
+    emit('submit', true)
+    handleCancel()
+}
+// 确定或者修改
+const addUpate = async (item) => {
+    item.period = Number(item.period)
+    let res;
+    if (item.id == '') {
+        res = await addTariffPackage({ TrafficId: traffIds.value, price: item.price, currency: item.currency, period: item.period, label: item.label })
+    } else {
+        res = await UpdateTariffTtems(item)
+    }
+
+    if (res.code === 200) {
+        Message.success(res.message)
+        await getList()
+    }
+}
+const handleCancel = () => {
+    emit('update:modelValue', false)
+    wanberFloter.value = [
+        { id: '', period: '', price: '', currency: '', label: '' }
+    ]
+    traffIds.value = undefined
+}
+const addMeal = () => {
+    wanberFloter.value.push({ id: '', period: '', price: '', currency: '', label: '' })
+}
+// 删除
+const deletaMeal = async (ids) => {
+    let res = await DeleteTariffItems({ id: ids })
+    if (res.code === 200) {
+        Message.success("删除成功")
+        await getList()
+    }
+}
+
+const handeDict = async () => {
+    Pricing.value = await Getdictionary('currencyType')
+}
+
+const getList = () => {
+    CheckTariffPackages({ tariffId: traffIds.value }).then(res => {
+        if (res.code === 200) {
+            indexSet.value = res.data.length
+            wanberFloter.value = res.data
+        }
+    })
+}
+
+watch(() => modelValue.value, async (val, newVal) => {
+    if (val) {
+        await getList()
+    }
+}, { deep: true })
+
+onMounted(() => {
+    handeDict()
+})
+</script>
+<style scoped lang="less">
+.add {
+    display: flex;
+    justify-content: end;
+}
+
+.item_warp {
+    margin-top: 20px;
+    display: flex;
+    flex-wrap: wrap;
+    gap: 10px;
+    justify-content: space-between;
+}
+</style>

+ 39 - 31
src/views/tariffManagement/config.js

@@ -1,18 +1,20 @@
 export let columns = [
-    { title: window.$t('tariffManagement.id'), dataIndex: 'id', align: 'center', width: 200 ,ellipsis:true},
+    { title: window.$t('tariffManagement.id'), dataIndex: 'id', align: 'center', width: 200, ellipsis: true },
     // { title: window.$t('tariffManagement.feeCode'), dataIndex: 'feeCode', align: 'center', width: 200 },
-    { title: window.$t('tariffManagement.userName'), dataIndex: 'userName', align: 'center', width: 200,ellipsis:true },
-    { title: window.$t('tariffManagement.label'), dataIndex: 'label', align: 'center', width: 200,ellipsis:true },
-    { title: window.$t('tariffManagement.source'), dataIndex: 'sourceName', align: 'center', width: 200,ellipsis:true },
+    { title: window.$t('tariffManagement.userName'), dataIndex: 'userName', align: 'center', width: 200, ellipsis: true },
+    { title: window.$t('tariffManagement.label'), dataIndex: 'label', align: 'center', width: 200, ellipsis: true },
+    { title: window.$t('tariffManagement.source'), dataIndex: 'sourceName', align: 'center', width: 200, ellipsis: true },
     // { 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 ,ellipsis:true},
+    { title: window.$t('tariffManagement.billingCycle'), dataIndex: 'billingCycleName', align: 'center', width: 200, ellipsis: true },
     // { title: window.$t('tariffManagement.bagSize'), dataIndex: 'bagSize', align: 'center', width: 200 },
-    { title: window.$t('tariffManagement.pricing'), dataIndex: 'pricingName', align: 'center', width: 200 ,ellipsis:true},
+    { title: window.$t('tariffManagement.pricing'), dataIndex: 'pricingName', align: 'center', width: 200, ellipsis: true },
     // { title: window.$t('tariffManagement.billingMethod'), dataIndex: 'billing_method', align: 'center', width: 200 },
-    { title: window.$t('tariffManagement.settlementCycleLabel'), dataIndex: 'settlementCycle', align: 'center', width: 200,ellipsis:true },
-    { title: window.$t('tariffManagement.ActivatedNames'), dataIndex: 'Activated', align: 'center', width: 200,ellipsis:true },
-    { title: window.$t('tariffManagement.feeStatus'), dataIndex: 'status', align: 'center', width: 200 ,ellipsis:true},
+    { title: window.$t('tariffManagement.settlementCycleLabel'), dataIndex: 'settlementCycle', align: 'center', width: 200, ellipsis: true },
+    { title: window.$t('tariffManagement.ActivatedNames'), dataIndex: 'Activated', align: 'center', width: 200, ellipsis: true },
+    { title: window.$t('tariffManagement.feeStatus'), dataIndex: 'status', align: 'center', width: 200, ellipsis: true },
+    { title: window.$t('tariffManagement.MRCName'), dataIndex: 'mrcAmount', align: 'center', width: 200, ellipsis: true },
+    { title: window.$t('tariffManagement.networkName'), dataIndex: 'networkAccessFee', align: 'center', width: 200, ellipsis: true },
     {
         title: window.$t('global.common.operations'),
         dataIndex: 'id',
@@ -23,22 +25,33 @@ export let columns = [
     }
 ]
 
-export const columnsCustomer = [
-    { title: window.$t('tariffManagement.id'), dataIndex: 'id', align: 'center', width: 200,ellipsis:true },
-    // { title: window.$t('tariffManagement.feeCode'), dataIndex: 'feeCode', align: 'center', width: 200 },
-    { title: window.$t('tariffManagement.userName'), dataIndex: 'userName', align: 'center', width: 200,ellipsis:true },
-    { title: window.$t('tariffManagement.label'), dataIndex: 'label', align: 'center', width: 200 ,ellipsis:true},
-    { title: window.$t('tariffManagement.source'), dataIndex: 'sourceName', align: 'center', width: 200 ,ellipsis:true},
-    // { 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,ellipsis:true },
-    // { title: window.$t('tariffManagement.bagSize'), dataIndex: 'bagSize', align: 'center', width: 200 },
-    { title: window.$t('tariffManagement.pricing'), dataIndex: 'pricingName', align: 'center', width: 200 ,ellipsis:true},
-    // { title: window.$t('tariffManagement.billingMethod'), dataIndex: 'billing_method', align: 'center', width: 200 },
-    { title: window.$t('tariffManagement.settlementCycleLabel'), dataIndex: 'settlementCycle', align: 'center', width: 200,ellipsis:true },
-    { title: window.$t('tariffManagement.ActivatedNames'), dataIndex: 'Activated', align: 'center', width: 200,ellipsis:true },
-    { title: window.$t('tariffManagement.feeStatus'), dataIndex: 'status', align: 'center', width: 200,ellipsis:true },
-]
+// export const columnsCustomer = [
+//     { title: window.$t('tariffManagement.id'), dataIndex: 'id', align: 'center', width: 200, ellipsis: true },
+//     // { title: window.$t('tariffManagement.feeCode'), dataIndex: 'feeCode', align: 'center', width: 200 },
+//     { title: window.$t('tariffManagement.userName'), dataIndex: 'userName', align: 'center', width: 200, ellipsis: true },
+//     { title: window.$t('tariffManagement.label'), dataIndex: 'label', align: 'center', width: 200, ellipsis: true },
+//     { title: window.$t('tariffManagement.source'), dataIndex: 'sourceName', align: 'center', width: 200, ellipsis: true },
+//     // { 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, ellipsis: true },
+//     // { title: window.$t('tariffManagement.bagSize'), dataIndex: 'bagSize', align: 'center', width: 200 },
+//     { title: '结算周期', dataIndex: 'billingCycleName', align: 'center', width: 200 },
+//     { title: '流量资费价格', dataIndex: 'bagSize', align: 'center', width: 200 },
+//     { title: '充值定价', dataIndex: '', align: 'center', width: 200 },
+//     { title: window.$t('tariffManagement.pricing'), dataIndex: 'pricingName', align: 'center', width: 200, ellipsis: true },
+//     // { title: window.$t('tariffManagement.billingMethod'), dataIndex: 'billing_method', align: 'center', width: 200 },
+//     { title: window.$t('tariffManagement.settlementCycleLabel'), dataIndex: 'settlementCycle', align: 'center', width: 200, ellipsis: true },
+//     { title: window.$t('tariffManagement.ActivatedNames'), dataIndex: 'Activated', align: 'center', width: 200, ellipsis: true },
+//     { title: window.$t('tariffManagement.feeStatus'), dataIndex: 'status', align: 'center', width: 200, ellipsis: true },
+//     {
+//         title: window.$t('global.common.operations'),
+//         dataIndex: 'id',
+//         slotName: 'id',
+//         align: 'center',
+//         width: 180,
+//         fixed: "right",
+//     }
+// ]
 
 
 export const planColumns = [
@@ -46,9 +59,4 @@ export const planColumns = [
     { 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.bagSize'), dataIndex: 'bag_size', align: 'center', width: 200 },
-]
-
-
-
-
-
+]

+ 152 - 90
src/views/tariffManagement/customer/NewCustomerForm.vue

@@ -1,39 +1,39 @@
 <template>
   <a-modal :visible="visible" :title="editMode ? $t('customer.editCustomer') : $t('customer.addCustomer')"
-    :loading="loading" @ok="handleSubmit" @cancel="handleCancel" :width="720" :okText="$t('customer.confirm')">
+           :loading="loading" @ok="handleSubmit" @cancel="handleCancel" :width="720" :okText="$t('customer.confirm')">
     <a-tabs>
       <!-- 基本信息 Tab -->
       <a-tab-pane key="1" :title="$t('customer.basicInfo')">
         <a-form :model="formData" :rules="rules" ref="formRef" :label-col-props="{ span: 6 }"
-          :wrapper-col-props="{ span: 18 }">
+                :wrapper-col-props="{ span: 18 }">
           <a-divider>{{ $t('customer.basicInfoSection') }}</a-divider>
           <!-- Customer Code -->
           <a-form-item field="zip" :label="$t('customer.customerCode')" required validate-trigger="blur">
             <a-input v-model="formData.zip" :placeholder="$t('customer.enterCustomerCode')" :max-length="60"
-              show-word-limit />
+                     show-word-limit/>
           </a-form-item>
 
           <a-form-item field="email" :label="$t('customer.emailName')" required validate-trigger="blur">
             <a-input v-model="formData.email" :placeholder="$t('customer.emailType')" :max-length="60"
-              show-word-limit />
+                     show-word-limit/>
           </a-form-item>
           <a-form-item field="phone" :label="$t('customer.phoneName')" required validate-trigger="blur">
-            <a-input v-model="formData.phone" :placeholder="$t('customer.phoneType')" show-word-limit />
+            <a-input v-model="formData.phone" :placeholder="$t('customer.phoneType')" show-word-limit/>
           </a-form-item>
           <!-- Customer Name -->
           <a-form-item field="name" :label="$t('customer.customerName')" required validate-trigger="blur">
             <a-input v-model="formData.name" :placeholder="$t('customer.enterCustomerName')" :max-length="60"
-              show-word-limit />
+                     show-word-limit/>
           </a-form-item>
           <!-- Account Number -->
           <a-form-item field="username" :label="$t('customer.accountNumber')" required validate-trigger="blur">
             <a-input v-model="formData.username" :placeholder="$t('customer.enterAccountNumber')" :max-length="60"
-              show-word-limit />
+                     show-word-limit/>
           </a-form-item>
           <!-- Password -->
           <a-form-item field="password" :label="$t('customer.password')" required validate-trigger="blur">
             <a-input-password v-model="formData.password" :placeholder="$t('customer.enterPassword')" :max-length="60"
-              show-word-limit />
+                              show-word-limit/>
             <a-button type="primary" @click="generatePassword">{{ $t('customer.generatePassword') }}</a-button>
           </a-form-item>
           <!--          role-->
@@ -52,17 +52,17 @@
           <!-- Remark -->
           <a-form-item field="note" :label="$t('customer.remark')" required validate-trigger="blur">
             <a-input v-model="formData.note" :placeholder="$t('customer.enterRemark')" :max-length="60"
-              show-word-limit />
+                     show-word-limit/>
           </a-form-item>
           <!-- Account Balance -->
           <a-form-item field="amount" :label="$t('customer.accountBalance')" required validate-trigger="blur">
             <a-input-number v-model="formData.amount" :min="0" :precision="2" :step="100"
-              :suffix="$t('customer.currency')" />
+                            :suffix="$t('customer.currency')"/>
           </a-form-item>
           <!-- Address -->
           <a-form-item field="addr" :label="$t('customer.address')" required validate-trigger="blur">
             <a-input v-model="formData.addr" :placeholder="$t('customer.addressMessage')" :max-length="50"
-              show-word-limit />
+                     show-word-limit/>
           </a-form-item>
           <!-- Status -->
           <a-form-item field="state" :label="$t('customer.statusName')" required validate-trigger="blur">
@@ -79,23 +79,23 @@
       <!-- SMS 信息 Tab -->
       <a-tab-pane key="2" :title="$t('customer.smsInfoSection')">
         <a-form :model="formData" :rules="rules" ref="formRef" :label-col-props="{ span: 6 }"
-          :wrapper-col-props="{ span: 18 }">
+                :wrapper-col-props="{ span: 18 }">
           <a-divider>{{ $t('customer.smsInfoSection') }}</a-divider>
           <a-form-item field="sms" :label="$t('customer.smsSubCode')" required validate-trigger="blur">
             <a-input v-model="formData.sms" :placeholder="$t('customer.enterSmsSubCode')" :max-length="60"
-              show-word-limit />
+                     show-word-limit/>
           </a-form-item>
           <a-form-item field="smsSignature" :label="$t('customer.smsName')" required validate-trigger="blur">
             <a-input v-model="formData.smsSignature" :placeholder="$t('customer.enterSmsName')" :max-length="60"
-              show-word-limit />
+                     show-word-limit/>
           </a-form-item>
           <a-form-item field="loginSms" :label="$t('customer.loginSmsTemplate')" required validate-trigger="blur">
             <a-input v-model="formData.loginSms" :placeholder="$t('customer.enterLoginSmsTemplate')" :max-length="60"
-              show-word-limit />
+                     show-word-limit/>
           </a-form-item>
           <a-form-item field="warnSms" :label="$t('customer.alarmSmsTemplate')" required validate-trigger="blur">
             <a-input v-model="formData.warnSms" :placeholder="$t('customer.enterAlarmSmsTemplate')" :max-length="60"
-              show-word-limit />
+                     show-word-limit/>
           </a-form-item>
         </a-form>
       </a-tab-pane>
@@ -103,43 +103,43 @@
       <!-- Billing Information Tab -->
       <a-tab-pane key="3" :title="$t('customer.billingInfo')">
         <a-form :model="formData" :rules="rules" ref="formRef" :label-col-props="{ span: 6 }"
-          :wrapper-col-props="{ span: 18 }">
+                :wrapper-col-props="{ span: 18 }">
           <a-divider>{{ $t('customer.InvoiceInformation') }}</a-divider>
           <a-form-item field="invoiceTitle" :label="$t('customer.invoiceTitle')" required validate-trigger="blur">
             <a-input v-model="formData.invoiceTitle" :placeholder="$t('customer.enterInvoiceTitle')" :max-length="60"
-              show-word-limit />
+                     show-word-limit/>
           </a-form-item>
           <a-form-item field="invoiceType" :label="$t('customer.invoice_vatTextType')" required validate-trigger="blur">
             <a-select v-model="formData.invoiceType" :style="{ width: '100%' }"
-              :placeholder="$t('customer.invoice_vatTextTypeSelect')">
-              <a-option v-for="item of invoiceList" :value="item.value" :label="item.label" />
+                      :placeholder="$t('customer.invoice_vatTextTypeSelect')">
+              <a-option v-for="item of invoiceList" :value="item.value" :label="item.label"/>
             </a-select>
           </a-form-item>
           <a-form-item field="invoiceAddr" :label="$t('customer.registeredAddress')" required validate-trigger="blur">
             <a-input v-model="formData.invoiceAddr" :placeholder="$t('customer.enterRegisteredAddress')"
-              :max-length="60" show-word-limit />
+                     :max-length="60" show-word-limit/>
           </a-form-item>
           <a-form-item field="invoiceZip" :label="$t('customer.invoiceCode')" required validate-trigger="blur">
             <a-input v-model="formData.invoiceZip" :placeholder="$t('customer.InvoiceCodeName')" :max-length="60"
-              show-word-limit />
+                     show-word-limit/>
           </a-form-item>
           <a-form-item field="invoiceEmail" :label="$t('customer.invoiceEmailName')" required validate-trigger="blur">
             <a-input v-model="formData.invoiceEmail" :placeholder="$t('customer.invoiceEmailNameType')" :max-length="60"
-              show-word-limit />
+                     show-word-limit/>
           </a-form-item>
           <a-form-item field="bankName" :label="$t('customer.bankName')" required validate-trigger="blur">
             <a-input v-model="formData.bankName" :placeholder="$t('customer.enterBankName')" :max-length="60"
-              show-word-limit />
+                     show-word-limit/>
           </a-form-item>
           <a-form-item field="bankAccount" :label="$t('customer.BankNumber')" required validate-trigger="blur">
             <a-input v-model="formData.bankAccount" :placeholder="$t('customer.BankNumberName')" :max-length="60"
-              show-word-limit />
+                     show-word-limit/>
           </a-form-item>
           <a-form-item field="bankBranch" :label="$t('customer.bank_branchName')" required validate-trigger="blur">
-            <a-input v-model="formData.bankBranch" :placeholder="$t('customer.bank_branchNameType')" show-word-limit />
+            <a-input v-model="formData.bankBranch" :placeholder="$t('customer.bank_branchNameType')" show-word-limit/>
           </a-form-item>
           <a-form-item field="businessLicense" :label="$t('customer.BusinessLicense')" required validate-trigger="blur">
-            <upload v-model="formData.businessLicense" />
+            <upload v-model="formData.businessLicense"/>
           </a-form-item>
         </a-form>
       </a-tab-pane>
@@ -147,15 +147,68 @@
       <!-- Tax Registration Tab -->
       <a-tab-pane key="4" :title="$t('customer.TaxRegistration')">
         <a-form :model="formData" :rules="rules" ref="formRef" :label-col-props="{ span: 8 }"
-          :wrapper-col-props="{ span: 16 }">
+                :wrapper-col-props="{ span: 16 }">
           <a-divider>{{ $t('customer.TaxRegistrationText') }}</a-divider>
           <a-form-item field="taxRegistrationCertificate" :label="$t('customer.photocopy')" required
-            validate-trigger="blur">
-            <upload v-model:modelValue="formData.taxRegistrationCertificate" />
+                       validate-trigger="blur">
+            <upload v-model:modelValue="formData.taxRegistrationCertificate"/>
           </a-form-item>
           <a-form-item field="taxpayerQualification" :label="$t('customer.CertificationQualification')" required
-            validate-trigger="blur">
-            <upload v-model:modelValue="formData.taxpayerQualification" />
+                       validate-trigger="blur">
+            <upload v-model:modelValue="formData.taxpayerQualification"/>
+          </a-form-item>
+        </a-form>
+      </a-tab-pane>
+
+      <a-tab-pane key="5" title="预警">
+        <a-form :model="formData" :rules="rules" ref="formRef" :label-col-props="{ span: 4 }"
+                :wrapper-col-props="{ span: 20 }">
+          <a-divider>预警设置</a-divider>
+          <a-form-item field="amountWarn" label="账号余额报警" required
+                       validate-trigger="blur">
+            <a-input v-model="formData.amountWarn" placeholder="请输入" :max-length="60" :style="{ width: '320px' }"
+                     show-word-limit/>
+          </a-form-item>
+          <a-form-item field="arriveWarn" label="达量预警" required
+                       validate-trigger="blur">
+            <a-input-number v-model="formData.arriveWarn" :style="{ width: '320px' }"
+                            placeholder="请输入" allow-clear hide-button>
+              <template #suffix>
+                %
+              </template>
+            </a-input-number>
+          </a-form-item>
+          <a-form-item field="arriveStop" label="达量停机" required
+                       validate-trigger="blur">
+            <a-input-number v-model="formData.arriveStop" :style="{ width: '320px' }"
+                            placeholder="请输入" allow-clear hide-button>
+              <template #suffix>
+                %
+              </template>
+            </a-input-number>
+            <a-radio-group v-model="formData.arriveStopOperation" :options="reachList"></a-radio-group>
+          </a-form-item>
+          <a-form-item field="arriveStop" label="达量断网" required
+                       validate-trigger="blur">
+            <a-input-number v-model="formData.arriveStop" :style="{ width: '320px' }"
+                            placeholder="请输入" allow-clear hide-button>
+              <template #suffix>
+                %
+              </template>
+            </a-input-number>
+            <a-radio-group v-model="formData.arriveStopNetwork" :options="reachList"></a-radio-group>
+          </a-form-item>
+          <a-form-item field="warnPhone" label="预警手机" required
+                       validate-trigger="blur">
+            <a-input-number v-model="formData.warnPhone" :style="{ width: '320px' }"
+                            placeholder="请输入" allow-clear hide-button>
+            </a-input-number>
+          </a-form-item>
+          <a-form-item field="warnEmail" label="预警邮箱" required
+                       validate-trigger="blur">
+            <a-input-number v-model="formData.warnEmail" :style="{ width: '320px' }"
+                            placeholder="请输入" allow-clear hide-button>
+            </a-input-number>
           </a-form-item>
         </a-form>
       </a-tab-pane>
@@ -165,17 +218,19 @@
 
 
 <script setup>
-import { ref, watch, onMounted } from 'vue';
-import { Message } from '@arco-design/web-vue';
-import { useI18n } from 'vue-i18n';
-import { useSystemStore } from '@/store/modules/systemStore.js'
-import { dictionaryDetail } from '@/api/path/dict.js'
+import {ref, watch, onMounted} from 'vue';
+import {Message} from '@arco-design/web-vue';
+import {useI18n} from 'vue-i18n';
+import {useSystemStore} from '@/store/modules/systemStore.js'
+import {dictionaryDetail} from '@/api/path/dict.js'
 import Upload from "@/components/upload/index.vue";
-import { systemFindRoleList } from "@/api/path/system.api.js";
-import { addCustomer, updateCustomer } from "@/api/customer.js";
-const { t } = useI18n();
+import {systemFindRoleList} from "@/api/path/system.api.js";
+import {addCustomer, updateCustomer} from "@/api/customer.js";
+
+const {t} = useI18n();
 const systemStore = useSystemStore()
-import { encryptByDES } from '@/utils/crypto.js'
+import {encryptByDES} from '@/utils/crypto.js'
+
 const props = defineProps({
   visible: Boolean,
   editMode: Boolean,
@@ -185,34 +240,29 @@ const props = defineProps({
 
 const invoiceList = ref([])
 const roles = ref([])
-const userTypeList = ref([])
 watch(
-  () => props.editData,
-  (newVal) => {
-    if (newVal && props.editMode) {
-      // 深拷贝编辑数据
-      const editDataCopy = JSON.parse(JSON.stringify(newVal));
+    () => props.editData,
+    (newVal) => {
+      if (newVal && props.editMode) {
+        // 深拷贝编辑数据
+        const editDataCopy = JSON.parse(JSON.stringify(newVal));
 
-      // 将 formData 中嵌套的 info 展平为一层
-      const flattenedFormData = ref(Object.fromEntries(Object.entries(editDataCopy).flatMap(([key, value]) => typeof value === 'object' && value !== null && !Array.isArray(value) ? Object.entries(value) : [[key, value]])));
-      if (editDataCopy.info) {
-        delete editDataCopy.info;
+        // 将 formData 中嵌套的 info 展平为一层
+        const flattenedFormData = ref(Object.fromEntries(Object.entries(editDataCopy).flatMap(([key, value]) => typeof value === 'object' && value !== null && !Array.isArray(value) ? Object.entries(value) : [[key, value]])));
+        if (editDataCopy.info) {
+          delete editDataCopy.info;
+        }
+        const formDataList = {...editDataCopy, ...flattenedFormData.value}
+        formData.value = formDataList
       }
-      const formDataList = { ...editDataCopy, ...flattenedFormData.value }
-      formData.value = formDataList
-      // Object.keys(formData.value).forEach(key => {
-      //   if (formDataList[key]) {
-      //     formData.value[key] = formDataList[key];
-      //   }
-      // });
-    }
-  },
-  { deep: true, immediate: true }
+    },
+    {deep: true, immediate: true}
 );
 
 const emit = defineEmits(['update:visible', 'submit']);
 
 const formRef = ref(null);
+const reachList = ref([])
 const formData = ref({
   username: "",
   state: "",
@@ -238,37 +288,44 @@ const formData = ref({
   bankBranch: "",
   businessLicense: "",
   taxRegistrationCertificate: "",
-  taxpayerQualification: ""
+  taxpayerQualification: "",
+  amountWarn: '',
+  arriveWarn: '',
+  arriveStop: '',
+  arriveStopOperation: '',
+  arriveStopNetwork: '',
+  warnPhone: '',
+  warnEmail: ''
 });
 
 const rules = {
-  userName: [{ required: true, message: t('customer.enterAccountNumber') }],
-  state: [{ required: true, message: t('customer.stateType') }],
-  name: [{ required: true, message: t('customer.nameType') }],
-  password: [{ required: true, message: t('customer.passwordRequired') }],
+  userName: [{required: true, message: t('customer.enterAccountNumber')}],
+  state: [{required: true, message: t('customer.stateType')}],
+  name: [{required: true, message: t('customer.nameType')}],
+  password: [{required: true, message: t('customer.passwordRequired')}],
   // roleIds: [{required: true, message: t('customer.roleIdsType')}],
   // userType: [{required: true, message: t('customer.userTypeType')}],
-  phone: [{ required: true, message: t('customer.phoneType') }],
-  email: [{ required: true, message: t('customer.emailType') }],
-  addr: [{ required: true, message: t('customer.addressRequired') }],
-  amount: [{ required: true, message: t('customer.amountRequired') }],
-  bankAccount: [{ required: true, message: t('customer.bankAccountRequired') }],
-  bankBranch: [{ required: true, message: t('customer.bankBranchRequired') }],
-  bankName: [{ required: true, message: t('customer.bankNameRequired') }],
-  businessLicense: [{ required: true, message: t('customer.businessLicenseRequired') }],
-  invoiceAddr: [{ required: true, message: t('customer.invoiceAddressRequired') }],
-  invoiceEmail: [{ required: true, message: t('customer.invoiceEmailRequired') }],
-  invoiceTitle: [{ required: true, message: t('customer.invoiceTitleRequired') }],
-  invoiceType: [{ required: true, message: t('customer.invoiceTypeRequired') }],
-  invoiceZip: [{ required: true, message: t('customer.invoiceZipRequired') }],
-  loginSms: [{ required: true, message: t('customer.loginSMSTemplateRequired') }],
-  note: [{ required: true, message: t('customer.noteRequired') }],
-  sms: [{ required: true, message: t('customer.smsRequired') }],
-  smsSignature: [{ required: true, message: t('customer.smsSignatureRequired') }],
-  warnSms: [{ required: true, message: t('customer.warnSMSTemplateRequired') }],
-  zip: [{ required: true, message: t('customer.zipCodeRequired') }],
-  taxRegistrationCertificate: [{ required: true, message: t('customer.taxRegistrationCertificateRequired') }],
-  taxpayerQualification: [{ required: true, message: t('customer.taxpayerQualificationRequired') }]
+  phone: [{required: true, message: t('customer.phoneType')}],
+  email: [{required: true, message: t('customer.emailType')}],
+  addr: [{required: true, message: t('customer.addressRequired')}],
+  amount: [{required: true, message: t('customer.amountRequired')}],
+  bankAccount: [{required: true, message: t('customer.bankAccountRequired')}],
+  bankBranch: [{required: true, message: t('customer.bankBranchRequired')}],
+  bankName: [{required: true, message: t('customer.bankNameRequired')}],
+  businessLicense: [{required: true, message: t('customer.businessLicenseRequired')}],
+  invoiceAddr: [{required: true, message: t('customer.invoiceAddressRequired')}],
+  invoiceEmail: [{required: true, message: t('customer.invoiceEmailRequired')}],
+  invoiceTitle: [{required: true, message: t('customer.invoiceTitleRequired')}],
+  invoiceType: [{required: true, message: t('customer.invoiceTypeRequired')}],
+  invoiceZip: [{required: true, message: t('customer.invoiceZipRequired')}],
+  loginSms: [{required: true, message: t('customer.loginSMSTemplateRequired')}],
+  note: [{required: true, message: t('customer.noteRequired')}],
+  sms: [{required: true, message: t('customer.smsRequired')}],
+  smsSignature: [{required: true, message: t('customer.smsSignatureRequired')}],
+  warnSms: [{required: true, message: t('customer.warnSMSTemplateRequired')}],
+  zip: [{required: true, message: t('customer.zipCodeRequired')}],
+  taxRegistrationCertificate: [{required: true, message: t('customer.taxRegistrationCertificateRequired')}],
+  taxpayerQualification: [{required: true, message: t('customer.taxpayerQualificationRequired')}]
 };
 
 
@@ -315,12 +372,17 @@ const generatePassword = () => {
 
 
 const getDistList = async () => {
-  let code = ['invoiceVat'];
+  let code = ['invoiceVat','reach'];
 
   for (let i = 0; i < code.length; i++) {
-    let res = await dictionaryDetail({ typeKey: code[i] });
+    let res = await dictionaryDetail({typeKey: code[i]});
     if (res.code === 200) {
-      invoiceList.value = res.data;
+      if(i==0){
+        invoiceList.value = res.data;
+      }else{
+        reachList.value = res.data;
+      }
+
     }
   }
 }

+ 7 - 7
src/views/tariffManagement/customer/index.vue

@@ -80,19 +80,19 @@ const {t} = useI18n();
 const loading = ref(false);
 
 const columns = computed(() => [
-  {title: t('customer.id'), dataIndex: 'id',width: 100},
+  {title: t('customer.id'), dataIndex: 'id',ellipsis:true},
   // {title: t('customer.customerCode'), dataIndex: 'customerCode'},
-  {title: t('customer.customerName'), dataIndex: 'name',width: 120},
+  {title: t('customer.customerName'), dataIndex: 'name',ellipsis:true},
   {title: t('customer.userAdmin'), dataIndex: 'username'},
   // {title: t('customer.accountBalance'), dataIndex: 'accountBalance'},
   // {title: t('customer.paymentMethodName'), dataIndex: 'paymentMethod'},
-  {title: t('customer.customerStatus'), slotName: 'state',width: 130},
+  {title: t('customer.customerStatus'), slotName: 'state',ellipsis:true},
   // {title: t('customer.validPeriod'), dataIndex: 'validPeriod'},
   // {title: t('customer.activeCards'), dataIndex: 'activeCards'},
-  {title: t('customer.userTypeName'), dataIndex: 'userType',width: 100},
-  {title: t('customer.startTime'), dataIndex: 'createdAt',width: 200},
-  {title: t('customer.updateTime'), dataIndex: 'updatedAt',width: 200},
-  {title: t('global.common.operations'), slotName: 'operation', width: 150},
+  {title: t('customer.userTypeName'), dataIndex: 'userType',ellipsis:true},
+  {title: t('customer.startTime'), dataIndex: 'createdAt',ellipsis:true},
+  {title: t('customer.updateTime'), dataIndex: 'updatedAt',ellipsis:true},
+  {title: t('global.common.operations'), slotName: 'operation', ellipsis:true},
 ]);
 
 onMounted(() => {

+ 115 - 412
src/views/tariffManagement/index.vue

@@ -4,195 +4,48 @@
     <div class="head-title">
       <span>{{ route.meta.title }} </span>
       <span class="head-title-right">
-                <!-- <a-button class="m-r-10" type="primary" @click="dictShowModel(1, null)">{{ $t('form.Add') }}</a-button> -->
-            </span>
+        <!-- <a-button class="m-r-10" type="primary" @click="dictShowModel(1, null)">{{ $t('form.Add') }}</a-button> -->
+      </span>
     </div>
     <!-- 搜索条件区 -->
     <div class="search-section">
-
-      <a-form :model="searchForm" layout="inline">
-        <!--        资费名称-->
-        <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 field="label" :label="$t('tariffManagement.soundName')">
-          <a-select v-model="value" :style="{width:'320px'}" :placeholder="$t('lotCard.soundName')">
-            <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 field="label" :label="$t('tariffManagement.FlowType')">
-          <a-select v-model="value" :style="{width:'320px'}" :placeholder="$t('lotCard.FlowTypeName')">
-            <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>
-          <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>
+      <Search :SearchForm="SearchForm" />
     </div>
-
     <div class="audit-btn">
       <a-button type="text" @click="dictShowModel(1, null)" v-if="role.getRole == 1">
         <template #icon>
-          <icon-plus-circle/>
+          <icon-plus-circle />
         </template>
         <template #default>{{ $t('form.Add') }}</template>
       </a-button>
     </div>
-    <a-table row-key="id" :data="dataSource" :columns="role.getRole == 1 ? columns : columnsCustomer"
-             :pagination="pagination" :scroll="{ x: 'auto' }" @page-change="evChangePage">
+    <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.getRole == 1">{{
+          $t('form.Edit')
+        }}</a>
+        <a class="a-link" href="javascript:;" style="margin-right: 1rem" @click="meal(record)">套餐</a>
         <!-- 删除 -->
-        <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 :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" v-if="role.getRole == 1">{{
+            $t('form.Delete')
+          }}</a>
         </a-popconfirm>
       </template>
-
     </a-table>
 
 
-    <!--资费 弹框 -->
-    <a-modal :title="typeCurrent == 1 ? $t('form.Add') : $t('form.Edit')" v-model:visible="visible"
-             @onCancel="resetForm" centered :maskClosable="false" :footer="null" width="700px">
-      <a-form ref="formRef" :rules="rules" :model="formState" @submit="handleSubmit">
-        <div class="formTitle">基本信息</div>
-        <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="simDataPlanId">
-            <a-select v-model="formState.simDataPlanId">
-              <a-option v-for=" (item,index) in planList" :key="item.superior_id" :value="item.id"> 流量包{{
-                  item.productName
-                }}
-              </a-option>
-            </a-select>
-          </a-form-item>
-        </template>
-        <a-form-item :label="$t('tariffManagement.label')" field="label">
-          <a-input v-model="formState.label"/>
-        </a-form-item>
-        <a-form-item :label="$t('tariffManagement.userId')" field="userId">
-          <a-select v-model="formState.userId">
-            <a-option v-for=" item in userIdList" :key="item.id" :value="item.id">{{
-                item.name
-              }}
-            </a-option>
-          </a-select>
-        </a-form-item>
-        <a-form-item :label="$t('tariffManagement.billingMethod')" field="billingMethod">
-          <a-select v-model="formState.billingMethod">
-            <a-option v-for=" item in methodList" :key="item.id" :value="item.value">{{
-                item.label
-              }}
-            </a-option>
-          </a-select>
-        </a-form-item>
-        <a-form-item :label="$t('tariffManagement.currency')" field="currency">
-          <a-select v-model="formState.currency">
-            <a-option v-for=" item in currency" :key="item.id" :value="item.value">{{
-                item.label
-              }}
-            </a-option>
-          </a-select>
-        </a-form-item>
-        <div class="formTitle">计费信息</div>
-        <a-form-item field="billingCycle" :label="$t('tariffManagement.billingCycle')" required>
-          <a-radio-group v-model="formState.billingCycle">
-            <a-radio value="1">按天</a-radio>
-            <a-radio value="2">按月</a-radio>
-          </a-radio-group>
-        </a-form-item>
-        <a-form-item field="" :label="$t('tariffManagement.pricing')" required>
-          <a-input v-model="formState.pricing" v-if="formState.billingMethod==2">
-            <template #append>
-              {{ formState.currency === '0' ? '元' : '美金' }}
-            </template>
-          </a-input>
-          <a-input v-model="formState.trafficBilling" v-if="formState.billingMethod==1"></a-input>
-          <a-select v-model="formState.trafficBillingType" style="width: 80px; margin:0 8px;"
-                    v-if="formState.billingMethod==1">
-            <a-option value="KB">KB</a-option>
-            <a-option value="MB">MB</a-option>
-            <a-option value="GB">GB</a-option>
-          </a-select>
-          <a-input v-model="formState.trafficBillingAmount" v-if="formState.billingMethod==1">
-            <template #append>
-              {{ formState.currency === '0' ? '元' : '美金' }}
-            </template>
-          </a-input>
-        </a-form-item>
-        <a-form-item field="settlementCycle" :label="$t('tariffManagement.cycleBuy')">
-          <a-input v-model="formState.settlementCycleMap.starTime">
-            <template #prepend>
-              最短
-            </template>
-            <template #append>
-              个月,最长
-            </template>
-          </a-input>
-          <a-input v-model="formState.settlementCycleMap.endTime" style="width: 50%;">
-            <template #append>
-              个月
-            </template>
-          </a-input>
-        </a-form-item>
-        <a-form-item :label="$t('tariffManagement.MRCName')" field="mrcAmount">
-          <a-input v-model="formState.mrcAmount">
-            <template #append>
-              {{ formState.currency === '0' ? '元' : '美金' }}
-            </template>
-          </a-input>
-        </a-form-item>
-        <a-form-item :label="$t('tariffManagement.networkName')" field="networkAccessFee">
-          <a-input v-model="formState.networkAccessFee">
-            <template #append>
-              {{ formState.currency === '0' ? '元' : '美金' }}
-            </template>
-          </a-input>
-        </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-modal>
-
 
     <a-modal width="70%" :visible="planVisible" title="选择流量包" @ok="handleSubmitPlan" @cancel="handleCancel">
       <!-- 搜索条件区 -->
       <div class="search-section">
         <a-form :model="formData" layout="inline">
           <a-form-item field="label" :label="$t('tariffManagement.label')">
-            <a-input v-model="formData.label"
-                     :placeholder="$t('lotCard.please') + $t('tariffManagement.label')" allow-clear/>
+            <a-input v-model="formData.label" :placeholder="$t('lotCard.please') + $t('tariffManagement.label')"
+              allow-clear />
           </a-form-item>
           <a-form-item>
             <a-space>
@@ -203,44 +56,100 @@
         </a-form>
       </div>
       <a-table row-key="id" :data="planList" :columns="planColumns" :scroll="{ x: 'auto' }"
-               :row-selection="rowSelectionPlan" v-model:selectedKeys="selectedKeysPlan">
+        :row-selection="rowSelectionPlan" v-model:selectedKeys="selectedKeysPlan">
 
       </a-table>
 
     </a-modal>
+
+    <Meal v-model:model-value="modealShow" :traffIds="ids" @submit="intData()" />
+    <Add v-model:model-value="visible" :type-index="typeCurrent" :FormDataList="FormDataList" @submit="intData()"></Add>
   </div>
 </template>
 
 <script setup>
-import {onMounted, ref, reactive, getCurrentInstance, nextTick, watch} from "vue";
-import {useRoute} from "vue-router";
-import {columns, columnsCustomer, planColumns} from "./config";
-import {Message} from '@arco-design/web-vue'
-import {deleteTariff, updateTariff, addTariff, tariffList} from "@/api/path/tariffManagement.api"
-import {getDataPlanList} from "@/api/path/lotCard.api"
-import {getSTSInfoList} from '@/api/path/system.api'
-import {Getdictionary} from '@/mixins/index.js'
-import {useSystemStore} from '@/store/modules/systemStore'
-
+import { onMounted, ref, toRefs, getCurrentInstance } from "vue";
+import { useRoute } from "vue-router";
+import { columns, planColumns } from "./config";
+import { deleteTariff, tariffList } from "@/api/path/tariffManagement.api"
+import { Getdictionary } from '@/mixins/index.js'
+import { useSystemStore } from '@/store/modules/systemStore'
+import Meal from './Management/meal.vue'
+import Add from './Management/add.vue'
+import Search from '@/components/Search/index.vue'
 const role = useSystemStore()
-
-
-const {proxy} = getCurrentInstance()
-const formRef = ref()
-const searchForm = ref({
-  "label": "",
-});
-
-const currency = ref([])
-
-
-const dataSource = ref([]);
+const { proxy } = getCurrentInstance()
 const route = useRoute();
-const pagination = ref({
-  total: 0,
-  pageSize: 10,
-  current: 1,
+const SearchForm = [
+  {
+    type: 'input',
+    label: '资费名称',
+    field: 'source',
+    placeholder: '请输入资费名称',
+    value: '', // 双向绑定的值
+  },
+  {
+    type: 'input',
+    label: '客户名称',
+    field: 'trafficId',
+    placeholder: '请输入客户名称',
+    value: '', // 双向绑定的值
+  },
+  {
+    type: 'select',
+    label: '供应商名称',
+    field: 'simType',
+    placeholder: '请选择供应商名称',
+    options: [], // 默认空,后面会通过字典加载
+    value: '', // 双向绑定的值
+    dict: 'source', // 字典加载的标识
+    width: '200'
+  },
+]
+const state = ref({
+  searchForm: { "label": "", },
+  FormDataList: {},
+  currency: [],
+  dataSource: [],
+  pagination: {
+    total: 0,
+    pageSize: 10,
+    current: 1,
+  },
+  planList: [],
+  visible: false,
+  typeCurrent: null,
+  sourceList: [],
+  cycleist: [],
+  modealShow: false,
+  planVisible: false,
+  formData: {},
+  selectedKeysPlan: [],
+  rowSelectionPlan: {
+    type: 'radio',
+    showCheckedAll: true,
+    onlyCurrent: false,
+  },
+  ids: null
 })
+const {
+  searchForm,
+  FormDataList,
+  currency,
+  dataSource,
+  pagination,
+  planList,
+  visible,
+  typeCurrent,
+  sourceList,
+  cycleist,
+  modealShow,
+  planVisible,
+  formData,
+  selectedKeysPlan,
+  rowSelectionPlan,
+  ids
+} = toRefs(state.value);
 
 const intData = async () => {
   const param = {
@@ -248,20 +157,21 @@ const intData = async () => {
     size: pagination.value.pageSize,
     ...searchForm.value,
   }
-  const {data} = await tariffList(param)
+  const { data } = await tariffList(param)
   dataSource.value = (data.records || []).map((item, index) => {
     const sourceName = sourceList.value.find(val => val.value == item.source)?.label
     const billingCycleName = cycleist.value.find(val => val.value == item.billingCycle)?.label
     const pricingCurrty = currency.value.find(val => val.value == item.currency)?.label || '人民币'
-    const Activated = item.trafficBilling+'/'+item.trafficBillingType
-
+    const Activated = item.trafficBilling + '/' + item.trafficBillingType
+    const bagSize = item.pricing + '/' + item.mrcAmount + '/' + item.networkAccessFee
     return {
       ...item,
       sourceName,
       pricingName: item.pricing !== '' ? item.pricing + '/' + pricingCurrty : '',
       billingCycleName,
-      Activated:Activated,
-      status: "正常"
+      Activated: Activated,
+      status: "正常",
+      bagSize
     }
   })
   pagination.value.total = data.total
@@ -270,7 +180,7 @@ const intData = async () => {
 
 // 删除
 const handleDel = async (id) => {
-  const {code} = await deleteTariff({id})
+  const { code } = await deleteTariff({ id })
   if (code == 200) {
     Message.success({
       content: "删除成功!",
@@ -285,204 +195,13 @@ const evChangePage = (page) => {
   intData()
 }
 
-const handleSearch = () => {
-  intData()
-}
-const resetSearch = () => {
-  searchForm.value.label = ""
-  intData()
-}
-
-
-// -------------------弹窗数据------------------------------------
-const planList = ref([])
-const userIdList = ref([])
-
-
-const visible = ref(false);
-const typeCurrent = ref(null);
-const sourceList = ref([])
-const trafficList = ref([])
-const cycleist = ref([])
-const typeList = ref([])
-const methodList = ref([])
-const settlementCycleMap = ref([])
-
-const formState = ref({
-  // 资费名称(必填)
-  "label": "",
-  // 流量包ID(必填)
-  "simDataPlanId": null,
-  // 用户ID(必填)
-  "userId": null,
-  // 来源(必填)
-  "source": "",
-  // 计费周期(必填)
-  "billingCycle": "",
-  // 计费方式(必填)
-  "billingMethod": "1",
-  // 结算周期(必填)
-  "settlementCycle": "",
-  // 价格(必填)
-  "pricing": "",
-  // 币种(必填)
-  "currency": "0",
-  // 流量资费计费
-  "trafficBilling": '',
-  // 流量资费计费类型
-  "trafficBillingType": '',
-  // 流量资费计费金
-  "trafficBillingAmount": '',
-  // MRC金额
-  "mrcAmount": '',
-  // 网络接入费
-  "networkAccessFee": '',
-
-  "settlementCycleMap": {
-    "starTime": '',
-    "endTime": ''
-  }
-});
-
-const rules = {
-  label: [{required: true, trigger: 'change',}],
-  simDataPlanId: [{required: true, trigger: 'change',}],
-  userId: [{required: true, trigger: 'change',}],
-  source: [{required: true, trigger: 'change',}],
-  billingCycle: [{required: true, trigger: 'change',}],
-  billingMethod: [{required: true, trigger: 'change',}],
-  currency: [{required: true, trigger: 'change',}],
-  trafficBilling: [{required: true, trigger: 'change',}],
-  trafficBillingType: [{required: true, trigger: 'change',}],
-  trafficBillingAmount: [{required: true, trigger: 'change',}],
-  mrcAmount: [{required: true, trigger: 'change',}],
-  networkAccessFee: [{required: true, trigger: 'change',}],
-};
-
-
-// 提交
-const handleSubmit = ({values, errors}) => {
-  formRef.value.validate(async (errors) => {
-    if (!errors) {
-      const formVal = JSON.parse(JSON.stringify(values))
-      delete formVal.settlementCycleMap
-      formVal.userId = Number(values.userId)
-      formVal.simDataPlanId = String(values.simDataPlanId)
-      if (values.settlementCycleMap.starTime && values.settlementCycleMap.starTime) {
-        formVal.settlementCycle = values.settlementCycleMap.starTime + '~' + values.settlementCycleMap.endTime
-      } else {
-        Message.warning({
-          content: "请选择订购周期!",
-          duration: 2000,
-        })
-      }
-
-      if (formState.value.id!=='') {
-        const {code, data} = await updateTariff(formVal)
-
-        if (code == 200) {
-          Message.success({
-            content: "修改成功!",
-            duration: 2000,
-          })
-          visible.value = false;
-          intData()
-        }
-      } else {
-        const {code, data} = await addTariff(formVal)
-        if (code == 200) {
-          Message.success({
-            content: "添加成功!",
-            duration: 2000,
-          })
-          visible.value = false;
-          intData()
-        }
-      }
-    }
-  });
-
-}
 // 弹框
 const dictShowModel = (type, data) => {
-  handleModelId()
-  formRef.value.resetFields();
-  if (formState.value.settlementCycleMap) {
-    formState.value.settlementCycleMap.starTime = ''
-    formState.value.settlementCycleMap.endTime = ''
-  }
-
+  FormDataList.value = type == 1 ? {} : data
   typeCurrent.value = type;
-
-  // 编辑
-  if (type == 2) {
-    Object.keys(formState.value).forEach(key => {
-      if (data[key]) {
-        formState.value[key] = data[key]
-      }
-    })
-    formState.value.id = data.id
-    formState.value.simDataPlanId = Number(formState.value.simDataPlanId)
-    formState.value.userId = Number(formState.value.userId)
-    if (data.pricing !== '') {
-      formState.value.pricing = data.pricing.match(/\d+/)[0] || ''
-    }
-    if (data.settlementCycle) {
-      formState.value.settlementCycleMap.starTime = data.settlementCycle.split('~')[0] || ''
-      formState.value.settlementCycleMap.endTime = data.settlementCycle.split('~')[1] || ''
-    }
-  }
-  nextTick(() => {
-    visible.value = true;
-  })
+  visible.value = true;
 }
 
-// 获取id数组
-const handleModelId = async () => {
-  const param = {
-    current: 1,
-    size: 999,
-  }
-  getSTSInfoList(param).then(res => {
-    userIdList.value = (res.data.records || [])
-  })
-}
-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;
-  Object.keys(formState.value).forEach(key => {
-      formState.value[key] = ''
-  })
-  delete formState.value.id
-  formState.value.settlementCycleMap = {
-    starTime:'',
-    endTime:''
-  }
-}
-
-// --------------------------------------------------------
-
-// 资费弹窗------------------------------------------------
-const planVisible = ref(false)
-const formData = ref({})
-const selectedKeysPlan = ref([])
-const rowSelectionPlan = reactive({
-  type: 'radio',
-  showCheckedAll: true,
-  onlyCurrent: false,
-});
-
-
 const resetSearchPlan = () => {
 
 }
@@ -492,6 +211,7 @@ const handleSearchPlan = () => {
 const handleCancel = () => {
   planVisible.value = false
 }
+
 const handleSubmitPlan = () => {
   if (selectedKeysPlan.value.length > 0) {
     formState.value.simDataPlanId = String(selectedKeysPlan.value[0])
@@ -500,35 +220,18 @@ const handleSubmitPlan = () => {
 
 }
 
-watch(
-    () => formState.value.source,
-    (newValue, oldValue) => {
-
-      if (newValue != oldValue) {
-        handleDataPlan()
-      }
-    },
-    {immediate: true}
-);
-
-watch(()=>formState.value.billingMethod,val=>{
-   if(val==2){
-      formState.value.trafficBillingType = ''
-      formState.value.trafficBilling = ''
-      formState.value.trafficBillingAmount = ''
-   }
-})
 
-// -------------------------------------------------------
-// 获取字典
 const handleDictValue = async () => {
   sourceList.value = await Getdictionary('source')
   cycleist.value = await Getdictionary('Billingcycle')
-  typeList.value = await Getdictionary('Billingcycle')
-  methodList.value = await Getdictionary('billingMethod')
   currency.value = await Getdictionary('currencyType')
 }
 
+const meal = (data) => {
+  ids.value = data.id
+  modealShow.value = true
+}
+
 
 onMounted(async () => {
   await handleDictValue()

+ 63 - 68
vite.config.js

@@ -1,78 +1,73 @@
-import { defineConfig } from 'vite'
-import vue from '@vitejs/plugin-vue'
-import { createSvgIconsPlugin } from 'vite-plugin-svg-icons'
-
-import { resolve } from 'path'
+import { defineConfig } from "vite";
+import vue from "@vitejs/plugin-vue";
+import { createSvgIconsPlugin } from "vite-plugin-svg-icons";
 
+import { resolve } from "path";
 
 function pathResolve(dir) {
-  return resolve(process.cwd(), '.', dir)
+    return resolve(process.cwd(), ".", dir);
 }
 
 export default defineConfig({
-  resolve: {
-    alias: [
-      {
-        find: '@',
-        replacement: pathResolve('src')
-      }
+    resolve: {
+        alias: [{
+            find: "@",
+            replacement: pathResolve("src"),
+        }, ],
+        dedupe: ["vue"],
+    },
+    plugins: [
+        vue(),
+        createSvgIconsPlugin({
+            // 指定需要缓存的图标文件夹
+            iconDirs: [resolve(process.cwd(), "src/assets/svg")],
+            // 指定symbolId格式
+            symbolId: "icon-[dir]-[name]",
+        }),
     ],
-    dedupe: ['vue']
-  },
-  plugins: [
-    vue(),
-    createSvgIconsPlugin({
-      // 指定需要缓存的图标文件夹
-      iconDirs: [resolve(process.cwd(), 'src/assets/svg')],
-      // 指定symbolId格式
-      symbolId: 'icon-[dir]-[name]',
-    })
-  ],
-  css: {
-    // css预处理器
-    preprocessorOptions: {
-      less: {
-        charset: false, //  解决中文乱码
-        modifyVars: {
-            'arcoblue-6': '#d1402f',
+    css: {
+        // css预处理器
+        preprocessorOptions: {
+            less: {
+                charset: false, //  解决中文乱码
+                modifyVars: {
+                    "arcoblue-6": "#d1402f",
+                },
+                javascriptEnabled: true,
+                additionalData: '@import "@/assets/css/theme.less";@import "@/assets/css/global.less";',
+            },
         },
-        javascriptEnabled: true,
-        additionalData:
-          '@import "@/assets/css/theme.less";@import "@/assets/css/global.less";',
-        
-      },
     },
-  },
-  build: {
-    minify: true, // 生产环境不生成sourcemap
-    target: 'es2015',
-    // 警报门槛,限制大文件大小
-    chunkSizeWarningLimit: 5000,
-    rollupOptions: {
-      external: [], // 外部化处理那些你不想打包进库的依赖
-      // 静态资源分类打包
-      output: {
-        chunkFileNames: 'static/js/[name]-[hash].js',
-        entryFileNames: 'static/js/[name]-[hash].js',
-        assetFileNames: 'static/[ext]/[name]-[hash].[ext]'
-      },
+    build: {
+        minify: true, // 生产环境不生成sourcemap
+        target: "es2015",
+        // 警报门槛,限制大文件大小
+        chunkSizeWarningLimit: 5000,
+        rollupOptions: {
+            external: [], // 外部化处理那些你不想打包进库的依赖
+            // 静态资源分类打包
+            output: {
+                chunkFileNames: "static/js/[name]-[hash].js",
+                entryFileNames: "static/js/[name]-[hash].js",
+                assetFileNames: "static/[ext]/[name]-[hash].[ext]",
+            },
+        },
+    },
+    server: {
+        port: 8088,
+        host: "0.0.0.0",
+        open: true,
+        cors: true,
+        hmr: true,
+        proxy: {
+            "/api": {
+                // target: "http://sim.nanodreamtech.com",
+                // target: "http://127.0.0.1:3001",
+                target: "http://sim.ainets.net",
+                changeOrigin: true,
+                ws: true,
+                secure: true,
+            },
+        },
     },
-  },
-  server: {
-    port: 8088,
-    host: '0.0.0.0',
-    open: true,
-    cors: true,
-    hmr: true,
-    proxy: {
-      '/api': {
-        // target: "http://sim.nanodreamtech.com",
-        // target: "http://127.0.0.1:3001",
-        target:'http://sim.ainets.net',
-        changeOrigin: true,
-        ws: true,
-        secure: true,
-      },
-    }
-  }
-})
+});