<template>
|
<view class="content">
|
<view class="header-section">
|
<view class="currentFactory">
|
<up-text type="primary" :text="userStore.currentFactoryName" @click="show = true" size="18"
|
class="factoryName" suffixIcon="arrow-right" :iconStyle="iconStyle"></up-text>
|
</view>
|
<up-picker :show="show" :columns="factoryList" @confirm="changeFactory" @cancel="show = false"></up-picker>
|
</view>
|
|
<view class="hero-section">
|
<view class="bg-img">
|
<view class="hero-content">
|
<text class="hero-title">产品库存管理系统</text>
|
</view>
|
</view>
|
</view>
|
|
<view class="notice-section">
|
<view class="notice">
|
<view class="notice-content">
|
<view class="notice-left">
|
<text class="notice-status">通知</text>
|
</view>
|
<view class="notice-separator"></view>
|
<view class="notice-right">
|
<text class="notice-label">{{currentStatus}}</text>
|
<text class="notice-text">当日销售设备数:<text class="notice-number">{{number}}<text class="notice-unit">个</text></text></text>
|
</view>
|
</view>
|
</view>
|
</view>
|
|
<!-- 营销管理模块 -->
|
<view class="common-module marketing-module">
|
<view class="module-header">
|
<view class="module-title-container">
|
<text class="module-title">营销管理</text>
|
</view>
|
</view>
|
<view class="module-content">
|
<up-grid
|
:border="false"
|
col="4"
|
>
|
<up-grid-item
|
v-for="(item, index) in marketingItems"
|
:key="index"
|
@click="handleCommonItemClick(item)"
|
>
|
<view class="icon-container" :style="{ background: item.bgColor }">
|
<up-icon
|
:name="item.icon"
|
:size="26"
|
color="#ffffff"
|
></up-icon>
|
</view>
|
<text class="item-label">{{item.label}}</text>
|
</up-grid-item>
|
</up-grid>
|
</view>
|
</view>
|
|
<!-- 采购管理模块 -->
|
<view class="common-module purchase-module">
|
<view class="module-header">
|
<view class="module-title-container">
|
<text class="module-title">采购管理</text>
|
</view>
|
</view>
|
<view class="module-content">
|
<up-grid
|
:border="false"
|
col="4"
|
>
|
<up-grid-item
|
v-for="(item, index) in purchaseItems"
|
:key="index"
|
@click="handleCommonItemClick(item)"
|
>
|
<view class="icon-container" :style="{ background: item.bgColor }">
|
<up-icon
|
:name="item.icon"
|
:size="26"
|
color="#ffffff"
|
></up-icon>
|
</view>
|
<text class="item-label">{{item.label}}</text>
|
</up-grid-item>
|
</up-grid>
|
</view>
|
</view>
|
|
<!-- 协同办公模块 -->
|
<view class="common-module collaboration-module">
|
<view class="module-header">
|
<view class="module-title-container">
|
<text class="module-title">协同办公</text>
|
</view>
|
</view>
|
<view class="module-content">
|
<up-grid
|
:border="false"
|
col="4"
|
>
|
<up-grid-item
|
v-for="(item, index) in collaborationItems"
|
:key="index"
|
@click="handleCommonItemClick(item)"
|
>
|
<view class="icon-container" :style="{ background: item.bgColor }">
|
<up-icon
|
:name="item.icon"
|
:size="26"
|
color="#ffffff"
|
></up-icon>
|
</view>
|
<text class="item-label">{{item.label}}</text>
|
</up-grid-item>
|
</up-grid>
|
</view>
|
</view>
|
|
<!-- 设备管理模块 -->
|
<view class="common-module equipment-module">
|
<view class="module-header">
|
<view class="module-title-container">
|
<text class="module-title">设备管理</text>
|
</view>
|
</view>
|
<view class="module-content">
|
<up-grid
|
:border="false"
|
col="4"
|
>
|
<up-grid-item
|
v-for="(item, index) in equipmentItems"
|
:key="index"
|
@click="handleCommonItemClick(item)"
|
>
|
<view class="icon-container" :style="{ background: item.bgColor }">
|
<up-icon
|
:name="item.icon"
|
:size="26"
|
color="#ffffff"
|
></up-icon>
|
</view>
|
<text class="item-label">{{item.label}}</text>
|
</up-grid-item>
|
</up-grid>
|
</view>
|
</view>
|
</view>
|
</template>
|
|
<script setup>
|
import {ref, onMounted, nextTick, reactive} from 'vue';
|
import {userLoginFacotryList} from "@/api/login";
|
import modal from "@/plugins/modal";
|
import useUserStore from "@/store/modules/user";
|
|
const userStore = useUserStore()
|
const factoryId = ref('');
|
const show = ref(false);
|
const factoryList = ref([]);
|
const factoryListTem = ref([]);
|
const iconStyle = {
|
fontSize: '18px',
|
color: '#2979ff'
|
}
|
|
// 通知状态切换
|
const statusList = ['销售', '采购']
|
let statusIndex = 0
|
const currentStatus = ref(statusList[0])
|
const number = ref(7643)
|
|
// 定时器切换通知状态
|
const startStatusTimer = () => {
|
setInterval(() => {
|
statusIndex = (statusIndex + 1) % statusList.length
|
currentStatus.value = statusList[statusIndex]
|
}, 3000)
|
}
|
|
// 营销管理功能数据
|
const marketingItems = reactive([
|
{
|
icon: 'account',
|
label: '销售台账',
|
bgColor: '#2979ff'
|
},
|
{
|
icon: 'home',
|
label: '开票登记',
|
bgColor: '#1976d2'
|
},
|
{
|
icon: 'file-text',
|
label: '开票台账',
|
bgColor: '#42a5f5'
|
},
|
{
|
icon: 'shopping-cart',
|
label: '回款登记',
|
bgColor: '#64b5f6'
|
},
|
{
|
icon: 'chat',
|
label: '回款流水',
|
bgColor: '#90caf9'
|
},
|
{
|
icon: 'chat',
|
label: '客户往来',
|
bgColor: '#90caf9'
|
}
|
]);
|
|
// 采购管理功能数据
|
const purchaseItems = reactive([
|
{
|
icon: 'order',
|
label: '采购台账',
|
bgColor: '#bbdefb'
|
},
|
{
|
icon: 'truck',
|
label: '来票登记',
|
bgColor: '#e3f2fd'
|
},
|
{
|
icon: 'box',
|
label: '来票台账',
|
bgColor: '#f3e5f5'
|
},
|
{
|
icon: 'chart-line',
|
label: '付款登记',
|
bgColor: '#e8eaf6'
|
},
|
{
|
icon: 'settings',
|
label: '付款流水',
|
bgColor: '#f1f8e9'
|
},
|
{
|
icon: 'settings',
|
label: '供应商往来',
|
bgColor: '#f1f8e9'
|
},
|
]);
|
|
// 协同办公功能数据
|
const collaborationItems = reactive([
|
{
|
icon: 'checkmark-circle',
|
label: '协同审批',
|
bgColor: '#4caf50'
|
},
|
{
|
icon: 'map-pin',
|
label: '客户拜访',
|
bgColor: '#ff9800'
|
}
|
]);
|
|
// 设备管理功能数据
|
const equipmentItems = reactive([
|
{
|
icon: 'list',
|
label: '设备台账',
|
bgColor: '#9c27b0'
|
},
|
{
|
icon: 'wrench',
|
label: '设备报修',
|
bgColor: '#f44336'
|
},
|
{
|
icon: 'shield-check',
|
label: '设备保养',
|
bgColor: '#00bcd4'
|
}
|
]);
|
|
// 处理常用功能点击
|
const handleCommonItemClick = (item) => {
|
// 根据不同的功能项进行跳转
|
switch (item.label) {
|
case '销售台账':
|
uni.navigateTo({
|
url: '/pages/sales/salesAccount/index'
|
});
|
break;
|
case '开票登记':
|
uni.navigateTo({
|
url: '/pages/sales/invoicingRegistration/index'
|
});
|
break;
|
case '开票台账':
|
uni.navigateTo({
|
url: '/pages/sales/invoiceLedger/index'
|
});
|
break;
|
case '回款登记':
|
uni.navigateTo({
|
url: '/pages/sales/receiptPayment/index'
|
});
|
break;
|
case '回款流水':
|
uni.navigateTo({
|
url: '/pages/sales/receiptPaymentHistory/index'
|
});
|
break;
|
case '客户往来':
|
uni.navigateTo({
|
url: '/pages/sales/receiptPaymentLedger/index'
|
});
|
break;
|
case '协同审批':
|
uni.navigateTo({
|
url: '/pages/cooperativeOffice/collaborativeApproval/index'
|
});
|
break;
|
case '客户拜访':
|
uni.navigateTo({
|
url: '/pages/cooperativeOffice/clientVisit/index'
|
});
|
break;
|
default:
|
uni.showToast({
|
title: `点击了${item.label}`,
|
icon: 'none'
|
});
|
}
|
};
|
|
// 创建对子组件的引用
|
const uToastRef = ref(null);
|
|
function getUserLoginFacotryList() {
|
userLoginFacotryList({userName: userStore.nickName}).then(res => {
|
// 检查res.data是否为数组
|
factoryList.value[0] = []
|
if (res.data && Array.isArray(res.data)) {
|
factoryListTem.value = res.data
|
res.data.forEach(item => {
|
factoryList.value[0].push(item.deptName)
|
})
|
factoryId.value = userStore.currentDeptId
|
} else {
|
// 如果res.data不是数组,设置为空数组
|
factoryList.value = []
|
}
|
}).catch(error => {
|
modal.msgError('获取公司列表失败:', error)
|
factoryList.value = []
|
})
|
}
|
const changeFactory = async (arr) => {
|
show.value = false;
|
const factoryId = factoryListTem.value[arr.indexs[0]].deptId
|
const loginForm = {
|
username: userStore.name,
|
password: uni.getStorageSync('remembered_password'),
|
factoryId: factoryId,
|
}
|
modal.loading("刷新中,请耐心等待...")
|
userStore.loginCheckFactory(loginForm).then(() => {
|
modal.closeLoading()
|
nextTick(() => {
|
loginSuccess()
|
});
|
}).catch(() => {
|
modal.closeLoading()
|
})
|
}
|
function loginSuccess(result) {
|
uni.reLaunch({
|
url: '/pages/index'
|
});
|
}
|
|
// 定义方法
|
const click = (name) => {
|
if (uToastRef.value) {
|
uToastRef.value.success(`点击了第${name + 1}个`); // 注意:这里加1是因为通常我们是从第1个开始计数的
|
}
|
};
|
|
onMounted(() => {
|
// 设置用户信息
|
userStore.getInfo()
|
getUserLoginFacotryList()
|
// 启动通知状态定时器
|
startStatusTimer()
|
});
|
</script>
|
|
<style scoped lang="scss">
|
.content {
|
background: linear-gradient(135deg, #f8f9fa 0%, #e3f2fd 100%);
|
min-height: 100vh;
|
padding: 20px;
|
padding-top: env(safe-area-inset-top);
|
position: relative;
|
|
&::before {
|
content: '';
|
position: fixed;
|
top: 0;
|
left: 0;
|
right: 0;
|
bottom: 0;
|
background: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><defs><pattern id="dots" width="20" height="20" patternUnits="userSpaceOnUse"><circle cx="10" cy="10" r="1" fill="rgba(41, 121, 255, 0.03)"/></pattern></defs><rect width="100" height="100" fill="url(%23dots)"/></svg>');
|
pointer-events: none;
|
z-index: -1;
|
}
|
|
&::after {
|
content: '';
|
position: fixed;
|
top: 0;
|
left: 0;
|
right: 0;
|
bottom: 0;
|
background: radial-gradient(circle at 20% 80%, rgba(41, 121, 255, 0.02) 0%, transparent 50%),
|
radial-gradient(circle at 80% 20%, rgba(156, 39, 176, 0.02) 0%, transparent 50%);
|
pointer-events: none;
|
z-index: -1;
|
}
|
}
|
|
/* 本页不再定义 .safe-area-top,已移至全局样式 */
|
|
.header-section {
|
margin-bottom: 16px;
|
animation: fadeInDown 0.6s ease-out;
|
}
|
|
.currentFactory {
|
margin-top: 8px;
|
margin-left: 4px;
|
font-weight: 500;
|
display: flex;
|
}
|
|
.factoryName {
|
width: auto;
|
}
|
|
:deep(.u-text) {
|
align-items: center;
|
}
|
|
.hero-section {
|
margin-bottom: 16px;
|
animation: fadeInUp 0.6s ease-out 0.1s both;
|
}
|
|
.bg-img {
|
width: 100%;
|
height: 120px;
|
background: linear-gradient(135deg, #2979ff 0%, #1565c0 100%);
|
border-radius: 12px;
|
position: relative;
|
overflow: hidden;
|
box-shadow: 0 4px 20px rgba(41, 121, 255, 0.15);
|
|
&::before {
|
content: '';
|
position: absolute;
|
top: -50%;
|
left: -50%;
|
width: 200%;
|
height: 200%;
|
background: conic-gradient(from 0deg, transparent, rgba(255,255,255,0.1), transparent, rgba(255,255,255,0.05), transparent);
|
animation: rotate 20s linear infinite;
|
}
|
|
&::after {
|
content: '';
|
position: absolute;
|
top: 0;
|
right: 0;
|
width: 120px;
|
height: 120px;
|
background: radial-gradient(circle, rgba(255,255,255,0.15) 0%, transparent 70%);
|
border-radius: 50%;
|
transform: translate(40px, -40px);
|
}
|
}
|
|
.hero-content {
|
position: relative;
|
z-index: 1;
|
padding: 20px;
|
height: 100%;
|
display: flex;
|
align-items: center;
|
}
|
|
.hero-title {
|
color: #ffffff;
|
font-size: 24px;
|
font-weight: 600;
|
}
|
|
|
|
.notice-section {
|
margin-bottom: 16px;
|
animation: fadeInUp 0.6s ease-out 0.2s both;
|
}
|
|
.notice {
|
width: 100%;
|
background: linear-gradient(135deg, #EAF2FF 0%, #BBDEFB 100%);
|
border: 1px solid #e3f2fd;
|
border-radius: 12px;
|
padding: 16px;
|
box-shadow: 0 4px 20px rgba(41, 121, 255, 0.08);
|
position: relative;
|
overflow: hidden;
|
|
&::before {
|
content: '';
|
position: absolute;
|
top: -50%;
|
left: -50%;
|
width: 200%;
|
height: 200%;
|
background: linear-gradient(45deg, transparent, rgba(255,255,255,0.6), transparent);
|
animation: shine 4s infinite;
|
}
|
|
&::after {
|
content: '';
|
position: absolute;
|
top: 0;
|
right: 0;
|
width: 80px;
|
height: 80px;
|
background: radial-gradient(circle, rgba(255,255,255,0.2) 0%, transparent 70%);
|
border-radius: 50%;
|
transform: translate(30px, -30px);
|
}
|
}
|
|
|
|
@keyframes shine {
|
0% {
|
transform: translateX(-100%) translateY(-100%) rotate(45deg);
|
}
|
100% {
|
transform: translateX(100%) translateY(100%) rotate(45deg);
|
}
|
}
|
|
@keyframes fadeInDown {
|
from {
|
opacity: 0;
|
transform: translateY(-20px);
|
}
|
to {
|
opacity: 1;
|
transform: translateY(0);
|
}
|
}
|
|
@keyframes fadeInUp {
|
from {
|
opacity: 0;
|
transform: translateY(20px);
|
}
|
to {
|
opacity: 1;
|
transform: translateY(0);
|
}
|
}
|
|
@keyframes rotate {
|
from {
|
transform: rotate(0deg);
|
}
|
to {
|
transform: rotate(360deg);
|
}
|
}
|
|
.notice-content {
|
display: flex;
|
align-items: center;
|
height: 100%;
|
position: relative;
|
z-index: 1;
|
}
|
|
.notice-left {
|
margin-right: 16px;
|
}
|
|
.notice-status {
|
font-weight: 600;
|
font-size: 16px;
|
color: #1976d2;
|
}
|
|
.notice-separator {
|
width: 1px;
|
height: 24px;
|
background: #e0e0e0;
|
margin-right: 16px;
|
}
|
|
.notice-right {
|
display: flex;
|
align-items: center;
|
justify-content: space-between;
|
flex: 1;
|
}
|
|
.notice-label {
|
color: #333;
|
font-size: 14px;
|
font-weight: 500;
|
margin-right: 12px;
|
}
|
|
.notice-text {
|
font-weight: 400;
|
font-size: 14px;
|
color: #666666;
|
}
|
|
.notice-number {
|
font-weight: 600;
|
font-size: 16px;
|
color: #1976d2;
|
margin-left: 4px;
|
}
|
|
.notice-unit {
|
color: #666666;
|
font-size: 14px;
|
margin-left: 2px;
|
}
|
|
/* 功能模块样式 */
|
.common-module {
|
margin-bottom: 24px;
|
background: linear-gradient(135deg, #ffffff 0%, #fafbfc 100%);
|
border-radius: 16px;
|
padding: 16px;
|
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.06);
|
border: none;
|
position: relative;
|
overflow: hidden;
|
transition: all 0.3s ease;
|
|
&::after {
|
content: '';
|
position: absolute;
|
top: 0;
|
right: 0;
|
width: 60px;
|
height: 60px;
|
background: radial-gradient(circle, rgba(0,0,0,0.02) 0%, transparent 70%);
|
border-radius: 50%;
|
transform: translate(30px, -30px);
|
}
|
|
&:hover {
|
transform: translateY(-2px);
|
box-shadow: 0 8px 30px rgba(0, 0, 0, 0.1);
|
|
&::after {
|
background: radial-gradient(circle, rgba(0,0,0,0.04) 0%, transparent 70%);
|
}
|
}
|
}
|
|
.marketing-module {
|
--module-color: #2979ff;
|
}
|
|
.purchase-module {
|
--module-color: #1976d2;
|
}
|
|
.collaboration-module {
|
--module-color: #4caf50;
|
}
|
|
.equipment-module {
|
--module-color: #9c27b0;
|
}
|
|
.module-header {
|
margin-bottom: 24px;
|
display: flex;
|
align-items: center;
|
justify-content: space-between;
|
}
|
|
.module-title-container {
|
display: flex;
|
align-items: center;
|
}
|
|
.module-title {
|
color: #333333;
|
font-size: 18px;
|
font-weight: 600;
|
position: relative;
|
|
&::after {
|
content: '';
|
position: absolute;
|
bottom: -4px;
|
left: 0;
|
width: 100%;
|
height: 2px;
|
background: linear-gradient(90deg, var(--module-color), rgba(255,255,255,0.9));
|
border-radius: 1px;
|
transition: all 0.3s ease;
|
box-shadow: 0 0 8px rgba(0,0,0,0.1);
|
}
|
|
&:hover::after {
|
width: 30px;
|
box-shadow: 0 0 12px rgba(0,0,0,0.15);
|
}
|
}
|
|
.module-subtitle {
|
color: #666666;
|
font-size: 12px;
|
font-weight: 400;
|
margin-left: 8px;
|
}
|
|
.module-content {
|
width: 100%;
|
display: grid;
|
gap: 16px;
|
}
|
|
.icon-container {
|
width: 52px;
|
height: 52px;
|
border-radius: 12px;
|
display: flex;
|
align-items: center;
|
justify-content: center;
|
margin-bottom: 6px;
|
box-shadow: 0 3px 12px rgba(0, 0, 0, 0.12);
|
transition: all 0.3s ease;
|
position: relative;
|
overflow: hidden;
|
|
&::before {
|
content: '';
|
position: absolute;
|
top: 0;
|
left: 0;
|
right: 0;
|
bottom: 0;
|
background: linear-gradient(135deg, rgba(255,255,255,0.1) 0%, transparent 50%, rgba(255,255,255,0.05) 100%);
|
opacity: 0;
|
transition: opacity 0.3s ease;
|
}
|
|
&::after {
|
content: '';
|
position: absolute;
|
top: 0;
|
left: 0;
|
right: 0;
|
bottom: 0;
|
border-radius: 12px;
|
background: linear-gradient(45deg, transparent, rgba(255,255,255,0.2), transparent);
|
opacity: 0;
|
transition: opacity 0.3s ease;
|
}
|
|
&:hover {
|
transform: translateY(-3px) scale(1.02);
|
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.18);
|
|
&::before,
|
&::after {
|
opacity: 1;
|
}
|
}
|
}
|
|
.item-label {
|
font-size: 13px;
|
color: #555555;
|
text-align: center;
|
display: block;
|
line-height: 1.4;
|
font-weight: 500;
|
margin-top: 4px;
|
margin-bottom: 10px;
|
}
|
|
.grid-text {
|
font-size: 14px;
|
color: #909399;
|
padding: 10rpx 0 20rpx 0rpx;
|
/* #ifndef APP-PLUS */
|
box-sizing: border-box;
|
/* #endif */
|
}
|
|
|
</style>
|