update
This commit is contained in:
@@ -9,8 +9,10 @@
|
|||||||
"preview": "vite preview"
|
"preview": "vite preview"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"axios": "^1.8.2",
|
||||||
"pinia": "^3.0.1",
|
"pinia": "^3.0.1",
|
||||||
"pinia-plugin-persistedstate": "^4.2.0",
|
"pinia-plugin-persistedstate": "^4.2.0",
|
||||||
|
"vite-plugin-vue-devtools": "^7.7.2",
|
||||||
"vue": "^3.5.13",
|
"vue": "^3.5.13",
|
||||||
"vue-router": "^4.5.0"
|
"vue-router": "^4.5.0"
|
||||||
},
|
},
|
||||||
|
|||||||
762
pnpm-lock.yaml
generated
762
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,7 @@
|
|||||||
<script setup></script>
|
<script setup></script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<a-config-provider size="large">
|
<a-config-provider>
|
||||||
<router-view></router-view>
|
<router-view></router-view>
|
||||||
</a-config-provider>
|
</a-config-provider>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
7
src/api/index.ts
Normal file
7
src/api/index.ts
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
import system from './system.js';
|
||||||
|
|
||||||
|
const Api = {
|
||||||
|
system: {...system}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Api;
|
||||||
13
src/api/system.js
Normal file
13
src/api/system.js
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
import request from "../utils/request.js";
|
||||||
|
|
||||||
|
const system = {
|
||||||
|
getData: async (params) => {
|
||||||
|
return request({
|
||||||
|
url: '/m1/5995958-5684445-default/getList',
|
||||||
|
method: "POST",
|
||||||
|
data: params
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default system;
|
||||||
104
src/components/Filter/index.vue
Normal file
104
src/components/Filter/index.vue
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
<script setup>
|
||||||
|
import {defineModel} from 'vue';
|
||||||
|
|
||||||
|
const FROM_TYPE = {
|
||||||
|
INPUT: 'input',
|
||||||
|
SELECT: 'select',
|
||||||
|
DATETIME: 'datetime',
|
||||||
|
CUSTOM: 'custom',
|
||||||
|
}
|
||||||
|
const emits = defineEmits(['search']);
|
||||||
|
const {config} = defineProps({
|
||||||
|
config: {
|
||||||
|
type: Array,
|
||||||
|
default: []
|
||||||
|
}
|
||||||
|
});
|
||||||
|
const from = defineModel('from');
|
||||||
|
|
||||||
|
const reset = () => {
|
||||||
|
Object.keys(from.value).forEach(key => {
|
||||||
|
from.value[key] = null;
|
||||||
|
});
|
||||||
|
emits('search');
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="title">
|
||||||
|
查询任务
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex">
|
||||||
|
<div class="flex-grow">
|
||||||
|
<a-form class="AFORM">
|
||||||
|
<div class="grid grid-cols-3">
|
||||||
|
<template v-for="(item, index) in config" :key="index">
|
||||||
|
<a-form-item :label="item.label">
|
||||||
|
<template v-if="item.type === FROM_TYPE.INPUT">
|
||||||
|
<a-input
|
||||||
|
class="w-full"
|
||||||
|
v-model:model-value="from[item.key]"
|
||||||
|
:placeholder="item.placeholder">
|
||||||
|
</a-input>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template v-if="item.type === FROM_TYPE.SELECT">
|
||||||
|
<a-select
|
||||||
|
class="w-full"
|
||||||
|
v-model:model-value="from[item.key]"
|
||||||
|
:options="item.options"
|
||||||
|
:placeholder="item.placeholder">
|
||||||
|
</a-select>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template v-if="item.type === FROM_TYPE.DATETIME">
|
||||||
|
<a-range-picker
|
||||||
|
class="w-full"
|
||||||
|
@change="(v) => from[item.key] = `${v[0]}~${v[1]}`">
|
||||||
|
</a-range-picker>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template v-if="item.type === FROM_TYPE.CUSTOM">
|
||||||
|
<slot :name="item.slotName" :scope="item"></slot>
|
||||||
|
</template>
|
||||||
|
</a-form-item>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
</a-form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<a-divider direction="vertical" margin="20px"></a-divider>
|
||||||
|
|
||||||
|
<div class="flex flex-col gap-[16px]">
|
||||||
|
<a-button @click="emits('search')" type="primary">
|
||||||
|
<template #icon>
|
||||||
|
<icon-search/>
|
||||||
|
</template>
|
||||||
|
查询
|
||||||
|
</a-button>
|
||||||
|
<a-button @click="reset">
|
||||||
|
<template #icon>
|
||||||
|
<icon-refresh />
|
||||||
|
</template>
|
||||||
|
重置
|
||||||
|
</a-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.title {
|
||||||
|
color: rgb(29, 33, 41);
|
||||||
|
font-family: PingFang SC, serif;
|
||||||
|
font-size: 20px;
|
||||||
|
font-weight: 400;
|
||||||
|
line-height: 28px;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
.AFORM {
|
||||||
|
:deep(.arco-row) {
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
10
src/components/Filter/mock.js
Normal file
10
src/components/Filter/mock.js
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
const config = [
|
||||||
|
{
|
||||||
|
key: 'keywords',
|
||||||
|
type: 'input',
|
||||||
|
label: '任务编号',
|
||||||
|
placeholder: '请输入集合编号'
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
export default config;
|
||||||
@@ -5,7 +5,7 @@ const SystemStore = useSystemStore();
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="w-full h-full flex items-center px-[24px] box-border">
|
<div class="w-full h-full flex items-center px-[24px] box-border bg-white">
|
||||||
<div class="title">
|
<div class="title">
|
||||||
代发平台-{{SystemStore.isRoot?'管理员':'商家'}}
|
代发平台-{{SystemStore.isRoot?'管理员':'商家'}}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,32 +1,31 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import {onMounted} from "vue";
|
import {onMounted} from "vue";
|
||||||
import mockRoutes from "./mock.js";
|
|
||||||
import routesMap from "../../router/routes-map.js";
|
|
||||||
import {toPath} from "../../utils/index.js";
|
import {toPath} from "../../utils/index.js";
|
||||||
|
import {useSystemStore} from "../../pinia/SystemStore/index.js";
|
||||||
|
|
||||||
|
const SystemStore = useSystemStore();
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
console.log(mockRoutes.map(v => ({
|
|
||||||
path: v.path,
|
|
||||||
name: v.name,
|
|
||||||
component: routesMap[v.component]
|
|
||||||
})))
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const menuItemClick = (e) => {
|
const menuItemClick = (e) => {
|
||||||
toPath(`/home${e}`);
|
toPath(`/home${e}`);
|
||||||
}
|
}
|
||||||
|
//--main-bg-color
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
<div class="w-full h-full box-border">
|
||||||
<a-menu @menu-item-click="menuItemClick">
|
<a-menu @menu-item-click="menuItemClick">
|
||||||
<a-sub-menu v-for="item in mockRoutes" :key="item.name">
|
<a-sub-menu v-for="item in SystemStore.RoutesTemp" :key="item.name">
|
||||||
<template #icon>
|
<template #icon>
|
||||||
<icon-apps></icon-apps>
|
<icon-apps></icon-apps>
|
||||||
</template>
|
</template>
|
||||||
<template #title>{{ item.title }}</template>
|
<template #title>{{ item.title }}</template>
|
||||||
<a-menu-item v-for="k in item.children" :key="item.path + k.path">{{k.title}}</a-menu-item>
|
<a-menu-item v-for="k in item.children" :key="`/${item.path}/${k.path}`">{{ k.title }}</a-menu-item>
|
||||||
</a-sub-menu>
|
</a-sub-menu>
|
||||||
</a-menu>
|
</a-menu>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
|||||||
31
src/components/TooltipTag/index.vue
Normal file
31
src/components/TooltipTag/index.vue
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
<script setup>
|
||||||
|
const {color, content} = defineProps({
|
||||||
|
color: {
|
||||||
|
type: String,
|
||||||
|
default: 'red',
|
||||||
|
},
|
||||||
|
content: {
|
||||||
|
type: String,
|
||||||
|
default: '内容',
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<a-tooltip :content="content">
|
||||||
|
<a-badge>
|
||||||
|
<template v-slot:content>
|
||||||
|
<icon-question-circle :style="{ verticalAlign: 'middle', color: 'rgb(var(--primary-6))' }"/>
|
||||||
|
|
||||||
|
<slot v-if="$slots.icon" name="icon"></slot>
|
||||||
|
</template>
|
||||||
|
<a-tag :color="color" class="cursor-pointer">
|
||||||
|
<slot></slot>
|
||||||
|
</a-tag>
|
||||||
|
</a-badge>
|
||||||
|
</a-tooltip>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
||||||
72
src/hooks/useTableQuery.js
Normal file
72
src/hooks/useTableQuery.js
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
import {ref, reactive, watch} from 'vue';
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param parameter
|
||||||
|
* @param api
|
||||||
|
* @param callback
|
||||||
|
* @param immediate
|
||||||
|
* @param watchParameter
|
||||||
|
*/
|
||||||
|
function useTableQuery({
|
||||||
|
parameter,
|
||||||
|
api,
|
||||||
|
callback,
|
||||||
|
immediate = true,
|
||||||
|
watchParameter = false,
|
||||||
|
}) {
|
||||||
|
const loading = ref(false);
|
||||||
|
|
||||||
|
const pagination = reactive({
|
||||||
|
current: 1,
|
||||||
|
pageSize: 20,
|
||||||
|
total: 0
|
||||||
|
});
|
||||||
|
|
||||||
|
const fetchData = async () => {
|
||||||
|
try {
|
||||||
|
loading.value = true;
|
||||||
|
|
||||||
|
const params = {
|
||||||
|
...parameter,
|
||||||
|
current: pagination.current,
|
||||||
|
pageSize: pagination.pageSize
|
||||||
|
}
|
||||||
|
|
||||||
|
const {data} = await api(params);
|
||||||
|
|
||||||
|
pagination.pageSize = data.page;
|
||||||
|
pagination.total = data.total;
|
||||||
|
|
||||||
|
callback && callback(data);
|
||||||
|
} finally {
|
||||||
|
loading.value = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const initFetchData = async () => {
|
||||||
|
pagination.current = 1;
|
||||||
|
pagination.total = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => [pagination.current, pagination.pageSize],
|
||||||
|
() => fetchData(),
|
||||||
|
{deep: true, immediate: immediate}
|
||||||
|
)
|
||||||
|
|
||||||
|
if (watchParameter) watch(
|
||||||
|
() => parameter,
|
||||||
|
() => fetchData(),
|
||||||
|
{deep: true}
|
||||||
|
);
|
||||||
|
|
||||||
|
return {
|
||||||
|
loading,
|
||||||
|
pagination,
|
||||||
|
fetchData,
|
||||||
|
initFetchData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default useTableQuery;
|
||||||
@@ -8,7 +8,7 @@ import LayoutSider from '../../components/LayoutSider/index.vue';
|
|||||||
<a-layout-header id="layout-header" style="height: 60px">
|
<a-layout-header id="layout-header" style="height: 60px">
|
||||||
<LayoutHeader></LayoutHeader>
|
<LayoutHeader></LayoutHeader>
|
||||||
</a-layout-header>
|
</a-layout-header>
|
||||||
<a-layout>
|
<a-layout class="mt-[4px]">
|
||||||
<a-layout-sider>
|
<a-layout-sider>
|
||||||
<LayoutSider></LayoutSider>
|
<LayoutSider></LayoutSider>
|
||||||
</a-layout-sider>
|
</a-layout-sider>
|
||||||
|
|||||||
@@ -2,6 +2,9 @@
|
|||||||
import {ref, reactive} from 'vue';
|
import {ref, reactive} from 'vue';
|
||||||
import {toPath} from "../../utils/index.js";
|
import {toPath} from "../../utils/index.js";
|
||||||
import VerificationCode from '../../components/VerificationCode/index.vue';
|
import VerificationCode from '../../components/VerificationCode/index.vue';
|
||||||
|
import {useUserStore} from "../../pinia/UserStore/index.js";
|
||||||
|
|
||||||
|
const {login} = useUserStore();
|
||||||
|
|
||||||
const MODE = {
|
const MODE = {
|
||||||
PHONE: 'PHONE',
|
PHONE: 'PHONE',
|
||||||
@@ -39,7 +42,7 @@ const mode = ref(MODE.PHONE);
|
|||||||
</a-input>
|
</a-input>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex flex-col mt-[50px] gap-[32px]">
|
<div class="flex flex-col mt-[50px] gap-[32px]">
|
||||||
<a-button type="primary">登陆</a-button>
|
<a-button @click="login" type="primary">登陆</a-button>
|
||||||
<a-button
|
<a-button
|
||||||
@click="toPath('/loginSYS/register')"
|
@click="toPath('/loginSYS/register')"
|
||||||
type="text">
|
type="text">
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<!-- 指派任务 -->
|
<!-- 指派任务 -->
|
||||||
|
指派任务
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
|||||||
@@ -4,8 +4,11 @@
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<!-- 任务中心 -->
|
<!-- 任务中心 -->
|
||||||
任务中心
|
<div id="Item-View" class="p-[20px]">
|
||||||
|
<a-card>
|
||||||
<router-view></router-view>
|
<router-view></router-view>
|
||||||
|
</a-card>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
|||||||
@@ -1,10 +1,207 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
|
import {reactive, computed} from 'vue';
|
||||||
|
import Filter from "../../../../components/Filter/index.vue";
|
||||||
|
import TooltipTag from "../../../../components/TooltipTag/index.vue";
|
||||||
|
import useTableQuery from "../../../../hooks/useTableQuery.js";
|
||||||
|
import Api from "../../../../api/index.js";
|
||||||
|
|
||||||
|
const columns = [
|
||||||
|
{
|
||||||
|
title: '任务编号',
|
||||||
|
dataIndex: 'name',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '任务名称',
|
||||||
|
dataIndex: 'name',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '发布渠道',
|
||||||
|
dataIndex: 'name',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '创建时间',
|
||||||
|
dataIndex: 'name',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '当前状态',
|
||||||
|
dataIndex: 'status',
|
||||||
|
slotName: 'status',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '子任务进度',
|
||||||
|
dataIndex: 'name',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '消耗金额',
|
||||||
|
dataIndex: 'money',
|
||||||
|
slotName: 'money',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '是否开始',
|
||||||
|
dataIndex: 'start',
|
||||||
|
slotName: 'start',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '操作',
|
||||||
|
dataIndex: 'action',
|
||||||
|
slotName: 'action',
|
||||||
|
width: 200,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '',
|
||||||
|
dataIndex: 'exp',
|
||||||
|
slotName: 'exp'
|
||||||
|
},
|
||||||
|
];
|
||||||
|
const FilterConfig = computed(() => [
|
||||||
|
{
|
||||||
|
key: 'wd',
|
||||||
|
type: 'input',
|
||||||
|
label: '任务编号',
|
||||||
|
placeholder: '请输入集合编号'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'wd',
|
||||||
|
type: 'input',
|
||||||
|
label: '任务名称',
|
||||||
|
placeholder: '请输入集合名称'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'wd',
|
||||||
|
type: 'select',
|
||||||
|
label: '任务渠道',
|
||||||
|
placeholder: '全部',
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
label: '选项一',
|
||||||
|
value: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '选项二',
|
||||||
|
value: 2,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '选项三',
|
||||||
|
value: 3,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'wd',
|
||||||
|
type: 'select',
|
||||||
|
label: '任务状态',
|
||||||
|
placeholder: '全部',
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
label: '选项一',
|
||||||
|
value: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '选项二',
|
||||||
|
value: 2,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '选项三',
|
||||||
|
value: 3,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'wd',
|
||||||
|
type: 'datetime',
|
||||||
|
label: '创建时间',
|
||||||
|
placeholder: '全部',
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
const vo = reactive({
|
||||||
|
page: '',
|
||||||
|
rows: [],
|
||||||
|
total: 0,
|
||||||
|
});
|
||||||
|
const po = reactive({
|
||||||
|
wd: null,
|
||||||
|
});
|
||||||
|
|
||||||
|
const {loading, pagination, initFetchData} = useTableQuery({
|
||||||
|
parameter: po,
|
||||||
|
api: Api.system.getData,
|
||||||
|
callback: (data) => {
|
||||||
|
Object.assign(vo, data);
|
||||||
|
console.log(vo);
|
||||||
|
}
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<!-- 悬赏任务 -->
|
<!-- 悬赏任务 -->
|
||||||
悬赏任务
|
<Filter v-model:from="po" :config="FilterConfig" @search="initFetchData"></Filter>
|
||||||
|
|
||||||
|
<div class="my-[20px]">
|
||||||
|
<div class="flex gap-[16px] mb-[20px]">
|
||||||
|
<a-button type="primary">
|
||||||
|
<template #icon>
|
||||||
|
<icon-plus/>
|
||||||
|
</template>
|
||||||
|
新建子任务
|
||||||
|
</a-button>
|
||||||
|
<a-button>
|
||||||
|
<template #icon>
|
||||||
|
<icon-plus/>
|
||||||
|
</template>
|
||||||
|
从模板快速创建
|
||||||
|
</a-button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<a-table
|
||||||
|
:columns="columns"
|
||||||
|
:data="vo.rows"
|
||||||
|
:loading="loading"
|
||||||
|
:pagination="pagination">
|
||||||
|
<template v-slot:status="{record}">
|
||||||
|
<TooltipTag v-if="record.status === 0" color="cyan">待完善</TooltipTag>
|
||||||
|
<TooltipTag v-if="record.status === 1" color="red">未通过</TooltipTag>
|
||||||
|
<TooltipTag v-if="record.status === 2" color="magenta">请完善子任务</TooltipTag>
|
||||||
|
<TooltipTag v-if="record.status === 3" color="magenta">待付款</TooltipTag>
|
||||||
|
<TooltipTag v-if="record.status === 4" color="blue">投放中</TooltipTag>
|
||||||
|
<TooltipTag v-if="record.status === 5" color="orangered">暂停中</TooltipTag>
|
||||||
|
<TooltipTag v-if="record.status === 6" color="purple">终止</TooltipTag>
|
||||||
|
<TooltipTag v-if="record.status === 7" color="green">已完成</TooltipTag>
|
||||||
|
</template>
|
||||||
|
<template v-slot:start="{record}">
|
||||||
|
<a-switch></a-switch>
|
||||||
|
</template>
|
||||||
|
<template v-slot:money>
|
||||||
|
<div class="flex flex-col gap-[8px]">
|
||||||
|
<div>120.00 / 600.00(元)</div>
|
||||||
|
<a-progress
|
||||||
|
:percent="200/600"
|
||||||
|
:show-text="false">
|
||||||
|
</a-progress>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<template v-slot:action>
|
||||||
|
<div class="flex gap-[16px]">
|
||||||
|
<a-link :hoverable="false">编辑</a-link>
|
||||||
|
<a-link :hoverable="false">查看子任务</a-link>
|
||||||
|
<a-link :hoverable="false" status="danger">终止</a-link>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<template v-slot:exp>
|
||||||
|
<a-trigger trigger="click" :unmount-on-close="false">
|
||||||
|
<a-link :hoverable="false">更多
|
||||||
|
<icon-down/>
|
||||||
|
</a-link>
|
||||||
|
<template #content>
|
||||||
|
<div class="demo-basic">
|
||||||
|
<a-button type="text">
|
||||||
|
存为模版
|
||||||
|
</a-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</a-trigger>
|
||||||
|
</template>
|
||||||
|
</a-table>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
|||||||
@@ -1,9 +1,47 @@
|
|||||||
import {defineStore} from "pinia";
|
import {defineStore} from "pinia";
|
||||||
import {ref} from "vue";
|
import {ref} from "vue";
|
||||||
|
import mockRoutes from './mock.js';
|
||||||
|
import router from "../../router/index.js";
|
||||||
|
import generateRouter from "../../router/generateRouter.js";
|
||||||
|
|
||||||
export const useSystemStore = defineStore("SystemStore", () => {
|
export const useSystemStore = defineStore("SystemStore", () => {
|
||||||
const isRoot = ref(false);
|
const isRoot = ref(false);
|
||||||
|
const RoutesTemp = ref([]);
|
||||||
|
|
||||||
|
const installRoute = async () => {
|
||||||
|
const routes = generateRouter(RoutesTemp.value);
|
||||||
|
router.removeRoute('home');
|
||||||
|
router.addRoute({
|
||||||
|
path: '/home',
|
||||||
|
name: 'home',
|
||||||
|
component: () => import('../../pages/layout/index.vue'),
|
||||||
|
redirect: `/home/${routes[0].path}`,
|
||||||
|
children: routes
|
||||||
|
});
|
||||||
|
await router.replace(router.currentRoute.value.fullPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
const setRouter = async () => {
|
||||||
|
RoutesTemp.value.length = 0;
|
||||||
|
// 请求资源 mockRoutes
|
||||||
|
const routes = generateRouter(mockRoutes);
|
||||||
|
RoutesTemp.value.push(...mockRoutes);
|
||||||
|
await installRoute();
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
isRoot
|
isRoot,
|
||||||
|
RoutesTemp,
|
||||||
|
setRouter,
|
||||||
|
installRoute,
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
persist: {
|
||||||
|
key: 'SystemStore',
|
||||||
|
storage: localStorage,
|
||||||
|
afterHydrate: (val) => {
|
||||||
|
val.store.installRoute && val.store.installRoute();
|
||||||
|
},
|
||||||
|
pick: ['RoutesTemp']
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,12 +1,25 @@
|
|||||||
import {defineStore} from "pinia";
|
import {defineStore} from "pinia";
|
||||||
import {ref} from "vue";
|
import {ref} from "vue";
|
||||||
|
import {useSystemStore} from "../SystemStore/index.js";
|
||||||
|
import router from "../../router/index.js";
|
||||||
|
|
||||||
export const useUserStore = defineStore("UserStore", () => {
|
export const useUserStore = defineStore("UserStore", () => {
|
||||||
const isLogin = ref(true);
|
const isLogin = ref(false);
|
||||||
const userInfo = ref(null);
|
const userInfo = ref(null);
|
||||||
|
|
||||||
|
const login = async (from) => {
|
||||||
|
// 请求
|
||||||
|
isLogin.value = true;
|
||||||
|
// 获取并安装路由
|
||||||
|
const { setRouter } = useSystemStore();
|
||||||
|
await setRouter();
|
||||||
|
// 跳转
|
||||||
|
await router.push('/home');
|
||||||
|
}
|
||||||
return {
|
return {
|
||||||
isLogin,
|
isLogin,
|
||||||
userInfo
|
userInfo,
|
||||||
|
login,
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
persist: {
|
persist: {
|
||||||
|
|||||||
15
src/router/generateRouter.js
Normal file
15
src/router/generateRouter.js
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
import routesMap from "./routes-map.js";
|
||||||
|
|
||||||
|
const generateRouter = (routes) => {
|
||||||
|
return routes.map(v => ({
|
||||||
|
path: v.path,
|
||||||
|
name: v.name,
|
||||||
|
component: routesMap[v.component],
|
||||||
|
children: v.children && v.children.length > 0 && [
|
||||||
|
{path: '', redirect: `/home/${v.name}/${v.children[0].name}`},
|
||||||
|
...generateRouter(v.children)
|
||||||
|
],
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
export default generateRouter;
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
import {createRouter, createWebHashHistory} from 'vue-router';
|
import {createRouter, createWebHashHistory} from 'vue-router';
|
||||||
import routes from "./routes.js";
|
import routes from "./routes.js";
|
||||||
import {useUserStore} from "../pinia/UserStore/index.js";
|
import {useUserStore} from "../pinia/UserStore/index.js";
|
||||||
|
import {useSystemStore} from "../pinia/SystemStore/index.js";
|
||||||
|
|
||||||
const router = createRouter({
|
const router = createRouter({
|
||||||
history: createWebHashHistory(),
|
history: createWebHashHistory(),
|
||||||
@@ -9,6 +10,7 @@ const router = createRouter({
|
|||||||
|
|
||||||
router.beforeEach((to, from, next) => {
|
router.beforeEach((to, from, next) => {
|
||||||
const {isLogin} = useUserStore();
|
const {isLogin} = useUserStore();
|
||||||
|
const SystemStore = useSystemStore();
|
||||||
|
|
||||||
if (!isLogin && !to.path.includes('loginSYS')) {
|
if (!isLogin && !to.path.includes('loginSYS')) {
|
||||||
next({ path: '/loginSYS' });
|
next({ path: '/loginSYS' });
|
||||||
|
|||||||
@@ -1,27 +0,0 @@
|
|||||||
// const merchant = [
|
|
||||||
// {
|
|
||||||
// path: '/task-center',
|
|
||||||
// name: 'task-center',
|
|
||||||
// title: '任务中心',
|
|
||||||
// icon: '',
|
|
||||||
// component: () => import('../pages/merchant/pages/task-center/index.vue'),
|
|
||||||
// children: [
|
|
||||||
// {
|
|
||||||
// path: '/reward-mission',
|
|
||||||
// name: 'reward-mission',
|
|
||||||
// title: '悬赏任务',
|
|
||||||
// icon: '',
|
|
||||||
// component: () => import('../pages/merchant/pages/task-center/reward-mission.vue'),
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// path: '/appointed-task',
|
|
||||||
// name: 'appointed-task',
|
|
||||||
// title: '任务指派',
|
|
||||||
// icon: '',
|
|
||||||
// component: () => import('../pages/merchant/pages/task-center/appointed-task.vue'),
|
|
||||||
// }
|
|
||||||
// ]
|
|
||||||
// },
|
|
||||||
// ]
|
|
||||||
//
|
|
||||||
// export default merchant;
|
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
const routesMap = {
|
const routesMap = {
|
||||||
'task-center': import('../pages/merchant/pages/task-center/index.vue'),
|
'task-center': () => import('../pages/merchant/pages/task-center/index.vue'),
|
||||||
'reward-mission': import('../pages/merchant/pages/task-center/reward-mission.vue'),
|
'reward-mission': () => import('../pages/merchant/pages/task-center/reward-mission.vue'),
|
||||||
'appointed-task': import('../pages/merchant/pages/task-center/appointed-task.vue'),
|
'appointed-task': () => import('../pages/merchant/pages/task-center/appointed-task.vue'),
|
||||||
};
|
};
|
||||||
|
|
||||||
export default routesMap;
|
export default routesMap;
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import routesMap from "./routes-map.js";
|
||||||
|
|
||||||
const routes = [
|
const routes = [
|
||||||
{
|
{
|
||||||
path: '/',
|
path: '/',
|
||||||
@@ -7,6 +9,7 @@ const routes = [
|
|||||||
path: '/home',
|
path: '/home',
|
||||||
name: 'home',
|
name: 'home',
|
||||||
component: () => import('../pages/layout/index.vue'),
|
component: () => import('../pages/layout/index.vue'),
|
||||||
|
children: [],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/loginSYS',
|
path: '/loginSYS',
|
||||||
|
|||||||
@@ -1,5 +1,26 @@
|
|||||||
|
:root {
|
||||||
|
--main-bg-color: rgb(247, 248, 250);
|
||||||
|
}
|
||||||
* {
|
* {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
font-family: "PingFang SC", serif;
|
font-family: "PingFang SC", serif;
|
||||||
}
|
}
|
||||||
|
body {
|
||||||
|
background-color: var(--main-bg-color);
|
||||||
|
}
|
||||||
|
#Item-View {
|
||||||
|
.arco-card-body {
|
||||||
|
@apply p-[20px];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.demo-basic { // 默认下拉框样式
|
||||||
|
padding: 5px;
|
||||||
|
width: auto;
|
||||||
|
background-color: var(--color-bg-popup);
|
||||||
|
border-radius: 4px;
|
||||||
|
box-shadow: 0 2px 8px 0 rgba(0, 0, 0, 0.15);
|
||||||
|
}
|
||||||
|
.arco-btn-text {
|
||||||
|
color: var(--color-text-2) !important;
|
||||||
|
}
|
||||||
|
|||||||
41
src/utils/request.js
Normal file
41
src/utils/request.js
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
import axios from 'axios';
|
||||||
|
// import {useUserStore} from "../pinia/UserStore";
|
||||||
|
|
||||||
|
// 创建 Axios 实例
|
||||||
|
const request = axios.create({
|
||||||
|
baseURL: import.meta.env.VITE_API_URL, // 替换为你的基础 URL
|
||||||
|
timeout: 10000, // 请求超时设置
|
||||||
|
});
|
||||||
|
|
||||||
|
// 请求拦截器
|
||||||
|
request.interceptors.request.use(
|
||||||
|
(config) => {
|
||||||
|
// const {userInfo} = useUserStore();
|
||||||
|
|
||||||
|
// 如果 token 存在,则将其添加到请求头中
|
||||||
|
// if (userInfo?.token) {
|
||||||
|
// config.headers['token'] = `${userInfo?.token}`;
|
||||||
|
// }
|
||||||
|
|
||||||
|
return config;
|
||||||
|
},
|
||||||
|
(error) => {
|
||||||
|
return Promise.reject(error);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// 响应拦截器
|
||||||
|
request.interceptors.response.use(
|
||||||
|
(response) => {
|
||||||
|
return response.data;
|
||||||
|
},
|
||||||
|
(error) => {
|
||||||
|
if (error.response) {
|
||||||
|
return Promise.reject(error.response.data); // 返回错误信息
|
||||||
|
} else { // 网络错误
|
||||||
|
return Promise.reject(error.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
export default request; // 导出 Axios 实例
|
||||||
@@ -2,6 +2,7 @@ import {defineConfig} from 'vite';
|
|||||||
import vue from '@vitejs/plugin-vue';
|
import vue from '@vitejs/plugin-vue';
|
||||||
import tailwindcss from 'tailwindcss';
|
import tailwindcss from 'tailwindcss';
|
||||||
import AutoImport from 'unplugin-auto-import/vite';
|
import AutoImport from 'unplugin-auto-import/vite';
|
||||||
|
import vueDevTools from 'vite-plugin-vue-devtools';
|
||||||
import Components from 'unplugin-vue-components/vite';
|
import Components from 'unplugin-vue-components/vite';
|
||||||
import {vitePluginForArco} from '@arco-plugins/vite-vue';
|
import {vitePluginForArco} from '@arco-plugins/vite-vue';
|
||||||
import {ArcoResolver} from 'unplugin-vue-components/resolvers';
|
import {ArcoResolver} from 'unplugin-vue-components/resolvers';
|
||||||
@@ -11,6 +12,7 @@ export default defineConfig({
|
|||||||
base: './',
|
base: './',
|
||||||
plugins: [
|
plugins: [
|
||||||
vue(),
|
vue(),
|
||||||
|
vueDevTools(),
|
||||||
AutoImport({
|
AutoImport({
|
||||||
resolvers: [ArcoResolver()],
|
resolvers: [ArcoResolver()],
|
||||||
}),
|
}),
|
||||||
@@ -38,6 +40,6 @@ export default defineConfig({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
server: {
|
server: {
|
||||||
port: 9000
|
port: 9050
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user