Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
A
admin
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
华润手术跟台
admin
Commits
8221c4e2
提交
8221c4e2
authored
11月 08, 2022
作者:
袁伟伟
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
feat: 商城导航
上级
64d60edb
隐藏空白字符变更
内嵌
并排
正在显示
14 个修改的文件
包含
410 行增加
和
86 行删除
+410
-86
goodsApi.ts
src/api/product/goodsApi.ts
+0
-5
goodsCategoryApi.ts
src/api/product/goodsCategoryApi.ts
+9
-0
nav.ts
src/api/store/nav.ts
+0
-0
thirdApi.ts
src/api/system/thirdApi.ts
+8
-0
index.ts
src/hooks/myhooks/index.ts
+38
-0
user.ts
src/store/modules/user.ts
+11
-0
index.vue
src/views/product/goods-category/index.vue
+1
-1
modal.vue
src/views/product/goods-category/modal.vue
+2
-2
type.ts
src/views/product/goods-category/type.ts
+2
-0
basicInfo.vue
src/views/product/goods/components/basicInfo.vue
+10
-0
nav.vue
src/views/store/components/nav.vue
+63
-0
search.vue
src/views/store/components/search.vue
+25
-0
index.vue
src/views/store/goodsList/index.vue
+187
-3
index.vue
src/views/store/home/index.vue
+54
-75
没有找到文件。
src/api/product/goodsApi.ts
浏览文件 @
8221c4e2
...
...
@@ -67,8 +67,3 @@ export const batchUpdate = (entityList: Array<Goods>) =>
* 查询数量
*/
export
const
count
=
(
params
?:
GoodsParams
)
=>
defHttp
.
get
<
Number
>
({
url
:
`
${
baseApi
}
/count`
,
params
});
/**
* 产品线查询
*/
export
const
line
=
()
=>
defHttp
.
get
<
Number
>
({
url
:
`/v1/system/third/get/product/line`
});
src/api/product/goodsCategoryApi.ts
浏览文件 @
8221c4e2
...
...
@@ -85,3 +85,12 @@ export const tree = (params) =>
url
:
`
${
baseApi
}
/tree`
,
params
,
});
/**
* 查询经销商分类树
*/
export
const
dealerTree
=
(
params
)
=>
defHttp
.
get
<
DataItem
[]
>
({
url
:
`
${
baseApi
}
/distributor/tree`
,
params
,
});
src/api/store/nav.ts
0 → 100644
浏览文件 @
8221c4e2
src/api/system/thirdApi.ts
0 → 100644
浏览文件 @
8221c4e2
import
{
defHttp
}
from
'/@/utils/http/axios'
;
const
baseApi
=
'/v1/system/third'
;
/**
* 产品线查询
*/
export
const
line
=
()
=>
defHttp
.
get
<
Number
>
({
url
:
`
${
baseApi
}
/get/product/line`
});
src/hooks/myhooks/index.ts
浏览文件 @
8221c4e2
import
lodash
from
'lodash'
;
import
{
reactive
}
from
'vue'
;
import
*
as
goodsCategoryApi
from
'/@/api/product/goodsCategoryApi'
;
import
{
useUserStore
}
from
'/@/store/modules/user'
;
const
userStore
=
useUserStore
();
const
pagination
=
{
current
:
1
,
...
...
@@ -28,3 +32,37 @@ export const usePagination = (fun: () => void) => {
};
return
reactive
(
p
);
};
const
getNavTree
=
(
navList
,
init
?:
Function
,
str
)
=>
{
goodsCategoryApi
.
dealerTree
({
parentId
:
0
}).
then
((
res
)
=>
{
navList
.
value
=
res
;
userStore
.
setUserNavList
(
navList
.
value
);
if
(
init
)
{
if
(
str
===
'getGrandsonList'
)
{
init
(
navList
.
value
);
}
else
{
init
();
}
}
});
};
const
navTree
=
(
navList
,
init
?:
Function
,
str
)
=>
{
const
navListStore
=
userStore
.
getNavList
;
if
(
navListStore
.
length
<=
0
)
{
getNavTree
(
navList
,
init
,
str
);
}
else
{
navList
.
value
=
navListStore
;
if
(
init
)
{
if
(
str
===
'getGrandsonList'
)
{
init
(
navList
.
value
);
}
else
{
init
();
}
}
}
};
export
const
useNavTree
=
()
=>
{
return
navTree
;
};
src/store/modules/user.ts
浏览文件 @
8221c4e2
...
...
@@ -15,6 +15,8 @@ import { RouteRecordRaw } from 'vue-router';
import
{
PAGE_NOT_FOUND_ROUTE
}
from
'/@/router/routes/basic'
;
import
{
isArray
}
from
'/@/utils/is'
;
import
{
h
}
from
'vue'
;
import
{
DataItem
}
from
'/@/views/product/goods-category/type'
;
// import { useSocketStore } from './socket';
// import { useThingsBoard } from './thingsboard';
...
...
@@ -25,6 +27,7 @@ interface UserState {
sessionTimeout
?:
boolean
;
lastUpdateTime
:
number
;
authorityList
:
Authority
[];
navList
:
DataItem
[];
}
export
const
useUserStore
=
defineStore
({
...
...
@@ -41,6 +44,7 @@ export const useUserStore = defineStore({
// Last fetch time
lastUpdateTime
:
0
,
authorityList
:
[],
navList
:
[],
}),
getters
:
{
getUserInfo
():
User
{
...
...
@@ -73,6 +77,10 @@ export const useUserStore = defineStore({
getIsDistributor
():
boolean
{
return
this
.
getDistributorId
!==
0
;
},
getNavList
():
DataItem
[]
{
return
this
.
navList
;
},
},
actions
:
{
setToken
(
info
:
string
|
undefined
)
{
...
...
@@ -192,6 +200,9 @@ export const useUserStore = defineStore({
},
});
},
setUserNavList
(
navList
:
DataItem
[])
{
this
.
navList
=
navList
;
},
},
});
...
...
src/views/product/goods-category/index.vue
浏览文件 @
8221c4e2
...
...
@@ -24,7 +24,7 @@
>
禁用
</a-button
>
<a-button
type=
"link"
v-else
@
click=
"handleChangeStatus(record.id, 'YES')"
>
启用
</a-button>
<a-button
type=
"link"
>
添加商品
</a-button>
<a-button
type=
"link"
v-if=
"record.level === 5"
>
添加商品
</a-button>
<a-popconfirm
title=
"是否确认删除?"
ok-text=
"是"
...
...
src/views/product/goods-category/modal.vue
浏览文件 @
8221c4e2
...
...
@@ -59,7 +59,7 @@
import
{
defineExpose
,
ref
,
reactive
,
defineEmits
,
watch
,
defineProps
,
onMounted
}
from
'vue'
;
import
{
message
}
from
'ant-design-vue'
;
import
*
as
GoodsCategoryApi
from
'/@/api/product/goodsCategoryApi'
;
import
*
as
GoodsApi
from
'/@/api/product/goods
Api'
;
import
*
as
thirdApi
from
'/@/api/system/third
Api'
;
import
{
DataItem
}
from
'/@/views/product/goods-category/type'
;
import
{
GoodsCategory
}
from
'/@/api/model/goodsCategory'
;
...
...
@@ -113,7 +113,7 @@
};
const
handleGetLineList
=
()
=>
{
Goods
Api
.
line
().
then
((
res
)
=>
{
third
Api
.
line
().
then
((
res
)
=>
{
thirdProductOption
.
value
=
res
;
});
};
...
...
src/views/product/goods-category/type.ts
浏览文件 @
8221c4e2
export
interface
DataItem
{
children
?:
DataItem
[];
name
:
string
;
id
:
number
;
disabled
?:
boolean
;
}
src/views/product/goods/components/basicInfo.vue
浏览文件 @
8221c4e2
...
...
@@ -98,10 +98,20 @@
// 获取树结构
const
getTreeData
=
()
=>
{
GoodsCategoryApi
.
tree
({
parentId
:
0
,
status
:
'YES'
}).
then
((
res
:
DataItem
[])
=>
{
let
idx
=
0
;
addDisabled
(
res
,
idx
);
classifyTree
.
value
=
res
;
});
};
const
addDisabled
=
(
arr
:
DataItem
[],
idx
:
number
)
=>
{
if
(
++
idx
===
5
)
return
;
arr
.
forEach
((
item
)
=>
{
item
.
disabled
=
true
;
if
(
item
.
children
)
addDisabled
(
item
.
children
,
idx
);
});
};
const
validate
=
()
=>
{
formRef
.
value
.
validate
().
then
(()
=>
{
emits
(
'handleSubmit'
);
...
...
src/views/store/components/nav.vue
0 → 100644
浏览文件 @
8221c4e2
<
template
>
<div
class=
"nav"
>
<ul>
<li>
产品线
</li>
<template
v-for=
"(item, index) in navList"
>
<li
v-if=
"index !== 4"
>
|
</li>
<li
class=
"title"
:class=
"
{ active: navActiveKey === item.id }" @click="handleChangeNav(item.id)">
{{
item
.
name
}}
</li>
</
template
>
</ul>
</div>
</template>
<
script
lang=
"ts"
setup
>
import
{
defineProps
,
defineEmits
,
createVNode
}
from
'vue'
;
import
{
Modal
}
from
'ant-design-vue'
;
import
{
ExclamationCircleOutlined
}
from
'@ant-design/icons-vue'
;
const
props
=
defineProps
([
'navList'
,
'navActiveKey'
]);
const
emits
=
defineEmits
([
'handleChangeNavId'
,
'update:navActiveKey'
]);
const
handleChangeNav
=
(
id
)
=>
{
if
(
props
.
navActiveKey
===
id
)
return
;
Modal
.
confirm
({
title
:
'提示'
,
icon
:
createVNode
(
ExclamationCircleOutlined
),
content
:
'你确定切换产品线吗?切换产品线会清空购物车!'
,
onOk
()
{
emits
(
'update:navActiveKey'
,
id
);
},
onCancel
()
{},
});
};
</
script
>
<
style
lang=
"less"
scoped
>
.nav {
background: #f7f9fa;
text-align: center;
border-radius: 10px;
ul {
height: 50px;
padding: 5px;
li {
font-size: 20px;
height: 40px;
line-height: 40px;
display: inline-block;
margin: 0 15px;
}
.active {
color: #1890ff;
}
.title {
cursor: pointer;
}
}
}
</
style
>
src/views/store/components/search.vue
0 → 100644
浏览文件 @
8221c4e2
<
template
>
<div
class=
"searchWrap"
>
<a-input-search
v-model:value=
"searchInfo"
placeholder=
"请输入"
enter-button=
"搜索"
size=
"large"
@
search=
"onSearch"
/>
</div>
</
template
>
<
script
lang=
"ts"
setup
>
import
{
ref
}
from
'vue'
;
const
searchInfo
=
ref
(
''
);
const
onSearch
=
()
=>
{};
</
script
>
<
style
lang=
"less"
scoped
>
.searchWrap {
width: 500px;
margin: 0 auto 30px;
}
</
style
>
src/views/store/goodsList/index.vue
浏览文件 @
8221c4e2
<
template
>
111
</
template
>
<
template
>
<div
class=
"containe"
>
<Search></Search>
<div
class=
"contentWrap"
>
<div
class=
"top"
>
<div
class=
"title"
>
{{
title
}}
</div>
<div
class=
"wrap"
>
<Nav
v-model:navList=
"navList"
v-model:navActiveKey=
"navActiveKey"
/>
</div>
</div>
<div
class=
"classify"
>
<div
class=
"title"
>
全部分类
</div>
<div
class=
"classifyWrap"
>
<ul
class=
"classifyList"
>
<li
class=
"item"
@
click=
"handleChangeLevelFour('all')"
:class=
"
{ active: levelFourActiveKey === 'all' }"
>全部
</li
>
<li
class=
"item"
:class=
"
{ active: levelFourActiveKey === item.id }"
v-for="item in levelFourTree"
@click="handleChangeLevelFour(item)"
>
{{
item
.
name
}}
</li>
</ul>
<ul
class=
"classifyList"
>
<li
class=
"item"
@
click=
"handleChangeLevelFive('all')"
:class=
"
{ active: levelFiveActiveKey === 'all' }"
>全部
</li
>
<li
class=
"item"
:class=
"
{ active: levelFiveActiveKey === item.id }"
v-for="item in levelFiveTree"
@click="handleChangeLevelFive(item)"
>
{{
item
.
name
}}
</li>
</ul>
</div>
</div>
</div>
</div>
</
template
>
<
script
lang=
"ts"
></
script
>
<
script
lang=
"ts"
setup
>
import
{
ref
,
onMounted
,
watch
}
from
'vue'
;
import
{
useRoute
}
from
'vue-router'
;
import
Search
from
'../components/search.vue'
;
import
Nav
from
'../components/nav.vue'
;
import
{
useGo
}
from
'/@/hooks/web/usePage'
;
import
{
toNumber
}
from
'lodash'
;
import
{
useUserStore
}
from
'/@/store/modules/user'
;
import
{
useNavTree
}
from
'/@/hooks/myhooks/index'
;
import
{
DataItem
}
from
'/@/views/product/goods-category/type'
;
<
style
lang=
"less"
scoped
></
style
>
const
go
=
useGo
();
const
route
=
useRoute
();
const
navTree
=
useNavTree
();
const
query
=
route
.
query
;
const
navId
=
toNumber
(
query
.
nav
);
// 一级选择id
const
tabId
=
toNumber
(
query
.
tab
);
// 二级选择id
const
tabItemId
=
toNumber
(
query
.
tabItem
);
// 三级选择id
const
navList
=
ref
<
DataItem
[]
>
([]);
// 菜单树
const
navActiveKey
=
ref
(
navId
);
// 一级标签选择
const
levelFourTree
=
ref
<
DataItem
[]
>
([]);
// 四级菜单树
const
levelFourActiveKey
=
ref
<
string
|
number
>
(
'all'
);
const
levelFiveTree
=
ref
<
DataItem
[]
>
([]);
// 五级菜单树
const
levelFiveActiveKey
=
ref
<
string
|
number
>
(
'all'
);
const
title
=
ref
(
''
);
const
userStore
=
useUserStore
();
navList
.
value
=
userStore
.
getNavList
;
const
getGrandsonList
=
(
arr
:
DataItem
[])
=>
{
arr
.
some
((
item
)
=>
{
if
(
item
.
id
===
navId
||
item
.
id
===
tabId
)
{
if
(
item
.
id
===
navId
)
title
.
value
=
item
.
name
;
if
(
item
.
children
)
{
getGrandsonList
(
item
.
children
);
return
true
;
}
}
else
if
(
item
.
id
===
tabItemId
)
{
levelFourTree
.
value
=
item
.
children
;
return
true
;
}
});
};
const
handleChangeLevelFour
=
(
item
:
DataItem
|
string
)
=>
{
if
(
typeof
item
===
'string'
)
{
levelFourActiveKey
.
value
=
'all'
;
}
else
{
levelFiveTree
.
value
=
item
.
children
;
levelFourActiveKey
.
value
=
item
.
id
;
}
};
const
handleChangeLevelFive
=
(
item
:
DataItem
|
string
)
=>
{
if
(
typeof
item
===
'string'
)
{
levelFiveActiveKey
.
value
=
'all'
;
}
else
{
levelFiveActiveKey
.
value
=
item
.
id
;
}
};
watch
(
()
=>
navActiveKey
.
value
,
(
n
)
=>
{
go
(
'/main/store/home'
+
`?id=
${
n
}
`
);
},
);
onMounted
(()
=>
{
navTree
(
navList
,
getGrandsonList
,
'getGrandsonList'
);
});
</
script
>
<
style
lang=
"less"
scoped
>
.active {
color: #1890ff;
}
.containe {
padding: 30px;
.contentWrap {
padding: 30px;
background: #fff;
border-radius: 10px;
.top {
display: flex;
justify-content: space-between;
.title {
width: 25%;
background: #f7f9fa;
color: #1890ff;
border-radius: 10px;
text-align: center;
height: 50px;
padding: 5px;
line-height: 40px;
font-size: 20px;
}
.wrap {
width: 73%;
margin: 0;
}
}
.classify {
display: flex;
justify-content: flex-start;
margin: 30px 0 20px 60px;
.title {
height: 100px;
line-height: 100px;
padding-right: 40px;
margin-right: 20px;
font-size: 22px;
border-right: 1px solid rgb(214, 214, 214);
}
.classifyWrap {
flex: 1;
.classifyList {
border-bottom: 1px solid rgb(214, 214, 214);
padding-bottom: 10px;
display: flex;
justify-content: flex-start;
.item {
margin-right: 10px;
cursor: pointer;
&:hover {
color: rgb(129, 129, 129);
}
}
}
}
}
}
}
</
style
>
src/views/store/home/index.vue
浏览文件 @
8221c4e2
<
template
>
<div
class=
"containe"
>
<div
class=
"searchWrap"
>
<a-input-search
v-model:value=
"searchInfo"
placeholder=
"请输入"
enter-button=
"搜索"
size=
"large"
@
search=
"onSearch"
/>
</div>
<Search></Search>
<div
class=
"contentWrap"
>
<div
class=
"top"
>
<div
class=
"menu"
>
<a-tabs
v-model:activeKey=
"activeKey"
centered
>
<a-tab-pane
key=
"1"
tab=
"器械"
>
<ul>
<li
@
click=
"handleGoGoodsList"
><bank-outlined
/>
<span>
单件器械-创伤-钉板
</span></li>
<li><bank-outlined
/>
<span>
单件器械-髓内钉
</span></li>
<li><bank-outlined
/>
<span>
手术动力
</span></li>
<li><bank-outlined
/>
<span>
成套器械
</span></li>
</ul>
</a-tab-pane>
<a-tab-pane
key=
"2"
tab=
"产品"
>
<a-tabs
v-model:activeKey=
"activeTabKey"
centered
>
<a-tab-pane
:key=
"item.id"
:tab=
"item.name"
v-for=
"item in tabList"
>
<ul>
<li><bank-outlined
/>
<span>
单件器械-创伤-钉板
</span></li>
<li><bank-outlined
/>
<span>
单件器械-髓内钉
</span></li>
<li><bank-outlined
/>
<span>
手术动力
</span></li>
<li><bank-outlined
/>
<span>
成套器械
</span></li>
<li
@
click=
"handleGoGoodsList(el.id)"
v-for=
"el in item.children"
><span>
{{
el
.
name
}}
</span></li
>
</ul>
</a-tab-pane>
</a-tabs>
</div>
<dir
class=
"wrap"
>
<div
class=
"nav"
>
<ul>
<template
v-for=
"(item, index) in navList"
>
<li
class=
"title"
:class=
"
{ active: navActiveKey === index }" @click="handleChangeNav(index)">
{{
item
.
title
}}
</li>
<li
v-if=
"index !== 4"
>
|
</li>
</
template
>
</ul>
</div>
<Nav
v-model:navList=
"navList"
v-model:navActiveKey=
"navActiveKey"
/>
<div
class=
"bannerWrap"
>
<div
class=
"banner"
>
<a-carousel
arrows
>
...
...
@@ -133,25 +107,59 @@
</template>
<
script
lang=
"ts"
setup
>
import
{
ref
}
from
'vue'
;
import
{
BankOutlined
,
LeftCircleOutlined
,
RightCircleOutlined
,
UserOutlined
}
from
'@ant-design/icons-vue
'
;
import
{
navList
}
from
'./schema
'
;
import
{
ref
,
onMounted
,
watch
}
from
'vue'
;
import
{
useRoute
}
from
'vue-router
'
;
import
{
LeftCircleOutlined
,
RightCircleOutlined
,
UserOutlined
}
from
'@ant-design/icons-vue
'
;
import
{
useGo
}
from
'/@/hooks/web/usePage'
;
import
Search
from
'../components/search.vue'
;
import
Nav
from
'../components/nav.vue'
;
import
{
toNumber
}
from
'lodash'
;
import
{
useNavTree
}
from
'/@/hooks/myhooks/index'
;
import
{
DataItem
}
from
'/@/views/product/goods-category/type'
;
const
go
=
useGo
();
const
searchInfo
=
ref
(
''
);
const
onSearch
=
()
=>
{};
const
activeKey
=
ref
(
'1'
);
const
navActiveKey
=
ref
(
1
);
const
handleChangeNav
=
(
i
)
=>
{
if
(
i
===
0
)
return
;
navActiveKey
.
value
=
i
;
const
route
=
useRoute
();
const
navTree
=
useNavTree
();
const
navList
=
ref
<
DataItem
[]
>
([]);
// 菜单树
const
navActiveKey
=
ref
();
// 选中的一级菜单id
const
tabList
=
ref
<
DataItem
[]
>
([]);
// 二级菜单树
const
activeTabKey
=
ref
();
// 选中的二级菜单id
const
id
=
route
.
query
.
id
;
// 二次选择一级id
// 初始化选中状态
const
init
=
(
changeId
?:
number
)
=>
{
let
idx
=
0
;
let
findId
=
changeId
?
changeId
:
id
;
if
(
id
||
changeId
)
{
idx
=
navList
.
value
.
findIndex
((
item
)
=>
{
return
item
.
id
===
toNumber
(
findId
);
});
if
(
idx
===
-
1
)
idx
=
0
;
}
if
(
navList
.
value
.
length
>
0
)
{
tabList
.
value
=
navList
.
value
[
idx
]?.
children
;
navActiveKey
.
value
=
navList
.
value
[
idx
]?.
id
;
activeTabKey
.
value
=
navList
.
value
[
idx
]?.
children
[
0
]?.
id
;
}
};
const
handleGoGoodsList
=
()
=>
{
go
(
'/main/store/goods-classify'
);
const
handleGoGoodsList
=
(
id
)
=>
{
go
(
'/main/store/goods-classify'
+
`?nav=
${
navActiveKey
.
value
}
&tab=
${
activeTabKey
.
value
}
&tabItem=
${
id
}
`
);
};
watch
(
()
=>
navActiveKey
.
value
,
(
n
)
=>
{
init
(
n
);
},
);
onMounted
(()
=>
{
navTree
(
navList
,
init
,
'init'
);
});
</
script
>
<
style
lang=
"less"
scoped
>
...
...
@@ -161,10 +169,6 @@
}
.containe {
padding: 30px;
.searchWrap {
width: 500px;
margin: 0 auto 30px;
}
.contentWrap {
padding: 30px;
...
...
@@ -197,31 +201,6 @@
width: 73%;
margin: 0;
padding: 0;
.nav {
background: #f7f9fa;
text-align: center;
border-radius: 10px;
ul {
height: 50px;
padding: 5px;
li {
font-size: 20px;
height: 40px;
line-height: 40px;
display: inline-block;
margin: 0 15px;
}
.active {
color: #1890ff;
}
.title {
cursor: pointer;
}
}
}
.bannerWrap {
width: 100%;
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论