소스 검색

1. 封禁功能
2. 订单查询功能

ith5 6 달 전
부모
커밋
6f71acf4fb

+ 5 - 0
src/components/sa-table/index.vue

@@ -636,6 +636,9 @@ const __summary = ({ data }) => {
               summaryData[item.dataIndex] +=
                 parseFloat(record[item.dataIndex]) / length;
             }
+            if (item.action && item.action === "totalRow") {
+              summaryData[item.dataIndex] = tableData.totalRow;
+            }
           }
         });
       }
@@ -824,9 +827,11 @@ const requestData = async () => {
     if (response.data && response.data.data) {
       tableData.total = response.data.total;
       tableData.data = response.data.data;
+      tableData.totalRow = response.data?.totalRow || 0;
     } else {
       tableData.total = 0;
       tableData.data = response.data;
+      tableData.totalRow = 0;
     }
   } else {
     console.error(`sa-table error:crud.api is not Function.`);

+ 16 - 0
src/views/v1/api/customer/account.js

@@ -88,4 +88,20 @@ export default {
       data,
     });
   },
+  // 封禁列表
+  getBanListApi(params = {}) {
+    return request({
+      url: "/v1/customer/Account/getBanList",
+      method: "get",
+      params,
+    });
+  },
+  // 封禁
+  saveBanApi(data) {
+    return request({
+      url: "/v1/customer/Account/saveBan",
+      method: "post",
+      data,
+    });
+  },
 };

+ 76 - 0
src/views/v1/api/customer/sdkOrder.js

@@ -0,0 +1,76 @@
+import { request } from "@/utils/request.js";
+
+/**
+ * 用户订单记录 API接口
+ */
+export default {
+  /**
+   * 数据列表
+   * @returns
+   */
+  getPageList(params = {}) {
+    return request({
+      url: "/v1/customer/SdkOrder/index",
+      method: "get",
+      params,
+    });
+  },
+
+  /**
+   * 添加数据
+   * @returns
+   */
+  save(params = {}) {
+    return request({
+      url: "/v1/customer/SdkOrder/save",
+      method: "post",
+      data: params,
+    });
+  },
+
+  /**
+   * 更新数据
+   * @returns
+   */
+  update(id, data = {}) {
+    return request({
+      url: "/v1/customer/SdkOrder/update?id=" + id,
+      method: "put",
+      data,
+    });
+  },
+
+  /**
+   * 读取数据
+   * @returns
+   */
+  read(id) {
+    return request({
+      url: "/v1/customer/SdkOrder/read?id=" + id,
+      method: "get",
+    });
+  },
+
+  /**
+   * 删除数据
+   * @returns
+   */
+  destroy(data) {
+    return request({
+      url: "/v1/customer/SdkOrder/destroy",
+      method: "delete",
+      data,
+    });
+  },
+
+  /**
+   * 补发
+   * @returns
+   */
+  send(orderid) {
+    return request({
+      url: "/v1/customer/SdkOrder/send?orderid=" + orderid,
+      method: "post",
+    });
+  },
+};

+ 116 - 0
src/views/v1/customer/account/addBan.vue

@@ -0,0 +1,116 @@
+<template>
+  <component
+    is="a-modal"
+    :width="tool.getDevice() === 'mobile' ? '100%' : '600px'"
+    v-model:visible="visible"
+    :title="title"
+    :mask-closable="false"
+    :ok-loading="loading"
+    @cancel="close"
+    @before-ok="submit"
+  >
+    <!-- 表单信息 start -->
+    <a-form
+      ref="formRef"
+      :model="formData"
+      :rules="rules"
+      :auto-label-width="true"
+    >
+      <a-form-item label="操作" field="action">
+        <a-radio-group v-model="formData.action">
+          <a-radio value="1">封禁</a-radio>
+          <a-radio value="2">解除封禁</a-radio>
+        </a-radio-group>
+      </a-form-item>
+      <a-form-item label="类型" field="type">
+        <a-radio-group v-model="formData.type">
+          <a-radio value="1">UID</a-radio>
+          <a-radio value="2">IP</a-radio>
+          <a-radio value="3">设备</a-radio>
+        </a-radio-group>
+      </a-form-item>
+      <a-form-item label="值" field="value">
+        <a-textarea v-model="formData.value" placeholder="请输入值" :rows="3">
+        </a-textarea>
+        <template #extra> 多个请用英文逗号,隔开 </template>
+      </a-form-item>
+      <a-form-item label="理由" field="reason">
+        <a-textarea v-model="formData.reason" placeholder="请输入理由" />
+      </a-form-item>
+    </a-form>
+    <!-- 表单信息 end -->
+  </component>
+</template>
+
+<script setup>
+import { ref, reactive, computed } from "vue";
+import tool from "@/utils/tool";
+import { Message, Modal } from "@arco-design/web-vue";
+import api from "../../api/customer/account";
+
+const emit = defineEmits(["success"]);
+// 引用定义
+const visible = ref(false);
+const loading = ref(false);
+const formRef = ref();
+
+let title = computed(() => {
+  return "封禁|解除封禁";
+});
+
+// 表单初始值
+const initialFormData = {
+  action: "",
+  type: "",
+  value: "",
+  reason: "",
+};
+
+// 表单信息
+const formData = reactive({ ...initialFormData });
+
+// 验证规则
+const rules = {
+  action: [{ required: true, message: "操作必需填写" }],
+  type: [{ required: true, message: "类型必需填写" }],
+  value: [{ required: true, message: "值必需填写" }],
+  reason: [{ required: true, message: "理由必需填写" }],
+};
+
+// 打开弹框
+const open = async () => {
+  formRef.value.clearValidate();
+  formRef.value.resetFields();
+  visible.value = true;
+  await initPage();
+};
+
+// 初始化页面数据
+const initPage = async () => {};
+
+// 数据保存
+const submit = async (done) => {
+  const validate = await formRef.value?.validate();
+  if (!validate) {
+    loading.value = true;
+    let data = { ...formData };
+    let result = await api.saveBanApi(data);
+
+    if (result.code === 200) {
+      Message.success("操作成功");
+      emit("success");
+      done(true);
+    }
+    // 防止连续点击提交
+    setTimeout(() => {
+      loading.value = false;
+    }, 500);
+  }
+  done(false);
+};
+
+// 关闭弹窗
+const close = () => (visible.value = false);
+
+defineExpose({ open });
+</script>

+ 103 - 0
src/views/v1/customer/account/banList.vue

@@ -0,0 +1,103 @@
+<template>
+  <div class="ma-content-block">
+    <sa-table
+      ref="crudRef"
+      :options="options"
+      :columns="columns"
+      :searchForm="searchForm"
+    >
+      <template #tableSearch>
+        <a-col :sm="6" :xs="24">
+          <a-form-item label="操作" field="action">
+            <a-select
+              v-model="searchForm.action"
+              allow-clear
+              placeholder="请选择操作"
+            >
+              <a-option value="1">封禁</a-option>
+              <a-option value="2">解封</a-option>
+            </a-select>
+          </a-form-item>
+        </a-col>
+      </template>
+
+      <!-- Table 自定义渲染 -->
+    </sa-table>
+    <!-- 编辑表单 -->
+    <add-ban ref="addRef" @success="refresh" />
+  </div>
+</template>
+
+<script setup>
+import { ref, reactive, onMounted } from "vue";
+import api from "../../api/customer/account";
+import AddBan from "./addBan.vue";
+
+const addRef = ref();
+const crudRef = ref();
+
+// 搜索表单
+const searchForm = ref({});
+
+// SaTable 基础配置
+const options = reactive({
+  api: api.getBanListApi,
+  operationColumn: false,
+  add: {
+    show: true,
+    auth: ["/v1/customer/Account/banList/add"],
+    text: "添加封禁|解除封禁",
+    icon: "",
+    func: async () => {
+      addRef.value?.open();
+    },
+  },
+});
+
+const columns = ref([
+  {
+    title: "操作",
+    dataIndex: "action",
+    key: "action",
+  },
+  {
+    title: "类型",
+    key: "type",
+    dataIndex: "type",
+  },
+  {
+    title: "值",
+    key: "value",
+    dataIndex: "value",
+  },
+  {
+    title: "理由",
+    key: "reason",
+    dataIndex: "reason",
+  },
+  {
+    title: "操作人",
+    key: "auth_name",
+    dataIndex: "auth_name",
+  },
+  {
+    title: "操作时间",
+    key: "created_time",
+    dataIndex: "created_time",
+  },
+]);
+
+// 页面数据初始化
+const initPage = async () => {};
+
+// SaTable 数据请求
+const refresh = async () => {
+  crudRef.value?.refresh();
+};
+
+// 页面加载完成执行
+onMounted(async () => {
+  initPage();
+  refresh();
+});
+</script>

+ 1 - 1
src/views/v1/customer/roleData/index.vue

@@ -161,6 +161,6 @@ const refresh = async () => {
 // 页面加载完成执行
 onMounted(async () => {
   initPage();
-  refresh();
+  // refresh();
 });
 </script>

+ 122 - 0
src/views/v1/customer/sdkOrder/edit.vue

@@ -0,0 +1,122 @@
+<template>
+  <component
+    is="a-modal"
+    :width="tool.getDevice() === 'mobile' ? '100%' : '600px'"
+    v-model:visible="visible"
+    :title="title"
+    :mask-closable="false"
+    :ok-loading="loading"
+    @cancel="close"
+    @before-ok="submit">
+    <!-- 表单信息 start -->
+    <a-form ref="formRef" :model="formData" :rules="rules" :auto-label-width="true">
+    </a-form>
+    <!-- 表单信息 end -->
+  </component>
+</template>
+
+<script setup>
+import { ref, reactive, computed } from 'vue'
+import tool from '@/utils/tool'
+import { Message, Modal } from '@arco-design/web-vue'
+import api from '../../api/customer/sdkOrder'
+
+const emit = defineEmits(['success'])
+// 引用定义
+const visible = ref(false)
+const loading = ref(false)
+const formRef = ref()
+const mode = ref('')
+
+let title = computed(() => {
+  return '用户订单记录' + (mode.value == 'add' ? '-新增' : '-编辑')
+})
+
+// 表单初始值
+const initialFormData = {
+  id: null,
+}
+
+// 表单信息
+const formData = reactive({ ...initialFormData })
+
+// 验证规则
+const rules = {
+  orderid: [{ required: true, message: '订单号必需填写' }],
+  cp_orderid: [{ required: true, message: '研发订单号必需填写' }],
+  pay_channel: [{ required: true, message: '充值方式必需填写' }],
+  money: [{ required: true, message: '金额必需填写' }],
+  paid_amount: [{ required: true, message: '净额必需填写' }],
+  game_id: [{ required: true, message: '充值游戏必需填写' }],
+  media_id: [{ required: true, message: '媒体ID必需填写' }],
+  auth_id: [{ required: true, message: '负责人ID必需填写' }],
+  agent_id: [{ required: true, message: '渠道ID必需填写' }],
+  site_id: [{ required: true, message: '广告位ID必需填写' }],
+  uid: [{ required: true, message: 'UID必需填写' }],
+  user_name: [{ required: true, message: '充值账号必需填写' }],
+  user_ip: [{ required: true, message: '充值IP必需填写' }],
+  server_id: [{ required: true, message: '服务器ID必需填写' }],
+  server_name: [{ required: true, message: '充值区服必需填写' }],
+  role_name: [{ required: true, message: '角色名必需填写' }],
+  payname: [{ required: true, message: '必需填写' }],
+  pay_date: [{ required: true, message: '支付时间必需填写' }],
+  sync_status: [{ required: true, message: '支付状态必需填写' }],
+  send_status: [{ required: true, message: '发货状态必需填写' }],
+  product_name: [{ required: true, message: '充值商品名必需填写' }],
+}
+
+// 打开弹框
+const open = async (type = 'add') => {
+  mode.value = type
+  // 重置表单数据
+  Object.assign(formData, initialFormData)
+  formRef.value.clearValidate()
+  visible.value = true
+  await initPage()
+}
+
+// 初始化页面数据
+const initPage = async () => {}
+
+// 设置数据
+const setFormData = async (data) => {
+  for (const key in formData) {
+    if (data[key] != null && data[key] != undefined) {
+      formData[key] = data[key]
+    }
+  }
+}
+
+// 数据保存
+const submit = async (done) => {
+  const validate = await formRef.value?.validate()
+  if (!validate) {
+    loading.value = true
+    let data = { ...formData }
+    let result = {}
+    if (mode.value === 'add') {
+      // 添加数据
+      data.id = undefined
+      result = await api.save(data)
+    } else {
+      // 修改数据
+      result = await api.update(data.id, data)
+    }
+    if (result.code === 200) {
+      Message.success('操作成功')
+      emit('success')
+      done(true)
+    }
+    // 防止连续点击提交
+    setTimeout(() => {
+      loading.value = false
+    }, 500)
+  }
+  done(false)
+}
+
+// 关闭弹窗
+const close = () => (visible.value = false)
+
+defineExpose({ open, setFormData })
+</script>

+ 255 - 0
src/views/v1/customer/sdkOrder/index.vue

@@ -0,0 +1,255 @@
+<template>
+  <div class="ma-content-block">
+    <sa-table
+      ref="crudRef"
+      :options="options"
+      :columns="columns"
+      :searchForm="searchForm"
+    >
+      <!-- 搜索区 tableSearch -->
+      <template #tableSearch>
+        <a-col :sm="8" :xs="24">
+          <a-form-item label="游戏" field="game_id">
+            <a-select
+              v-model="searchForm.game_id"
+              placeholder="请选择游戏"
+              allow-clear
+              allow-search
+            >
+              <a-option
+                v-for="item in allGameOptions"
+                :key="item.id"
+                :value="item.id"
+              >
+                [{{ item.id }}] {{ item.name }}
+              </a-option>
+            </a-select>
+          </a-form-item>
+        </a-col>
+        <a-col :sm="8" :xs="24">
+          <a-form-item label="日期" field="pay_date">
+            <a-range-picker
+              v-model="searchForm.pay_date"
+              :show-time="false"
+              mode="date"
+              style="width: 100%"
+            />
+          </a-form-item>
+        </a-col>
+        <a-col :sm="8" :xs="24">
+          <a-form-item label="账号" field="user_name">
+            <a-input
+              v-model="searchForm.user_name"
+              placeholder="请输入账号"
+              allow-clear
+            />
+          </a-form-item>
+        </a-col>
+        <a-col :sm="8" :xs="24">
+          <a-form-item label="角色ID" field="role_id">
+            <a-input
+              v-model="searchForm.role_id"
+              placeholder="请输入角色ID"
+              allow-clear
+            />
+          </a-form-item>
+        </a-col>
+        <a-col :sm="8" :xs="24">
+          <a-form-item label="订单号" field="orderid">
+            <a-input
+              v-model="searchForm.orderid"
+              placeholder="请输入订单号"
+              allow-clear
+            />
+          </a-form-item>
+        </a-col>
+        <a-col :sm="8" :xs="24">
+          <a-form-item label="交易订单号" field="tradeid">
+            <a-input
+              v-model="searchForm.tradeid"
+              placeholder="请输入交易订单号"
+              allow-clear
+            />
+          </a-form-item>
+        </a-col>
+      </template>
+
+      <!-- Table 自定义渲染 -->
+      <template #game_id="{ record }">
+        [{{ record.game_id }}] {{ record.game_name }}
+      </template>
+      <template #sync_status="{ record }">
+        <!-- 1成功 2失败 3处理中 -->
+        <a-tag
+          :color="
+            record.sync_status === 1
+              ? 'green'
+              : record.sync_status === 2
+              ? 'red'
+              : 'blue'
+          "
+        >
+          {{
+            record.sync_status === 1
+              ? "成功"
+              : record.sync_status === 2
+              ? "失败"
+              : "异常回调"
+          }}
+        </a-tag>
+      </template>
+      <template #send_status="{ record }">
+        <a-tag :color="record.send_status === 1 ? 'green' : 'red'">
+          {{ record.send_status === 1 ? "成功" : "失败" }}
+        </a-tag>
+      </template>
+      <template #operationCell="{ record }">
+        <a-button
+          type="primary"
+          v-if="record?.send_status === 0 && record?.sync_status === 1"
+          @click="handleSend(record)"
+          >补发</a-button
+        >
+      </template>
+    </sa-table>
+
+    <!-- 编辑表单 -->
+    <edit-form ref="editRef" @success="refresh" />
+  </div>
+</template>
+
+<script setup>
+import { onMounted, ref, reactive } from "vue";
+import { Message, Modal } from "@arco-design/web-vue";
+import EditForm from "./edit.vue";
+import api from "../../api/customer/sdkOrder";
+import commonApi from "../../api/common";
+
+// 引用定义
+const crudRef = ref();
+const editRef = ref();
+const viewRef = ref();
+const allGameOptions = ref([]);
+
+// 搜索表单
+const searchForm = ref({
+  orderid: "",
+  tradeid: "",
+  game_id: "",
+  user_name: "",
+  role_id: "",
+  pay_date: [],
+});
+
+// SaTable 基础配置
+const options = reactive({
+  api: api.getPageList,
+  showSummary: true,
+  summary: [
+    {
+      text: "总金额",
+      suffixText: "元",
+
+      action: "totalRow",
+      dataIndex: "money",
+    },
+  ],
+
+  add: {
+    show: false,
+    auth: ["/v1/customer/SdkOrder/save"],
+    func: async () => {
+      editRef.value?.open();
+    },
+  },
+  edit: {
+    show: false,
+    auth: ["/v1/customer/SdkOrder/update"],
+    func: async (record) => {
+      editRef.value?.open("edit");
+      editRef.value?.setFormData(record);
+    },
+  },
+  delete: {
+    show: false,
+    auth: ["/v1/customer/SdkOrder/destroy"],
+    func: async (params) => {
+      const resp = await api.destroy(params);
+      if (resp.code === 200) {
+        Message.success(`删除成功!`);
+        crudRef.value?.refresh();
+      }
+    },
+  },
+});
+
+// SaTable 列配置
+const columns = reactive([
+  { title: "充值账号", dataIndex: "user_name", width: 180 },
+  { title: "充值IP", dataIndex: "user_ip", width: 180 },
+  { title: "订单号", dataIndex: "orderid", width: 180 },
+  { title: "交易订单号", dataIndex: "tradeid", width: 180 },
+  { title: "研发订单号", dataIndex: "cp_orderid", width: 180 },
+  { title: "支付时间", dataIndex: "pay_date", width: 180 },
+  {
+    title: "金额",
+    dataIndex: "money",
+    width: 180,
+  },
+  { title: "充值游戏", dataIndex: "game_id", width: 180 },
+
+  { title: "充值区服", dataIndex: "server_name", width: 180 },
+  { title: "角色ID", dataIndex: "role_id", width: 180 },
+  { title: "角色名", dataIndex: "role_name", width: 180 },
+
+  { title: "支付状态", dataIndex: "sync_status", width: 180 },
+  { title: "发货状态", dataIndex: "send_status", width: 180 },
+
+  { title: "充值方式", dataIndex: "pay_channel_name", width: 180 },
+
+  { title: "支付返回值", dataIndex: "sync_result", width: 180 },
+  { title: "回调信息", dataIndex: "sync_data", width: 180 },
+
+  { title: "SDK版本", dataIndex: "sdk_version", width: 180 },
+]);
+
+// 页面数据初始化
+const initPage = async () => {
+  await getGameOptions();
+};
+
+// 获取子游戏options
+const getGameOptions = async () => {
+  const res = await commonApi.getGameOptionsApiNoAuth();
+  allGameOptions.value = res.data;
+};
+
+// 补发
+const handleSend = async (record) => {
+  console.log(record);
+  Modal.info({
+    title: "补发",
+    content: "确定要补发吗?",
+    okText: "确定",
+    cancelText: "取消",
+    onOk: async () => {
+      const resp = await api.send(record.orderid);
+      if (resp.code === 200) {
+        Message.success(`操作成功,请稍后刷新`);
+        crudRef.value?.refresh();
+      }
+    },
+  });
+};
+
+// SaTable 数据请求
+const refresh = async () => {
+  crudRef.value?.refresh();
+};
+
+// 页面加载完成执行
+onMounted(async () => {
+  initPage();
+  // refresh();
+});
+</script>