Selaa lähdekoodia

增加操作日志 修改变更记录

吴sir 2 kuukautta sitten
vanhempi
sitoutus
ed39bc74e0

+ 9 - 0
src/api/customer.js

@@ -51,4 +51,13 @@ export  function  getMessUserList(data){
 // 客户详情
 export  function  deleteMessUser(params){
     return service.get('admin/platform/customerInfo', {params})
+}
+
+// 操作日志
+export function OperationLogSetNear(data){
+    return service({
+        url: '/logs/logOperation',
+        method: 'post',
+        data
+    })
 }

+ 1 - 1
src/mixins/index.js

@@ -75,4 +75,4 @@ export function tableFunction(_this, apiRequest, processData) {
         tableData,
         SearchForm
     };
-}
+}

+ 4 - 4
src/router/router.update.js

@@ -23,7 +23,7 @@ const component = (view) => {
 
 // 路由格式转化
 const toRoutesJson = (data) => {
-  const LANG =  getLocalStorage("LANG") || {lang}
+  const LANG = getLocalStorage("LANG") || { lang }
   return data.map((item) => {
     const routeItem = {
       path: `/${item.path}`,
@@ -44,7 +44,7 @@ const toRoutesJson = (data) => {
 };
 
 export const updateRouteByMenu = async (router, systemStore) => {
-  if(!systemStore.getToken) {
+  if (!systemStore.getToken) {
     router.push({
       name: "login",
     })
@@ -64,11 +64,11 @@ export const updateRouteByMenu = async (router, systemStore) => {
       name: "main",
       redirect: pathHome.path,
       component: LAYOUT,
-      children: [...publicMenu,...mainRoutes],
+      children: [...publicMenu, ...mainRoutes],
     };
     router.options.routes = [routes, ...systemRoutes];
     await router.addRoute(routes);
-  } catch(err) {
+  } catch (err) {
     console.log(err)
   }
 };

+ 68 - 0
src/views/admin/OperationLog/config.js

@@ -0,0 +1,68 @@
+export const columns = [
+  {
+    title: "序号",
+    dataIndex: "index",
+    align: "center",
+    ellipsis: true,
+    render: ({ rowIndex }) => rowIndex + 1,
+  },
+  {
+    title: "userId",
+    dataIndex: "userId",
+    align: "center",
+    ellipsis: true,
+  },
+  {
+    title: "客户名称",
+    dataIndex: "name",
+    align: "center",
+    ellipsis: true,
+  },
+  {
+    title: "账号名称",
+    dataIndex: "username",
+    align: "center",
+    ellipsis: true,
+  },
+  {
+    title: "请求方式",
+    dataIndex: "method",
+    align: "center",
+    ellipsis: true,
+  },
+  {
+    title: "请求域名",
+    dataIndex: "remark",
+    align: "center",
+    ellipsis: true,
+  },
+  {
+    title: "操作参数",
+    dataIndex: "param",
+    align: "center",
+    width: 300,
+  },
+  {
+    title: "操作时间",
+    dataIndex: "createdAt",
+    align: "center",
+    width: 300,
+  },
+]
+
+export const SearchFrom = [
+  {
+    type: "input",
+    label: "账号名称",
+    field: "name",
+    value: "", // 双向绑定的值
+  },
+  {
+    type: "range-picker",
+    label: "操作时间",
+    field: "createdAt",
+    value: [], // 双向绑定的值
+    width: "300",
+    Custom: 'mode="month"', // 自定义值
+  },
+]

+ 57 - 0
src/views/admin/OperationLog/index.vue

@@ -0,0 +1,57 @@
+<template>
+    <div>
+        <div class="search-section">
+            <Search :SearchForm="SearchFrom" @query="initData" @reset="reset" />
+        </div>
+        <a-table row-key="id" :data="tableData" :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)">编辑</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>
+            </template>
+        </a-table>
+    </div>
+</template>
+
+<script setup>
+import { onMounted, ref } from 'vue';
+import Search from '@/components/Search/index.vue'
+import { columns, SearchFrom } from './config'
+import { OperationLogSetNear } from '@/api/customer'
+import { tableFunction, filterDict } from '@/mixins/index.js'
+
+const pagination = ref({
+    total: 0,
+    pageSize: 10,
+    current: 1,
+})
+const processData = (data) => {
+    return (data.records || []).map((item, index) => {
+        return {
+            ...item,
+            param: JSON.stringify(JSON.parse(item.param))
+        }
+    })
+}
+
+const { tableData, evChangePage, initData, reset } = tableFunction(pagination.value, OperationLogSetNear, processData)
+
+onMounted(()=>{
+    initData()
+})
+</script>
+
+<style scoped lang="less">
+.search-section {
+    margin-top: 20px;
+    margin-bottom: 20px;
+}
+</style>

+ 0 - 240
src/views/admin/OperationRecord/config.js

@@ -1,240 +0,0 @@
-export let columns = [
-  {
-    title: window.$t("tariffManagement.id"),
-    dataIndex: "Number",
-    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.simDataPlanIdName"),
-    dataIndex: "metadataPackagesName",
-    align: "center",
-    width: 200,
-    ellipsis: true,
-  },
-  {
-    title: window.$t("tariffManagement.TestFlowPacketName"),
-    dataIndex: "testMetadataPackagesName",
-    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.BillingMode"),
-    dataIndex: "billingMethodName",
-    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.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("tariffManagement.endDate"),
-    dataIndex: "endDate",
-    align: "center",
-    width: 200,
-    ellipsis: true,
-  },
-];
-// 资费套餐
-export const planColumns = [
-  {
-    title: window.$t("tariffManagement.feeCode"),
-    dataIndex: "feeCode",
-    align: "center",
-    width: 200,
-  },
-  {
-    title: window.$t("tariffManagement.label"),
-    dataIndex: "label",
-    align: "center",
-    width: 200,
-  },
-  {
-    title: window.$t("tariffManagement.source"),
-    dataIndex: "sourceName",
-    align: "center",
-    width: 200,
-  },
-  {
-    title: window.$t("tariffManagement.bagSize"),
-    dataIndex: "bag_size",
-    align: "center",
-    width: 200,
-  },
-];
-
-// 资费搜索字段
-export const trafficSearchFrom = [
-  {
-    type: "input",
-    label: "客户名称",
-    field: "username",
-    value: "", // 双向绑定的值
-  },
-  {
-    type: "input",
-    label: "资费名称",
-    field: "label",
-    value: "", // 双向绑定的值
-  },
-  {
-    type: "select",
-    label: "供应商名称",
-    field: "source",
-    options: [], // 默认空,后面会通过字典加载
-    dict: "source",
-    value: "", // 双向绑定的值
-    width: "200",
-  },
-  {
-    type: "select",
-    label: "流量结算方式",
-    field: "billingMethod",
-    options: [], // 默认空,后面会通过字典加载
-    dict: "billingMethod",
-    value: "", // 双向绑定的值
-    width: "200",
-  },
-  {
-    type: "select",
-    label: "账单计费周期",
-    field: "BillingCycle",
-    options: [], // 默认空,后面会通过字典加载
-    dict: "BillingCycle",
-    value: "", // 双向绑定的值
-    width: "200",
-  },
-  {
-    type: "date-picker",
-    label: "有效期",
-    field: "endDate",
-    value: "", // 双向绑定的值
-    width: "200",
-  },
-];
-
-
-
-// 流量池
-export const columnsFlow = [
-  { title: window.$t('flowPool.poolNumber'), dataIndex: 'id', align: 'center', ellipsis:true,width: 50 },
-  { title: '池类型', dataIndex: 'trafficPoolType', align: 'center', ellipsis:true,width: 50 },
-  { title: window.$t('flowPool.label'), dataIndex: 'label', align: 'center', width: 200 ,tooltip:true,ellipsis:true},
-  { title: window.$t('flowPool.trafficPoolStatus'), slotName: 'status', align: 'center', width: 200 ,tooltip:true,ellipsis:true},
-  { title: window.$t('flowPool.source'), dataIndex: 'sourceName', align: 'center', width: 200 ,tooltip:true,ellipsis:true},
-  { title: window.$t('flowPool.tariffName'), dataIndex: 'simTariffName', align: 'center', width: 200 ,tooltip:true,ellipsis:true},
-  { title:'池大小', dataIndex: 'size', align: 'center', width: 200 ,tooltip:true,ellipsis:true},
-  { title: window.$t('flowPool.ActivatedName'),dataIndex:'Activated', align: 'center', width: 200 ,tooltip:true,ellipsis:true},
-  { title: window.$t('flowPool.HaveBeenUsedName'), dataIndex: 'HaveBeenUsed', align: 'center', width: 200 ,tooltip:true,ellipsis:true},
-  { title: window.$t('flowPool.updated_at'), dataIndex: 'updatedAt', align: 'center', width: 200,tooltip:true,ellipsis:true },
-]
-
-
-export const SearchFormList = [
-  {
-    type: "input",
-    label: "流量池名称",
-    field: "label",
-    value: "", // 双向绑定的值
-  },
-  {
-    type: "select",
-    label: "流量池状态",
-    field: "status",
-    options: [], // 默认空,后面会通过字典加载
-    dict: "trafficPacketStatus",
-    value: "", // 双向绑定的值
-    width: "200",
-  },
-  {
-    type: "select",
-    label: "运营商名称",
-    field: "source",
-    options: [], // 默认空,后面会通过字典加载
-    dict: "source",
-    value: "", // 双向绑定的值
-    width: "200",
-  },
-  {
-    type: "input",
-    label: "资费名称",
-    field: "tariffName",
-    value: "", // 双向绑定的值
-  },
-  {
-    type: "range-picker",
-    label: "更新日期",
-    field: "updatedAt",
-    value: "", // 双向绑定的值
-    width: "240",
-  },
-];
-

+ 3 - 3
src/views/admin/OperationRecord/FlowpoolRecord/index.vue → src/views/admin/flowPool/FlowpoolRecord/index.vue

@@ -3,10 +3,10 @@
   <div class="container">
     <!-- 搜索条件区 -->
     <div class="search-section">
-      <Search :SearchForm="SearchFormList" @query="initData" @reset="reset"></Search>
+      <Search :SearchForm="SearchFormListOperationLog" @query="initData" @reset="reset"></Search>
     </div>
 
-    <a-table row-key="id" :data="tableData" :columns="columnsFlow" :pagination="pagination" :scroll="{ x: 'auto' }"
+    <a-table row-key="id" :data="tableData" :columns="columnsFlowOperationLog" :pagination="pagination" :scroll="{ x: 'auto' }"
       @page-change="evChangePage">
 
       <template #status="{ record }">
@@ -22,7 +22,7 @@
 
 <script setup>
 import { onMounted, ref, toRefs } from "vue";
-import { columnsFlow, SearchFormList } from "../config";
+import { columnsFlowOperationLog, SearchFormListOperationLog } from "../config";
 import {
   updateFlowPoolData,
 } from "@/api/path/flowPool.api"

+ 61 - 0
src/views/admin/flowPool/config.js

@@ -207,3 +207,64 @@ export const SearchFormList = [
     width: "240",
   },
 ];
+
+
+
+
+
+
+// 流量池
+export const columnsFlowOperationLog = [
+  { title: window.$t('flowPool.poolNumber'), dataIndex: 'id', align: 'center', ellipsis:true,width: 50 },
+  { title: '池类型', dataIndex: 'trafficPoolType', align: 'center', ellipsis:true,width: 50 },
+  { title: window.$t('flowPool.label'), dataIndex: 'label', align: 'center', width: 200 ,tooltip:true,ellipsis:true},
+  { title: window.$t('flowPool.trafficPoolStatus'), slotName: 'status', align: 'center', width: 200 ,tooltip:true,ellipsis:true},
+  { title: window.$t('flowPool.source'), dataIndex: 'sourceName', align: 'center', width: 200 ,tooltip:true,ellipsis:true},
+  { title: window.$t('flowPool.tariffName'), dataIndex: 'simTariffName', align: 'center', width: 200 ,tooltip:true,ellipsis:true},
+  { title:'池大小', dataIndex: 'size', align: 'center', width: 200 ,tooltip:true,ellipsis:true},
+  { title: window.$t('flowPool.ActivatedName'),dataIndex:'Activated', align: 'center', width: 200 ,tooltip:true,ellipsis:true},
+  { title: window.$t('flowPool.HaveBeenUsedName'), dataIndex: 'HaveBeenUsed', align: 'center', width: 200 ,tooltip:true,ellipsis:true},
+  { title: window.$t('flowPool.updated_at'), dataIndex: 'updatedAt', align: 'center', width: 200,tooltip:true,ellipsis:true },
+]
+
+
+export const SearchFormListOperationLog= [
+  {
+    type: "input",
+    label: "流量池名称",
+    field: "label",
+    value: "", // 双向绑定的值
+  },
+  {
+    type: "select",
+    label: "流量池状态",
+    field: "status",
+    options: [], // 默认空,后面会通过字典加载
+    dict: "trafficPacketStatus",
+    value: "", // 双向绑定的值
+    width: "200",
+  },
+  {
+    type: "select",
+    label: "运营商名称",
+    field: "source",
+    options: [], // 默认空,后面会通过字典加载
+    dict: "source",
+    value: "", // 双向绑定的值
+    width: "200",
+  },
+  {
+    type: "input",
+    label: "资费名称",
+    field: "tariffName",
+    value: "", // 双向绑定的值
+  },
+  {
+    type: "range-picker",
+    label: "更新日期",
+    field: "updatedAt",
+    value: "", // 双向绑定的值
+    width: "240",
+  },
+];
+

+ 18 - 9
src/views/admin/system/menu/index.vue

@@ -225,15 +225,24 @@ const fnDeleteTreeSon = (data) => {
 };
 
 const fnGetFormData = async () => {
-  const arr = [];
-  const comp = import.meta.glob("../../../views/**/index.vue");
-  if (comp) {
-    Object.keys(comp).forEach((key) => {
-      arr.push(`${comp[key]}`.replace(/^.*import\("\/src\/([^?"]+).*$/, '$1'));
-    });
-    arr.push("views/system/menu/index.vue")
-    refData.menuList = arr
-  }
+    const arr = [];
+    // 匹配 views 目录下所有直接的 .vue 文件以及 admin 和 user 子文件夹下的 .vue 文件
+    const comp = import.meta.glob([
+        "../../../../views/*.vue", 
+        "../../../../views/admin/**/*.vue", 
+        "../../../../views/user/**/*.vue"
+    ]);
+    console.log(comp);
+
+    if (comp) {
+        for (const key in comp) {
+            const original = `${comp[key]}`;
+            const replaced = original.replace(/^.*import\("\/src\/([^?"]+).*$/, '$1');
+            arr.push(replaced);
+        }
+        arr.push("views/system/menu/index.vue");
+        refData.menuList = arr;
+    }
 };
 
 const evCancel = () => {

+ 3 - 3
src/views/admin/OperationRecord/TariffRecord/index.vue → src/views/admin/tariffManagement/TariffRecord/index.vue

@@ -3,9 +3,9 @@
   <div class="container">
     <!-- 搜索条件区 -->
     <div class="search-section">
-      <Search :SearchForm="trafficSearchFrom" @query="initData" @reset="reset" />
+      <Search :SearchForm="trafficSearchFromOperationLog" @query="initData" @reset="reset" />
     </div>
-    <a-table row-key="id" :data="tableData" :columns="columns" :pagination="pagination" :scroll="{ x: 'auto' }"
+    <a-table row-key="id" :data="tableData" :columns="columnsOperationLog" :pagination="pagination" :scroll="{ x: 'auto' }"
       @page-change="evChangePage">
       <template #id="{ record }">
         <a-button type="text" @click="detaile(record)">详情</a-button>
@@ -16,7 +16,7 @@
 
 <script setup>
 import { onMounted, ref, toRefs } from "vue";
-import { columns, planColumns, trafficSearchFrom } from "../config";
+import { columnsOperationLog, trafficSearchFromOperationLog } from "../config";
 import { tariffList } from "@/api/path/tariffManagement.api"
 import { Getdictionary, tableFunction, filterDict } from '@/mixins/index.js'
 import Search from '@/components/Search/index.vue'

+ 157 - 0
src/views/admin/tariffManagement/config.js

@@ -399,3 +399,160 @@ export const trafficSearchFrom = [
     width: "200",
   },
 ];
+
+
+export let columnsOperationLog = [
+  {
+    title: window.$t("tariffManagement.id"),
+    dataIndex: "Number",
+    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.simDataPlanIdName"),
+    dataIndex: "metadataPackagesName",
+    align: "center",
+    width: 200,
+    ellipsis: true,
+  },
+  {
+    title: window.$t("tariffManagement.TestFlowPacketName"),
+    dataIndex: "testMetadataPackagesName",
+    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.BillingMode"),
+    dataIndex: "billingMethodName",
+    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.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("tariffManagement.endDate"),
+    dataIndex: "endDate",
+    align: "center",
+    width: 200,
+    ellipsis: true,
+  },
+];
+
+// 资费搜索字段
+export const trafficSearchFromOperationLog = [
+  {
+    type: "input",
+    label: "客户名称",
+    field: "username",
+    value: "", // 双向绑定的值
+  },
+  {
+    type: "input",
+    label: "资费名称",
+    field: "label",
+    value: "", // 双向绑定的值
+  },
+  {
+    type: "select",
+    label: "供应商名称",
+    field: "source",
+    options: [], // 默认空,后面会通过字典加载
+    dict: "source",
+    value: "", // 双向绑定的值
+    width: "200",
+  },
+  {
+    type: "select",
+    label: "流量结算方式",
+    field: "billingMethod",
+    options: [], // 默认空,后面会通过字典加载
+    dict: "billingMethod",
+    value: "", // 双向绑定的值
+    width: "200",
+  },
+  {
+    type: "select",
+    label: "账单计费周期",
+    field: "BillingCycle",
+    options: [], // 默认空,后面会通过字典加载
+    dict: "BillingCycle",
+    value: "", // 双向绑定的值
+    width: "200",
+  },
+  {
+    type: "date-picker",
+    label: "有效期",
+    field: "endDate",
+    value: "", // 双向绑定的值
+    width: "200",
+  },
+];

+ 1 - 1
src/views/lotCard/cardList/trafficUseDialog.vue

@@ -226,7 +226,7 @@ const state = ref({
   dataOperation: []
 })
 
-const {visible,Card_info,dataPackage,dataSource,pageData,pageDataAounmt,pagination,option,dataCard,dataTopup,dataAmount,dataOperation} = toRefs(state.value)
+const { visible, Card_info, dataPackage, dataSource, pageData, pageDataAounmt, pagination, option, dataCard, dataTopup, dataAmount, dataOperation } = toRefs(state.value)
 
 const open = async (data) => {
   if (!data) {