feat: 动态路由&询盘首页

This commit is contained in:
cyonjan 2025-06-11 08:40:59 +08:00
parent 5546c9cb6f
commit d452020044
13 changed files with 1007 additions and 73 deletions

View File

@ -6,3 +6,27 @@ export const wechatPlatform = (platform) => {
url: `/auth/wechatPlatform/${platform}`
})
}
export const sellerList = () => {
return service({
method: 'post',
url: '/accessory/sellerlist/'
})
}
export const shopList = (ids) => {
return service({
method: 'post',
url: '/accessory/shoplist',
data: {
ids
}
})
}
export const supplierList = () => {
return service({
method: 'post',
url: `/member/supplierlist/`,
})
}

33
src/api/inquiry.js Normal file
View File

@ -0,0 +1,33 @@
import service from '@/service'
export const inquiryFilter = (users,status,days=7) => {
return service({
method: 'get',
url: '/store/inquiryFilter',
params: {
users,
status,
days
}
})
}
export const inquiryList = (users,keys={},page=1,page_size=20) => {
return service({
method: 'post',
url: '/store/inquiryList',
data: {
users,
keys,
page,
page_size,
}
})
}
export const customerList = () => {
return service({
method: 'get',
url: '/store/customerList'
})
}

View File

@ -36,3 +36,10 @@ export const getEmailCode = (email) => {
url: `/accessory/mailVerifyCode?email=${email}`
})
}
export const loadShopInfo = () => {
return service({
method: 'get',
url: '/store/loadShopInfo'
})
}

View File

@ -33,6 +33,12 @@
active-text-color="#409EFF"
router
>
<el-menu-item index="/home">
<i class="fa fa-desktop"></i>
<template #title>
<span class="ml-2">我的工作台</span>
</template>
</el-menu-item>
<template v-for="item in menuItems" :key="item.id">
<!-- 无子菜单的菜单项 -->
<el-menu-item v-if="!item.children" :index="item.id">

View File

@ -1,6 +1,6 @@
import { createRouter,createWebHashHistory } from 'vue-router'
import { getToken } from '@/utils'
import { verifyToken } from '@/api/user'
import { useUserStore } from '@/store'
const modules = import.meta.glob("../views/**/**.vue")
const routes = [
{
@ -27,10 +27,6 @@ const routes = [
path:'/settings',
name:'Settings',
component: () => import('../views/Settings.vue')
},{
path:'/order',
name:'Order',
component: () => import('../views/order/index.vue')
}
]
}
@ -41,12 +37,53 @@ const router = createRouter({
routes
})
router.beforeEach((to, from, next) => {
const isLogin = getToken() ? true : false;
const addDynamicRoutes = async (data) => {
if (!data || !data.length) return;
const homeRouters = routes.filter(v => v.path === '/main')[0];
if (!homeRouters) return;
homeRouters.children = [];
homeRouters.children.push({
path: '/home',
name: 'Home',
component: () => import('../views/Home.vue'),
});
homeRouters.children.push({
path: '/settings',
name: 'Settings',
component: () => import('../views/Settings.vue'),
});
data.forEach(item => {
homeRouters.children.push({
path: item.path,
name: item.name,
component: modules[`../views/${item.component}.vue`],
})
})
homeRouters.children.push({
path: '/:pathMatch(.*)',
name: 'NotFound',
component: () => import('../views/404.vue'),
});
return homeRouters;
}
router.beforeEach(async (to, from, next) => {
if(to.path == '/login' || to.path == "/register" || to.path == "/wxlogin") {
next()
} else {
isLogin ? next() : next('/')
const userStore = useUserStore()
if(userStore.isLoggedIn) {
if(userStore.routeSetted) {
next()
} else {
const homeRoutes = await addDynamicRoutes(userStore.routerList)
router.addRoute(homeRoutes)
userStore.routeSetted = true;
next()
}
} else {
next('/');
}
}
})

View File

@ -1,30 +1,261 @@
import { defineStore } from 'pinia'
import { loadShopInfo } from '../api/user'
const adminRoutes = [
{
path:'/inquiry-list',
name:'InquiryList',
component: 'inquiry/Index'
},{
path:'/customer-list',
name:'CustomerList',
component: 'customer/Index'
},{
path:'/order-list',
name:'OrderList',
component: 'order/index'
},{
path:'/product-list',
name:'ProductList',
component: 'product/Index'
}
]
const adminMenus = [
{
icon: 'fa fa-gavel',
name: '询盘报价',
id: 'inquiry',
children: [
{
icon: 'fa fa-list',
name: '询盘列表',
path: '/inquiry-list'
},{
icon: 'fa fa-plus',
name: '新增询价',
path: '/inquiry-create'
}
]
},{
icon: 'fa fa-yen',
name: '订单处理',
id: 'order',
children: [
{
icon: 'fa fa-list-alt',
name: '报价列表',
path: '/order-list'
},{
icon: 'fa fa-plus-square',
name: '新增报价',
path: '/order-create'
}
]
},{
icon: 'fa fa-cubes',
name: '商品管理',
id: 'product',
children: [
{
icon: 'fa fa-list-alt',
name: '商品列表',
path: '/product-list'
},{
icon: 'fa fa-plus-square',
name: '新增商品项',
path: '/product-create'
},{
icon: 'fa fa-plus-square',
name: '大件跟踪',
path: '/product-tracking'
},{
icon: 'fa fa-plus-square',
name: '更新件号',
path: '/product-new-number'
}
]
},{
icon: 'fa fa-vcard',
name: '客户关系',
id: 'customer',
children: [
{
icon: 'fa fa-list-alt',
name: '客户关系',
path: '/customer-list'
},{
icon: 'fa fa-plus-square',
name: '供应商联系',
path: '/supplier-list'
}
]
}
]
const managerRoutes = [
{
path:'/inquiry',
name:'Inquiry',
component: 'inquiry/index'
},{
path:'/customer',
name:'Customer',
component: 'customer/index'
},{
path:'/order',
name:'Order',
component: 'order/index'
}
]
const userRoutes = [
{
path:'/inquiry',
name:'Inquiry',
component: 'inquiry/index'
},{
path:'/customer',
name:'Customer',
component: 'customer/index'
},{
path:'/order',
name:'Order',
component: 'order/index'
}
]
export const useUserStore = defineStore('user-info',{
state: () => {
return {
userInfo: {},
authList: [],
menuList: []
shopInfo: {},
routerList: [],
menuList: [],
user_groups: [],
routeSetted: false,
}
},
actions: {
setInfo(userinfo) {
async setInfo(userinfo) {
this.userInfo = userinfo
switch (userinfo.role) {
case '0':
this.routerList = adminRoutes
break
case '1':
this.routerList = managerRoutes
break
case '2':
this.routerList = userRoutes
break
}
this.menuList = adminMenus
const {data: res} = await loadShopInfo()
if (res.error === 0) {
this.shopInfo = res.data
} else {
this.shopInfo = {}
}
if(userinfo.role === '0') {
this.userInfo.team = this.shopInfo.account.map(item => item.id)
} else {
this.userInfo.team = [userinfo.id]
if(userinfo.authority && Object.keys(userinfo.authority).length > 0) {
let authority = JSON.parse(userinfo.authority)
if(authority.team && authority.team.length > 0) {
this.userInfo.team = this.userInfo.team.concat(authority.team)
}
}
}
},
clearInfo() {
this.userInfo = {}
this.user_groups = []
this.shopInfo = {}
this.routerList = []
this.menuList = []
this.routeSetted = false
},
logout() {
this.userInfo = {}
this.authList = []
this.menuList = []
this.clearInfo()
}
},
getters: {
userId: (state) => {
return state.userInfo.id || ''
},
isAdmin: (state) => {
return state.userInfo.role === '0' || state.userInfo.role === '1'
},
isSalesman: (state) => {
return state.userInfo.role !== '0' && state.userInfo.role !== '1'
},
isLoggedIn: (state) => {
return Object.keys(state.userInfo).length > 0
},
hasRouterList: (state) => {
return state.routerList.length > 0
},
team: (state) => {
return state.userInfo.team
},
teamInfo: (state) => {
let groups_info = {}
state.userInfo.team.forEach(id => {
let item = state.shopInfo.account.find(el => el.id === id)
if(item) {
groups_info[id] = {
id: item.id,
name: item.nickname || item.name,
role: item.role
}
} else {
groups_info[id] = {
id: id,
name: '未知用户',
role: '2'
}
}
})
return groups_info
}
},
persist: true
})
export const useInquiryListStore = defineStore('inquiry-list',{
state: () => {
return {
currentPage: 1,
pageSize: 20,
keys: {}
}
},
actions: {
reset() {
this.currentPage = 1
this.pageSize = 20
this.keys = {}
}
},
getters: {}
})
export const useOrderListStore = defineStore('order-list',{
state: () => {
return {
currentPage: 1,
pageSize: 20,
keys: {}
}
},
actions: {
reset() {
this.currentPage = 1
this.pageSize = 20
this.keys = {}
}
},
getters: {}
})

30
src/views/404.vue Normal file
View File

@ -0,0 +1,30 @@
<template>
<el-empty description="无效的页面访问权限!">
<template #description>
<div class="w-full text-center mt-6">
<span class="font-bold text-red-600 text-lg">
你访问了一个无效的页面或没有权限访问该页面请联系管理员处理
</span>
</div>
</template>
<div class="flex justify-center items-center">
<el-button type="info" @click="backToPrev" size="large"><i class="fa fa-arrow-left pr-2"></i>返回</el-button>
<el-button type="primary" @click="backToHome" class="ml-6" size="large"><i class="fa fa-desktop pr-2"></i>工作台</el-button>
</div>
</el-empty>
</template>
<script setup>
import { useRouter } from 'vue-router'
const router = useRouter()
const backToHome = () => {
router.push('/home')
}
const backToPrev = () => {
router.back()
}
</script>
<style scoped>
</style>

View File

@ -1,26 +1,131 @@
<template>
<div>
<h2>首页</h2>
<p>欢迎使用本系统</p>
<p>当前时间{{ new Date().toLocaleString() }}</p>
<div class="mt-4">
<el-button type="danger" @click="logout">注销退出</el-button>
<div class="w-full grid grid-cols-3 flex gap-4 p-4">
<el-card shadow="hover" :style="{height: cardHeight + 'px'}">
<template #header>
<div class="flex items-center px-4 justify-between">
<div class="font-bold text-lg">7日内待分派询盘单</div>
<el-button type="primary" size="small" @click="getInquiryList">刷新</el-button>
</div>
</template>
<el-table
:data="allocating_inquiry"
border
:height="tableHeight"
size="small"
class="w-full pb-2"
>
<el-table-column type="index" label="#" width="40" header-align="center" align="center" :index="1"></el-table-column>
<el-table-column prop="order_no" label="询单尾号" width="80" header-align="center" align="center">
<template #default="{row}">
<span>{{ row.order_no.slice(12) }}</span>
</template>
</el-table-column>
<el-table-column prop="true_name" label="客户名称" width="120" header-align="center" show-overflow-tooltip>
<template #default="{row}">
<span>{{ row.true_name ? row.true_name : row.user_name }}</span>
</template>
</el-table-column>
<el-table-column prop="create_time" label="创建时间" width="160" header-align="center"></el-table-column>
<el-table-column label="操作" header-align="center">
<template #default="{row}">
<div v-if="userStore.userInfo.role == '0' || userStore.userInfo.role == '1'" class="flex items-center justify-evenly">
<el-button type="primary" size="small" @click="() => {}">派单</el-button>
<el-button type="danger" size="small" @click="() => {}">丢弃</el-button>
</div>
<div v-else class="flex justify-center items-center">
<el-button type="primary" size="small" @click="() => {}">抢单</el-button>
</div>
</template>
</el-table-column>
</el-table>
</el-card>
<el-card shadow="hover" :style="{height: cardHeight + 'px'}">
<template #header>
<div class="flex items-center px-4 justify-between">
<div class="font-bold text-lg">7日内待完成询盘单</div>
<el-button type="primary" size="small" @click="getProcessingInquiryList">刷新</el-button>
</div>
</template>
<el-table
:data="processing_inquiry"
border
:height="tableHeight"
size="small"
class="w-full pb-2"
>
<el-table-column type="index" label="#" width="40" header-align="center" align="center" :index="1"></el-table-column>
<el-table-column prop="order_no" label="询单尾号" width="80" header-align="center" align="center">
<template #default="{row}">
<span>{{ row.order_no.slice(12) }}</span>
</template>
</el-table-column>
<el-table-column prop="true_name" label="客户名称" width="120" header-align="center" show-overflow-tooltip>
<template #default="{row}">
<span>{{ row.true_name ? row.true_name : row.user_name }}</span>
</template>
</el-table-column>
<el-table-column label="业务主办" width="80" header-align="center" align="center" show-overflow-tooltip v-if="userStore.isAdmin">
<template #default="{row}">
<span>{{ userStore.teamInfo[row.creator]?.name || '未知' }}</span>
</template>
</el-table-column>
<el-table-column label="工作节点" width="80" header-align="center" align="center">
<template #default="{row}">
<span>{{ row.status == 0 ? '未开始' : row.status == 1 ? '待报价': row.status == 3 ? '已报价' : '其他' }}</span>
</template>
</el-table-column>
<el-table-column prop="create_time" label="创建时间" width="160" header-align="center"></el-table-column>
<el-table-column label="操作" header-align="center">
<template #default="{row}">
<div v-if="userStore.isAdmin" class="flex items-center justify-evenly">
<el-button type="primary" size="small" @click="() => {}">处理</el-button>
<el-button type="danger" size="small" @click="() => {}">结单</el-button>
</div>
<div v-else class="flex justify-center items-center">
<el-button type="primary" size="small" @click="() => {}">结单</el-button>
</div>
</template>
</el-table-column>
</el-table>
</el-card>
</div>
</template>
<script setup>
import { ref,onMounted } from 'vue'
import { useRouter } from 'vue-router'
import { useUserStore } from '@/store'
import { removeToken } from '@/utils'
import { inquiryFilter } from '@/api/inquiry'
const cardHeight = ref(420)
const tableHeight = ref(320)
const router = useRouter()
const userStore = useUserStore()
const logout = () => {
userStore.clearInfo()
removeToken()
router.push('/login')
const allocating_inquiry = ref([])
const processing_inquiry = ref([])
onMounted(async () => {
await getInquiryList()
await getProcessingInquiryList()
})
const getInquiryList = async () => {
const {data: res} = await inquiryFilter('0','start',7)
if (res.error === 0) {
allocating_inquiry.value = res.data
} else {
allocating_inquiry.value = []
}
}
const getProcessingInquiryList = async () => {
const {data: res} = await inquiryFilter(`${userStore.team.join(',')}`,'process',7)
if (res.error === 0) {
processing_inquiry.value = res.data
} else {
processing_inquiry.value = []
}
}
</script>

View File

@ -3,7 +3,7 @@
<!-- 侧边菜单 -->
<div class="sidebar" :class="{ 'collapsed': isCollapsed }" @mouseenter="expandMenu" @mouseleave="collapseMenu">
<!-- 侧边面板 -->
<SidePanel :is-collapsed="isCollapsed" :menu-items="menuItems" logo="jifuyun.cn.png" />
<SidePanel :is-collapsed="isCollapsed" :menu-items="menuItems" :logo="logo" :title="title" />
</div>
<div class="main-container">
@ -34,50 +34,16 @@
const isCollapsed = ref(true)
const isLoggedIn = computed(() => userStore.isLoggedIn)
const logo = ref('jifuyun.cn.png')
if(userStore.shopInfo && userStore.shopInfo.logo) {
logo.value = 'https://www.jifuyun.cn/' + userStore.shopInfo.logo
}
const title = ref('机联云维')
if(userStore.shopInfo && userStore.shopInfo.true_name) {
title.value = userStore.shopInfo.true_name
}
//
const menuItems = [
{
icon: 'fa fa-home',
name: '首页概览',
path: '/home',
id: 'home'
},{
icon: 'fa fa-shopping-cart',
name: '询价管理',
id: 'inquiry',
children: [
{
icon: 'fa fa-list',
name: '询价列表',
path: '/order'
},{
icon: 'fa fa-plus',
name: '新增询价',
path: '/inquiry/create'
}
]
},{
icon: 'fa fa-file-text',
name: '报价管理',
id: 'quote',
children: [
{
icon: 'fa fa-list-alt',
name: '报价列表',
path: '/quote/list'
},{
icon: 'fa fa-plus-square',
name: '新增报价',
path: '/quote/create'
}
]
},{
icon: 'fa fa-cog',
name: '系统设置',
path: '/settings',
id: 'settings',
}
]
const menuItems = userStore.menuList || []
//
const newsList = [
@ -97,7 +63,7 @@
}
const logout = () => {
userStore.$reset()
userStore.logout()
removeToken()
router.push('/login')
}

View File

@ -226,7 +226,7 @@
router.push('/home')
} else {
ElMessage.error(res.msg)
user_store.clearInfo()
user_store.logout()
removeToken()
}
}

View File

@ -0,0 +1,28 @@
<template>
<div>
<h2>客户首页</h2>
<p>当前时间{{ new Date().toLocaleString() }}</p>
<div class="mt-4">
<el-button type="danger" @click="logout">注销退出</el-button>
</div>
</div>
</template>
<script setup>
import { useRouter } from 'vue-router'
import { useUserStore } from '@/store'
import { removeToken } from '@/utils'
const router = useRouter()
const userStore = useUserStore()
const logout = () => {
userStore.logout()
removeToken()
router.push('/login')
}
</script>
<style lang="scss" scoped>
</style>

439
src/views/inquiry/Index.vue Normal file
View File

@ -0,0 +1,439 @@
<template>
<el-row :gutter="12">
<el-col :span="6">
<div class="flex items-center gap-2">
<el-select
v-model="filterVariable.customer"
placeholder="选择客户"
size="large"
multiple
filterable
collapse-tags
collapse-tags-tooltip
@change="startFilter"
>
<el-option v-for="customer in customer_list" :label="customer_name(customer)" :value="customer.id" :key="customer.id" />
</el-select>
<el-input v-model="filterVariable.code" placeholder="订单包含件号" size="large" @change="startFilter" />
</div>
</el-col>
<el-col :span="3">
<div class="flex items-center gap-2">
<el-select
v-if="userStore.team.length > 1"
v-model="filterVariable.operator"
placeholder="选择业务员"
size="large"
multiple
collapse-tags
collapse-tags-tooltip
@change="startFilter"
>
<el-option v-for="[id,item] of Object.entries(userStore.teamInfo)" :label="item.name" :value="id" :key="id" />
</el-select>
<el-select v-model="filterVariable.status" placeholder="订单状态" size="large" @change="startFilter">
<el-option label="所有询盘单" :value="0"/>
<el-option label="待处理" :value="1"/>
<el-option label="已报价" :value="4"/>
<el-option label="待付款" :value="6"/>
</el-select>
</div>
</el-col>
<el-col :span="4">
<div class="flex items-center gap-2">
<el-date-picker
v-model="filterVariable.date"
type="daterange"
unlink-panels
range-separator="到"
start-placeholder="开始日期"
end-placeholder="终到日期"
size="large"
value-format="YYYY-MM-DD"
@change="startFilter"
/>
<el-button @click="resetFilter" type="success" class="hover:(bg-red-400 text-white)">重置筛选</el-button>
</div>
</el-col>
</el-row>
<el-table
ref="orderTableRef"
:data="order_list"
:height="tableHeight"
stripe
fit
style="width: 100%;"
size="large"
row-class-name="no-expand-icon"
row-key="id"
@row-click="expandPanel"
@expand-change="expandChange"
class="mt-2"
>
<!-- <el-table-column type="expand" width="0">
<template #default="{row}">
<div class="mt-2 p-2 flex justify-center overflow-auto">
<el-table
size="small"
fit
:data="row.offer"
class="text-xs w-auto"
style="border: 1px solid black;"
:header-cell-style="{background: '#e0f2fe', color: 'black',borderColor: 'black'}"
:cell-style="{borderColor: 'black'}"
border
>
<el-table-column type="index" label="#" width="50" align="center" header-align="center"/>
<el-table-column prop="brand_name" label="品牌" show-overflow-tooltip width="100" align="center" header-align="center"/>
<el-table-column prop="code" label="件号" show-overflow-tooltip width="120" align="center" header-align="center"/>
<el-table-column prop="name" label="品名" show-overflow-tooltip width="120" align="center" header-align="center"/>
<el-table-column prop="market_price" label="面价" show-overflow-tooltip width="100" align="right" header-align="center">
<template #default="{row}">
{{ (Math.round(row.market_price * 100) / 100.00).toFixed(2) }}
</template>
</el-table-column>
<el-table-column prop="store" label="库存数" width="72" align="right" header-align="center"/>
<el-table-column label="供应商采购" width="120" align="center" header-align="center">
<el-table-column prop="selected" label="供应商" show-overflow-tooltip width="120" align="center" header-align="center">
<template #default="{row}">
{{ supplierName(row.selected) }}
</template>
</el-table-column>
<el-table-column label="报价" width="100" align="right" header-align="center">
<template #default="{row}">
{{ parseFloat(row.from[0]) ? parseFloat(row.from[0]).toFixed(2) : 0.00 }}
</template>
</el-table-column>
<el-table-column label="急件价" width="100" align="right" header-align="center">
<template #default="{row}">
{{ row.from[3] && parseFloat(row.from[3]) ? parseFloat(row.from[3]).toFixed(2) : 0.00 }}
</template>
</el-table-column>
<el-table-column label="可供数" width="60" align="right" header-align="center">
<template #default="{row}">
{{ row.from[1] }}
</template>
</el-table-column>
<el-table-column label="货源" show-overflow-tooltip width="100" align="center" header-align="center">
<template #default="{row}">
{{ row.from[5] ? row.from[5] : '' }}
</template>
</el-table-column>
<el-table-column label="备注" show-overflow-tooltip width="100" align="right" header-align="center">
<template #default="{row}">
{{ row.from[2] }}
</template>
</el-table-column>
</el-table-column>
<el-table-column label="客户销售" header-align="center">
<el-table-column prop="sell_price" label="售价" show-overflow-tooltip width="100" align="right" header-align="center">
<template #default="{row}">
{{ (Math.round(row.sell_price * 100) / 100.00).toFixed(2) }}
</template>
</el-table-column>
<el-table-column prop="sell_price2" label="急件价" show-overflow-tooltip width="100" align="right" header-align="center">
<template #default="{row}">
{{ (Math.round(row.sell_price2 * 100) / 100.00).toFixed(2) }}
</template>
</el-table-column>
<el-table-column prop="amount" label="销售数" width="60" align="right" header-align="center"/>
<el-table-column prop="note" label="备注" show-overflow-tooltip width="80" header-align="center"/>
</el-table-column>
</el-table>
</div>
</template>
</el-table-column> -->
<el-table-column prop="order_no" label="订单号" header-align="center" align="center" width="200px">
<template #default="{row}">
<el-link type="primary" :underline="false" @click="router.push({path:'/pre-order/edit',query:{id:row.id}})"><el-text size="small" tag="b" class="hover:(bg-transparent text-red-900)">{{ row.order_no }}</el-text></el-link>
</template>
</el-table-column>
<el-table-column label="客户名称" :show-overflow-tooltip="true">
<template #default="{row}">
<el-text size="small">{{ row.true_name ? row.true_name : row.user_name }}</el-text>
</template>
</el-table-column>
<el-table-column label="询盘状态" align="center">
<template #default="{row}">
<el-tag effect="dark" :type="row.status==0 ? 'danger' : row.status==5 ? 'success' : 'primary'" size="large" v-if="Object.keys(statusList).length">
{{ row.status==0 ? (row.goods.length == 0 ? '添加商品' : (statusList[row.id][1] == 0 ? '制询价函' : (statusList[row.id][1] == statusList[row.id][2] ? '等待报价' : '等待回函'))) : orderStatus(row.status,row.is_del) }}
</el-tag>
</template>
</el-table-column>
<el-table-column label="询价状态" align="center">
<template #default="{row}">
<el-tag size="large" effect="dark" :type="inquiryShow(statusList[row.id][2],statusList[row.id][1])" v-if="Object.keys(statusList).length">
{{ `${statusList[row.id][2]}/${statusList[row.id][1]}` }}
</el-tag>
</template>
</el-table-column>
<!-- <el-table-column label="订单商品" align="center" header-align="center">
<template #default="{row}">
<el-popover effect="light" trigger="hover" placement="left-start" width="auto">
<template #default>
<el-table
fit
:data="goodsSorted(row.goods)"
:height="240"
style="width:320px"
>
<el-table-column prop="code" label="编码" :show-overflow-tooltip="true" width="100px"/>
<el-table-column prop="b_name" label="品牌" :show-overflow-tooltip="true" width="80px" />
<el-table-column prop="name" label="品名" :show-overflow-tooltip="true" width="80px" />
<el-table-column prop="amount" label="数量" width="60px" />
</el-table>
</template>
<template #reference>
<el-tag color="#00828a" size="large" effect="dark" round>{{row.offer.length}}/{{row.goods.length}}</el-tag>
</template>
</el-popover>
</template>
</el-table-column> -->
<el-table-column label="询盘报价" align="right" header-align="center" prop="total_price">
<template #default="{row}">
<el-text :type="row.total_price==0?'danger':'primary'">{{`${row.total_price.toFixed(2)}`}}</el-text>
</template>
</el-table-column>
<el-table-column prop="note" label="订单备注" :show-overflow-tooltip="true" width="100px">
<template #default="{row}">
<el-text size="small" tag="b">{{ row.note }}</el-text>
</template>
</el-table-column>
<el-table-column prop="creator" label="业务主办" width="160px" :show-overflow-tooltip="true" header-align="center" align="center" v-if="userStore.team.length > 1">
<template #default="{row}">
{{ userStore.teamInfo[row.creator]?.name || `ID-${row.creator}` }}
</template>
</el-table-column>
<el-table-column prop="create_time" label="下单时间" width="200px"/>
<el-table-column label="操作记录" header-align="center" align="center">
<template #default="scope">
<el-button
size="default"
type="default"
@click="handleWorkflow(scope.row)"
:icon="Share"
/>
</template>
</el-table-column>
</el-table>
<div class="pages">
<el-pagination
v-model:current-page="currentPage"
v-model:page-size="pageSize"
:page-sizes="[20,30,40,50]"
:disabled="false"
size="small"
:background="background"
layout="total, sizes, prev, pager, next, jumper"
:total="total"
@update:current-page="handleCurrentChange"
@update:page-size="handleSizeChange"
/>
</div>
<!--
<el-dialog
v-model="workflowDialogVisible"
title="订单工作流"
width="30%"
destroy-on-close
center
:draggable="true"
>
<div style="max-height: 50vh;overflow: auto;">
<el-card class="box-card-edit">
<el-timeline>
<el-timeline-item
v-for="(activity, index) in workflow"
:key="index"
:timestamp="activity.addtime"
placement="top"
>
<el-card>
<h4>{{ activity.action }}</h4>
<p>{{ activity.user }}{{ activity.addtime }}提交</p>
</el-card>
</el-timeline-item>
</el-timeline>
</el-card>
</div>
<template #footer>
<span class="dialog-footer">
<el-button type="primary" @click="workflowDialogVisible=false" :icon="Share">知道了!</el-button>
</span>
</template>
</el-dialog> -->
</template>
<script setup>
import { ref,onMounted,computed } from 'vue'
import { useRouter } from 'vue-router'
// import { orderFilter,orderCustomer,orderSeller,orderCreator,$orderStatus,getActionLog,supplierList,sellerList } from '@/api'
// import { supplierList,sellerList } from '@/api'
import { inquiryList,customerList } from '@/api/inquiry'
// import { Edit,Share,Refresh } from '@element-plus/icons-vue'
// import _ from 'lodash'
import { storeToRefs } from 'pinia'
import { useUserStore,useInquiryListStore } from '@/store'
const userStore = useUserStore()
const router = useRouter()
const inquiryStore = useInquiryListStore()
const { currentPage,pageSize,keys: filterVariable } = storeToRefs(inquiryStore)
const order_list = ref([])
const total = ref(0)
const orderTableRef = ref()
const orderIds = ref([])
const statusList = ref({})
const customer_list = ref([])
const seller_list = ref([])
const seller_list2 = ref([])
const supplier_list = ref([])
const background = ref(false)
const selectionRows = ref([])
const workflowDialogVisible = ref(false)
const tableHeight = ref(0)
onMounted(async () => {
tableHeight.value = window.innerHeight - 180
const { data:customer } = await customerList()
if(customer.error == 0) {
customer_list.value = customer.data
}
await get_order_list()
// const {data:supplier} = await supplierList()
// supplier_list.value = supplier.data.map(item => ({id:item.sid,name:item.sname,mobile:item.mobile}))
// const {data:seller} = await sellerList()
// seller_list2.value = seller.data.map(item => ({id:`G${item.id}`,name:`**${item.seller_name}`,mobile:item.mobile}))
})
const get_order_list = async () => {
statusList.value = {}
const { data:res } = await inquiryList(userStore.team.toString(),filterVariable.value,currentPage.value,pageSize.value)
order_list.value = res.data
total.value = res.total
orderIds.value = []
order_list.value.forEach(async (item) => {
let total = 0
item.offer.forEach(g => total += g.amount * parseFloat(g.sell_price))
item['total_price'] = total
orderIds.value.push(item.id)
})
// get_order_status()
}
const get_order_status = async () => {
let ids = order_list.value.map(item => item.id)
const {data:status} = await $orderStatus(ids)
statusList.value = status.data
}
const workflow = ref([])
const handleWorkflow = async (row) => {
workflow.value = []
const {data:res} = await getActionLog(row.id)
workflow.value = res.data
workflowDialogVisible.value = true
}
const supplierName = computed(() => (id) => {
if(`${id}`.startsWith('G')) {
let ids = `${id}`.split('-')
let idx = seller_list2.value.findIndex(item => item.id == ids[0])
if(idx != -1) {
return seller_list2.value[idx].name
}
} else {
let idx = supplier_list.value.findIndex(item => item.id == id)
if(idx != -1) {
return supplier_list.value[idx].name
}
}
return 'unknown'
})
const customer_name = computed(() => (item) => {
let val = `${item.true_name}`
if(item.username != item.true_name) {
val += ` ${item.username}`
}
if(item.mobile != null && item.mobile != '') {
val += ` ${item.mobile}`
}
return val
})
const expandPanel = (row) => {
if(row.offer && row.offer.length > 0) {
orderTableRef.value.toggleRowExpansion(row)
}
}
const expandRowKeys = ref([])
const isExpanded = computed(() => (id) => expandRowKeys.value.findIndex(it => it == id))
const expandChange = async (row,rows) => {
expandRowKeys.value = rows.map(item => item.id)
}
const startFilter = async () => {
currentPage.value = 1
await get_order_list()
}
const resetFilter = async () => {
inquiryStore.reset()
await get_order_list()
}
const handleSizeChange = async (val) => {
currentPage.value = 1
await get_order_list()
}
const handleCurrentChange = async (val) => {
await get_order_list()
}
const orderStatus = computed(() => (status,isdel) => {
status = parseInt(status)
isdel = parseInt(isdel)
if(isdel == 0) {
return ['等待处理','已发询价','询价有回','已建报价','已发报价','待付款订单'][status]
} else if(isdel == 1) {
return '用户取消'
} else {
return '客服取消'
}
})
const goodsSorted = computed(() => (goods) => {
return _.orderBy(goods, ['code', 'brand'], ['asc', 'asc'])
})
const inquiryShow = computed(() => (val,total) => {
if (val == 0 || val == '0') {
return 'warning'
} else if(total == val) {
return 'success'
} else {
return 'primary'
}
})
const handleSelectionChange = (rows) => selectionRows.value = rows
</script>
<style scoped>
.el-table .cell {
white-space: pre-wrap;
}
.pages {
padding-top: 20px;
}
:deep(.no-expand-icon .el-table__expand-icon) {
display: none;
}
</style>

View File

@ -0,0 +1,28 @@
<template>
<div>
<h2>产品首页</h2>
<p>当前时间{{ new Date().toLocaleString() }}</p>
<div class="mt-4">
<el-button type="danger" @click="logout">注销退出</el-button>
</div>
</div>
</template>
<script setup>
import { useRouter } from 'vue-router'
import { useUserStore } from '@/store'
import { removeToken } from '@/utils'
const router = useRouter()
const userStore = useUserStore()
const logout = () => {
userStore.logout()
removeToken()
router.push('/login')
}
</script>
<style lang="scss" scoped>
</style>