This commit is contained in:
2025-03-19 16:43:17 +08:00
parent 824f0ed09d
commit f097902e8c
31 changed files with 2733 additions and 30 deletions

1
.env
View File

@@ -1 +1,2 @@
VITE_API_URL=http://127.0.0.1:4523 VITE_API_URL=http://127.0.0.1:4523
VITE_TINYMCE_KEY=agmu6i1c6k7bcp36oenzyz7yi1yplptq7goyx88y1g6ofnqu

View File

@@ -10,9 +10,11 @@
"commit": "git add . && git commit -m 'update' && git push" "commit": "git add . && git commit -m 'update' && git push"
}, },
"dependencies": { "dependencies": {
"@tinymce/tinymce-vue": "^6.1.0",
"axios": "^1.8.2", "axios": "^1.8.2",
"pinia": "^3.0.1", "pinia": "^3.0.1",
"pinia-plugin-persistedstate": "^4.2.0", "pinia-plugin-persistedstate": "^4.2.0",
"tinymce": "^7.7.2",
"uqrcodejs": "^4.0.7", "uqrcodejs": "^4.0.7",
"uuid": "^11.1.0", "uuid": "^11.1.0",
"vite-plugin-vue-devtools": "^7.7.2", "vite-plugin-vue-devtools": "^7.7.2",

26
pnpm-lock.yaml generated
View File

@@ -8,6 +8,9 @@ importers:
.: .:
dependencies: dependencies:
'@tinymce/tinymce-vue':
specifier: ^6.1.0
version: 6.1.0(tinymce@7.7.2)(vue@3.5.13)
axios: axios:
specifier: ^1.8.2 specifier: ^1.8.2
version: 1.8.2 version: 1.8.2
@@ -17,6 +20,9 @@ importers:
pinia-plugin-persistedstate: pinia-plugin-persistedstate:
specifier: ^4.2.0 specifier: ^4.2.0
version: 4.2.0(pinia@3.0.1(vue@3.5.13)) version: 4.2.0(pinia@3.0.1(vue@3.5.13))
tinymce:
specifier: ^7.7.2
version: 7.7.2
uqrcodejs: uqrcodejs:
specifier: ^4.0.7 specifier: ^4.0.7
version: 4.0.7 version: 4.0.7
@@ -630,6 +636,15 @@ packages:
resolution: {integrity: sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==} resolution: {integrity: sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==}
engines: {node: '>=18'} engines: {node: '>=18'}
'@tinymce/tinymce-vue@6.1.0':
resolution: {integrity: sha512-7JdaKMOaohuFWpjKwRmaZJbT/eNVUUYHG93R7+lUf7SUN+hSqd2spbuqZcki+tG9kaSAGd2ZmvJIsmzWDNAzpw==}
peerDependencies:
tinymce: ^7.0.0 || ^6.0.0 || ^5.5.1
vue: ^3.0.0
peerDependenciesMeta:
tinymce:
optional: true
'@types/estree@1.0.6': '@types/estree@1.0.6':
resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==} resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==}
@@ -1620,6 +1635,9 @@ packages:
resolution: {integrity: sha512-qkf4trmKSIiMTs/E63cxH+ojC2unam7rJ0WrauAzpT3ECNTxGRMlaXxVbfxMUC/w0LaYk6jQ4y/nGR9uBO3tww==} resolution: {integrity: sha512-qkf4trmKSIiMTs/E63cxH+ojC2unam7rJ0WrauAzpT3ECNTxGRMlaXxVbfxMUC/w0LaYk6jQ4y/nGR9uBO3tww==}
engines: {node: '>=12.0.0'} engines: {node: '>=12.0.0'}
tinymce@7.7.2:
resolution: {integrity: sha512-GX7Jd0ac9ph3QM2yei4uOoxytKX096CyG6VkkgQNikY39T6cDldoNgaqzHHlcm62WtdBMCd7Ch+PYaRnQo+NLA==}
to-regex-range@5.0.1: to-regex-range@5.0.1:
resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
engines: {node: '>=8.0'} engines: {node: '>=8.0'}
@@ -2317,6 +2335,12 @@ snapshots:
'@sindresorhus/merge-streams@4.0.0': {} '@sindresorhus/merge-streams@4.0.0': {}
'@tinymce/tinymce-vue@6.1.0(tinymce@7.7.2)(vue@3.5.13)':
dependencies:
vue: 3.5.13
optionalDependencies:
tinymce: 7.7.2
'@types/estree@1.0.6': {} '@types/estree@1.0.6': {}
'@types/node@16.18.126': {} '@types/node@16.18.126': {}
@@ -3333,6 +3357,8 @@ snapshots:
fdir: 6.4.3(picomatch@4.0.2) fdir: 6.4.3(picomatch@4.0.2)
picomatch: 4.0.2 picomatch: 4.0.2
tinymce@7.7.2: {}
to-regex-range@5.0.1: to-regex-range@5.0.1:
dependencies: dependencies:
is-number: 7.0.0 is-number: 7.0.0

View File

@@ -10,7 +10,7 @@ const FROM_TYPE = {
CUSTOM: 'custom', CUSTOM: 'custom',
} }
const emits = defineEmits(['search']); const emits = defineEmits(['search']);
const {config, title} = defineProps({ const {config, title, buttonCol, formBottom} = defineProps({
config: { config: {
type: Array, type: Array,
default: [], default: [],
@@ -19,7 +19,11 @@ const {config, title} = defineProps({
title: { title: {
type: String, type: String,
default: '查询任务' default: '查询任务'
} },
buttonCol: {
type: Boolean,
default: true,
},
}); });
const from = defineModel('from'); const from = defineModel('from');
@@ -36,7 +40,7 @@ const reset = () => {
{{ title }} {{ title }}
</div> </div>
<div class="flex"> <div class="flex mb-[16px]">
<div class="flex-grow"> <div class="flex-grow">
<a-form <a-form
:auto-label-width="true" :auto-label-width="true"
@@ -44,7 +48,7 @@ const reset = () => {
<a-row :gutter="24"> <a-row :gutter="24">
<template v-for="(item, index) in config" :key="index"> <template v-for="(item, index) in config" :key="index">
<a-col :span="item.span || 8"> <a-col :span="item.span || 8">
<a-form-item :label="item.label"> <a-form-item :label="item.label" :class="Math.ceil((index+1) / 3) !== Math.ceil(config.length / 3) ? 'mb20' : ''">
<template v-if="item.type === FROM_TYPE.INPUT"> <template v-if="item.type === FROM_TYPE.INPUT">
<a-input <a-input
class="w-full" class="w-full"
@@ -81,7 +85,7 @@ const reset = () => {
<a-divider direction="vertical" margin="20px"></a-divider> <a-divider direction="vertical" margin="20px"></a-divider>
<div class="flex flex-col gap-[16px]"> <div class="flex gap-[16px]" :style="{flexDirection: buttonCol ? 'column' : 'row'}">
<a-button @click="emits('search')" type="primary"> <a-button @click="emits('search')" type="primary">
<template #icon> <template #icon>
<icon-search/> <icon-search/>
@@ -109,9 +113,13 @@ const reset = () => {
margin-bottom: 16px; margin-bottom: 16px;
} }
.mb20 {
margin-bottom: 20px !important;
}
.AFORM { .AFORM {
:deep(.arco-row) { :deep(.arco-form-item) {
margin-bottom: 16px; margin-bottom: 0;
} }
:deep(.arco-form-item-label) { :deep(.arco-form-item-label) {
@apply whitespace-nowrap; @apply whitespace-nowrap;

View File

@@ -0,0 +1,20 @@
<script setup>
</script>
<template>
<div class="flex gap-[10px]">
<a-link :hoverable="false">
<icon-arrow-rise/>
上移
</a-link>
<a-link :hoverable="false">
<icon-arrow-fall/>
下移
</a-link>
</div>
</template>
<style scoped lang="scss">
</style>

View File

@@ -0,0 +1,54 @@
<script setup>
import {ref} from "vue";
import Editor from "@tinymce/tinymce-vue";
import {VITE_TINYMCE_KEY} from "../../utils/index.js";
const loading = ref(true);
const {skin} = defineProps({
skin: {
type: String,
default: 'borderless', // 'fluent'
}
});
const onEditorReady = () => {
loading.value = false;
}
const INIT = ref({
language: 'zh_CN',
skin: skin,
content_css: skin === 'fluent' ? 'fluent' : null,
toolbar_mode: skin === 'fluent' ? 'floating' : null,
plugins: 'advlist anchor autolink charmap code codesample directionality help image editimage insertdatetime link lists media nonbreaking pagebreak preview searchreplace table tableofcontents visualblocks visualchars wordcount',
toolbar: 'undo redo | blocks | bold italic strikethrough forecolor backcolor blockquote | link image media | alignleft aligncenter alignright alignjustify | numlist bullist outdent indent | removeformat',
init_instance_callback: onEditorReady,
})
</script>
<template>
<div id="TinyMCE" class="h-auto w-full">
<a-spin
dot
:size="20"
class="w-full h-auto"
:loading="loading"
tip="编辑器加载中">
<Editor
:init="INIT"
:api-key="VITE_TINYMCE_KEY()"
@on-ready="onEditorReady">
</Editor>
</a-spin>
</div>
</template>
<style scoped lang="scss">
#TinyMCE {
:deep(.tox) {
width: 100%;
height: 100%;
min-height: 500px !important;
}
}
</style>

View File

@@ -0,0 +1,47 @@
<script setup>
import TinyMCE from "./index.vue";
import {ref} from "vue";
const visible = ref(false);
const fullscreen = ref(false);
</script>
<template>
<a-link v-if="!$slots.default" :hoverable="false" @click="visible=true">编辑</a-link>
<div v-else><slot></slot></div>
<a-modal
id="TinyMCEModal"
:mask-closable="false"
:unmount-on-close="true"
:fullscreen="fullscreen"
width="800px"
:draggable="true"
title-align="start"
title="编辑"
v-model:visible="visible">
<template #title>
<div class="flex justify-between w-full pr-[30px]">
<div>
编辑
</div>
<a-link @click="fullscreen = !fullscreen">
<icon-fullscreen v-if="!fullscreen" />
<icon-fullscreen-exit v-else />
</a-link>
</div>
</template>
<TinyMCE :skin="fullscreen ? 'fluent' : 'borderless'"></TinyMCE>
</a-modal>
</template>
<style scoped lang="scss">
</style>
<style lang="scss">
#TinyMCEModal {
.arco-modal-body {
@apply p-0 h-full min-h-[500px];
}
}
</style>

View File

@@ -1,10 +1,129 @@
<script setup> <script setup>
import Filter from "../../../../components/Filter/index.vue";
import {reactive} from "vue";
import useTableQuery from "../../../../hooks/useTableQuery.js";
import Api from "../../../../api/index.js";
const columns = [
{
title: '商家ID',
dataIndex: 'key',
},
{
title: '渠道',
dataIndex: 'key',
},
{
title: '达人ID',
dataIndex: 'key',
},
{
title: '推广账号ID',
dataIndex: 'image',
slotName: 'image',
},
{
title: '推广账号',
dataIndex: 'image',
slotName: 'image',
},
{
title: '拉黑原因',
dataIndex: 'key',
},
{
title: '拉黑效果',
dataIndex: 'key',
},
{
title: '开始日期',
dataIndex: 'key',
},
{
title: '结束日期',
dataIndex: 'key',
},
{
title: '关联任务ID',
dataIndex: 'key',
},
{
title: '关联子任务ID',
dataIndex: 'key',
},
{
title: '操作',
dataIndex: 'action',
slotName: 'action',
width: 90,
},
];
const FilterConfig = [
{
key: 'wd',
type: 'input',
label: '达人ID',
placeholder: '请输入达人ID',
},
{
key: 'wd',
type: 'input',
label: '账号',
placeholder: '请输入账号',
},
{
key: 'wd',
type: 'input',
label: '推广账号',
placeholder: '请输入推广账号',
},
{
key: 'wd',
type: 'datetime',
label: '推广日期',
},
];
const po = reactive({
wd: null,
});
const vo = reactive({
page: '',
rows: [],
total: 0,
});
const {loading, pagination, initFetchData} = useTableQuery({
parameter: po,
api: Api.system.getData,
callback: (data) => {
Object.assign(vo, data);
}
});
</script> </script>
<template> <template>
<!-- 拉黑记录 --> <!-- 拉黑记录 -->
拉黑记录 <a-card>
<Filter
v-model:from="po"
:config="FilterConfig">
</Filter>
<a-table
:data="vo.rows"
@page-change="(e) => pagination.current = e"
:pagination="pagination"
:loading="loading"
:columns="columns"
class="flex-grow">
<template v-slot:action>
<div class="flex gap-[20px]">
<a-link :hoverable="false">取消拉黑</a-link>
</div>
</template>
</a-table>
</a-card>
</template> </template>
<style scoped> <style scoped>

View File

@@ -1,10 +1,168 @@
<script setup> <script setup>
import Filter from "../../../../components/Filter/index.vue";
import {reactive} from "vue";
import useTableQuery from "../../../../hooks/useTableQuery.js";
import Api from "../../../../api/index.js";
const columns = [
{
title: '商家ID',
dataIndex: 'key',
},
{
title: '昵称',
dataIndex: 'key',
},
{
title: '头像',
dataIndex: 'key',
},
{
title: '手机号',
dataIndex: 'key',
},
{
title: '微信号',
dataIndex: 'image',
slotName: 'image',
},
{
title: '状态',
dataIndex: 'status',
slotName: 'status',
},
{
title: '邀请人',
dataIndex: 'key',
},
{
title: '上上',
dataIndex: 'key',
},
{
title: '上上上',
dataIndex: 'key',
},
{
title: '等级',
dataIndex: 'key',
},
{
title: '入驻日期',
dataIndex: 'key',
},
{
title: '分佣比例',
dataIndex: 'key',
},
{
title: '任务收益',
dataIndex: 'key',
},
{
title: '操作',
dataIndex: 'action',
slotName: 'action',
width: 140,
},
];
const FilterConfig = [
{
key: 'wd',
type: 'input',
label: '达人ID',
placeholder: '请输入达人ID',
},
{
key: 'wd',
type: 'input',
label: '邀请人',
placeholder: '请输入邀请人',
},
{
key: 'wd',
type: 'input',
label: '手机号',
placeholder: '请输入手机号',
},
{
key: 'wd',
type: 'select',
label: '状态',
placeholder: '请选择状态',
api: async () => ({
data: [
{
name: '选项一',
id: 1,
},
{
name: '选项二',
id: 2,
},
{
name: '选项三',
id: 3,
},
]
}),
},
{
key: 'wd',
type: 'datetime',
label: '入驻时间',
},
{
key: 'wd',
type: 'datetime',
label: '任务收益所属日期',
},
];
const po = reactive({
wd: null,
});
const vo = reactive({
page: '',
rows: [],
total: 0,
});
const {loading, pagination, initFetchData} = useTableQuery({
parameter: po,
api: Api.system.getData,
callback: (data) => {
Object.assign(vo, data);
}
});
</script> </script>
<template> <template>
<!-- 达人账号 --> <!-- 达人账号 -->
达人账号 <a-card>
<Filter
v-model:from="po"
:config="FilterConfig">
</Filter>
<a-table
:data="vo.rows"
@page-change="(e) => pagination.current = e"
:pagination="pagination"
:loading="loading"
:columns="columns"
class="flex-grow">
<template v-slot:status>
状态
</template>
<template v-slot:action>
<div class="flex gap-[20px]">
<a-link :hoverable="false">编辑</a-link>
<a-link :hoverable="false">快速进入</a-link>
</div>
</template>
</a-table>
</a-card>
</template> </template>
<style scoped> <style scoped>

View File

@@ -11,6 +11,16 @@
</div> </div>
</template> </template>
<style scoped> <style lang="scss" scoped>
.fade-enter-active,
.fade-leave-active {
transition: opacity 0.5s;
position: relative;
}
.fade-enter-from,
.fade-leave-to {
opacity: 0;
position: absolute;
}
</style> </style>

View File

@@ -1,10 +1,148 @@
<script setup> <script setup>
import {reactive} from "vue";
import useTableQuery from "../../../../hooks/useTableQuery.js";
import Api from "../../../../api/index.js";
import Filter from "../../../../components/Filter/index.vue";
const columns = [
{
title: '商家ID',
dataIndex: 'key',
},
{
title: '昵称',
dataIndex: 'key',
},
{
title: '头像',
dataIndex: 'key',
},
{
title: '手机号',
dataIndex: 'key',
},
{
title: '微信号',
dataIndex: 'image',
slotName: 'image',
},
{
title: '状态',
dataIndex: 'status',
slotName: 'status',
},
{
title: '邀请人',
dataIndex: 'key',
},
{
title: '入驻日期',
dataIndex: 'key',
},
{
title: '操作',
dataIndex: 'action',
slotName: 'action',
width: 120,
},
];
const FilterConfig = [
{
key: 'wd',
type: 'input',
label: '商家ID',
placeholder: '请输入商家ID',
},
{
key: 'wd',
type: 'input',
label: '邀请人',
placeholder: '请输入邀请人',
},
{
key: 'wd',
type: 'input',
label: '手机号',
placeholder: '请输入手机号',
},
{
key: 'wd',
type: 'select',
label: '状态',
placeholder: '请选择状态',
api: async () => ({
data: [
{
name: '选项一',
id: 1,
},
{
name: '选项二',
id: 2,
},
{
name: '选项三',
id: 3,
},
]
}),
},
{
key: 'wd',
type: 'datetime',
label: '入驻时间',
},
{
key: 'wd',
type: 'datetime',
label: '确认结算金额所属日期',
},
];
const po = reactive({
wd: null,
});
const vo = reactive({
page: '',
rows: [],
total: 0,
});
const {loading, pagination, initFetchData} = useTableQuery({
parameter: po,
api: Api.system.getData,
callback: (data) => {
Object.assign(vo, data);
}
});
</script> </script>
<template> <template>
<!-- 商家账号 --> <!-- 商家账号 -->
商家账号 <a-card>
<Filter
v-model:from="po"
:config="FilterConfig">
</Filter>
<a-table
:data="vo.rows"
@page-change="(e) => pagination.current = e"
:pagination="pagination"
:loading="loading"
:columns="columns"
class="flex-grow">
<template v-slot:status>
状态
</template>
<template v-slot:action>
<div class="flex gap-[20px]">
<a-link :hoverable="false">编辑</a-link>
<a-link :hoverable="false">卡密</a-link>
</div>
</template>
</a-table>
</a-card>
</template> </template>
<style scoped> <style scoped>

View File

@@ -1,10 +1,122 @@
<script setup> <script setup>
import {reactive} from "vue";
import useTableQuery from "../../../../hooks/useTableQuery.js";
import Api from "../../../../api/index.js";
import Filter from "../../../../components/Filter/index.vue";
const columns = [
{
title: '账号ID',
dataIndex: 'key',
},
{
title: '达人ID',
dataIndex: 'key',
},
{
title: '渠道',
dataIndex: 'key',
},
{
title: '主页截图',
dataIndex: 'image',
slotName: 'image',
},
{
title: '主页二维码',
dataIndex: 'image',
slotName: 'image',
},
{
title: '账号',
dataIndex: 'key',
},
{
title: '昵称',
dataIndex: 'key',
},
{
title: '推广账号状态',
dataIndex: 'status',
slotName: 'status',
},
{
title: '添加日期',
dataIndex: 'key',
},
{
title: '操作',
dataIndex: 'action',
slotName: 'action',
width: 160,
},
];
const FilterConfig = [
{
key: 'wd',
type: 'input',
label: '达人ID',
placeholder: '请输入达人ID',
},
{
key: 'wd',
type: 'input',
label: '账号',
placeholder: '请输入账号',
},
{
key: 'wd',
type: 'datetime',
label: '推广日期',
},
];
const po = reactive({
wd: null,
});
const vo = reactive({
page: '',
rows: [],
total: 0,
});
const {loading, pagination, initFetchData} = useTableQuery({
parameter: po,
api: Api.system.getData,
callback: (data) => {
Object.assign(vo, data);
}
});
</script> </script>
<template> <template>
<!-- 推广账号 --> <!-- 推广账号 -->
推广账号 <a-card>
<Filter
v-model:from="po"
:config="FilterConfig"
:button-col="false">
</Filter>
<a-table
:data="vo.rows"
@page-change="(e) => pagination.current = e"
:pagination="pagination"
:loading="loading"
:columns="columns"
class="flex-grow">
<template v-slot:status>
状态
</template>
<template v-slot:action>
<div class="flex gap-[20px]">
<a-link :hoverable="false">编辑</a-link>
<a-link :hoverable="false" status="success">通过</a-link>
<a-link :hoverable="false" status="danger">拒绝</a-link>
</div>
</template>
</a-table>
</a-card>
</template> </template>
<style scoped> <style scoped>

View File

@@ -0,0 +1,49 @@
<script setup>
import {ref} from "vue";
import XSelect from '../../../../../components/XSelect/index.vue';
import Api from "../../../../../api/index.js";
const visible = ref(false);
const success = () => {
}
</script>
<template>
<a-link :hover="false" @click="visible=true">编辑</a-link>
<a-modal
@ok="success"
ok-text="确定修改"
title-align="start"
title="编辑"
v-model:visible="visible">
<a-form layout="vertical">
<a-form-item label="提现方式">
<XSelect :api="Api.system.getSelect" placeholder="请选择提现方式"></XSelect>
</a-form-item>
<a-form-item label="卡号">
<a-input placeholder="请输入卡号"></a-input>
</a-form-item>
<a-form-item label="姓名">
<a-input placeholder="请输入姓名"></a-input>
</a-form-item>
<a-form-item label="身份证号">
<a-input placeholder="请输入身份证号"></a-input>
</a-form-item>
<a-form-item label="手机号">
<a-input placeholder="请输入手机号"></a-input>
</a-form-item>
<a-form-item label="费率">
<a-input-number placeholder="请输入费率">
<template #suffix>%</template>
</a-input-number>
</a-form-item>
</a-form>
</a-modal>
</template>
<style scoped>
</style>

View File

@@ -1,12 +1,328 @@
<script setup> <script setup>
const RADIO_LIST = [
{
label: '累计',
value: 1,
},
{
label: '今日',
value: 2,
},
{
label: '昨日',
value: 3,
},
{
label: '本周',
value: 4,
},
{
label: '本月',
value: 5,
},
{
label: '自定义',
value: 6,
},
];
</script> </script>
<template> <template>
<!-- 资金概览 --> <!-- 资金概览 -->
资金概览 <div class="mock-card mb-[20px]">
<div class="flex justify-between mb-[16px]">
<div class="title">
资金概览
</div>
<div>
<a-radio-group type="button">
<a-radio
v-for="item in RADIO_LIST"
:key="item.value"
:value="item.value">
{{ item.label }}
</a-radio>
</a-radio-group>
</div>
</div>
<div class="grid grid-cols-6 gap-[20px]" id="statistic-card">
<div
class="bg-[rgb(var(--arcoblue-1))] hover:bg-[rgb(var(--arcoblue-5))] duration-500 p-[20px] statistic-item">
<a-statistic
:value="8.06"
:precision="2"
:value-from="0"
animation>
<template #title>
商家充值含服务款
</template>
</a-statistic>
</div>
<div
class="bg-[rgb(var(--arcoblue-1))] hover:bg-[rgb(var(--arcoblue-5))] duration-500 p-[20px] statistic-item">
<a-statistic
:value="8.06"
:precision="2"
:value-from="0"
animation>
<template #title>
进行中的任务款
</template>
</a-statistic>
</div>
<div
class="bg-[rgb(var(--arcoblue-1))] hover:bg-[rgb(var(--arcoblue-5))] duration-500 p-[20px] statistic-item">
<a-statistic
:value="8.06"
:precision="2"
:value-from="0"
animation>
<template #title>
商家未提现资金
</template>
</a-statistic>
</div>
<div
class="bg-[rgb(var(--arcoblue-1))] hover:bg-[rgb(var(--arcoblue-5))] duration-500 p-[20px] statistic-item">
<a-statistic
:value="8.06"
:precision="2"
:value-from="0"
animation>
<template #title>
达人未提现资金
</template>
</a-statistic>
</div>
<div class="bg-[rgb(var(--orange-1))] hover:bg-[rgb(var(--orange-5))] duration-500 p-[20px] statistic-item">
<a-statistic
:value="8.06"
:precision="2"
:value-from="0"
animation>
<template #title>
毛利算法1
</template>
</a-statistic>
</div>
<div class="bg-[rgb(var(--orange-1))] hover:bg-[rgb(var(--orange-5))] duration-500 p-[20px] statistic-item">
<a-statistic
:value="8.06"
:precision="2"
:value-from="0"
animation>
<template #title>
毛利算法2
</template>
</a-statistic>
</div>
</div>
</div>
<div class="mock-card mb-[20px]">
<div class="title mb-[16px]">
资金概览
</div>
<div class="grid grid-cols-6 gap-[20px]">
<div class="bg-[var(--color-neutral-1)] p-[20px]">
<a-statistic
:value="8.06"
:precision="2"
:value-from="0"
animation>
<template #title>
商家充值含服务款
</template>
</a-statistic>
</div>
<div class="bg-[var(--color-neutral-1)] p-[20px]">
<a-statistic
:value="8.06"
:precision="2"
:value-from="0"
animation>
<template #title>
商家充值含服务款
</template>
</a-statistic>
</div>
</div>
</div>
<div class="flex gap-[20px] box-border mb-[20px]">
<div class="mock-card flex-grow">
<div class="title mb-[16px]">
资金概览
</div>
<a-descriptions table-layout="fixed" :column="1">
<a-descriptions-item>
<template #label>
<div class="label">任务款已消耗</div>
</template>
<div class="value">60.00</div>
</a-descriptions-item>
<a-descriptions-item>
<template #label>
<div class="label">任务服务费盈利</div>
</template>
<div class="value">6.00</div>
</a-descriptions-item>
<a-descriptions-item>
<template #label>
<div class="label">任务差额盈利</div>
</template>
<div class="value">30.00</div>
</a-descriptions-item>
</a-descriptions>
</div>
<div class="mock-card flex-grow">
<div class="title mb-[16px]">
商家
</div>
<a-descriptions table-layout="fixed" :column="1">
<a-descriptions-item>
<template #label>
<div class="label">商家发起提现</div>
</template>
<div class="value">60.00</div>
</a-descriptions-item>
<a-descriptions-item>
<template #label>
<div class="label">商家提现手续费</div>
</template>
<div class="value">6.00</div>
</a-descriptions-item>
<a-descriptions-item>
<template #label>
<div class="label">商家提现到手</div>
</template>
<div class="value">30.00</div>
</a-descriptions-item>
</a-descriptions>
</div>
</div>
<a-card>
<div class="title mb-[16px]">
达人
</div>
<a-descriptions table-layout="fixed" :column="2">
<a-descriptions-item>
<template #label>
<div class="label">商家发起提现</div>
</template>
<div class="value">60.00</div>
</a-descriptions-item>
<a-descriptions-item>
<template #label>
<div class="label">商家提现手续费</div>
</template>
<div class="value">6.00</div>
</a-descriptions-item>
<a-descriptions-item>
<template #label>
<div class="label">商家提现到手</div>
</template>
<div class="value">30.00</div>
</a-descriptions-item>
<a-descriptions-item>
<template #label>
<div class="label">商家发起提现</div>
</template>
<div class="value">60.00</div>
</a-descriptions-item>
<a-descriptions-item>
<template #label>
<div class="label">商家提现手续费</div>
</template>
<div class="value">6.00</div>
</a-descriptions-item>
<a-descriptions-item>
<template #label>
<div class="label">商家提现到手</div>
</template>
<div class="value">30.00</div>
</a-descriptions-item>
</a-descriptions>
</a-card>
</template> </template>
<style scoped> <style lang="scss" scoped>
#statistic-card {
.statistic-item {
cursor: pointer;
&:hover {
:deep(.arco-statistic) {
.arco-statistic-title,
.arco-statistic-content>.arco-statistic-value {
color: #fff;
}
}
}
:deep(.arco-statistic) {
.arco-statistic-title,
.arco-statistic-content>.arco-statistic-value {
transition: 500ms;
}
}
@for $i from 1 through 6 {
&:nth-child(#{$i}) {
:deep(.arco-statistic) .arco-statistic-value {
color: rgb(var(--#{if($i < 5, 'arcoblue-6', 'orange-5')}));
}
}
}
}
}
.value {
color: rgb(29, 33, 41);
font-family: Nunito Sans, serif;
font-size: 20px;
font-weight: 600;
line-height: 32px;
letter-spacing: 0;
text-align: left;
}
.label {
$color: rgb(78, 89, 105);
color: $color;
font-size: 14px;
font-weight: 400;
line-height: 22px;
letter-spacing: 0;
text-align: left;
display: flex;
align-items: center;
gap: 6px;
padding-left: 12px;
&::before {
content: '';
width: 4px;
height: 4px;
display: block;
background-color: $color;
border-radius: 50%;
}
}
.title {
color: rgb(29, 33, 41);
font-size: 18px;
font-weight: 500;
line-height: 24px;
letter-spacing: 0;
text-align: left;
}
</style> </style>

View File

@@ -1,10 +1,181 @@
<script setup> <script setup>
import Filter from "../../../../components/Filter/index.vue";
import {reactive} from "vue";
import useTableQuery from "../../../../hooks/useTableQuery.js";
import Api from "../../../../api/index.js";
const columns = [
{
title: '动账日期',
dataIndex: 'key',
},
{
title: '动账时间',
dataIndex: 'key',
},
{
title: '交易流水号',
dataIndex: 'key',
},
{
title: '动账渠道',
dataIndex: 'key',
},
{
title: '状态',
dataIndex: 'image',
slotName: 'image',
},
{
title: '动账用途',
dataIndex: 'key',
},
{
title: '动账金额(元)',
dataIndex: 'key',
},
{
title: '类型',
dataIndex: 'key',
},
{
title: '付款人账户',
dataIndex: 'key',
},
{
title: '收款人账户',
dataIndex: 'key',
},
{
title: '商家ID',
dataIndex: 'key',
},
{
title: '关联任务ID',
dataIndex: 'key',
},
{
title: '子任务ID',
dataIndex: 'key',
},
{
title: '达人iD',
dataIndex: 'key',
},
{
title: '推广账号iD',
dataIndex: 'key',
},
{
title: '推广账号',
dataIndex: 'key',
},
];
const FilterConfig = [
{
key: 'wd',
type: 'input',
label: '商家ID',
placeholder: '请输入商家ID',
},
{
key: 'wd',
type: 'input',
label: '关联任务ID',
placeholder: '请输入关联任务ID',
},
{
key: 'wd',
type: 'input',
label: '达人ID',
placeholder: '请输入达人ID',
},
{
key: 'wd',
type: 'select',
label: '动账渠道',
placeholder: '请选择动账渠道',
api: async () => ({
data: [
{
name: '选项一',
id: 1,
},
{
name: '选项二',
id: 2,
},
{
name: '选项三',
id: 3,
},
]
}),
},
{
key: 'wd',
type: 'select',
label: '动账用途',
placeholder: '请选择动账用途',
api: async () => ({
data: [
{
name: '选项一',
id: 1,
},
{
name: '选项二',
id: 2,
},
{
name: '选项三',
id: 3,
},
]
}),
},
{
key: 'wd',
type: 'datetime',
label: '动账日期',
}
];
const po = reactive({
wd: null,
});
const vo = reactive({
page: '',
rows: [],
total: 0,
});
const {loading, pagination, initFetchData} = useTableQuery({
parameter: po,
api: Api.system.getData,
callback: (data) => {
Object.assign(vo, data);
}
});
</script> </script>
<template> <template>
<!-- 资金管理() --> <!-- 资金管理() -->
资金管理() <a-card>
<Filter
v-model:from="po"
:config="FilterConfig">
</Filter>
<a-table
:data="vo.rows"
@page-change="(e) => pagination.current = e"
:pagination="pagination"
:loading="loading"
:columns="columns"
class="flex-grow">
</a-table>
</a-card>
</template> </template>
<style scoped> <style scoped>

View File

@@ -1,10 +1,181 @@
<script setup> <script setup>
import Filter from "../../../../components/Filter/index.vue";
import {reactive} from "vue";
import useTableQuery from "../../../../hooks/useTableQuery.js";
import Api from "../../../../api/index.js";
const columns = [
{
title: '动账日期',
dataIndex: 'key',
},
{
title: '动账时间',
dataIndex: 'key',
},
{
title: '交易流水号',
dataIndex: 'key',
},
{
title: '动账渠道',
dataIndex: 'key',
},
{
title: '状态',
dataIndex: 'image',
slotName: 'image',
},
{
title: '动账用途',
dataIndex: 'key',
},
{
title: '动账金额(元)',
dataIndex: 'key',
},
{
title: '付款人账户',
dataIndex: 'key',
},
{
title: '收款人账户',
dataIndex: 'key',
},
{
title: '商家ID',
dataIndex: 'key',
},
{
title: '关联任务ID',
dataIndex: 'key',
},
{
title: '子任务ID',
dataIndex: 'key',
},
{
title: '达人iD',
dataIndex: 'key',
},
{
title: '推广账号iD',
dataIndex: 'key',
},
{
title: '推广账号',
dataIndex: 'key',
},
{
title: '关联活动ID',
dataIndex: 'key',
},
];
const FilterConfig = [
{
key: 'wd',
type: 'input',
label: '达人ID',
placeholder: '请输入达人ID',
},
{
key: 'wd',
type: 'input',
label: '关联任务ID',
placeholder: '请输入关联任务ID',
},
{
key: 'wd',
type: 'input',
label: '子任务ID',
placeholder: '请输入子任务ID',
},
{
key: 'wd',
type: 'select',
label: '动账渠道',
placeholder: '请选择动账渠道',
api: async () => ({
data: [
{
name: '选项一',
id: 1,
},
{
name: '选项二',
id: 2,
},
{
name: '选项三',
id: 3,
},
]
}),
},
{
key: 'wd',
type: 'select',
label: '动账用途',
placeholder: '请选择动账用途',
api: async () => ({
data: [
{
name: '选项一',
id: 1,
},
{
name: '选项二',
id: 2,
},
{
name: '选项三',
id: 3,
},
]
}),
},
{
key: 'wd',
type: 'datetime',
label: '动账日期',
}
];
const po = reactive({
wd: null,
});
const vo = reactive({
page: '',
rows: [],
total: 0,
});
const {loading, pagination, initFetchData} = useTableQuery({
parameter: po,
api: Api.system.getData,
callback: (data) => {
Object.assign(vo, data);
}
});
</script> </script>
<template> <template>
<!-- 资金管理() --> <!-- 资金管理() -->
资金管理() <a-card>
<Filter
v-model:from="po"
:config="FilterConfig">
</Filter>
<a-table
:data="vo.rows"
@page-change="(e) => pagination.current = e"
:pagination="pagination"
:loading="loading"
:columns="columns"
class="flex-grow">
</a-table>
</a-card>
</template> </template>
<style scoped> <style scoped>

View File

@@ -1,12 +1,249 @@
<script setup> <script setup>
import Filter from "../../../../components/Filter/index.vue";
import {reactive} from "vue";
import useTableQuery from "../../../../hooks/useTableQuery.js";
import Api from "../../../../api/index.js";
const columns = [
{
title: 'ID',
dataIndex: 'key',
},
{
title: '身份',
dataIndex: 'key',
},
{
title: '提现方式',
dataIndex: 'key',
},
{
title: '姓名',
dataIndex: 'key',
},
{
title: '卡号',
dataIndex: 'image',
slotName: 'image',
},
{
title: '金额',
dataIndex: 'key',
},
{
title: '申请日期',
dataIndex: 'key',
},
{
title: '状态',
dataIndex: 'status',
slotName: 'status',
},
{
title: '到账日期',
dataIndex: 'key',
},
{
title: '操作',
dataIndex: 'action',
slotName: 'action',
width: 80,
},
{
title: '备注',
dataIndex: 'remark',
slotName: 'remark',
width: 250,
},
];
const FilterConfig = [
{
key: 'wd',
type: 'input',
label: 'ID',
placeholder: '请输入ID',
},
{
key: 'wd',
type: 'input',
label: '姓名',
placeholder: '请输入姓名',
},
{
key: 'wd',
type: 'input',
label: '卡号',
placeholder: '请输入卡号',
},
{
key: 'wd',
type: 'select',
label: '身份',
placeholder: '请选择身份',
api: async () => ({
data: [
{
name: '选项一',
id: 1,
},
{
name: '选项二',
id: 2,
},
{
name: '选项三',
id: 3,
},
]
}),
},
{
key: 'wd',
type: 'datetime',
label: '申请时间',
},
{
key: 'wd',
type: 'select',
label: '状态',
placeholder: '请选择状态',
api: async () => ({
data: [
{
name: '选项一',
id: 1,
},
{
name: '选项二',
id: 2,
},
{
name: '选项三',
id: 3,
},
]
}),
},
];
const po = reactive({
wd: null,
});
const vo = reactive({
page: '',
rows: [],
total: 0,
});
const {loading, pagination, initFetchData} = useTableQuery({
parameter: po,
api: Api.system.getData,
callback: (data) => {
Object.assign(vo, data);
}
});
</script> </script>
<template> <template>
<!-- 打款管理 --> <!-- 打款管理 -->
打款管理 <div class="mock-card mb-[20px]">
<div class="title mb-[16px]">打款商户</div>
<div class="grid grid-cols-6 gap-[20px]" id="statistic-card">
<div
class="bg-[rgb(var(--arcoblue-1))] hover:bg-[rgb(var(--arcoblue-5))] duration-500 p-[20px] statistic-item">
<a-statistic
show-group-separator
:value="5436.24"
:precision="2"
:value-from="0"
animation>
<template #title>
商户1剩余
</template>
</a-statistic>
</div>
<div
class="bg-[rgb(var(--arcoblue-1))] hover:bg-[rgb(var(--arcoblue-5))] duration-500 p-[20px] statistic-item">
<a-statistic
show-group-separator
:value="12790.58"
:precision="2"
:value-from="0"
animation>
<template #title>
商户2剩余
</template>
</a-statistic>
</div>
</div>
</div>
<div class="mock-card mb-[20px]">
<Filter
v-model:from="po"
:config="FilterConfig">
</Filter>
</div>
<a-card>
<a-table
:data="vo.rows"
@page-change="(e) => pagination.current = e"
:pagination="pagination"
:loading="loading"
:columns="columns"
class="flex-grow">
<template v-slot:status>
状态
</template>
<template v-slot:action>
<a-link :hoverable="false">打款</a-link>
</template>
<template v-slot:remark>
<a-input class="w-full" placeholder="请输入备注信息"></a-input>
</template>
</a-table>
</a-card>
</template> </template>
<style scoped> <style lang="scss" scoped>
#statistic-card {
.statistic-item {
cursor: pointer;
&:hover {
:deep(.arco-statistic) {
.arco-statistic-title,
.arco-statistic-content > .arco-statistic-value {
color: #fff;
}
}
}
:deep(.arco-statistic) {
.arco-statistic-title,
.arco-statistic-content > .arco-statistic-value {
transition: 500ms;
}
}
@for $i from 1 through 6 {
&:nth-child(#{$i}) {
:deep(.arco-statistic) .arco-statistic-value {
color: rgb(var(--arcoblue-6));
}
}
}
}
}
.title {
color: rgb(29, 33, 41);
font-size: 20px;
font-weight: 500;
line-height: 24px;
letter-spacing: 0;
text-align: left;
}
</style> </style>

View File

@@ -1,10 +1,168 @@
<script setup> <script setup>
import Filter from "../../../../components/Filter/index.vue";
import {reactive} from "vue";
import useTableQuery from "../../../../hooks/useTableQuery.js";
import Api from "../../../../api/index.js";
import EditWithdrawalModal from "./components/EditWithdrawalModal.vue";
const columns = [
{
title: 'ID',
dataIndex: 'key',
},
{
title: '身份',
dataIndex: 'key',
},
{
title: '身份ID',
dataIndex: 'key',
},
{
title: '提现方式',
dataIndex: 'key',
},
{
title: '卡号',
dataIndex: 'key',
slotName: 'key',
},
{
title: '姓名',
dataIndex: 'key',
},
{
title: '身份证',
dataIndex: 'key',
},
{
title: '电话',
dataIndex: 'key',
},
{
title: '费率',
dataIndex: 'key',
},
{
title: '添加日期',
dataIndex: 'key',
},
{
title: '操作',
dataIndex: 'action',
slotName: 'action',
width: 70,
},
];
const FilterConfig = [
{
key: 'wd',
type: 'select',
label: '身份',
placeholder: '请选择身份',
api: async () => ({
data: [
{
name: '选项一',
id: 1,
},
{
name: '选项二',
id: 2,
},
{
name: '选项三',
id: 3,
},
]
}),
},
{
key: 'wd',
type: 'input',
label: '身份ID',
placeholder: '请输入身份ID',
},
{
key: 'wd',
type: 'input',
label: '身份证号',
placeholder: '请输入身份证号',
},
{
key: 'wd',
type: 'input',
label: '卡号',
placeholder: '请输入卡号',
},
{
key: 'wd',
type: 'input',
label: '电话号',
placeholder: '请输入电话号',
},
{
key: 'wd',
type: 'select',
label: '提现方式',
placeholder: '请选择提现方式',
api: async () => ({
data: [
{
name: '选项一',
id: 1,
},
{
name: '选项二',
id: 2,
},
{
name: '选项三',
id: 3,
},
]
}),
},
];
const po = reactive({
wd: null,
});
const vo = reactive({
page: '',
rows: [],
total: 0,
});
const {loading, pagination, initFetchData} = useTableQuery({
parameter: po,
api: Api.system.getData,
callback: (data) => {
Object.assign(vo, data);
}
});
</script> </script>
<template> <template>
<!-- 提现信息 --> <!-- 提现信息 -->
提现信息 <a-card>
<Filter
v-model:from="po"
:config="FilterConfig">
</Filter>
<a-table
:data="vo.rows"
@page-change="(e) => pagination.current = e"
:pagination="pagination"
:loading="loading"
:columns="columns"
class="flex-grow">
<template v-slot:action>
<EditWithdrawalModal></EditWithdrawalModal>
</template>
</a-table>
</a-card>
</template> </template>
<style scoped> <style scoped>

View File

@@ -0,0 +1,87 @@
<script setup>
import SequenceAdjustment from "../../../../../components/SequenceAdjustment/index.vue";
import {reactive} from "vue";
import useTableQuery from "../../../../../hooks/useTableQuery.js";
import Api from "../../../../../api/index.js";
const columns = [
{
title: 'ID',
dataIndex: 'key',
width: 120,
},
{
title: '封面',
dataIndex: 'key',
},
{
title: '跳转方式',
dataIndex: 'key',
},
{
title: '是否启用',
dataIndex: 'isA',
slotName: 'isA',
width: 100,
align: 'center',
},
{
title: '排序',
dataIndex: 'sort',
slotName: 'sort',
width: 140,
},
{
title: '操作',
dataIndex: 'action',
slotName: 'action',
width: 60,
},
];
const po = reactive({});
const vo = reactive({
page: '',
rows: [],
total: 0,
});
const {loading, pagination, initFetchData} = useTableQuery({
parameter: po,
api: Api.system.getData,
callback: (data) => {
Object.assign(vo, data);
}
});
</script>
<template>
<a-button type="primary">
<template #icon>
<icon-plus/>
</template>
新建
</a-button>
<a-table
:loading="loading"
@page-change="(e) => pagination.current = e"
:pagination="pagination"
:data="vo.rows"
:columns="columns"
class="flex-grow mt-[20px] w-full">
<template v-slot:isA>
<a-switch></a-switch>
</template>
<template v-slot:sort>
<SequenceAdjustment></SequenceAdjustment>
</template>
<template v-slot:action>
<a-link :hoverable="false" status="danger">删除</a-link>
</template>
</a-table>
</template>
<style scoped lang="scss">
</style>

View File

@@ -0,0 +1,85 @@
<script setup>
import {reactive} from "vue";
import useTableQuery from "../../../../../hooks/useTableQuery.js";
import Api from "../../../../../api/index.js";
import SequenceAdjustment from "../../../../../components/SequenceAdjustment/index.vue";
const columns = [
{
title: 'ID',
dataIndex: 'key',
width: 120,
},
{
title: '内容',
dataIndex: 'content',
slotName: 'content',
},
{
title: '排序',
dataIndex: 'sort',
slotName: 'sort',
width: 140,
},
{
title: '操作',
dataIndex: 'action',
slotName: 'action',
width: 60,
},
];
const po = reactive({});
const vo = reactive({
page: '',
rows: [],
total: 0,
});
const {loading, pagination, initFetchData} = useTableQuery({
parameter: po,
api: Api.system.getData,
callback: (data) => {
Object.assign(vo, data);
}
});
const success = async (item) => {
}
</script>
<template>
<a-button type="primary">
<template #icon>
<icon-plus/>
</template>
新建
</a-button>
<a-table
:loading="loading"
@page-change="(e) => pagination.current = e"
:pagination="pagination"
:data="vo.rows"
:columns="columns"
class="flex-grow mt-[20px] w-full">
<template v-slot:content="{record}">
<a-textarea
@blur="success(record)"
v-model:model-value="record.key"
auto-size>
</a-textarea>
</template>
<template v-slot:sort>
<SequenceAdjustment></SequenceAdjustment>
</template>
<template v-slot:action>
<a-link :hoverable="false" status="danger">删除</a-link>
</template>
</a-table>
</template>
<style scoped lang="scss">
</style>

View File

@@ -0,0 +1,131 @@
<script setup>
import {reactive, ref} from "vue";
import SequenceAdjustment from "../../../../../components/SequenceAdjustment/index.vue";
import useTableQuery from "../../../../../hooks/useTableQuery.js";
import Api from "../../../../../api/index.js";
const tabs = [
{
title: '常见问题',
key: '1',
},
{
title: '基础教学',
key: '2',
},
{
title: 'banner管理',
key: '3',
},
{
title: '二级分类管理',
key: '4',
},
];
const columns = [
{
title: 'ID',
dataIndex: 'key',
width: 120,
},
{
title: '二级分类',
dataIndex: 'key',
},
{
title: '标题',
dataIndex: 'key',
},
{
title: '简介',
dataIndex: 'key',
},
{
title: '是否启用',
dataIndex: 'isA',
slotName: 'isA',
width: 100,
align: 'center',
},
{
title: '是否置顶',
dataIndex: 'isTop',
slotName: 'isTop',
width: 100,
align: 'center',
},
{
title: '排序',
dataIndex: 'sort',
slotName: 'sort',
width: 140,
},
{
title: '操作',
dataIndex: 'action',
slotName: 'action',
width: 120,
},
];
const activeKey = ref('1');
const po = reactive({});
const vo = reactive({
page: '',
rows: [],
total: 0,
});
const {loading, pagination, initFetchData} = useTableQuery({
parameter: po,
api: Api.system.getData,
callback: (data) => {
Object.assign(vo, data);
}
});
</script>
<template>
<a-tabs v-model:active-key="activeKey" type="text">
<a-tab-pane
v-for="item in tabs"
:key="item.key"
:title="item.title">
</a-tab-pane>
</a-tabs>
<a-button type="primary">
<template #icon>
<icon-plus/>
</template>
新建
</a-button>
<a-table
:loading="loading"
@page-change="(e) => pagination.current = e"
:pagination="pagination"
:data="vo.rows"
:columns="columns"
class="flex-grow mt-[20px] w-full">
<template v-slot:isA>
<a-switch></a-switch>
</template>
<template v-slot:isTop>
<a-switch></a-switch>
</template>
<template v-slot:sort>
<SequenceAdjustment></SequenceAdjustment>
</template>
<template v-slot:action>
<div class="flex gap-[20px]">
<a-link :hoverable="false">编辑</a-link>
<a-link :hoverable="false" status="danger">删除</a-link>
</div>
</template>
</a-table>
</template>
<style scoped lang="scss">
</style>

View File

@@ -0,0 +1,87 @@
<script setup>
import SequenceAdjustment from "../../../../../components/SequenceAdjustment/index.vue";
import {reactive} from "vue";
import useTableQuery from "../../../../../hooks/useTableQuery.js";
import Api from "../../../../../api/index.js";
const columns = [
{
title: 'ID',
dataIndex: 'key',
width: 120,
},
{
title: '封面',
dataIndex: 'key',
},
{
title: '跳转方式',
dataIndex: 'key',
},
{
title: '是否启用',
dataIndex: 'isA',
slotName: 'isA',
width: 100,
align: 'center',
},
{
title: '排序',
dataIndex: 'sort',
slotName: 'sort',
width: 140,
},
{
title: '操作',
dataIndex: 'action',
slotName: 'action',
width: 60,
},
];
const po = reactive({});
const vo = reactive({
page: '',
rows: [],
total: 0,
});
const {loading, pagination, initFetchData} = useTableQuery({
parameter: po,
api: Api.system.getData,
callback: (data) => {
Object.assign(vo, data);
}
});
</script>
<template>
<a-button type="primary">
<template #icon>
<icon-plus/>
</template>
新建
</a-button>
<a-table
:loading="loading"
@page-change="(e) => pagination.current = e"
:pagination="pagination"
:data="vo.rows"
:columns="columns"
class="flex-grow mt-[20px] w-full">
<template v-slot:isA>
<a-switch></a-switch>
</template>
<template v-slot:sort>
<SequenceAdjustment></SequenceAdjustment>
</template>
<template v-slot:action>
<a-link :hoverable="false" status="danger">删除</a-link>
</template>
</a-table>
</template>
<style scoped lang="scss">
</style>

View File

@@ -0,0 +1,108 @@
<script setup>
import {reactive} from "vue";
import useTableQuery from "../../../../../hooks/useTableQuery.js";
import Api from "../../../../../api/index.js";
import SequenceAdjustment from "../../../../../components/SequenceAdjustment/index.vue";
const columns = [
{
title: 'ID',
dataIndex: 'key',
width: 120,
},
{
title: '标题',
dataIndex: 'key',
},
{
title: '简介',
dataIndex: 'key',
},
{
title: '跳转方式',
dataIndex: 'key',
},
{
title: '发布时间',
dataIndex: 'key',
},
{
title: '是否启用',
dataIndex: 'isA',
slotName: 'isA',
width: 100,
align: 'center',
},
{
title: '是否置顶',
dataIndex: 'isTop',
slotName: 'isTop',
width: 100,
align: 'center',
},
{
title: '排序',
dataIndex: 'sort',
slotName: 'sort',
width: 140,
},
{
title: '操作',
dataIndex: 'action',
slotName: 'action',
width: 120,
},
];
const po = reactive({});
const vo = reactive({
page: '',
rows: [],
total: 0,
});
const {loading, pagination, initFetchData} = useTableQuery({
parameter: po,
api: Api.system.getData,
callback: (data) => {
Object.assign(vo, data);
}
});
</script>
<template>
<a-button type="primary">
<template #icon>
<icon-plus/>
</template>
新建
</a-button>
<a-table
:loading="loading"
@page-change="(e) => pagination.current = e"
:pagination="pagination"
:data="vo.rows"
:columns="columns"
class="flex-grow mt-[20px] w-full">
<template v-slot:isA>
<a-switch></a-switch>
</template>
<template v-slot:isTop>
<a-switch></a-switch>
</template>
<template v-slot:sort>
<SequenceAdjustment></SequenceAdjustment>
</template>
<template v-slot:action>
<div class="flex gap-[20px]">
<a-link :hoverable="false">编辑</a-link>
<a-link :hoverable="false" status="danger">删除</a-link>
</div>
</template>
</a-table>
</template>
<style scoped lang="scss">
</style>

View File

@@ -0,0 +1,69 @@
<script setup>
import {reactive} from "vue";
import useTableQuery from "../../../../../hooks/useTableQuery.js";
import Api from "../../../../../api/index.js";
const columns = [
{
title: 'ID',
dataIndex: 'key',
width: 100,
},
{
title: '位置',
dataIndex: 'key',
},
{
title: '二维码',
dataIndex: 'qrcode',
slotName: 'qrcode',
},
{
title: '操作',
dataIndex: 'action',
slotName: 'action',
width: 60,
},
];
const po = reactive({});
const vo = reactive({
page: '',
rows: [],
total: 0,
});
const {loading, pagination, initFetchData} = useTableQuery({
parameter: po,
api: Api.system.getData,
callback: (data) => {
Object.assign(vo, data);
}
});
</script>
<template>
<a-table
:loading="loading"
@page-change="(e) => pagination.current = e"
:pagination="pagination"
:data="vo.rows"
:columns="columns"
class="flex-grow mt-[20px] w-full">
<template v-slot:qrcode>
<a-image
width="48px"
height="48px"
src="https://p1-arco.byteimg.com/tos-cn-i-uwbnlip3yd/a8c8cdb109cb051163646151a4a5083b.png~tplv-uwbnlip3yd-webp.webp">
</a-image>
</template>
<template v-slot:action>
<a-link :hoverable="false">编辑</a-link>
</template>
</a-table>
</template>
<style scoped lang="scss">
</style>

View File

@@ -0,0 +1,76 @@
<script setup>
import TinyMCEModal from "../../../../../components/TinyMCE/modal.vue";
import {reactive} from "vue";
import useTableQuery from "../../../../../hooks/useTableQuery.js";
import Api from "../../../../../api/index.js";
const columns = [
{
title: 'ID',
dataIndex: 'key',
width: 120,
},
{
title: '标题',
dataIndex: 'key',
},
{
title: '预览',
dataIndex: 'preview',
slotName: 'preview',
width: 100,
},
{
title: '操作',
dataIndex: 'action',
slotName: 'action',
width: 120,
},
];
const po = reactive({});
const vo = reactive({
page: '',
rows: [],
total: 0,
});
const {loading, pagination, initFetchData} = useTableQuery({
parameter: po,
api: Api.system.getData,
callback: (data) => {
Object.assign(vo, data);
}
});
</script>
<template>
<a-button type="primary">
<template #icon>
<icon-plus/>
</template>
新建
</a-button>
<a-table
:loading="loading"
@page-change="(e) => pagination.current = e"
:pagination="pagination"
:data="vo.rows"
:columns="columns"
class="flex-grow mt-[20px] w-full">
<template v-slot:preview>
<a-link :hoverable="false"><icon-eye />预览</a-link>
</template>
<template v-slot:action>
<div class="flex gap-[20px]">
<TinyMCEModal></TinyMCEModal>
<a-link :hoverable="false" status="danger">删除</a-link>
</div>
</template>
</a-table>
</template>
<style scoped lang="scss">
</style>

View File

@@ -1,12 +1,90 @@
<script setup> <script setup>
import {defineAsyncComponent} from "vue";
// 懒加载组件
const HomepageBannerMessage = defineAsyncComponent(() => import('./components/HomepageBannerMessage.vue'));
const PlatformNews = defineAsyncComponent(() => import('./components/PlatformNews.vue'));
const HomeBanner = defineAsyncComponent(() => import('./components/HomeBanner.vue'));
const PersonalCenterBanner = defineAsyncComponent(() => import('./components/PersonalCenterBanner.vue'));
const QRCode = defineAsyncComponent(() => import('./components/QRCode.vue'));
const NoviceTeaching = defineAsyncComponent(() => import('./components/NoviceTeaching.vue'));
const RichTextContentLibrary = defineAsyncComponent(() => import('./components/RichTextContentLibrary.vue'));
const tabs = [
{
key: '1',
title: '首页横幅消息',
component: HomepageBannerMessage,
},
{
key: '2',
title: '平台消息',
component: PlatformNews,
},
{
key: '3',
title: '首页banner',
component: HomeBanner,
},
{
key: '4',
title: '个人中心banner',
component: PersonalCenterBanner,
},
{
key: '5',
title: '二维码',
component: QRCode,
},
{
key: '6',
title: '新手教学',
component: NoviceTeaching,
},
{
key: '7',
title: '富文本内容库',
component: RichTextContentLibrary,
},
];
</script> </script>
<template> <template>
<!-- 达人端物料 --> <!-- 达人端物料 -->
达人端物料 <a-card>
<div class="title">
达人端物料
</div>
<a-tabs
:justify="true"
:destroy-on-hide="true"
type="rounded">
<a-tab-pane v-for="item in tabs" :key="item.key" :title="item.title">
<Suspense>
<template #default>
<div class="h-full flex flex-col items-start">
<component :is="item.component"></component>
</div>
</template>
<template #fallback>
加载中...
</template>
</Suspense>
</a-tab-pane>
</a-tabs>
</a-card>
</template> </template>
<style scoped> <style lang="scss" scoped>
.title {
color: rgb(29, 33, 41);
font-size: 20px;
font-weight: 500;
line-height: 28px;
letter-spacing: 0;
text-align: left;
margin-bottom: 16px;
}
</style> </style>

View File

@@ -1,12 +1,102 @@
<script setup> <script setup>
import {reactive} from "vue";
import useTableQuery from "../../../../hooks/useTableQuery.js";
import Api from "../../../../api/index.js";
import SequenceAdjustment from "../../../../components/SequenceAdjustment/index.vue";
const columns = [
{
title: '任务编号',
dataIndex: 'key',
},
{
title: '任务名称',
dataIndex: 'key',
},
{
title: '发布渠道',
dataIndex: 'key',
},
{
title: '创建时间',
dataIndex: 'key',
},
{
title: '子任务数',
dataIndex: 'key',
},
{
title: '子任务报价',
dataIndex: 'key',
},
{
title: '商家ID',
dataIndex: 'key',
},
{
title: '平台报价',
dataIndex: 'key',
},
{
title: '是否置顶',
dataIndex: 'topUp',
slotName: 'topUp',
width: 100,
align: 'center',
},
{
title: '排序',
dataIndex: 'action',
slotName: 'action',
width: 130,
},
];
const po = reactive({});
const vo = reactive({
page: '',
rows: [],
total: 0,
});
const {loading, pagination, initFetchData} = useTableQuery({
parameter: po,
api: Api.system.getData,
callback: (data) => {
Object.assign(vo, data);
}
});
</script> </script>
<template> <template>
<!-- 任务排序 --> <!-- 任务排序 -->
任务排序 <a-card>
<div class="title">任务排序</div>
<a-table
:loading="loading"
@page-change="(e) => pagination.current = e"
:pagination="pagination"
:data="vo.rows"
:columns="columns"
class="flex-grow">
<template v-slot:topUp>
<a-switch></a-switch>
</template>
<template v-slot:action>
<SequenceAdjustment></SequenceAdjustment>
</template>
</a-table>
</a-card>
</template> </template>
<style scoped> <style lang="scss" scoped>
.title {
color: rgb(29, 33, 41);
font-size: 20px;
font-weight: 500;
line-height: 28px;
letter-spacing: 0;
text-align: left;
margin-bottom: 16px;
}
</style> </style>

View File

@@ -1,12 +1,100 @@
<script setup> <script setup>
import {reactive} from "vue";
import useTableQuery from "../../../../hooks/useTableQuery.js";
import Api from "../../../../api/index.js";
const columns = [
{
title: 'ID',
dataIndex: 'key',
width: 120,
},
{
title: '达人ID',
dataIndex: 'key',
width: 120,
},
{
title: '投诉截图',
dataIndex: 'key',
},
{
title: '投诉内容',
dataIndex: 'key',
},
{
title: '联系方式',
dataIndex: 'key',
width: 150,
},
{
title: '状态',
dataIndex: 'action',
slotName: 'action',
width: 120,
},
];
const po = reactive({});
const vo = reactive({
page: '',
rows: [],
total: 0,
});
const {loading, pagination, initFetchData} = useTableQuery({
parameter: po,
api: Api.system.getData,
callback: (data) => {
Object.assign(vo, data);
}
});
</script> </script>
<template> <template>
<!-- 团队投诉 --> <!-- 团队投诉 -->
团队投诉 <a-card>
<div class="title">
团队投诉
</div>
<div class="flex gap-[16px] mb-[16px]">
<a-button type="primary">
<template #icon>
<icon-check/>
</template>
批量已处理
</a-button>
<a-button type="primary">
<template #icon>
<icon-clock-circle/>
</template>
批量已处理
</a-button>
</div>
<a-table
:loading="loading"
@page-change="(e) => pagination.current = e"
:pagination="pagination"
:data="vo.rows"
:columns="columns"
class="flex-grow">
<template v-slot:action>
</template>
</a-table>
</a-card>
</template> </template>
<style scoped> <style lang="scss" scoped>
.title {
color: rgb(29, 33, 41);
font-size: 20px;
font-weight: 500;
line-height: 28px;
letter-spacing: 0;
text-align: left;
margin-bottom: 16px;
}
</style> </style>

View File

@@ -397,7 +397,7 @@ const mockRoutes2 = [
{ {
path: 'manage-expert-management', path: 'manage-expert-management',
name: 'manage-expert-management', name: 'manage-expert-management',
title: '资金', title: '达人端管理',
icon: '', icon: '',
meta: { meta: {
name: '达人端管理' name: '达人端管理'

View File

@@ -43,6 +43,9 @@ body {
} }
} }
} }
.arco-table-th-title {
@apply whitespace-nowrap flex-shrink-0;
}
.mock-card { .mock-card {
@apply p-[20px] bg-[#fff]; @apply p-[20px] bg-[#fff];
border: 1px solid var(--color-neutral-3); border: 1px solid var(--color-neutral-3);

View File

@@ -3,3 +3,7 @@ import router from "../router/index.js";
export const toPath = (path) => { export const toPath = (path) => {
router.push(path).then(); router.push(path).then();
} }
export const VITE_TINYMCE_KEY = () => {
return import.meta.env.VITE_TINYMCE_KEY;
}