Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
W
wangxiaolu-sfa-ui
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
sfa
wangxiaolu-sfa-ui
Commits
a1ed177c
提交
a1ed177c
authored
4月 23, 2025
作者:
lidongxu
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
feat(mobile/promotion/plan): 促销移动端:批量删除计划功能
同上
上级
53641a5e
隐藏空白字符变更
内嵌
并排
正在显示
9 个修改的文件
包含
284 行增加
和
39 行删除
+284
-39
index.vue
src/components/BackToUp/index.vue
+2
-2
touch.js
src/mobile/directive/touch.js
+38
-0
main.js
src/mobile/main.js
+4
-0
index.vue
src/mobile/views/menu/index.vue
+106
-0
index.vue
src/mobile/views/promotion/plan/detail/index.vue
+4
-0
index.vue
src/mobile/views/promotion/plan/editing/index.vue
+11
-4
index.vue
src/mobile/views/promotion/plan/index/index.vue
+111
-31
index.js
src/router/index.js
+7
-1
user.js
src/store/modules/user.js
+1
-1
没有找到文件。
src/components/BackToUp/index.vue
浏览文件 @
a1ed177c
...
...
@@ -19,8 +19,8 @@ const { x, y } = useWindowScroll({
lang=
"scss"
>
.back-to-top
{
position
:
fixed
;
bottom
:
3
0px
;
right
:
10
px
;
bottom
:
5
0px
;
right
:
24
px
;
z-index
:
999
;
width
:
46px
;
height
:
46px
;
...
...
src/mobile/directive/touch.js
0 → 100644
浏览文件 @
a1ed177c
// 长按手势指令
import
{
ref
}
from
'vue'
;
const
longPressDuration
=
ref
(
500
);
// 长按时间阈值,单位毫秒
let
start
=
null
;
// 记录触摸开始时间
let
cancel
=
null
;
export
default
{
beforeMount
(
el
,
binding
)
{
let
pressTimer
=
null
;
start
=
(
e
)
=>
{
if
(
pressTimer
===
null
)
{
pressTimer
=
setTimeout
(()
=>
{
binding
.
value
();
},
longPressDuration
.
value
);
}
};
cancel
=
(
e
)
=>
{
if
(
pressTimer
!==
null
)
{
clearTimeout
(
pressTimer
);
pressTimer
=
null
;
}
};
el
.
addEventListener
(
'touchstart'
,
start
);
el
.
addEventListener
(
'touchend'
,
cancel
);
el
.
addEventListener
(
'touchcancel'
,
cancel
);
},
unmounted
(
el
)
{
el
.
removeEventListener
(
'touchstart'
,
start
);
el
.
removeEventListener
(
'touchend'
,
cancel
);
el
.
removeEventListener
(
'touchcancel'
,
cancel
);
}
};
\ No newline at end of file
src/mobile/main.js
浏览文件 @
a1ed177c
...
...
@@ -5,6 +5,9 @@ import PickerSearch from './components/PickerSearch'
// 选择日期
import
PickerCalendar
from
'./components/PickerCalendar'
// 指令
import
longPress
from
'./directive/touch'
// 只有在移动端引入
if
(
isMobile
())
{
(
function
()
{
...
...
@@ -25,4 +28,5 @@ if (isMobile()) {
export
default
function
(
app
)
{
app
.
component
(
'PickerSearch'
,
PickerSearch
);
app
.
component
(
'PickerCalendar'
,
PickerCalendar
);
app
.
directive
(
'longPress'
,
longPress
)
}
src/mobile/views/menu/index.vue
0 → 100644
浏览文件 @
a1ed177c
<
template
>
<div
class=
"mobile-container"
>
<div
v-for=
"(module, moduleIndex) in modules"
:key=
"moduleIndex"
class=
"function-module"
>
<p
class=
"function-module-title"
>
{{
module
.
title
}}
</p>
<div
class=
"function-icons"
>
<div
v-for=
"(icon, iconIndex) in module.icons"
:key=
"iconIndex"
class=
"function-icon"
@
click=
"handleIconClick(icon)"
>
<div
class=
"function-icon-wrap"
:style=
"
{ backgroundColor: icon.iconColor }">
<van-icon
:name=
"icon.iconName"
/>
</div>
<p>
{{
icon
.
name
}}
</p>
</div>
</div>
</div>
</div>
</
template
>
<
script
setup
>
const
router
=
useRouter
();
const
modules
=
[
{
title
:
'促销管理'
,
icons
:
[
{
name
:
'促销计划'
,
iconName
:
'shop-o'
,
iconColor
:
'#5aaeec'
,
to
:
'/m/promotion_plan'
},
{
name
:
'稽核'
,
iconName
:
'manager-o'
,
iconColor
:
'#feb73b'
,
to
:
'/m/promotion_plan'
},
]
}
]
const
handleIconClick
=
(
icon
)
=>
{
router
.
push
(
icon
.
to
)
};
</
script
>
<
style
scoped
lang=
"scss"
>
.mobile-container
{
background-color
:
#f3f3f3
;
min-height
:
100%
;
font-size
:
14px
;
padding
:
20px
;
p
{
margin
:
0
;
}
.function-module
{
background-color
:
#fff
;
/* 设置白色背景 */
border-radius
:
8px
;
/* 设置圆角 */
box-shadow
:
0
2px
12px
0
rgba
(
0
,
0
,
0
,
0
.1
);
/* 添加阴影 */
padding
:
16px
;
/* 添加内边距 */
margin-bottom
:
16px
;
/* 设置模块间的间距 */
.function-module-title
{
font-size
:
16px
;
/* 设置标题字体大小 */
font-weight
:
bold
;
/* 设置标题字体加粗 */
margin-bottom
:
16px
;
/* 设置标题与内容的间距 */
}
.function-icons
{
display
:
flex
;
flex-wrap
:
wrap
;
gap
:
16px
;
/* 设置图标间的间距 */
.function-icon
{
width
:
80px
;
text-align
:
center
;
.function-icon-wrap
{
width
:
60px
;
height
:
60px
;
margin
:
0
auto
10px
;
background-color
:
aqua
;
display
:
flex
;
justify-content
:
center
;
align-items
:
center
;
border-radius
:
50%
;
box-shadow
:
0
2px
12px
0
rgba
(
0
,
0
,
0
,
0
.1
);
.van-icon
{
color
:
white
;
font-size
:
35px
;
}
}
}
}
}
}
</
style
>
\ No newline at end of file
src/mobile/views/promotion/plan/detail/index.vue
浏览文件 @
a1ed177c
...
...
@@ -363,6 +363,10 @@ const onChange = (ind) => {
height
:
135
px
;
}
p
{
display
:
block
;
}
}
&
::
-
webkit
-
scrollbar
-
track
{
...
...
src/mobile/views/promotion/plan/editing/index.vue
浏览文件 @
a1ed177c
...
...
@@ -162,8 +162,12 @@
import
{
getPlanStoreListAPI
,
getChargeListAPI
,
addPlanByWebAPI
,
getPlanDetailAPI
,
updatePlanByWebAPI
}
from
'@/api'
import
userStore
from
'@/store/modules/user'
import
{
parseTime
}
from
'@/utils'
const
myForm
=
ref
({})
const
{
proxy
}
=
getCurrentInstance
();
const
employeeNo
=
computed
(()
=>
userStore
().
employeeNo
)
const
employeeName
=
computed
(()
=>
userStore
().
employeeName
)
const
employeeInfo
=
computed
(()
=>
userStore
().
employeeInfo
)
const
isCityManager
=
ref
(
userStore
().
promotionIdentity
)
const
form
=
reactive
({})
const
router
=
useRouter
();
...
...
@@ -208,10 +212,10 @@ const validatorIncidentals = (value, obj) => {
}
}
const
onSubmit
=
async
()
=>
{
const
data
=
userStore
().
employeeInfo
for
(
const
key
in
data
)
{
form
[
key
]
=
data
[
key
]
for
(
let
key
in
employeeInfo
.
value
)
{
form
[
key
]
=
employeeInfo
.
value
[
key
]
}
if
(
planId
)
{
const
res
=
await
updatePlanByWebAPI
(
form
)
proxy
.
$modal
.
msgSuccess
(
res
.
msg
)
...
...
@@ -219,6 +223,7 @@ const onSubmit = async () => {
const
res
=
await
addPlanByWebAPI
(
form
)
proxy
.
$modal
.
msgSuccess
(
res
.
msg
)
}
clickBack
()
}
...
...
@@ -278,7 +283,8 @@ const getBelongList = async () => {
const
res
=
await
getChargeListAPI
()
allBelongList
.
value
=
res
.
data
.
map
(
item
=>
({
text
:
item
.
name
,
value
:
item
.
employeeNo
value
:
item
.
employeeNo
,
id
:
item
.
id
}))
columns
.
value
=
allBelongList
.
value
// 判断如果是城市经理,则设置默认归属人为自己
...
...
@@ -370,6 +376,7 @@ const confirm = (value) => {
const
{
selectedOptions
}
=
value
form
.
employeeName
=
selectedOptions
[
0
]?.
text
form
.
employeeNo
=
selectedOptions
[
0
]?.
value
form
.
employeeId
=
selectedOptions
[
0
]?.
id
}
showPicker
.
value
=
false
}
...
...
src/mobile/views/promotion/plan/index/index.vue
浏览文件 @
a1ed177c
<
template
>
<div
class=
"mobile-container"
>
<van-nav-bar
right-text=
"搜索"
left-
text=
"新增计划"
@
click-left=
"$router.
push('/m/promotion_plan_editing'
)"
left-
arrow
@
click-left=
"$router.
back(
)"
@
click-right=
"showSearch = true"
placeholder
fixed
/>
...
...
@@ -18,9 +18,13 @@
@
load=
"onLoad"
>
<van-cell-group
inset
>
<van-swipe-cell
v-for=
"item in planList"
:key=
"item.id"
>
:key=
"item.id"
v-long-press=
"onLongPress"
>
<van-checkbox
v-show=
"showSelect"
v-model=
"item.checked"
shape=
"square"
/>
<van-cell
:title=
"item.storeName"
:to=
"`/m/promotion_plan_detail/$
{item.id}`
">
@
click=
"clickDetail(item)
"
>
<template
#
label
>
<p
class=
"employee"
>
{{
item
.
employeeName
}}
</p>
<p
:class=
"
{ 'plan-go': item.planStatus === 1 }">
...
...
@@ -32,7 +36,8 @@
<p>
{{
parseTime
(
item
.
date
,
'{y
}
-{m
}
-{d
}
(周{a
}
)'
)
}}
<
/p
>
<
/template
>
<
/van-cell
>
<
template
#
right
>
<
template
#
right
v
-
if
=
"!showSelect"
>
<
van
-
button
square
type
=
"success"
text
=
"编辑"
...
...
@@ -46,13 +51,24 @@
<
/van-cell-group
>
<
/van-list
>
<
/van-pull-refresh
>
<!--
搜索组件
-->
<
PlanSearch
v
-
model
:
show
=
"showSearch"
v
-
model
:
query
=
"query"
:
planColumns
=
"planColumns"
:
allEmpolyeeList
=
"allEmpolyeeList"
@
query
=
"querySearch"
/>
<!--
新增组件(浮动气泡)
-->
<
van
-
floating
-
bubble
icon
=
"plus"
@
click
=
"$router.push('/m/promotion_plan_editing')"
/>
<!--
底部
-
长按操作栏
-->
<
van
-
action
-
bar
v
-
show
=
"showSelect"
>
<
span
@
click
=
"showSelect = false"
>
取消
<
/span
>
<
van
-
action
-
bar
-
button
type
=
"warning"
text
=
"修改归属人"
/>
<
van
-
action
-
bar
-
button
type
=
"danger"
text
=
"删除"
@
click
=
"clickDelSome"
/>
<
/van-action-bar
>
<
/div
>
<
/template
>
...
...
@@ -150,15 +166,19 @@ const onRefresh = () => {
}
,
300
)
}
const
clickDetail
=
(
row
)
=>
{
if
(
showSelect
.
value
)
return
// 当前处于长按状态,点击详情不做任何操作
router
.
push
(
`/m/promotion_plan_detail/${row.id
}
`
)
}
// 搜索表单
const
querySearch
=
()
=>
{
query
.
pageNum
=
1
planList
.
value
=
[]
getPlanList
()
onRefresh
()
}
// 编辑计划
const
editPlan
=
(
row
)
=>
{
console
.
log
(
123
)
if
(
!
checkPlanExpire
(
row
))
{
return
proxy
.
$modal
.
msgWarning
(
'无法编辑,已执行或之前计划'
)
}
...
...
@@ -176,9 +196,8 @@ const deletePlan = (row) => {
employeeNo
:
employeeNo
.
value
}
)
proxy
.
$modal
.
msgSuccess
(
'删除成功'
)
// 找到 row 在数组里第几条删除
const
index
=
planList
.
value
.
findIndex
(
item
=>
item
.
id
===
row
.
id
)
planList
.
value
.
splice
(
index
,
1
)
// 重新获取列表
onRefresh
()
}
)
}
...
...
@@ -187,6 +206,40 @@ const init = async () => {
getPlanList
()
}
init
()
onActivated
(()
=>
{
querySearch
()
}
)
// 长按出现全选功能
const
showSelect
=
ref
(
false
)
const
onLongPress
=
()
=>
{
showSelect
.
value
=
true
}
// 删除全选的计划
const
clickDelSome
=
()
=>
{
const
ids
=
planList
.
value
.
filter
(
item
=>
item
.
checked
).
map
(
item
=>
item
.
id
)
if
(
ids
.
length
===
0
)
{
return
proxy
.
$modal
.
msgWarning
(
'请选择要删除的计划'
)
}
proxy
.
$modal
.
confirm
(
`确认删除${ids.length
}
条计划吗?`
).
then
(
async
()
=>
{
// 循环判断计划是否含有以前和执行中的
for
(
let
i
=
0
;
i
<
ids
.
length
;
i
++
)
{
const
item
=
planList
.
value
.
find
(
o
=>
o
.
id
===
ids
[
i
])
if
(
!
checkPlanExpire
(
item
))
{
return
proxy
.
$modal
.
msgWarning
(
'无法删除,已执行或之前计划'
)
}
}
await
deletePlanAPI
({
planIds
:
ids
,
employeeNo
:
employeeNo
.
value
}
)
proxy
.
$modal
.
msgSuccess
(
'删除成功'
)
showSelect
.
value
=
false
onRefresh
()
}
)
}
<
/script
>
<
style
scoped
...
...
@@ -201,33 +254,60 @@ init()
.
van
-
cell
-
group
{
background
:
#
f5f5f5
;
.
van
-
cell
{
margin
-
top
:
10
px
;
.
van
-
swipe
-
cell
{
/* 阻止长按选文字效果 */
-
webkit
-
user
-
select
:
none
;
-
moz
-
user
-
select
:
none
;
-
ms
-
user
-
select
:
none
;
user
-
select
:
none
;
.
van
-
cell__label
{
font
-
size
:
14
px
!
important
;
}
/* Standard syntax */
::
v
-
deep
(.
van
-
swipe
-
cell__wrapper
)
{
display
:
flex
;
margin
-
top
:
10
px
;
.
employee
{
margin
-
bottom
:
5
px
!
important
;
}
.
van
-
checkbox
{
padding
-
right
:
10
px
;
}
.
plan
-
go
{
color
:
#
39
bb74
;
}
.
van
-
cell
{
p
{
margin
:
0
;
}
}
.
van
-
cell__label
{
font
-
size
:
14
px
!
important
;
}
.
employee
{
margin
-
bottom
:
5
px
!
important
;
}
.
van
-
swipe
-
cell__right
{
display
:
flex
;
.
plan
-
go
{
color
:
#
39
bb74
;
}
button
{
height
:
100
%
;
p
{
margin
:
0
;
}
}
.
van
-
swipe
-
cell__right
{
display
:
flex
;
button
{
height
:
100
%
;
}
}
}
}
}
}
/* 底部菜单 */
.
van
-
action
-
bar
{
span
{
font
-
size
:
14
px
;
padding
:
0
10
px
;
}
}
}
...
...
src/router/index.js
浏览文件 @
a1ed177c
...
...
@@ -95,10 +95,16 @@ export const constantMobileRoutes = [
},
{
path
:
'/m'
,
redirect
:
'/m/
promotion_plan
'
,
redirect
:
'/m/
menu
'
,
component
:
()
=>
import
(
'@/mobile/index'
),
hidden
:
true
,
children
:
[
// 菜单页
{
path
:
'menu'
,
component
:
()
=>
import
(
'@/mobile/views/menu'
),
name
:
'm_menu'
,
},
// 促销计划
{
path
:
'promotion_plan'
,
// 列表
...
...
src/store/modules/user.js
浏览文件 @
a1ed177c
...
...
@@ -98,7 +98,7 @@ export default defineStore(
promotionIdentity
(
state
)
{
return
getPromotionRole
(
state
.
userInfo
.
privilegeId
)
===
CITY_MANAGER
},
//
获取
员工工号,姓名,id
//
操作人
员工工号,姓名,id
employeeInfo
(
state
)
{
return
{
operNo
:
state
.
userInfo
.
userName
,
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论