Commit e91e8d4f by qinjianhui

feat: 订单页面开发

parent d9bf58fb
......@@ -9,15 +9,23 @@ declare module 'vue' {
export interface GlobalComponents {
ElButton: typeof import('element-plus/es')['ElButton']
ElConfigProvider: typeof import('element-plus/es')['ElConfigProvider']
ElDropdown: typeof import('element-plus/es')['ElDropdown']
ElDropdownItem: typeof import('element-plus/es')['ElDropdownItem']
ElDropdownMenu: typeof import('element-plus/es')['ElDropdownMenu']
ElForm: typeof import('element-plus/es')['ElForm']
ElFormItem: typeof import('element-plus/es')['ElFormItem']
ElIcon: typeof import('element-plus/es')['ElIcon']
ElInput: typeof import('element-plus/es')['ElInput']
ElMenu: typeof import('element-plus/es')['ElMenu']
ElMenuItem: typeof import('element-plus/es')['ElMenuItem']
ElPagination: typeof import('element-plus/es')['ElPagination']
ElSubMenu: typeof import('element-plus/es')['ElSubMenu']
NavMenu: typeof import('./src/components/navMenu.vue')['default']
ElTable: typeof import('element-plus/es')['ElTable']
ElTableColumn: typeof import('element-plus/es')['ElTableColumn']
ElTag: typeof import('element-plus/es')['ElTag']
NavMenu: typeof import('./src/components/NavMenu.vue')['default']
RouterLink: typeof import('vue-router')['RouterLink']
RouterView: typeof import('vue-router')['RouterView']
TableView: typeof import('./src/components/TableView.vue')['default']
}
}
......@@ -5,19 +5,27 @@
"type": "module",
"scripts": {
"dev": "vite",
"build": "vue-tsc && vite build",
"preview": "vite preview"
"build": "npm run lint && vue-tsc && vite build",
"preview": "vite preview",
"lint": "vue-tsc --noEmit && eslint"
},
"dependencies": {
"@element-plus/icons-vue": "^2.3.1",
"axios": "^1.6.7",
"element-plus": "^2.6.0",
"lodash-es": "^4.17.21",
"pinia": "^2.1.7",
"vue": "^3.4.19",
"vue-router": "^4.3.0"
},
"devDependencies": {
"@typescript-eslint/eslint-plugin": "^7.1.1",
"@typescript-eslint/parser": "^7.1.1",
"@vitejs/plugin-vue": "^5.0.4",
"@vue/eslint-config-typescript": "^12.0.0",
"eslint": "^8.57.0",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-vue": "^9.22.0",
"sass": "^1.71.1",
"typescript": "^5.2.2",
"unplugin-auto-import": "^0.17.5",
......

981 Bytes | W: | H:

955 Bytes | W: | H:

src/assets/images/factory-logo.png
src/assets/images/factory-logo.png
src/assets/images/factory-logo.png
src/assets/images/factory-logo.png
  • 2-up
  • Swipe
  • Onion skin
<template>
<div class="table-view">
<div></div>
</div>
</template>
<script setup lang="ts">
import { defineProps } from 'vue'
const prop = defineProps({
// 表头
header: {
type: Array,
default: () => [],
},
// 数据
data: {
type: Array,
default: () => [],
},
})
</script>
<style lang="scss" scoped></style>
\ No newline at end of file
......@@ -4,9 +4,71 @@
<img src="../assets/images/factory-logo.png" alt="logo" />
</div>
<!-- 导航栏 -->
<el-menu
class="el-menu-demo"
mode="horizontal"
background-color="#001529"
text-color="#fff"
:default-active="defaultActive"
router
>
<template v-for="item in menuList">
<el-menu-item
:key="item.id"
:index="item.index"
v-if="!item.children"
>{{ item.label }}</el-menu-item
>
<el-sub-menu :key="item.index" :index="item.index" v-else>
<template #title>
<span class="label">{{ item.label }}</span>
</template>
<el-menu-item
v-for="sub in item.children"
:index="sub.index"
:key="sub.id"
>{{ sub.label }}</el-menu-item
>
</el-sub-menu>
</template>
</el-menu>
<div class="user-info">
<span class="user-avatar">
<el-icon><User /></el-icon>
</span>
<el-dropdown style="color: #fff; font-size: 12px">
<span class="el-dropdown-link">
<el-icon style="vertical-align: middle"><User /></el-icon>
用户
<el-icon style="vertical-align: middle" class="el-icon--right">
<arrow-down />
</el-icon>
</span>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item @click="logout">退出登录</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</div>
</div>
</template>
<script setup lang="ts"></script>
<script setup lang="ts">
import { User, ArrowDown } from '@element-plus/icons-vue'
import { ref, reactive } from 'vue'
import { useRoute } from 'vue-router'
import Menu from '@/router/menu'
import userUserStore from '@/store/user'
const route = useRoute()
const defaultActive = ref(route.path)
const menuList = reactive(Menu)
const userInfo = userUserStore().user
const logout = () => {
userUserStore().logout()
}
</script>
<style lang="scss" scoped>
.nav-menu {
height: 60px;
......@@ -20,5 +82,14 @@
flex: 1;
height: 100%;
border-bottom: none;
margin-left: 20px;
:deep(.el-menu-item) {
border-bottom: none !important;
}
:deep(.el-menu-item.is-active) {
background-color: #409eff !important;
color: #fff !important;
border: none !important;
}
}
</style>
......@@ -4,6 +4,9 @@ import Login from '@/views/Login.vue'
import Reset from '@/views/Reset.vue'
import Home from '@/views/Home.vue'
import Dashboard from '@/views/Dashboard.vue'
import Error from '@/views/error/404.vue'
import OrderList from '@/views/order/index.vue'
import ProductionComplete from '@/views/production/complete.vue'
const router = createRouter({
history: createWebHistory(),
......@@ -17,6 +20,14 @@ const router = createRouter({
path: '/dashboard',
component: Dashboard,
},
{
path: '/order/list',
component: OrderList
},
{
path: '/production/complete',
component: ProductionComplete
}
],
},
// 登录
......@@ -28,6 +39,11 @@ const router = createRouter({
path: '/user/reset',
component: Reset,
},
// 其他路由
{
path: '/:pathMatch(.*)*',
component: Error,
},
],
})
// router.beforeEach((to, from, next) => {
......
export interface MenuItem {
index: string,
id: number,
label: string,
children?: MenuItem[],
}
const menu: MenuItem[] = [
{
index: '/dashboard',
id: 1,
label: '概览',
},
{
index: '/order/list',
id: 2,
label: '订单',
},
{
index: '',
id: 3,
label: '生产管理',
children: [
{
index: '/production/complete',
id: 4,
label: '生产完成',
}
]
},
]
export default menu
......@@ -8,7 +8,7 @@ export interface AppStoreState {
user?: User
}
const useAppStore = defineStore('app', {
const useUserStore = defineStore('user', {
state: () => ({} as AppStoreState),
actions: {
setUser(user?: User) {
......@@ -18,7 +18,8 @@ const useAppStore = defineStore('app', {
const resp = await loginApi(data)
// resp.
},
async logout() {},
},
})
export default useAppStore
export default useUserStore
.card {
background-color: #fff;
padding: 10px;
border-radius: 5px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}
.w-100 {
width: 100%;
}
.h-100 {
height: 100%;
}
.overflow-hidden {
overflow: hidden;
}
.flex {
display: flex;
}
.flex-column {
display: flex;
flex-direction: column;
}
.flex-1 {
flex: 1;
}
::-webkit-scrollbar {
width: 5px;
height: 5px;
background-color: transparent;
}
::-webkit-scrollbar-thumb {
border-radius: 5px;
background-color: rgba(221, 221, 221, 1);
transition: all 0.4s ease;
-moz-transition: all 0.4s ease;
-webkit-transition: all 0.4s ease;
-o-transition: all 0.4s ease;
}
::-webkit-scrollbar-track {
border: none;
outline: none;
background-color: rgba(0, 0, 0, 0);
}
.el-table thead {
color: #333;
font-size: 14px;
height: 50px;
min-height: 50px;
}
.el-table thead th.el-table__cell {
background-color: #FAFAFA;
}
.el-table__row {
height: 40px;
min-height: 40px;
}
\ No newline at end of file
@import './common.scss';
@import './element.scss'
interface ResizeObserverElement extends HTMLElement {
__resizeListeners__?: ((entry: ResizeObserverEntry) => void)[]
__ro__?: ResizeObserver
}
// copy from element-ui
const resizeHandler = function (entries: ResizeObserverEntry[]) {
for (const entry of entries) {
const listeners =
(entry.target as ResizeObserverElement).__resizeListeners__ || []
if (listeners.length) {
listeners.forEach((fn) => {
fn(entry)
})
}
}
}
// copy from element-ui
export const addResizeListener = function (
element: ResizeObserverElement,
fn: (entry: ResizeObserverEntry) => void,
) {
if (!element.__resizeListeners__) {
element.__resizeListeners__ = []
element.__ro__ = new ResizeObserver(resizeHandler)
element.__ro__.observe(element)
}
element.__resizeListeners__.push(fn)
}
// copy from element-ui
export const removeResizeListener = function (
element: ResizeObserverElement,
fn: () => void,
) {
if (!element || !element.__resizeListeners__) return
element.__resizeListeners__.splice(element.__resizeListeners__.indexOf(fn), 1)
if (!element.__resizeListeners__.length) {
element.__ro__?.disconnect()
}
}
type DOMClass =
| string
| string[]
| Record<string, number | string | boolean | undefined | null>
| undefined
export function normalizeClasses(cls: DOMClass) {
if (typeof cls === 'string') return cls
else if (Array.isArray(cls)) return cls.join(' ')
else if (typeof cls === 'object') {
let classes = ''
for (const key in cls) {
if (cls[key]) classes += cls + ' '
}
return classes.trim()
}
return ''
}
export function concatClasses(cls: DOMClass, ...classes: DOMClass[]) {
return (
normalizeClasses(cls) +
' ' +
classes.map(normalizeClasses).join(' ')
).trim()
}
import { Ref, onBeforeUnmount, onMounted, ref } from 'vue'
import { addResizeListener, removeResizeListener } from '../dom'
import { debounce } from 'lodash-es'
export default function useElTableColumnWidth(
selector: string,
): [Ref<HTMLElement | null>, Ref<number>] {
const tableWrapperRef = ref<HTMLDivElement | null>(null)
let cleanupResizeEventListener: (() => void) | undefined
const width = ref(0)
const onThOrderDetailResize = debounce(
() => {
const el = tableWrapperRef.value
if (!el) return
const th = el.querySelector(selector) as HTMLElement | null
if (th) {
width.value = th.offsetWidth
}
},
50,
{ leading: true },
)
onMounted(() => {
const el = tableWrapperRef.value
if (!el) return
cleanupResizeEventListener = () => {
removeResizeListener(el, onThOrderDetailResize)
}
addResizeListener(el, onThOrderDetailResize)
})
onBeforeUnmount(() => {
cleanupResizeEventListener?.()
})
return [tableWrapperRef, width]
}
<template>
<div class="dashboard">概览页面</div>
<div class="card dashboard">概览页面</div>
</template>
<script setup></script>
<script setup lang="ts"></script>
<style lang="scss" scoped>
.dashboard {
height: calc(100vh - 60px - 20px);
......
<template>
<div class="home">
<!-- 顶部导航栏 -->
<navMenu></navMenu>
<NavMenu />
<div class="container">
<RouterView></RouterView>
<RouterView />
</div>
</div>
</template>
<script setup lang="ts">
import useAppStore from '@/store/app'
import navMenu from '@/components/navMenu.vue'
const appStore = useAppStore()
const a = appStore.user
console.log(a)
import NavMenu from '@/components/NavMenu.vue'
</script>
<style lang="scss" scoped>
.home {
height: 100%;
display: flex;
flex-direction: column;
overflow: hidden;
}
.container {
flex: 1;
padding: 10px;
background-color: #f6f6f6;
overflow: hidden;
}
</style>
<template>
<div class="error404">
<error code="404" title="哎呀,出错了!您访问的页面不存在…"></error>
</div>
</template>
<script lang="ts" setup>
import Error from '@/views/error/error.vue'
</script>
<style lang="scss" scoped>
.error404 {
height: 100%;
}
</style>
\ No newline at end of file
<template>
<div class="error">
<div>
<slot name="content">
<div class="error-code">{{ code }}</div>
</slot>
<div class="text-lg text-tx-secondary mt-7 mb-7">{{ title }}</div>
<el-button v-if="showBtn" type="primary" @click="router.go(-1)">
{{ second }} 秒后返回上一页
</el-button>
</div>
</div>
</template>
<script lang="ts" setup>
import { onUnmounted, ref } from 'vue'
import { useRouter } from 'vue-router'
const props = defineProps({
code: String,
title: String,
showBtn: {
type: Boolean,
default: true,
},
})
let timer: number | undefined
const second = ref(5)
const router = useRouter()
props.showBtn &&
(timer = setInterval(() => {
if (second.value === 0) {
clearInterval(timer)
router.go(-1)
} else {
second.value--
}
}, 1000))
onUnmounted(() => {
timer && clearInterval(timer)
})
</script>
<style lang="scss" scoped>
.error {
text-align: center;
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
.error-code {
color: #409eff;
font-size: 150px;
}
.el-button {
width: 176px;
}
}
</style>
import type { TableColumnCtx } from 'element-plus'
export interface SearchForm {
mainSku: string
endProductId: string
orderOnlineNo: string
shopNumber: string
supplierId: string
internalMemo: string
}
export interface Tab {
label: string
quality: number
code: string
}
export interface OrderData {
id: number
moreable?: boolean
shopNumber?: string
orderNumber?: string
addressId?: number
status?: number
productAmount?: number
totalAmount?: number
paymentTime?: string
startStockingTime?: string
source?: string
createTime?: string
updateTime?: string
productList?: ProductList[]
address?: Address
delayMinDay?: number
internalMemoList?: MemoList[]
sourceType?: string
}
export interface ProductList {
id: number
customOrderId?: number
subOrderNumber?: string
shopNumber?: string
baseSku?: string
variantSku?: string
variantImage?: string
erpProductItemId?: number
endProductId?: string
chimaId?: string
diyId?: string
facotoryNo?: string
num?: number
shipmentNum?: number
price?: number
productName?: string
createTime?: string
updateTime?: string
}
export interface Address {
id: number
name?: string
swDefault?: 1
deliveryType?: string
lanshouName?: string
lanshouPhone?: string
lanshouRegion?: string
lanshouAddress?: string
lanshouPost?: string
jijianCompanyName?: string
jijianMobile?: string
jijianName?: string
jijianTel?: string
jijianCountryCode?: string
jijianCountryName?: string
jijianProvince?: string
jijianProvinceCode?: string
jijianCity?: string
jijianCityCode?: string
jijianCounty?: string
jijianPostCode?: string
jijianStreet?: string
jijianEmail?: string
tuihuoName?: string
tuihuoPhone?: string
tuihuoRegion?: string
tuihuoAddress?: string
tuihuoPost?: string
remark?: string
createTime?: string
}
export interface MemoList {
id: number
type?: number
outId?: number
operatorEmployeeName?: string
content?: string
remark?: string
operatorTime?: string
}
export interface SpanMethodProps {
row: OrderData
column: TableColumnCtx<OrderData>
rowIndex: number
columnIndex: number
}
<template>
<div class="card complete">生产完成页面</div>
</template>
<script setup lang="ts"></script>
<style lang="scss" scoped>
.complete {
height: calc(100vh - 60px - 20px);
}
</style>
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment