Handy_Cao 6 месяцев назад
Родитель
Сommit
4a45f321fd

+ 2 - 0
public/locales/en-US.json

@@ -3504,6 +3504,8 @@
         "system_clientlog": "Terminal Login Log",
         "system_userblacklist": "Account Blacklist Management",
         "system_ipblacklist": "IP Blacklist Management",
+        "system_ipblacklist_add": "Add",
+        "system_ipblacklist_delete": "Delete",
         "system_exrate": "System Exchange Rate Management",
         "marketrun": "Market Operation Management",
         "marketrun_market": "Market Monitoring",

+ 2 - 0
public/locales/th-TH.json

@@ -3504,6 +3504,8 @@
         "system_clientlog": "บันทึกการเข้าสู่ระบบของอุปกรณ์",
         "system_userblacklist": "การจัดการบัญชีแบล็คลิสต์",
         "system_ipblacklist": "การจัดการ IP แบล็คลิสต์",
+        "system_ipblacklist_add": "เพิ่มใหม่",
+        "system_ipblacklist_delete": "ลบ",
         "system_exrate": "การจัดการอัตราแลกเปลี่ยนของระบบ",
         "marketrun": "การจัดการการดำเนินงานของตลาด",
         "marketrun_market": "การตรวจสอบตลาด",

+ 2 - 0
public/locales/vi-VN.json

@@ -3504,6 +3504,8 @@
         "system_clientlog": "Nhật ký đăng nhập thiết bị",
         "system_userblacklist": "Quản lý danh sách đen mở tài khoản",
         "system_ipblacklist": "Quản lý danh sách đen mở IP",
+        "system_ipblacklist_add": "Thêm mới",
+        "system_ipblacklist_delete": "Xóa",
         "system_exrate": "Quản lý tỷ giá hệ thống",
         "marketrun": "Quản lý vận hành thị trường",
         "marketrun_market": "Giám sát thị trường",

+ 2 - 0
public/locales/zh-CN.json

@@ -3504,6 +3504,8 @@
         "system_clientlog": "终端登录日志",
         "system_userblacklist": "开户黑名单管理",
         "system_ipblacklist": "IP黑名单管理",
+        "system_ipblacklist_add": "新增",
+        "system_ipblacklist_delete": "删除",
         "system_exrate": "系统汇率管理",
         "marketrun": "市场运行管理",
         "marketrun_market": "市场监控",

+ 2 - 0
public/locales/zh-TW.json

@@ -3504,6 +3504,8 @@
         "system_clientlog": "終端登錄日誌",
         "system_userblacklist": "開戶黑名單管理",
         "system_ipblacklist": "IP黑名單管理",
+        "system_ipblacklist_add": "新增",
+        "system_ipblacklist_delete": "刪除",
         "system_exrate": "系統匯率管理",
         "marketrun": "市場運行管理",
         "marketrun_market": "市場監控",

+ 0 - 0
src/packages/pc/views/system/client_log/components/details/index.vue


+ 101 - 1
src/packages/pc/views/system/client_log/index.vue

@@ -1,7 +1,107 @@
 <!-- 系统运行管理-终端登录日志 -->
 <template>
-    <app-view></app-view>
+    <app-view>
+        <template #header>
+            <app-filter :option="filterOption">
+                <!-- 历史查询 -->
+                <template #ishis="{ item }">
+                    <el-form-item :label="item.label" prop="ishis">
+                        <el-switch v-model="item.value" active-value="1" inactive-value="0" />
+                    </el-form-item>
+                </template>
+            </app-filter>
+        </template>
+        <app-table :data="dataList" showIndex :columns="tableColumns" :loading="loading">
+            <!-- 操作 -->
+            <template #operate="{ row }">
+                <app-operation size="small" :data-list="getActionButtons(['system_clientlog_details'])"
+                    @click="(code: string) => openComponent(code, row)" circle />
+            </template>
+            <template #footer>
+                <app-pagination :total="total" v-model:page-size="pageSize" v-model:page-index="pageIndex"
+                    @change="onSearch" />
+            </template>
+        </app-table>
+        <component :is="componentMap.get(componentId)" v-bind="{ record }" @closed="closeComponent"
+            v-if="componentId" />
+    </app-view>
 </template>
 
 <script lang="ts" setup>
+import { ref } from 'vue'
+import { ElMessage } from 'element-plus'
+import { useDataFilter } from '@/hooks/datatable-v2'
+import { useRequest } from '@/hooks/request'
+import { useOperation } from '@/hooks/operation'
+import { queryloginlog } from '@/services/api/system'
+import { i18n } from '@/stores'
+import { useEnum } from '@/hooks/enum'
+import AppTable from '@pc/components/base/table/index.vue'
+import AppPagination from '@pc/components/base/pagination/index.vue'
+import AppOperation from '@pc/components/base/operation/index.vue'
+import AppFilter from '@pc/components/base/table-filter-v2/index.vue'
+import { formatDate } from '@/filters'
+
+const { global: { t } } = i18n
+// 状态
+const logintypeEnum = useEnum('logintype')
+const operatetypeEnum = useEnum('operatetype')
+const loginretcodeEnum = useEnum('loginretcode')
+
+const { componentMap, componentId, record, openComponent, closeComponent, getActionButtons } = useOperation<Model.LoginLogViewRsp>({
+    onClose: () => onSearch()
+})
+
+const { dataList, total, pageSize, pageIndex, loading, run } = useRequest(queryloginlog, {
+    params: {
+        pageNum: 1,
+        pageSize: 20
+    },
+    onError: (err) => {
+        ElMessage.error(err)
+    }
+})
+
+const tableColumns = ref<Model.TableColumn[]>([
+    { field: 'logincode', label: '登录账号' },
+    { field: 'accountname', label: '客户名称	' },
+    { field: 'areaname', label: '所属机构' },
+    { field: 'membername', label: '所属会员' },
+    { field: 'loginip', label: '登录IP' },
+    { field: 'logintype', label: '登录/登出', formatValue: (val) => logintypeEnum.getEnumTypeName(val) },
+    { field: 'operatetime', label: '时间', formatValue: (val) => formatDate(val) },
+    { field: 'loginretcode', label: '结果', formatValue: (val) => loginretcodeEnum.getEnumTypeName(val) },
+    { field: 'operatetype', label: '操作类型', formatValue: (val) => operatetypeEnum.getEnumTypeName(val) },
+    { field: 'operate', label: 'common.operate', fixed: 'right' }
+])
+
+const { filterOption, getQueryParams, resetFilters } = useDataFilter<Model.LoginLogExportReq>({
+    filters: [
+        {
+            field: 'logincode',
+            label: '登录账号',
+            placeholder: '模糊匹配',
+        },
+        {
+            field: 'accountname',
+            label: '客户名称',
+            placeholder: '模糊匹配',
+        },
+        {
+            field: 'ishis',
+            label: '历史查询',
+            value: 0
+        },
+    ],
+    buttons: [
+        { label: t('operation.search'), className: 'el-button--primary', onClick: () => onSearch() },
+        { label: t('operation.reset'), className: 'el-button--primary', validateEvent: false, onClick: () => resetFilters() }
+    ]
+})
+
+const onSearch = () => {
+    const qs = getQueryParams()
+    run(qs)
+}
+
 </script>

+ 0 - 7
src/packages/pc/views/system/ip_blacklist/index.vue

@@ -1,7 +0,0 @@
-<!-- 系统运行管理-IP黑名单管理 -->
-<template>
-    <app-view></app-view>
-</template>
-
-<script lang="ts" setup>
-</script>

+ 54 - 0
src/packages/pc/views/system/ipblacklist/components/delete/index.vue

@@ -0,0 +1,54 @@
+<!-- 系统运行管理-IP黑名单管理-删除 -->
+<template>
+    <app-drawer :title="t('common.alert')" v-model:show="show" :loading="loading" :refresh="refresh">
+        <div class="g-text-message">确定删除该IP地址?</div>
+        <template #footer>
+            <el-button @click="onCancel(false)">{{ t('operation.cancel') }}</el-button>
+            <el-button type="primary" @click="onSubmit">{{ t('operation.confirm') }}</el-button>
+        </template>
+    </app-drawer>
+</template>
+
+<script lang="ts" setup>
+import { shallowRef, PropType } from 'vue'
+import { ElMessage } from 'element-plus'
+import { delIPList } from '@/services/api/system'
+import AppDrawer from '@pc/components/base/drawer/index.vue'
+import { i18n } from '@/stores'
+
+const props = defineProps({
+    record: {
+        type: Object as PropType<Model.IPListRsp>,
+        required: true
+    }
+})
+
+const { global: { t } } = i18n
+const show = shallowRef(true)
+const refresh = shallowRef(false)
+const loading = shallowRef(false)
+
+const onCancel = (isRefresh = false) => {
+    show.value = false
+    refresh.value = isRefresh
+}
+
+const onSubmit = () => {
+    loading.value = true
+    // 删除
+    delIPList({
+        data: {
+            ip: props.record.ip,
+            iptype: props.record.iptype,
+        }
+    }).then(() => {
+        ElMessage.success(t('common.tips5'))
+        onCancel(true)
+    }).catch((err) => {
+        ElMessage.error(t('common.tips6') + err)
+        onCancel()
+    }).finally(() => {
+        loading.value = false
+    })
+}
+</script>

+ 65 - 0
src/packages/pc/views/system/ipblacklist/components/edit/index.vue

@@ -0,0 +1,65 @@
+<!-- 系统运行管理-IP黑名单管理-新增 -->
+<template>
+    <app-drawer title="新增" width="500" v-model:show="show" :loading="loading" :refresh="refresh">
+        <el-form ref="formRef" label-width="80px" :model="formData" :rules="formRules" :show-message="false">
+            <el-form-item label="IP地址" prop="ip">
+                <el-input v-model="formData.ip" maxlength="50" :placeholder="t('common.pleaseenter')" />
+            </el-form-item>
+            <el-form-item label="IP类型" prop="iptype">
+                <app-enum code="iptype" v-model="formData.iptype" />
+            </el-form-item>
+        </el-form>
+        <template #footer>
+            <el-button @click="onCancel(false)">{{ t('operation.cancel') }}</el-button>
+            <el-button type="primary" @click="onSubmit">{{ t('operation.save') }}</el-button>
+        </template>
+    </app-drawer>
+</template>
+
+<script lang="ts" setup>
+import { shallowRef, ref } from 'vue'
+import { ElMessage, FormInstance, FormRules } from 'element-plus'
+import { i18n } from '@/stores'
+import { addIPList } from '@/services/api/system'
+import AppDrawer from '@pc/components/base/drawer/index.vue'
+import AppEnum from '@pc/components/modules/enum/index.vue'
+
+const formData = ref<Partial<Model.AddIPListReq>>({})
+
+const { global: { t } } = i18n
+const formRef = ref<FormInstance>()
+const show = shallowRef(true)
+const refresh = shallowRef(false)
+const loading = shallowRef(false)
+
+// 表单验证规则
+const formRules: FormRules = {
+    ip: [{ required: true }],
+    iptype: [{ required: true }]
+}
+
+const onSubmit = () => {
+    const rawData = { ...formData.value }
+    formRef.value?.validate((valid) => {
+        if (valid) {
+            loading.value = true
+            addIPList({
+                data: rawData
+            }).then(() => {
+                ElMessage.success(t('common.tips3'))
+                onCancel(true)
+            }).catch((err) => {
+                ElMessage.error(t('common.tips4') + err)
+            }).finally(() => {
+                loading.value = false
+            })
+        }
+    })
+}
+
+const onCancel = (isRefresh = false) => {
+    show.value = false
+    refresh.value = isRefresh
+}
+
+</script>

+ 85 - 0
src/packages/pc/views/system/ipblacklist/index.vue

@@ -0,0 +1,85 @@
+<!-- 系统运行管理-IP黑名单管理 -->
+<template>
+    <app-view>
+        <template #header>
+            <app-filter :option="filterOption" />
+        </template>
+        <app-table :data="dataList" showIndex :columns="tableColumns" :loading="loading">
+            <template #headerLeft>
+                <app-operation :data-list="getActionButtons(['system_ipblacklist_add'])"
+                    @click="openComponent" />
+            </template>
+            <!-- 操作 -->
+            <template #operate="{ row }">
+                <app-operation size="small" :data-list="getActionButtons(['system_ipblacklist_delete'])"
+                    @click="(code: string) => openComponent(code, row)" circle />
+            </template>
+            <template #footer>
+                <app-pagination :total="total" v-model:page-size="pageSize" v-model:page-index="pageIndex"
+                    @change="onSearch" />
+            </template>
+        </app-table>
+        <component :is="componentMap.get(componentId)" v-bind="{ record }" @closed="closeComponent"
+            v-if="componentId" />
+    </app-view>
+</template>
+
+<script lang="ts" setup>
+import { ref } from 'vue'
+import { ElMessage } from 'element-plus'
+import { useDataFilter } from '@/hooks/datatable-v2'
+import { useRequest } from '@/hooks/request'
+import { useOperation } from '@/hooks/operation'
+import { queryIPList } from '@/services/api/system'
+import { i18n } from '@/stores'
+import { useEnum } from '@/hooks/enum'
+import AppTable from '@pc/components/base/table/index.vue'
+import AppPagination from '@pc/components/base/pagination/index.vue'
+import AppOperation from '@pc/components/base/operation/index.vue'
+import AppFilter from '@pc/components/base/table-filter-v2/index.vue'
+
+const { global: { t } } = i18n
+// 状态
+const iptypeEnum = useEnum('iptype')
+
+const { componentMap, componentId, record, openComponent, closeComponent, getActionButtons } = useOperation<Model.IPListRsp>({
+    onClose: () => onSearch()
+})
+
+const { dataList, total, pageSize, pageIndex, loading, run } = useRequest(queryIPList, {
+    params: {
+        pageNum: 1,
+        pageSize: 20
+    },
+    onError: (err) => {
+        ElMessage.error(err)
+    }
+})
+
+const tableColumns = ref<Model.TableColumn[]>([
+    { field: 'ip', label: 'IP地址' },
+    { field: 'iptype', label: 'IP类型', formatValue: (val) => iptypeEnum.getEnumTypeName(val) },
+    { field: 'operate', label: 'common.operate', fixed: 'right' }
+])
+
+const { filterOption, getQueryParams, resetFilters } = useDataFilter<Model.IPListReq>({
+    filters: [
+        {
+            field: 'adress',
+            label: 'IP地址',
+            placeholder: '输入IP地址模糊匹配',
+            required: true,
+        }
+    ],
+    buttons: [
+        { label: t('operation.search'), className: 'el-button--primary', onClick: () => onSearch() },
+        { label: t('operation.reset'), className: 'el-button--primary', validateEvent: false, onClick: () => resetFilters() }
+    ]
+})
+
+const onSearch = () => {
+    const qs = getQueryParams()
+    run(qs)
+}
+
+</script>

+ 88 - 1
src/packages/pc/views/system/service_log/index.vue

@@ -1,7 +1,94 @@
 <!-- 系统运行管理-系统服务运行日志 -->
 <template>
-    <app-view></app-view>
+    <app-view>
+        <template #header>
+            <app-filter :option="filterOption">
+                <!-- 交易日 -->
+                <template #tradedate="{ item }">
+                    <el-form-item prop="tradedate">
+                        <el-date-picker v-model="item.value" value-format="YYYY-MM-DD"
+                            :placeholder="t('common.pleasechoice')" />
+                    </el-form-item>
+                </template>
+            </app-filter>
+        </template>
+        <app-table :data="dataList" showIndex :columns="tableColumns" :loading="loading">
+            <template #footer>
+                <app-pagination :total="total" v-model:page-size="pageSize" v-model:page-index="pageIndex"
+                    @change="onSearch" />
+            </template>
+        </app-table>
+        <component :is="componentMap.get(componentId)" v-bind="{ record }" @closed="closeComponent"
+            v-if="componentId" />
+    </app-view>
 </template>
 
 <script lang="ts" setup>
+import { ref } from 'vue'
+import { ElMessage } from 'element-plus'
+import { useDataFilter } from '@/hooks/datatable-v2'
+import { useRequest } from '@/hooks/request'
+import { useOperation } from '@/hooks/operation'
+import { querymrsl } from '@/services/api/system'
+import { i18n } from '@/stores'
+import { useEnum } from '@/hooks/enum'
+import { formatDate } from '@/filters'
+import { useMarket } from '@/hooks/market'
+import AppTable from '@pc/components/base/table/index.vue'
+import AppPagination from '@pc/components/base/pagination/index.vue'
+import AppFilter from '@pc/components/base/table-filter-v2/index.vue'
+
+const { global: { t } } = i18n
+const { getMarketOptions } = useMarket()
+
+// 状态
+const runstatusEnum = useEnum('runstatus')
+
+const { componentMap, componentId, record, closeComponent } = useOperation<Model.MrslRsp>({
+    onClose: () => onSearch()
+})
+
+const { dataList, total, pageSize, pageIndex, loading, run } = useRequest(querymrsl, {
+    params: {
+        pageNum: 1,
+        pageSize: 20
+    },
+    onError: (err) => {
+        ElMessage.error(err)
+    }
+})
+
+const tableColumns = ref<Model.TableColumn[]>([
+    { field: 'tradedate', label: '交易日' },
+    { field: 'updatetime', label: '时间', formatValue: (val) => formatDate(val) },
+    { field: 'marketname', label: '服务模块' },
+    { field: 'runstatus', label: '运行类型', formatValue: (val) => runstatusEnum.getEnumTypeName(val) },
+    { field: 'runstatus', label: '运行状态' },
+    { field: 'remark', label: '备注',},
+])
+
+const { filterOption, getQueryParams, resetFilters } = useDataFilter<Model.MrslReq>({
+    filters: [
+        {
+            field: 'tradedate',
+            label: '交易日',
+            placeholder: '模糊匹配',
+        },
+        {
+            field: 'marketid',
+            label: '市场',
+            options: () => getMarketOptions()
+        }
+    ],
+    buttons: [
+        { label: t('operation.search'), className: 'el-button--primary', onClick: () => onSearch() },
+        { label: t('operation.reset'), className: 'el-button--primary', validateEvent: false, onClick: () => resetFilters() }
+    ]
+})
+
+const onSearch = () => {
+    const qs = getQueryParams()
+    run(qs)
+}
+
 </script>