Răsfoiți Sursa

优化功能

ith5 5 luni în urmă
părinte
comite
ac9668708d

+ 62 - 69
src/layout/components/mixed/index.vue

@@ -1,41 +1,22 @@
 <template>
   <a-layout class="layout flex flex-col h-full">
-    <a-layout-header
-      class="ma-ui-header flex justify-between h-50 layout-banner-header operation-area"
-    >
+    <a-layout-header class="ma-ui-header flex justify-between h-50 layout-banner-header operation-area">
       <div class="flex justify-between md:justify-center logo">
-        <a-avatar class="mt-1 ml-2 md:ml-0" :size="40"
-          ><img :src="`${$url}logo.png`" class="bg-white"
-        /></a-avatar>
-        <span class="ml-2 text-xl mt-2.5 hidden md:block">{{ $title }}</span>
+        <a-avatar class="mt-1 ml-2 md:ml-0" :size="40"><img :src="`${$url}logo.png`" class="bg-white" /></a-avatar>
+        <span class="ml-2 text-xl mt-2.5 hidden md:block">{{ title }}</span>
       </div>
       <div class="flex justify-between w-full layout-banner">
-        <top-menu
-          v-model="userStore.routers"
-          :active="active"
-          @go="loadMenu"
-          ref="topMenuRef"
-        />
+        <top-menu v-model="userStore.routers" :active="active" @go="loadMenu" ref="topMenuRef" />
         <ma-operation />
       </div>
     </a-layout-header>
-    <div
-      class="flex"
-      :style="`height:calc(100% - ${appStore.tag ? '87px' : '52px'}); `"
-    >
+    <div class="flex" :style="`height:calc(100% - ${appStore.tag ? '87px' : '52px'}); `">
       <a-layout-sider
         id="layout-mixed-left-panel"
         class="layout-classic-sider h-full flex flex-col hidden lg:block"
-        :style="`width: ${
-          appStore.menuCollapse ? '48px' : appStore.menuWidth + 'px'
-        };`"
-        v-show="showMenu"
-      >
-        <ma-menu
-          ref="MaMenuRef"
-          height="100%"
-          :class="`${appStore.menuCollapse ? 'ml-1.5' : ''};`"
-        />
+        :style="`width: ${appStore.menuCollapse ? '48px' : appStore.menuWidth + 'px'};`"
+        v-show="showMenu">
+        <ma-menu ref="MaMenuRef" height="100%" :class="`${appStore.menuCollapse ? 'ml-1.5' : ''};`" />
       </a-layout-sider>
       <div class="w-full" :style="`width: calc(100% - ${containerWidth}px)`">
         <ma-tags class="hidden lg:flex ma-ui-tags" />
@@ -46,82 +27,94 @@
 </template>
 
 <script setup>
-import { ref, watch, onMounted } from "vue";
-import { useAppStore, useUserStore } from "@/store";
-import { useRoute, useRouter } from "vue-router";
-import ResizeObserver from "resize-observer-polyfill";
-import MaOperation from "../ma-operation.vue";
-import MaWorkerArea from "../ma-workerArea.vue";
-import MaTags from "../ma-tags.vue";
-import MaMenu from "../ma-menu.vue";
-import topMenu from "./top-menu.vue";
+import { ref, watch, onMounted } from 'vue'
+import { useAppStore, useUserStore } from '@/store'
+import { useRoute, useRouter } from 'vue-router'
+import ResizeObserver from 'resize-observer-polyfill'
+import MaOperation from '../ma-operation.vue'
+import MaWorkerArea from '../ma-workerArea.vue'
+import MaTags from '../ma-tags.vue'
+import MaMenu from '../ma-menu.vue'
+import topMenu from './top-menu.vue'
+import commonApi from '@/views/v1/api/common'
 
-const route = useRoute();
-const router = useRouter();
+const route = useRoute()
+const router = useRouter()
 
-const topMenuRef = ref(null);
-const MaMenuRef = ref(null);
-const userStore = useUserStore();
-const appStore = useAppStore();
-const showMenu = ref(false);
-const active = ref();
+const topMenuRef = ref(null)
+const MaMenuRef = ref(null)
+const userStore = useUserStore()
+const appStore = useAppStore()
+const showMenu = ref(false)
+const active = ref()
+const title = ref('')
 
 onMounted(() => {
-  initMenu();
-});
+  initMenu()
+})
 
 watch(
   () => route,
   (v) => {
-    initMenu();
+    initMenu()
   },
   { deep: true }
-);
+)
 
 const initMenu = () => {
   if (route.matched[1]?.meta?.breadcrumb) {
-    active.value = route.matched[1].meta.breadcrumb[0].name;
+    active.value = route.matched[1].meta.breadcrumb[0].name
   } else {
-    active.value = "home";
+    active.value = 'home'
   }
   if (userStore.routers && userStore.routers.length > 0) {
     userStore.routers.map((item, index) => {
-      if (item.name == active.value) loadMenu(item);
-    });
+      if (item.name == active.value) loadMenu(item)
+    })
   }
-};
+}
 
 const loadMenu = (bigMenu) => {
-  if (bigMenu.meta.type === "L") {
-    window.open(bigMenu.path);
-    return;
+  if (bigMenu.meta.type === 'L') {
+    window.open(bigMenu.path)
+    return
   }
   if (bigMenu.children && bigMenu.children.length > 0) {
-    MaMenuRef.value.loadChildMenu(bigMenu);
-    showMenu.value = true;
+    MaMenuRef.value.loadChildMenu(bigMenu)
+    showMenu.value = true
   } else {
-    showMenu.value = false;
-    router.push(bigMenu.path);
+    showMenu.value = false
+    router.push(bigMenu.path)
   }
-  topMenuRef.value.updateActive(bigMenu.name);
-};
+  topMenuRef.value.updateActive(bigMenu.name)
+}
 
-const containerWidth = ref(0);
+const containerWidth = ref(0)
+
+// 获取系统配置
+const getSystemConfig = async () => {
+  const { data } = await commonApi.getSystemConfigApi({
+    group_code: 'site_config',
+    key: 'site_name',
+  })
+  title.value = data.value
+}
 
 onMounted(() => {
-  const dom = document.getElementById("layout-mixed-left-panel");
+  const dom = document.getElementById('layout-mixed-left-panel')
   const robserver = new ResizeObserver((entries) => {
     for (const entry of entries) {
       // 可以通过 判断 entry.target得知当前改变的 Element,分别进行处理。
       switch (entry.target) {
         case dom:
-          containerWidth.value = entry.contentRect.width;
-          break;
+          containerWidth.value = entry.contentRect.width
+          break
       }
     }
-  });
-  robserver.observe(dom);
-});
+  })
+  getSystemConfig()
+  robserver.observe(dom)
+})
 </script>
 
 <style scoped lang="less">

+ 63 - 103
src/views/login.vue

@@ -1,78 +1,82 @@
 <script setup>
-import { reactive, ref } from "vue";
-import loginApi from "@/api/login";
-import { useUserStore } from "@/store";
-import { useRouter, useRoute } from "vue-router";
-import packageJson from "../../package.json";
-import { useAppStore } from "@/store";
+import { reactive, ref } from 'vue'
+import loginApi from '@/api/login'
+import { useUserStore } from '@/store'
+import { useRouter, useRoute } from 'vue-router'
+import packageJson from '../../package.json'
+import { useAppStore } from '@/store'
+import commonApi from '@/views/v1/api/common'
 
-const appStore = useAppStore();
-const router = useRouter();
-const route = useRoute();
-const captcha = ref(null);
+const appStore = useAppStore()
+const router = useRouter()
+const route = useRoute()
+const captcha = ref(null)
+const title = ref('')
 
-const loading = ref(false);
+const loading = ref(false)
 
-let isDevelop = import.meta.env.VITE_APP_ENV === "development";
+let isDevelop = import.meta.env.VITE_APP_ENV === 'development'
 
-var odata = isDevelop
-  ? { username: "admin", password: "123456", code: "" }
-  : { username: "", password: "", code: "" };
+var odata = isDevelop ? { username: 'admin', password: '123456', code: '' } : { username: '', password: '', code: '' }
 
-const form = reactive(odata);
+const form = reactive(odata)
 
 const refreshCaptcha = () => {
-  form.code = "";
-  form.uuid = "";
+  form.code = ''
+  form.uuid = ''
   loginApi.getCaptch().then((res) => {
     if (res.code === 200) {
-      captcha.value = res.data.image;
-      form.uuid = res.data.uuid;
+      captcha.value = res.data.image
+      form.uuid = res.data.uuid
     }
-  });
-};
+  })
+}
+
+refreshCaptcha()
+
+const userStore = useUserStore()
 
-refreshCaptcha();
+// 获取系统配置
+const getSystemConfig = async () => {
+  const { data } = await commonApi.getSystemConfigApi({
+    group_code: 'site_config',
+    key: 'site_name',
+  })
+  title.value = data.value
+}
 
-const userStore = useUserStore();
+getSystemConfig()
 
-const redirect = route.query.redirect ? route.query.redirect : "/";
+const redirect = route.query.redirect ? route.query.redirect : '/'
 
 const handleSubmit = async ({ values, errors }) => {
   if (loading.value) {
-    return;
+    return
   }
-  loading.value = true;
+  loading.value = true
   if (!errors) {
-    const result = await userStore.login(form);
+    const result = await userStore.login(form)
     if (!result) {
-      loading.value = false;
-      refreshCaptcha();
-      return;
+      loading.value = false
+      refreshCaptcha()
+      return
     }
-    router.push(redirect);
+    router.push(redirect)
   }
-  loading.value = false;
-};
+  loading.value = false
+}
 </script>
 <template>
-  <div
-    class="login-container"
-    :style="{ background: appStore.mode === 'dark' ? '#2e2e30e3' : '' }"
-  >
+  <div class="login-container" :style="{ background: appStore.mode === 'dark' ? '#2e2e30e3' : '' }">
     <h3 class="login-logo">
       <!-- <img src="/logo.png" alt="logo" />
       <span>{{ $title }}</span> -->
     </h3>
 
-    <div
-      class="login-width md:w-10/12 w-11/12 mx-auto flex justify-between h-full items-center"
-    >
-      <div
-        class="w-6/12 mx-auto left-panel rounded-l pl-5 pr-5 hidden md:block"
-      >
+    <div class="login-width md:w-10/12 w-11/12 mx-auto flex justify-between h-full items-center">
+      <div class="w-6/12 mx-auto left-panel rounded-l pl-5 pr-5 hidden md:block">
         <div class="logo">
-          <span>{{ $title }} v{{ packageJson.version }}</span>
+          <span>{{ title }} v{{ packageJson.version }}</span>
         </div>
         <div class="slogan flex justify-end">
           <!-- <span>---- {{ $t('sys.login.slogan') }}</span> -->
@@ -81,23 +85,19 @@ const handleSubmit = async ({ values, errors }) => {
 
       <div class="md:w-6/12 w-11/12 md:rounded-r mx-auto pl-5 pr-5 pb-10">
         <h2 class="mt-10 text-3xl pb-0 mb-10 login-title">
-          {{ $t("sys.login.title") }}
+          {{ $t('sys.login.title') }}
         </h2>
         <a-form :model="form" @submit="handleSubmit">
           <a-form-item
             field="username"
             :hide-label="true"
-            :rules="[
-              { required: true, message: $t('sys.login.usernameNotice') },
-            ]"
-          >
+            :rules="[{ required: true, message: $t('sys.login.usernameNotice') }]">
             <a-input
               v-model="form.username"
               class="w-full"
               size="large"
               :placeholder="$t('sys.login.username')"
-              allow-clear
-            >
+              allow-clear>
               <template #prefix><icon-user /></template>
             </a-input>
           </a-form-item>
@@ -105,16 +105,8 @@ const handleSubmit = async ({ values, errors }) => {
           <a-form-item
             field="password"
             :hide-label="true"
-            :rules="[
-              { required: true, message: $t('sys.login.passwordNotice') },
-            ]"
-          >
-            <a-input-password
-              v-model="form.password"
-              :placeholder="$t('sys.login.password')"
-              size="large"
-              allow-clear
-            >
+            :rules="[{ required: true, message: $t('sys.login.passwordNotice') }]">
+            <a-input-password v-model="form.password" :placeholder="$t('sys.login.password')" size="large" allow-clear>
               <template #prefix><icon-lock /></template>
             </a-input-password>
           </a-form-item>
@@ -128,34 +120,18 @@ const handleSubmit = async ({ values, errors }) => {
                 match: /^[a-zA-Z0-9]{4}$/,
                 message: $t('sys.login.verifyCodeNotice'),
               },
-            ]"
-          >
-            <a-input
-              v-model="form.code"
-              :placeholder="$t('sys.login.verifyCode')"
-              size="large"
-              allow-clear
-            >
+            ]">
+            <a-input v-model="form.code" :placeholder="$t('sys.login.verifyCode')" size="large" allow-clear>
               <template #prefix><icon-safe /></template>
               <template #append>
-                <img
-                  :src="captcha"
-                  style="height: 120px; height: 36px; cursor: pointer"
-                  @click="refreshCaptcha"
-                />
+                <img :src="captcha" style="height: 120px; height: 36px; cursor: pointer" @click="refreshCaptcha" />
               </template>
             </a-input>
           </a-form-item>
 
           <a-form-item :hide-label="true" class="mt-5">
-            <a-button
-              html-type="submit"
-              type="primary"
-              long
-              size="large"
-              :loading="loading"
-            >
-              {{ $t("sys.login.loginBtn") }}
+            <a-button html-type="submit" type="primary" long size="large" :loading="loading">
+              {{ $t('sys.login.loginBtn') }}
             </a-button>
           </a-form-item>
 
@@ -290,11 +266,7 @@ const handleSubmit = async ({ values, errors }) => {
   width: 100px;
   height: 100px;
   border-radius: 50%;
-  background: linear-gradient(
-    to right,
-    rgba(var(--primary-6), 0.07),
-    rgba(var(--primary-6), 0.04)
-  );
+  background: linear-gradient(to right, rgba(var(--primary-6), 0.07), rgba(var(--primary-6), 0.04));
   animation: move-ce64e0ea 2.5s linear infinite;
 }
 
@@ -304,11 +276,7 @@ const handleSubmit = async ({ values, errors }) => {
   width: 150px;
   height: 150px;
   border-radius: 50%;
-  background: linear-gradient(
-    to right,
-    rgba(var(--primary-6), 0.08),
-    rgba(var(--primary-6), 0.04)
-  );
+  background: linear-gradient(to right, rgba(var(--primary-6), 0.08), rgba(var(--primary-6), 0.04));
   animation: move-ce64e0ea 3s linear infinite;
 }
 
@@ -318,11 +286,7 @@ const handleSubmit = async ({ values, errors }) => {
   width: 145px;
   height: 145px;
   border-radius: 50%;
-  background: linear-gradient(
-    to right,
-    rgba(var(--primary-6), 0.1),
-    rgba(var(--primary-6), 0.04)
-  );
+  background: linear-gradient(to right, rgba(var(--primary-6), 0.1), rgba(var(--primary-6), 0.04));
   animation: move-ce64e0ea 2.5s linear infinite;
 }
 
@@ -332,11 +296,7 @@ const handleSubmit = async ({ values, errors }) => {
   width: 160px;
   height: 160px;
   border-radius: 50%;
-  background: linear-gradient(
-    to right,
-    rgba(var(--primary-6), 0.02),
-    rgba(var(--primary-6), 0.04)
-  );
+  background: linear-gradient(to right, rgba(var(--primary-6), 0.02), rgba(var(--primary-6), 0.04));
   animation: move-ce64e0ea 3.5s linear infinite;
 }
 

+ 78 - 98
src/views/system/user/edit.vue

@@ -7,23 +7,13 @@
     :mask-closable="false"
     :ok-loading="loading"
     @cancel="close"
-    @before-ok="submit"
-  >
+    @before-ok="submit">
     <!-- 表单信息 start -->
-    <a-form
-      ref="formRef"
-      :model="formData"
-      :rules="rules"
-      :auto-label-width="true"
-    >
+    <a-form ref="formRef" :model="formData" :rules="rules" :auto-label-width="true">
       <a-row :gutter="16">
         <a-col :span="12">
           <a-form-item field="username" label="账户">
-            <a-input
-              v-model="formData.username"
-              :disabled="mode === 'edit'"
-              placeholder="请输入账户"
-            />
+            <a-input v-model="formData.username" placeholder="请输入账户" />
           </a-form-item>
         </a-col>
         <a-col :span="12">
@@ -33,8 +23,7 @@
               :data="deptData"
               :field-names="{ key: 'value', title: 'label' }"
               allow-clear
-              placeholder="请选择所属部门"
-            >
+              placeholder="请选择所属部门">
             </a-tree-select>
             <template #extra>
               <div>如果修改了部门,需要重新设置权限</div>
@@ -45,11 +34,7 @@
       <a-row :gutter="16">
         <a-col :span="12">
           <a-form-item field="password" label="密码">
-            <a-input-password
-              v-model="formData.password"
-              :disabled="mode === 'edit'"
-              placeholder="请输入密码"
-            />
+            <a-input-password v-model="formData.password" placeholder="请输入密码" />
           </a-form-item>
         </a-col>
         <a-col :span="12">
@@ -68,8 +53,7 @@
               :tree-check-strictly="true"
               allow-clear
               tree-checkable
-              placeholder="请选择角色"
-            >
+              placeholder="请选择角色">
             </a-tree-select>
           </a-form-item>
         </a-col>
@@ -89,11 +73,7 @@
       <a-row :gutter="16">
         <a-col :span="24">
           <a-form-item label="状态" field="status">
-            <sa-radio
-              v-model="formData.status"
-              dict="data_status"
-              placeholder="请选择状态"
-            />
+            <sa-radio v-model="formData.status" dict="data_status" placeholder="请选择状态" />
           </a-form-item>
         </a-col>
       </a-row>
@@ -110,125 +90,125 @@
 </template>
 
 <script setup>
-import { ref, reactive, computed } from "vue";
-import { Message } from "@arco-design/web-vue";
-import api from "@/api/system/user";
-import tool from "@/utils/tool";
-import commonApi from "@/api/common";
+import { ref, reactive, computed } from 'vue'
+import { Message } from '@arco-design/web-vue'
+import api from '@/api/system/user'
+import tool from '@/utils/tool'
+import commonApi from '@/api/common'
 
-const emit = defineEmits(["success"]);
+const emit = defineEmits(['success'])
 
 // 引用定义
-const formRef = ref();
-const mode = ref("");
-const visible = ref(false);
-const loading = ref(false);
-const deptData = ref([]);
-const roleData = ref([]);
-const postData = ref([]);
+const formRef = ref()
+const mode = ref('')
+const visible = ref(false)
+const loading = ref(false)
+const deptData = ref([])
+const roleData = ref([])
+const postData = ref([])
 
 let title = computed(() => {
-  return "用户管理" + (mode.value == "add" ? "-新增" : "-编辑");
-});
+  return '用户管理' + (mode.value == 'add' ? '-新增' : '-编辑')
+})
 
 // 表单初始值
 const initialFormData = {
-  id: "",
-  avatar: "",
-  username: "",
-  nickname: "",
-  dept_id: "",
-  password: "",
+  id: '',
+  avatar: '',
+  username: '',
+  nickname: '',
+  dept_id: '',
+  password: '',
   role_ids: [],
-  phone: "",
+  phone: '',
   post_ids: [],
-  email: "",
+  email: '',
   status: 1,
-  remark: "",
-};
+  remark: '',
+}
 
 // 表单信息
-const formData = reactive({ ...initialFormData });
+const formData = reactive({ ...initialFormData })
 
 // 验证规则
 const rules = {
-  username: [{ required: true, message: "账户不能为空" }],
-  dept_id: [{ required: true, message: "部门不能为空" }],
-  role_ids: [{ required: true, message: "角色不能为空" }],
-};
+  username: [{ required: true, message: '账户不能为空' }],
+  dept_id: [{ required: true, message: '部门不能为空' }],
+  role_ids: [{ required: true, message: '角色不能为空' }],
+}
 
 // 打开弹框
-const open = async (type = "add", id = "") => {
-  mode.value = type;
+const open = async (type = 'add', id = '') => {
+  mode.value = type
   // 重置表单数据
-  Object.assign(formData, initialFormData);
-  formRef.value.clearValidate();
-  visible.value = true;
-  await initPage();
-  if (type == "edit") {
-    const { data } = await api.read(id);
+  Object.assign(formData, initialFormData)
+  formRef.value.clearValidate()
+  visible.value = true
+  await initPage()
+  if (type == 'edit') {
+    const { data } = await api.read(id)
     if (data.postList) {
-      const post = data.postList.map((item) => item.id);
-      data.post_ids = post;
+      const post = data.postList.map((item) => item.id)
+      data.post_ids = post
     }
-    const role = data.roleList.map((item) => item.id);
-    data.role_ids = role;
-    data.password = "";
-    setFormData(data);
+    const role = data.roleList.map((item) => item.id)
+    data.role_ids = role
+    data.password = ''
+    setFormData(data)
   }
-};
+}
 
 // 初始化页面数据
 const initPage = async () => {
-  const deptResp = await commonApi.commonGet("/core/dept/accessDept");
-  deptData.value = deptResp.data;
+  const deptResp = await commonApi.commonGet('/core/dept/accessDept')
+  deptData.value = deptResp.data
 
-  const roleResp = await commonApi.commonGet("/core/role/accessRole");
-  roleData.value = roleResp.data;
+  const roleResp = await commonApi.commonGet('/core/role/accessRole')
+  roleData.value = roleResp.data
 
-  const postResp = await commonApi.commonGet("/core/post/accessPost");
-  postData.value = postResp.data;
-};
+  const postResp = await commonApi.commonGet('/core/post/accessPost')
+  postData.value = postResp.data
+}
 
 // 设置数据
 const setFormData = async (data) => {
   for (const key in formData) {
     if (data[key] != null && data[key] != undefined) {
-      formData[key] = data[key];
+      formData[key] = data[key]
     }
   }
-};
+}
 
 // 数据保存
 const submit = async (done) => {
-  const validate = await formRef.value?.validate();
+  const validate = await formRef.value?.validate()
   if (!validate) {
-    loading.value = true;
-    let data = { ...formData };
-    let result = {};
-    if (mode.value === "add") {
+    loading.value = true
+    let data = { ...formData }
+    let result = {}
+    if (mode.value === 'add') {
       // 添加数据
-      data.id = undefined;
-      result = await api.save(data);
+      data.id = undefined
+      result = await api.save(data)
     } else {
       // 修改数据
-      result = await api.update(data.id, data);
+      result = await api.update(data.id, data)
     }
     if (result.code === 200) {
-      Message.success("操作成功");
-      emit("success");
-      done(true);
+      Message.success('操作成功')
+      emit('success')
+      done(true)
     }
     // 防止连续点击提交
     setTimeout(() => {
-      loading.value = false;
-    }, 500);
+      loading.value = false
+    }, 500)
   }
-  done(false);
-};
+  done(false)
+}
 
 // 关闭弹窗
-const close = () => (visible.value = false);
+const close = () => (visible.value = false)
 
-defineExpose({ open, setFormData });
+defineExpose({ open, setFormData })
 </script>

+ 7 - 0
src/views/v1/advert/mediaCost/index.vue

@@ -24,6 +24,11 @@
             </a-select>
           </a-form-item>
         </a-col>
+        <a-col :sm="8" :xs="24">
+          <a-form-item label="广告账号ID" field="advertiser_id">
+            <a-input v-model="searchForm.advertiser_id" placeholder="请输入广告账号ID" allow-clear />
+          </a-form-item>
+        </a-col>
         <a-col :sm="8" :xs="24">
           <a-form-item label="渠道ID" field="agent_id">
             <a-input v-model="searchForm.agent_id" placeholder="请输入渠道ID" allow-clear />
@@ -127,6 +132,8 @@ const options = reactive({
 // SaTable 列配置
 const columns = reactive([
   { title: '结算日期', dataIndex: 'tdate', width: 120 },
+  { title: '媒体类型', dataIndex: 'media_name', width: 120 },
+  { title: '广告账号ID', dataIndex: 'advertiser_id', width: 120 },
   { title: '广告位ID', dataIndex: 'site_id', width: 120 },
   { title: '广告位名称', dataIndex: 'site_name', width: 120 },
   { title: '渠道ID', dataIndex: 'agent_id', width: 120 },

+ 0 - 4
src/views/v1/advert/mediaList/edit.vue

@@ -72,10 +72,6 @@ const formData = reactive({ ...initialFormData })
 const rules = {
   name: [{ required: true, message: '媒体名称必需填写' }],
   channel_name: [{ required: true, message: '媒体渠道简称必需填写' }],
-  andurl: [{ required: true, message: '安卓监测链接必需填写' }],
-  iosurl: [{ required: true, message: 'ios监测链接必需填写' }],
-  xyxurl: [{ required: true, message: '小游戏监测链接必需填写' }],
-  appleturl: [{ required: true, message: '小游戏路径参数补充必需填写' }],
   state: [{ required: true, message: '状态必需填写' }],
 }
 

+ 13 - 0
src/views/v1/api/center/common.js

@@ -27,5 +27,18 @@ export default {
       method: 'get',
       params
     })
+  },
+
+  /**
+   * 获取所有子游戏列表
+   * @param {Object} params
+   * @returns
+   */
+  getAllGameOptionsApi(params = {}) {
+    return request({
+      url: '/v1/common/getAllGameOptions',
+      method: 'get',
+      params
+    })
   }
 }

+ 10 - 0
src/views/v1/api/common.js

@@ -150,5 +150,15 @@ export default {
       method: 'get',
       params
     })
+  },
+  /**
+   * 获取系统配置
+   */
+  getSystemConfigApi(params = {}) {
+    return request({
+      url: '/v1/common/getSystemConfig',
+      method: 'get',
+      params
+    })
   }
 }

+ 31 - 32
src/views/v1/center/game/cp-info.vue

@@ -8,15 +8,14 @@
     @before-ok="handleOk"
     okText="复制"
     cancelText="关闭"
-    @cancel="close"
-  >
+    @cancel="close">
     <a-space direction="vertical" fill>
       <a-form>
         <a-form-item label="游戏名称">
           <a-input v-model="cp_info.name" readonly />
         </a-form-item>
-        <a-form-item label="appid">
-          <a-input v-model="cp_info.appid" readonly />
+        <a-form-item label="game_id">
+          <a-input v-model="cp_info.game_id" readonly />
         </a-form-item>
         <a-form-item label="appkey">
           <a-input v-model="cp_info.appkey" readonly />
@@ -36,61 +35,61 @@
 </template>
 
 <script setup>
-import { ref } from "vue";
-import tool from "@/utils/tool";
-import { Modal, Message } from "@arco-design/web-vue";
+import { ref } from 'vue'
+import tool from '@/utils/tool'
+import { Modal, Message } from '@arco-design/web-vue'
 // 引用定义
-const visible = ref(false);
-const cp_info = ref({});
+const visible = ref(false)
+const cp_info = ref({})
 
-const emit = defineEmits(["success"]);
+const emit = defineEmits(['success'])
 
 // 打开弹框
 const open = async () => {
-  visible.value = true;
-  await initPage();
-};
+  visible.value = true
+  await initPage()
+}
 
 // 设置表单数据
 const setFormData = (data) => {
-  cp_info.value = data;
-};
+  cp_info.value = data
+}
 
 // 初始化页面数据
-const initPage = async () => {};
+const initPage = async () => {}
 
 // 确定
 const handleOk = async () => {
   // 复制
   const copyText = `游戏名称:${cp_info.value.name}
-appid:${cp_info.value.appid}
+game_id:${cp_info.value.game_id}
 appkey:${cp_info.value.appkey}
 login_key:${cp_info.value.login_key}
 pay_key:${cp_info.value.pay_key}
-${cp_info.value.os == "5" ? `h5地址:${cp_info.value.channel_h5_url}` : ""}`;
+${cp_info.value.os == '5' ? `h5地址:${cp_info.value.channel_h5_url}` : ''}`
 
   try {
-    await tool.copy(copyText);
+    await tool.copy(copyText)
     Message.success({
-      title: "提示",
-      content: "复制成功",
-    });
+      title: '提示',
+      content: '复制成功',
+    })
   } catch (error) {
     Message.error({
-      title: "提示",
-      content: "复制失败,请手动复制",
-    });
-    console.error("复制失败:", error);
+      title: '提示',
+      content: '复制失败,请手动复制',
+    })
+    console.error('复制失败:', error)
   }
 
-  close();
-  emit("success");
-};
+  close()
+  emit('success')
+}
 
 // 关闭弹窗
 const close = () => {
-  visible.value = false;
-};
+  visible.value = false
+}
 
-defineExpose({ open, setFormData });
+defineExpose({ open, setFormData })
 </script>

+ 97 - 153
src/views/v1/center/game/edit.vue

@@ -7,59 +7,32 @@
     :mask-closable="false"
     :ok-loading="loading"
     @cancel="close"
-    @before-ok="submit"
-  >
+    @before-ok="submit">
     <!-- 表单信息 start -->
-    <a-form
-      ref="formRef"
-      :model="formData"
-      :rules="rules"
-      :auto-label-width="true"
-    >
+    <a-form ref="formRef" :model="formData" :rules="rules" :auto-label-width="true">
       <a-form-item label="产品归属" field="main_id">
         <a-select
           v-model="formData.main_id"
           :options="mainGameOptions"
           placeholder="请选择产品归属"
           :disabled="mode == 'edit'"
-          allow-clear
-        />
+          allow-clear />
       </a-form-item>
       <a-form-item label="游戏名称" field="name">
         <a-input v-model="formData.name" placeholder="请输入游戏名称" />
       </a-form-item>
       <a-form-item label="游戏平台" field="os">
-        <sa-select
-          v-model="formData.os"
-          dict="os"
-          placeholder="请选择平台"
-          allow-clear
-        />
+        <sa-select v-model="formData.os" dict="os" placeholder="请选择平台" allow-clear />
       </a-form-item>
 
       <a-form-item label="分成比例" field="divide">
-        <a-input-number
-          v-model="formData.divide"
-          placeholder="请输入分成比例"
-        />
+        <a-input-number v-model="formData.divide" placeholder="请输入分成比例" />
       </a-form-item>
-      <a-form-item
-        label="内购分成比例"
-        field="ios_divide"
-        v-if="formData.os == '2'"
-      >
-        <a-input-number
-          v-model="formData.ios_divide"
-          placeholder="请输入苹果内购分成比例"
-        />
+      <a-form-item label="内购分成比例" field="ios_divide" v-if="formData.os == '2'">
+        <a-input-number v-model="formData.ios_divide" placeholder="请输入苹果内购分成比例" />
       </a-form-item>
       <a-form-item label="游戏实名" field="realname_switch">
-        <sa-select
-          v-model="formData.realname_switch"
-          dict="realname_switch"
-          placeholder="请选择游戏实名"
-          allow-clear
-        />
+        <sa-select v-model="formData.realname_switch" dict="realname_switch" placeholder="请选择游戏实名" allow-clear />
       </a-form-item>
       <a-divider />
       <a-form-item label="游戏KEY" field="main_game_id">
@@ -68,65 +41,36 @@
           :options="gameOptions"
           placeholder="请选择主游戏"
           allow-clear
-          @change="handleMainGameChange"
-        />
+          @change="handleMainGameChange" />
       </a-form-item>
       <a-form-item label="游戏发货规则" field="cp_callback_type" hidden>
         <sa-radio v-model="formData.cp_callback_type" dict="cp_callback_type" />
       </a-form-item>
       <a-form-item label="游戏包名" field="package_name">
-        <a-input
-          v-model="formData.package_name"
-          placeholder="安装包的包名,IOS与过包技术确认后填写"
-        />
+        <a-input v-model="formData.package_name" placeholder="安装包的包名,IOS与过包技术确认后填写" />
         <template #extra>
           <div>格式:com.gamename.newname</div>
         </template>
       </a-form-item>
-      <a-form-item
-        label="分包参数"
-        field="wxgamepro"
-        v-if="formData.os == '3' || formData.os == '4'"
-      >
-        <a-input
-          v-model="formData.wxgamepro"
-          placeholder="请输入小游戏分包参数"
-        />
+      <a-form-item label="分包参数" field="wxgamepro" v-if="formData.os == '3' || formData.os == '4'">
+        <a-input v-model="formData.wxgamepro" placeholder="请输入小游戏分包参数" />
         <template #extra>
           <div>格式:wxgamepro=PkgCBgAAoxxxx</div>
         </template>
       </a-form-item>
-      <a-form-item
-        label="ISO商店APPID"
-        field="ios_appid"
-        v-if="formData.os == '2'"
-      >
+      <a-form-item label="ISO商店APPID" field="ios_appid" v-if="formData.os == '2'">
         <a-input v-model="formData.ios_appid" placeholder="请输入IOS APPID" />
       </a-form-item>
-      <a-form-item
-        label="iOS线上版本"
-        field="online_version"
-        v-if="formData.os == '2'"
-      >
-        <a-input
-          v-model="formData.online_version"
-          placeholder="请输入线上版本"
-        />
+      <a-form-item label="iOS线上版本" field="online_version" v-if="formData.os == '2'">
+        <a-input v-model="formData.online_version" placeholder="请输入线上版本" />
         <template #extra>
           <div>iOS包内传参大于该版本则接口会返回审核服</div>
         </template>
       </a-form-item>
       <a-form-item label="充值回调" field="cp_callback_url">
-        <a-input
-          v-model="formData.cp_callback_url"
-          placeholder="研发发货地址提供"
-        />
+        <a-input v-model="formData.cp_callback_url" placeholder="研发发货地址提供" />
       </a-form-item>
-      <a-form-item
-        label="研发登录地址"
-        field="cp_h5_url"
-        v-if="formData.os == '5'"
-      >
+      <a-form-item label="研发登录地址" field="cp_h5_url" v-if="formData.os == '5'">
         <a-input v-model="formData.cp_h5_url" placeholder="研发H5登录地址" />
         <template #extra>
           <div>H5或iOS-H5壳包必填</div>
@@ -147,149 +91,149 @@
 </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/center/game";
-import centerCommonApi from "../../api/center/common";
+import { ref, reactive, computed, watch } from 'vue'
+import tool from '@/utils/tool'
+import { Message, Modal } from '@arco-design/web-vue'
+import api from '../../api/center/game'
+import centerCommonApi from '../../api/center/common'
 
-const emit = defineEmits(["success"]);
+const emit = defineEmits(['success'])
 // 引用定义
-const visible = ref(false);
-const loading = ref(false);
-const formRef = ref();
-const mode = ref("");
-const mainGameOptions = ref([]);
-const gameOptions = ref([]);
+const visible = ref(false)
+const loading = ref(false)
+const formRef = ref()
+const mode = ref('')
+const mainGameOptions = ref([])
+const gameOptions = ref([])
 
 let title = computed(() => {
-  return "游戏列表" + (mode.value == "add" ? "-新增" : "-编辑");
-});
+  return '游戏列表' + (mode.value == 'add' ? '-新增' : '-编辑')
+})
 
 // 表单初始值
 const initialFormData = {
   id: null,
   main_id: null,
-  name: "",
+  name: '',
   os: 1,
-  cp_h5_url: "",
-  divide: "50",
-  ios_divide: "50",
-  main_game_id: "",
+  cp_h5_url: '',
+  divide: '50',
+  ios_divide: '50',
+  main_game_id: '',
   cp_callback_type: 0,
-  wxgamepro: "",
-  online_version: "",
+  wxgamepro: '',
+  online_version: '',
   status: 1,
   sort: null,
-  remark: "",
-  package_name: "",
-  cp_callback_url: "",
+  remark: '',
+  package_name: '',
+  cp_callback_url: '',
   realname_switch: 2,
-  ios_appid: "",
-};
+  ios_appid: '',
+}
 
 // 表单信息
-const formData = reactive({ ...initialFormData });
+const formData = reactive({ ...initialFormData })
 
 // 验证规则
 const rules = {
-  main_id: [{ required: true, message: "产品归属必需填写" }],
-  name: [{ required: true, message: "游戏名称必需填写" }],
-  os: [{ required: true, message: "平台必需选择" }],
-  divide: [{ required: true, message: "分成比例必需填写" }],
-  cp_callback_type: [{ required: true, message: "游戏发货规则必需选择" }],
-  realname_switch: [{ required: true, message: "游戏实名必需选择" }],
-};
+  main_id: [{ required: true, message: '产品归属必需填写' }],
+  name: [{ required: true, message: '游戏名称必需填写' }],
+  os: [{ required: true, message: '平台必需选择' }],
+  divide: [{ required: true, message: '分成比例必需填写' }],
+  cp_callback_type: [{ required: true, message: '游戏发货规则必需选择' }],
+  realname_switch: [{ required: true, message: '游戏实名必需选择' }],
+}
 
 // 打开弹框
-const open = async (type = "add") => {
-  mode.value = type;
+const open = async (type = 'add') => {
+  mode.value = type
   // 重置表单数据
-  Object.assign(formData, initialFormData);
-  formRef.value.clearValidate();
-  visible.value = true;
-  await initPage();
-};
+  Object.assign(formData, initialFormData)
+  formRef.value.clearValidate()
+  visible.value = true
+  await initPage()
+}
 
 // 初始化页面数据
 const initPage = async () => {
-  await getMainGameOptionsList();
-  await getGameOptionsList();
-};
+  await getMainGameOptionsList()
+  await getGameOptionsList()
+}
 
 // 获取主游戏列表
 const getMainGameOptionsList = async () => {
-  const { data } = await centerCommonApi.getMainGameOptionsApi();
-  mainGameOptions.value = data;
-};
+  const { data } = await centerCommonApi.getMainGameOptionsApi()
+  mainGameOptions.value = data
+}
 
-// 获取子游戏列
+// 获取子游戏列
 const getGameOptionsList = async () => {
-  const { data } = await centerCommonApi.getGameOptionsApi();
-  console.log(formData.name);
+  const { data } = await centerCommonApi.getAllGameOptionsApi()
+
   const newData = data.filter((item) => {
-    return item.label !== formData.name;
-  });
+    return item.label !== formData.name
+  })
   newData.unshift({
-    label: "默认生成独立key",
+    label: '默认生成独立key',
     value: 0,
-  });
-  gameOptions.value = newData;
-};
+  })
+  gameOptions.value = newData
+}
 
 // 设置数据
 const setFormData = async (data) => {
   for (const key in formData) {
     if (data[key] != null && data[key] != undefined) {
-      formData[key] = data[key];
+      formData[key] = data[key]
     }
   }
-};
+}
 
 // 数据保存
 const submit = async (done) => {
-  const validate = await formRef.value?.validate();
+  const validate = await formRef.value?.validate()
   if (!validate) {
-    loading.value = true;
+    loading.value = true
     let data = {
       ...formData,
       realname_switch: Number(formData.realname_switch),
-    };
+    }
 
-    let result = {};
-    if (mode.value == "add") {
+    let result = {}
+    if (mode.value == 'add') {
       // 添加数据
-      data.id = undefined;
-      result = await api.save(data);
+      data.id = undefined
+      result = await api.save(data)
     } else {
       // 修改数据
-      result = await api.update(data.id, data);
+      result = await api.update(data.id, data)
     }
     if (result.code == 200) {
-      Message.success("操作成功");
-      emit("success");
-      done(true);
+      Message.success('操作成功')
+      emit('success')
+      done(true)
     }
     // 防止连续点击提交
     setTimeout(() => {
-      loading.value = false;
-    }, 500);
+      loading.value = false
+    }, 500)
   }
-  done(false);
-};
+  done(false)
+}
 
 // handleMainGameChange
 const handleMainGameChange = (value) => {
-  console.log(value);
-  if (value == "") {
-    formData.cp_callback_type = "0";
+  console.log(value)
+  if (value == '') {
+    formData.cp_callback_type = '0'
   } else {
-    formData.cp_callback_type = "1";
+    formData.cp_callback_type = '1'
   }
-};
+}
 
 // 关闭弹窗
-const close = () => (visible.value = false);
+const close = () => (visible.value = false)
 
-defineExpose({ open, setFormData });
+defineExpose({ open, setFormData })
 </script>

+ 1 - 1
src/views/v1/center/game/index.vue

@@ -150,7 +150,7 @@ const checkCpInfo = async (record) => {
   let { appkey, login_key, pay_key, name, id, os } = record
   let cp_info = {
     name: name,
-    appid: id,
+    game_id: id,
     appkey: appkey,
     login_key: login_key,
     pay_key: pay_key,

+ 64 - 89
src/views/v1/center/iosPayWay/edit.vue

@@ -7,43 +7,17 @@
     :mask-closable="false"
     :ok-loading="loading"
     @cancel="close"
-    @before-ok="submit"
-  >
+    @before-ok="submit">
     <!-- 表单信息 start -->
-    <a-form
-      ref="formRef"
-      :model="formData"
-      :rules="rules"
-      :auto-label-width="true"
-    >
+    <a-form ref="formRef" :model="formData" :rules="rules" :auto-label-width="true">
       <a-form-item label="游戏名称" field="game_id">
-        <a-select
-          v-model="formData.game_id"
-          placeholder="请选择游戏"
-          search
-          allow-clear
-        >
-          <a-option
-            v-for="item in gameOptions"
-            :key="item.id"
-            :value="item.id"
-            :label="`${item.id}:${item.name}`"
-          />
-        </a-select>
+        <game-select v-model="formData.game_id" />
       </a-form-item>
       <a-form-item label="开启时间" field="pay_stime">
-        <a-time-picker
-          style="width: 100%"
-          v-model="formData.pay_stime"
-          placeholder="请选择开启时间"
-        />
+        <a-time-picker style="width: 100%" v-model="formData.pay_stime" placeholder="请选择开启时间" />
       </a-form-item>
       <a-form-item label="结束时间" field="pay_etime">
-        <a-time-picker
-          style="width: 100%"
-          v-model="formData.pay_etime"
-          placeholder="请选择结束时间"
-        />
+        <a-time-picker style="width: 100%" v-model="formData.pay_etime" placeholder="请选择结束时间" />
       </a-form-item>
       <a-form-item label="充值金额" field="pay_money">
         <a-input v-model="formData.pay_money" placeholder="请输入充值金额" />
@@ -66,115 +40,116 @@
 </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/center/iosPayWay";
-import centerCommonApi from "../../api/center/common";
+import { ref, reactive, computed } from 'vue'
+import tool from '@/utils/tool'
+import { Message, Modal } from '@arco-design/web-vue'
+import api from '../../api/center/iosPayWay'
+import centerCommonApi from '../../api/center/common'
+import GameSelect from '@/components/game-select/index.vue'
 
-const emit = defineEmits(["success"]);
+const emit = defineEmits(['success'])
 // 引用定义
-const visible = ref(false);
-const loading = ref(false);
-const formRef = ref();
-const mode = ref("");
-const gameOptions = ref([]);
+const visible = ref(false)
+const loading = ref(false)
+const formRef = ref()
+const mode = ref('')
+const gameOptions = ref([])
 
 let title = computed(() => {
-  return "ios切支付" + (mode.value == "add" ? "-新增" : "-编辑");
-});
+  return 'ios切支付' + (mode.value == 'add' ? '-新增' : '-编辑')
+})
 
 // 表单初始值
 const initialFormData = {
   id: null,
   game_id: null,
-  pay_stime: "",
-  pay_etime: "",
+  pay_stime: '',
+  pay_etime: '',
   pay_money: 45,
   pay_num: 2,
   reg_day: 1,
-  city: "",
+  city: '美国,香港,北京',
   apple_pay: 1,
   pay_way: 1,
-};
+}
 
 // 表单信息
-const formData = reactive({ ...initialFormData });
+const formData = reactive({ ...initialFormData })
 
 // 验证规则
 const rules = {
-  pay_stime: [{ required: true, message: "开启时间必需填写" }],
-  pay_etime: [{ required: true, message: "结束时间必需填写" }],
-  game_id: [{ required: true, message: "游戏名称必需填写" }],
-  pay_money: [{ required: true, message: "充值金额必需填写" }],
-  pay_num: [{ required: true, message: "充值次数必需填写" }],
-  reg_day: [{ required: true, message: "注册天数必需填写" }],
-  apple_pay: [{ required: true, message: "苹果支付必需填写" }],
-  pay_way: [{ required: true, message: "充值渠道开关必需填写" }],
-};
+  pay_stime: [{ required: true, message: '开启时间必需填写' }],
+  pay_etime: [{ required: true, message: '结束时间必需填写' }],
+  game_id: [{ required: true, message: '游戏名称必需填写' }],
+  pay_money: [{ required: true, message: '充值金额必需填写' }],
+  pay_num: [{ required: true, message: '充值次数必需填写' }],
+  reg_day: [{ required: true, message: '注册天数必需填写' }],
+  apple_pay: [{ required: true, message: '苹果支付必需填写' }],
+  pay_way: [{ required: true, message: '充值渠道开关必需填写' }],
+}
 
 // 获取游戏列表
 const getGameOptionsList = async () => {
-  const res = await centerCommonApi.getGameOptionsApi();
+  const res = await centerCommonApi.getGameOptionsApi()
   if (res.code == 200) {
-    gameOptions.value = res.data;
+    gameOptions.value = res.data
   }
-};
+}
 
 // 打开弹框
-const open = async (type = "add") => {
-  mode.value = type;
+const open = async (type = 'add') => {
+  mode.value = type
   // 重置表单数据
-  Object.assign(formData, initialFormData);
-  formRef.value.clearValidate();
-  visible.value = true;
-  await initPage();
-};
+  Object.assign(formData, initialFormData)
+  formRef.value.clearValidate()
+  visible.value = true
+  await initPage()
+}
 
 // 初始化页面数据
 const initPage = async () => {
-  await getGameOptionsList();
-};
+  await getGameOptionsList()
+}
 
 // 设置数据
 const setFormData = async (data) => {
   for (const key in formData) {
     if (data[key] != null && data[key] != undefined) {
-      formData[key] = data[key];
+      formData[key] = data[key]
     }
   }
-};
+}
 
 // 数据保存
 const submit = async (done) => {
-  const validate = await formRef.value?.validate();
+  const validate = await formRef.value?.validate()
   if (!validate) {
-    loading.value = true;
-    let data = { ...formData };
-    let result = {};
-    if (mode.value === "add") {
+    loading.value = true
+    let data = { ...formData }
+    let result = {}
+    if (mode.value === 'add') {
       // 添加数据
-      data.id = undefined;
-      result = await api.save(data);
+      data.id = undefined
+      result = await api.save(data)
     } else {
       // 修改数据
-      result = await api.update(data.id, data);
+      result = await api.update(data.id, data)
     }
     if (result.code === 200) {
-      Message.success("操作成功");
-      emit("success");
-      done(true);
+      Message.success('操作成功')
+      emit('success')
+      done(true)
     }
     // 防止连续点击提交
     setTimeout(() => {
-      loading.value = false;
-    }, 500);
+      loading.value = false
+    }, 500)
   }
-  done(false);
-};
+  done(false)
+}
 
 // 关闭弹窗
-const close = () => (visible.value = false);
+const close = () => (visible.value = false)
 
-defineExpose({ open, setFormData });
+defineExpose({ open, setFormData })
 </script>