Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gk
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
micro_app
gk
Commits
706c5c7c
Commit
706c5c7c
authored
Nov 17, 2025
by
daniel
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat(info): 信息收集后台开发
parent
6cdc86e2
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
1837 additions
and
2 deletions
+1837
-2
RoadMapper.xml
.../com/dlbridge/jadp/plugins/cmpt/dao/mapper/RoadMapper.xml
+1
-1
GpsDepositController.java
.../dlbridge/jadp/plugins/cmpt/web/GpsDepositController.java
+35
-0
InformationController.java
...dlbridge/jadp/plugins/cmpt/web/InformationController.java
+35
-0
gpsDeposit.jsp
src/main/webapp/WEB-INF/views/cmpt/gpsDeposit.jsp
+899
-0
information.jsp
src/main/webapp/WEB-INF/views/cmpt/information.jsp
+852
-0
menu.jsp
src/main/webapp/WEB-INF/views/common/menu.jsp
+15
-1
No files found.
src/main/java/com/dlbridge/jadp/plugins/cmpt/dao/mapper/RoadMapper.xml
View file @
706c5c7c
...
...
@@ -11,7 +11,7 @@
, a.id pathId
, a.path_name pathName
, a.create_time createTime
,
a.sort
,
a.sort
from gk_roads_gps a
WHERE 1=1
AND a.is_delete = 0
...
...
src/main/java/com/dlbridge/jadp/plugins/cmpt/web/GpsDepositController.java
0 → 100644
View file @
706c5c7c
package
com
.
dlbridge
.
jadp
.
plugins
.
cmpt
.
web
;
import
com.dlbridge.jadp.common.interceptor.PageView
;
import
com.dlbridge.jadp.plugins.cmpt.dao.model.Cmpt
;
import
com.dlbridge.jadp.plugins.cmpt.service.CmptService
;
import
io.swagger.annotations.Api
;
import
io.swagger.annotations.ApiOperation
;
import
org.springframework.web.bind.annotation.GetMapping
;
import
org.springframework.web.bind.annotation.PathVariable
;
import
org.springframework.web.bind.annotation.RequestMapping
;
import
org.springframework.web.bind.annotation.RestController
;
import
org.springframework.web.servlet.ModelAndView
;
import
javax.annotation.Resource
;
@RestController
@RequestMapping
(
"gk/gpsDeposit"
)
@Api
(
value
=
"GPS押金服务"
,
tags
=
"GPS押金服务"
)
public
class
GpsDepositController
{
@Resource
private
CmptService
cmptService
;
@GetMapping
(
"index/{cmptId}"
)
@PageView
@ApiOperation
(
value
=
"页面路径"
,
notes
=
"页面路径"
)
public
ModelAndView
modulePage
(
@PathVariable
(
"cmptId"
)
Integer
cmptId
,
ModelAndView
mv
)
{
Cmpt
cmpt
=
cmptService
.
queryCmptBycmptId
(
cmptId
);
mv
.
addObject
(
"cmpt"
,
cmpt
);
mv
.
setViewName
(
"cmpt/gpsDeposit"
);
return
mv
;
}
}
src/main/java/com/dlbridge/jadp/plugins/cmpt/web/InformationController.java
0 → 100644
View file @
706c5c7c
package
com
.
dlbridge
.
jadp
.
plugins
.
cmpt
.
web
;
import
com.dlbridge.jadp.common.interceptor.PageView
;
import
com.dlbridge.jadp.plugins.cmpt.dao.model.Cmpt
;
import
com.dlbridge.jadp.plugins.cmpt.service.CmptService
;
import
io.swagger.annotations.Api
;
import
io.swagger.annotations.ApiOperation
;
import
org.springframework.web.bind.annotation.GetMapping
;
import
org.springframework.web.bind.annotation.PathVariable
;
import
org.springframework.web.bind.annotation.RequestMapping
;
import
org.springframework.web.bind.annotation.RestController
;
import
org.springframework.web.servlet.ModelAndView
;
import
javax.annotation.Resource
;
@RestController
@RequestMapping
(
"gk/information"
)
@Api
(
value
=
"信息收集服务"
,
tags
=
"信息收集服务"
)
public
class
InformationController
{
@Resource
private
CmptService
cmptService
;
@GetMapping
(
"index/{cmptId}"
)
@PageView
@ApiOperation
(
value
=
"页面路径"
,
notes
=
"页面路径"
)
public
ModelAndView
modulePage
(
@PathVariable
(
"cmptId"
)
Integer
cmptId
,
ModelAndView
mv
)
{
Cmpt
cmpt
=
cmptService
.
queryCmptBycmptId
(
cmptId
);
mv
.
addObject
(
"cmpt"
,
cmpt
);
mv
.
setViewName
(
"cmpt/information"
);
return
mv
;
}
}
src/main/webapp/WEB-INF/views/cmpt/gpsDeposit.jsp
0 → 100644
View file @
706c5c7c
<%@ page
language=
"java"
contentType=
"text/html; charset=utf-8"
pageEncoding=
"utf-8"
%>
<%@ taglib
prefix=
"c"
uri=
"http://java.sun.com/jsp/jstl/core"
%>
<%@ taglib
prefix=
"form"
uri=
"http://www.springframework.org/tags/form"
%>
<%@ taglib
prefix=
"fmt"
uri=
"http://java.sun.com/jsp/jstl/fmt"
%>
<%@ taglib
prefix=
"fn"
uri=
"http://java.sun.com/jsp/jstl/functions"
%>
<%@ taglib
prefix=
"fns"
uri=
"/WEB-INF/tlds/fns.tld"
%>
<%@ taglib
prefix=
"fnc"
uri=
"/WEB-INF/tlds/fnc.tld"
%>
<c:set
var=
"ctx"
value=
"
${
pageContext
.
request
.
contextPath
}${
fns:
getAdminPath
()
}
"
/>
<c:set
var=
"path"
value=
"
${
pageContext
.
request
.
contextPath
}${
fns:
getPath
()
}
"
/>
<c:set
var=
"jaaproot"
value=
"
${
pageContext
.
request
.
contextPath
}
"
/>
<c:set
var=
"ctxStatic"
value=
"
${
pageContext
.
request
.
contextPath
}
/static"
/>
<!DOCTYPE html>
<html>
<head>
<meta
name=
"viewport"
content=
"width=device-width, initial-scale=1.0"
>
<title>
自助选号
</title>
<!-- ... 保留原有的 Vue 引入 ... -->
<script
src=
"${ctxStatic}/vue/vue.global.min.js"
></script>
<!-- 添加 Naive UI 的引入 -->
<!-- 会使用最新版本,你最好指定一个版本 -->
<script
src=
"${ctxStatic}/navie-ui/index.min.js"
></script>
<!-- <script nomodule
src="https://unpkg.com/ionicons@7.1.0/dist/ionicons/ionicons.js"></script> -->
<script
type=
"module"
src=
"https://unpkg.com/ionicons@7.1.0/dist/ionicons/ionicons.esm.js"
></script>
<script
nomodule
src=
"https://unpkg.com/ionicons@7.1.0/dist/ionicons/ionicons.js"
></script>
<!-- Favicon-->
<link
rel=
"shortcut icon"
href=
"https://img.geexek.com/files/home/favicon.ico"
>
<!-- 自定义css -->
<link
rel=
"stylesheet"
href=
"${ctxStatic}/css/base.css"
>
<!-- Bootstrap CSS-->
<link
rel=
"stylesheet"
href=
"${ctxStatic}/newdermon/vendor/bootstrap/css/bootstrap.min.css"
>
<!-- theme stylesheet-->
<link
rel=
"stylesheet"
href=
"${ctxStatic}/newdermon/css/style.default.css?v=
<%=
System
.
currentTimeMillis
()
%>
"
id=
"theme-stylesheet"
>
<!-- Custom stylesheet - for your changes-->
<link
rel=
"stylesheet"
href=
"${ctxStatic}/newdermon/css/custom.css?v=
<%=
System
.
currentTimeMillis
()
%>
"
>
<!-- Favicon-->
<link
rel=
"shortcut icon"
href=
"https://img.geexek.com/files/home/favicon.ico"
>
<link
rel=
"stylesheet"
href=
"${ctxStatic}/cmpt/setting.css?v=
<%=
System
.
currentTimeMillis
()
%>
"
>
<script
src=
"${ctxStatic}/newdermon/vendor/jquery/jquery.min.js"
></script>
<!-- 引入富文本 -->
<script
src=
"https://enroll.geexek.com/js/ueditor/ueditor.config-zs.js?v=
<%=
System
.
currentTimeMillis
()
%>
"
></script>
<script
src=
"https://enroll.geexek.com/js/ueditor/ueditor.all.js?v=
<%=
System
.
currentTimeMillis
()
%>
"
></script>
<style>
#app
{
padding
:
0
20px
20px
20px
;
}
.layout
{
min-height
:
100vh
;
}
.carousel-img
{
width
:
100%
;
height
:
240px
;
object-fit
:
cover
;
}
[
v-cloak
]
{
display
:
none
;
}
.n-message
.n-message__icon
>*
{
position
:
absolute
;
left
:
0
;
top
:
-5px
!important
;
right
:
0
;
bottom
:
0
;
}
.n-dialog__icon
>*
{
position
:
absolute
;
left
:
0
;
top
:
-2px
!important
;
right
:
0
;
bottom
:
0
;
}
</style>
</head>
<body>
<jsp:include
page=
"../common/header.jsp"
></jsp:include>
<div
class=
"page-content d-flex align-items-stretch main-body"
>
<jsp:include
page=
"../common/menu.jsp"
></jsp:include>
<div
id=
"app"
class=
"flex-1"
v-cloak
>
<n-config-provider
:locale=
"locale"
:date-locale=
"dateLocale"
>
<n-modal-provider>
<n-message-provider>
<n-notification-provider>
<my-app></my-app>
</n-notification-provider>
</n-message-provider>
</n-modal-provider>
</n-config-provider>
</div>
</div>
<script
type=
"text/x-template"
id=
"my-app"
>
<
n
-
space
vertical
>
<!--
顶部的搜索框
-->
<
n
-
card
:
bordered
=
"false"
>
<
div
class
=
"w-full flex flex-row items-center gap-x-2"
>
<
div
style
=
"min-width: 200px"
>
<
n
-
tabs
type
=
"segment"
@
update
:
value
=
"updateTab"
:
value
=
"tabIndex"
animated
pane
-
style
=
"padding:0;"
>
<
n
-
tab
-
pane
v
-
for
=
"item in TabEnum.data"
:
name
=
"item.value"
:
tab
=
"item.name"
/>
<
/n-tabs
>
<
/div
>
<
div
style
=
"min-width: 400px"
v
-
if
=
"!isSetting"
>
<
n
-
tabs
type
=
"segment"
@
update
:
value
=
"updateStatus"
:
value
=
"query.status"
animated
pane
-
style
=
"padding:0;"
>
<
n
-
tab
-
pane
v
-
for
=
"item in OrderStatusOptions"
:
name
=
"item.value"
:
tab
=
"item.name+'('+item.total+')'"
/>
<
/n-tabs
>
<
/div
>
<
div
class
=
"ml-auto"
v
-
if
=
"!isSetting"
>
<
n
-
input
v
-
model
:
value
=
"keyword"
placeholder
=
"请输入关键字进行搜索"
:
clearable
=
"true"
@
change
=
"fetchData"
/>
<
/div
>
<
/div
>
<
div
class
=
"w-full gap-x-2 flex flex-row items-center mt-3"
>
<
div
class
=
"flex-1"
v
-
if
=
"!isSetting"
>
<
n
-
tabs
type
=
"segment"
@
update
:
value
=
"updateStatus"
:
value
=
"query.status"
animated
pane
-
style
=
"padding:0;"
>
<
n
-
tab
-
pane
v
-
for
=
"item in GpsStatusOptions"
:
name
=
"item.value"
:
tab
=
"item.name+'('+item.total+')'"
/>
<
/n-tabs
>
<
/div
>
<
n
-
space
>
<
n
-
button
type
=
"primary"
>
导出未交押金
<
/n-button
>
<
n
-
button
type
=
"primary"
>
导出已交押金
<
/n-button
>
<
n
-
button
>
订单下载
<
/n-button
>
<
n
-
button
>
一键归还
<
/n-button
>
<
n
-
button
v
-
if
=
"checkedRowKeys.length"
type
=
"error"
>
批量退款
<
/n-button
>
<
/n-space
>
<
/div
>
<
/n-card
>
<!--
搜索框
-->
<
n
-
data
-
table
v
-
if
=
"!isSetting"
:
columns
=
"playersColumns"
:
loading
=
"loading"
:
row
-
key
=
"rowKey"
:
data
=
"list"
:
pagination
=
"pagination"
:
bordered
=
"false"
:
remote
=
"true"
@
update
:
checked
-
row
-
keys
=
"handleCheck"
/>
<
n
-
card
v
-
else
title
=
"押金详情"
:
bordered
=
"false"
>
<
n
-
form
ref
=
"depositFormRef"
:
model
=
"depositForm"
:
rules
=
"depositRules"
label
-
placement
=
"left"
label
-
width
=
"auto"
>
<
n
-
form
-
item
label
=
"组别"
path
=
"roadIds"
>
<
n
-
select
v
-
model
:
value
=
"depositForm.roadIds"
multiple
:
options
=
"roadOptions"
/>
<
/n-form-item
>
<
n
-
form
-
item
label
=
"押金金额"
path
=
"money"
>
<
n
-
input
-
number
v
-
model
:
value
=
"depositForm.money"
placeholder
=
"请输入押金金额"
/>
<
/n-form-item
>
<
n
-
form
-
item
label
=
"状态"
>
<
n
-
switch
:
checked
-
value
=
"1"
:
unchecked
-
value
=
"0"
v
-
model
:
value
=
"depositForm.status"
>
<
template
#
checked
>
开启
<
/template
>
<
template
#
unchecked
>
关闭
<
/template
>
<
/n-switch
>
<
/n-form-item
>
<
n
-
form
-
item
label
=
"公告"
>
<
n
-
input
type
=
"textarea"
v
-
model
:
value
=
"depositForm.notice"
placeholder
=
"请输入公告"
/>
<
/n-form-item
>
<
n
-
form
-
item
label
=
"内容"
>
<
div
class
=
"w-full"
id
=
"rich-text-container"
><
/div
>
<
/n-form-item
>
<
/n-form
>
<
template
#
header
-
extra
>
<
n
-
button
class
=
"flex-1"
:
loading
=
"loading"
type
=
'primary'
@
click
=
"onSubmit"
>
保存
<
/n-button
>
<
/template
>
<
/n-card
>
<
n
-
modal
v
-
model
:
show
=
"showModal"
preset
=
"dialog"
title
=
"确认"
content
=
"是否确定开始随机分配?"
positive
-
text
=
"确认"
negative
-
text
=
"取消"
@
positive
-
click
=
"randomAssign"
/>
<
n
-
modal
v
-
model
:
show
=
"showBatchModal"
preset
=
"dialog"
title
=
"批量退款"
content
=
"是否确定对选中的用户进行退款?"
positive
-
text
=
"确认"
negative
-
text
=
"取消"
@
positive
-
click
=
"batchRefund"
/>
<
/n-space
>
</script>
<script>
const
cmpt
=
JSON
.
parse
(
'${fns:toJson(cmpt)}'
);
console
.
log
({
cmpt
})
// 枚举class
class
SuperEnum
{
constructor
(
param
)
{
const
keyObj
=
{};
const
valueObj
=
{};
const
nameObj
=
{};
if
(
!
Array
.
isArray
(
param
))
{
throw
new
TypeError
(
'param is not an array!'
);
}
param
.
forEach
((
element
)
=>
{
if
(
!
element
.
key
||
!
element
.
name
)
{
return
;
}
// 使用对象存储键值对,方便快速查找
keyObj
[
element
.
key
]
=
element
;
valueObj
[
element
.
value
]
=
element
;
nameObj
[
element
.
name
]
=
element
;
// 动态添加属性
this
[
element
.
key
]
=
element
;
this
[
element
.
name
]
=
element
;
if
(
element
.
key
!==
element
.
value
)
{
this
[
element
.
value
]
=
element
;
}
});
// 保存源数组
this
.
data
=
param
;
this
.
keyObj
=
keyObj
;
this
.
valueObj
=
valueObj
;
this
.
nameObj
=
nameObj
;
// 防止被修改
Object
.
freeze
(
this
);
}
getColorByKey
(
key
)
{
const
prop
=
this
.
keyOf
(
key
);
if
(
!
prop
)
{
const
error
=
new
Error
(
'No enum constant'
);
error
.
code
=
'ENUM_NOT_FOUND'
;
throw
error
;
}
return
prop
.
color
;
}
getData
()
{
return
this
.
data
;
}
getKeyByName
(
name
)
{
const
prop
=
this
.
nameOf
(
name
);
if
(
!
prop
)
{
const
error
=
new
Error
(
'No enum constant'
);
error
.
code
=
'ENUM_NOT_FOUND'
;
throw
error
;
}
return
prop
.
key
;
}
getNameByKey
(
key
)
{
const
prop
=
this
.
keyOf
(
key
);
if
(
!
prop
)
{
const
error
=
new
Error
(
'No enum constant'
);
error
.
code
=
'ENUM_NOT_FOUND'
;
throw
error
;
}
return
prop
.
name
;
}
getNameByValue
(
value
)
{
const
prop
=
this
.
valueOf
(
value
);
if
(
!
prop
)
{
const
error
=
new
Error
(
'No enum constant'
);
error
.
code
=
'ENUM_NOT_FOUND'
;
throw
error
;
}
return
prop
.
name
;
}
getValueByKey
(
key
)
{
const
prop
=
this
.
keyOf
(
key
);
if
(
!
prop
)
{
const
error
=
new
Error
(
'No enum constant'
);
error
.
code
=
'ENUM_NOT_FOUND'
;
throw
error
;
}
return
prop
.
value
;
}
getValueByName
(
name
)
{
const
prop
=
this
.
nameOf
(
name
);
if
(
!
prop
)
{
const
error
=
new
Error
(
'No enum constant'
);
error
.
code
=
'ENUM_NOT_FOUND'
;
throw
error
;
}
return
prop
.
value
;
}
keyOf
(
key
)
{
return
this
.
keyObj
[
key
];
}
nameOf
(
name
)
{
return
this
.
nameObj
[
name
];
}
valueOf
(
value
)
{
return
this
.
valueObj
[
value
];
}
}
// to 方法,封装try catch
const
to
=
async
(
promise
,
errorExt
,
)
=>
{
try
{
const
data
=
await
promise
const
result
=
[
null
,
data
]
return
result
}
catch
(
error
)
{
if
(
errorExt
)
{
const
parsedError
=
Object
.
assign
({},
error
,
errorExt
)
return
[
parsedError
,
undefined
]
}
return
[
error
,
undefined
]
}
}
// 状态
const
StatusEnum
=
new
SuperEnum
([
{
key
:
'PICKED'
,
name
:
'已选'
,
color
:
'warning'
,
value
:
1
},
// 增值
{
key
:
'UN_PICKED'
,
name
:
'未选'
,
color
:
'success'
,
value
:
0
},
])
// 自动与手动
const
AutoEnum
=
new
SuperEnum
([
{
key
:
'AUTO'
,
name
:
'自动'
,
color
:
'warning'
,
value
:
1
},
// 增值
{
key
:
'MANUAL'
,
name
:
'手动'
,
color
:
'success'
,
value
:
0
},
])
// tab类型
const
TabEnum
=
new
SuperEnum
([
{
key
:
'SETTING'
,
name
:
'押金配置'
,
color
:
'warning'
,
value
:
1
},
{
key
:
'ORDER'
,
name
:
'订单列表'
,
color
:
'success'
,
value
:
2
},
])
</script>
<script>
const
{
createApp
,
defineComponent
,
reactive
,
ref
,
onMounted
,
h
,
computed
}
=
Vue
;
const
{
useMessage
,
useNotification
,
dateZhCN
,
NButton
,
NTag
,
zhCN
,
NSpace
,
NImageGroup
,
NImage
,
NText
}
=
naive
// 添加全局 loading 指令
const
uploadUrl
=
window
.
location
.
origin
+
'/api-common/v1/upload?folder='
+
'gk/invoice'
+
'&cmptId='
+
getCId
()
const
BASE_ECC_URL
=
"https://ecc.geexek.com"
// 人员列表
const
PLAYERS_URL
=
BASE_ECC_URL
+
'/api-pick/v1/enroll-page'
const
PLAYERS_EXPORT_URL
=
BASE_ECC_URL
+
'/api-pick/v1/export-markno-enroll?cmptId='
+
getCId
()
const
PLAYERS_IMPORT_URL
=
BASE_ECC_URL
+
'/api-pick/v1/import-mark-enroll'
const
PLAYERS_DOWNLOAD_URL
=
"https://geexekimgoss-sxk.oss-cn-hangzhou.aliyuncs.com/gk/common/markNoSelect/%E9%80%89%E5%8F%B7%E5%90%8D%E5%8D%95%E8%A1%A8%E6%A8%A1%E7%89%88v1.xlsx"
// 号码簿列表
const
MARK_NO_URL
=
BASE_ECC_URL
+
'/api-pick/v1/mark-list'
const
MARK_NO_EXPORT_URL
=
BASE_ECC_URL
+
'/api-pick/v1/export-markno-library-v1?cmptId='
+
getCId
()
const
MARK_NO_IMPORT_URL
=
BASE_ECC_URL
+
'/api-pick/v1/import-mark-library'
const
MARK_NO_DOWNLOAD_URL
=
"https://geexekimgoss-sxk.oss-cn-hangzhou.aliyuncs.com/gk/common/markNoSelect/%E5%8F%82%E8%B5%9B%E5%8F%B7%E5%85%A5%E5%BA%93%E6%A8%A1%E7%89%88v1.xlsx"
// 随机分配名单
const
RANDOM_ASSIGN_URL
=
BASE_ECC_URL
+
'/api-pick/v1/pick-up-batch?cmptId='
+
getCId
()
// TODO 保存押金配置
const
SAVE_DEPOSIT_URL
=
""
const
GET_DEPOSIT_URL
=
""
const
MyApp
=
defineComponent
({
name
:
'MyApp'
,
template
:
'#my-app'
,
setup
()
{
const
message
=
useMessage
()
const
notification
=
useNotification
()
const
loading
=
ref
(
false
)
/***----------------选手名单相关 start -----------------*/
const
tabIndex
=
ref
(
1
)
const
isSetting
=
computed
(()
=>
tabIndex
.
value
===
1
)
const
PLAYER
=
"player"
const
MARK_NO
=
"markNo"
// 状态统计
const
OrderStatusOptions
=
ref
([
{
name
:
'全部'
,
value
:
''
,
total
:
0
},
{
name
:
'已支付'
,
value
:
1
,
total
:
0
},
{
name
:
'待支付'
,
value
:
2
,
total
:
0
},
{
name
:
'已退款'
,
value
:
4
,
total
:
0
},
{
name
:
'退款中'
,
value
:
4
,
total
:
0
},
])
const
GpsStatusOptions
=
ref
([
{
name
:
'全部'
,
value
:
''
,
total
:
0
},
{
name
:
'已绑定'
,
value
:
1
,
total
:
0
},
{
name
:
'未绑定'
,
value
:
2
,
total
:
0
},
{
name
:
'已发放'
,
value
:
3
,
total
:
0
},
{
name
:
'未发放'
,
value
:
4
,
total
:
0
},
{
name
:
'已归还'
,
value
:
5
,
total
:
0
},
{
name
:
'未归还'
,
value
:
6
,
total
:
0
}
])
// 勾选的行数据
const
checkedRowKeys
=
ref
([])
// 列表配置
const
playersColumns
=
[
{
type
:
'selection'
,
},
{
title
:
'姓名'
,
key
:
'name'
,
},
{
title
:
'参赛号'
,
key
:
MARK_NO
,
},
{
title
:
'手机号'
,
key
:
'phone'
,
},
{
title
:
'证件号'
,
key
:
'identityNo'
,
},
{
title
:
'操作'
,
key
:
'action'
,
width
:
200
,
fixed
:
'right'
,
align
:
'center'
,
render
:
(
row
)
=>
{
// 两个按钮,一个 编辑 一个 删除
return
h
(
NSpace
,
{},
[
h
(
NButton
,
{
type
:
'error'
,
size
:
'small'
,
onClick
:
async
()
=>
{
}
},
'发放'
),
h
(
NButton
,
{
type
:
'primary'
,
size
:
'small'
,
onClick
:
()
=>
{
}
},
'归还'
),
h
(
NButton
,
{
type
:
'primary'
,
size
:
'small'
,
onClick
:
async
()
=>
{
}
},
'退款'
),
])
}
},
]
// 分页
const
pagination
=
reactive
({
pageSize
:
20
,
page
:
1
,
pageCount
:
0
,
showSizePicker
:
true
,
itemCount
:
0
,
pageSizes
:
[
20
,
50
,
200
,
500
],
prefix
:
(
info
)
=>
"共"
+
info
.
itemCount
+
"条数据"
,
onChange
:
(
page
)
=>
{
pagination
.
page
=
page
fetchData
()
},
onUpdatePageSize
:
(
pageSize
)
=>
{
pagination
.
pageSize
=
pageSize
pagination
.
page
=
1
fetchData
()
}
})
// 查询的参数
const
query
=
reactive
({
keyword
:
undefined
,
isPickUp
:
1
,
markNo
:
undefined
,
})
const
keyword
=
ref
(
''
)
// 删除自助选号
const
showModal
=
ref
(
false
)
const
showBatchModal
=
ref
(
false
)
// 名单列表
const
list
=
ref
([])
/***----------------订单列表 start -----------------*/
function
handleCheck
(
rowKeys
)
{
checkedRowKeys
.
value
=
rowKeys
}
function
rowKey
(
row
)
{
return
row
.
markNo
}
/***----------------订单列表 end -----------------*/
/***----------------押金配置 start -----------------*/
// ref 押金表单
const
depositFormRef
=
ref
()
// 组别选项
const
roadOptions
=
ref
([
{
label
:
'组别一'
,
value
:
'song0'
,
disabled
:
true
},
{
label
:
'组别二'
,
value
:
'song1'
},
{
label
:
'组别三'
,
value
:
'song2'
},
])
// 押金表单
const
depositForm
=
reactive
({
money
:
500
,
// 金额
notice
:
''
,
// 公告
content
:
''
,
// 富文本
status
:
0
,
// 0 关闭,1开启
})
// 押金配置规则
const
depositRules
=
{
money
:
[{
required
:
true
,
message
:
'请输入押金金额'
,
trigger
:
[
'blur'
,
'change'
]
}],
}
// 状态更新
const
updateStatus
=
(
value
)
=>
{
pagination
.
page
=
1
query
.
isPickUp
=
value
fetchData
()
}
// 状态tab
const
updateTab
=
(
value
)
=>
{
tabIndex
.
value
=
value
fetchData
()
}
// 上传完成
const
uploadFinish
=
({
file
,
event
})
=>
{
const
response
=
JSON
.
parse
(
event
?.
target
?.
response
)
file
.
url
=
response
.
content
return
file
}
// 重置form数据
const
resetForm
=
()
=>
{
Object
.
assign
(
formData
,
{
id
:
null
,
remarks
:
null
,
name
:
""
,
markNo
:
""
,
phone
:
""
,
area
:
""
,
province
:
""
,
city
:
""
,
location
:
""
,
deliveryNo
:
""
,
expressCompany
:
""
,
status
:
StatusEnum
.
SUBMIT
.
value
,
remark
:
""
})
}
// 获取自助选号分页列表
const
fetchData
=
async
()
=>
{
list
.
value
=
[]
loading
.
value
=
true
let
params
=
{
...
query
,
current
:
pagination
.
page
,
size
:
pagination
.
pageSize
,
cmptId
:
getCId
(),
keyword
:
keyword
.
value
,
}
// 发起请求
const
[
err
,
res
]
=
await
to
(
fetch
(
PLAYERS_URL
,
{
method
:
"POST"
,
headers
:
{
'Content-Type'
:
'application/json'
},
body
:
JSON
.
stringify
(
params
)
}).
then
(
res
=>
res
.
json
()))
loading
.
value
=
false
if
(
err
)
{
message
.
error
(
err
)
return
}
if
(
res
.
code
===
200
)
{
list
.
value
=
res
.
data
.
records
pagination
.
itemCount
=
res
.
data
.
total
// // 全部状态下不获取统计
getStats
()
}
else
{
message
.
error
(
res
.
message
)
}
}
// 随机分配名单
const
randomAssign
=
async
()
=>
{
loading
.
value
=
true
const
[
err
,
res
]
=
await
to
(
fetch
(
RANDOM_ASSIGN_URL
,
{
method
:
"GET"
,
headers
:
{
'Content-Type'
:
'application/json'
}
}).
then
(
res
=>
res
.
json
()))
loading
.
value
=
false
if
(
err
)
{
message
.
error
(
err
)
return
}
if
(
res
.
code
===
200
)
{
message
.
success
(
'随机分配成功'
)
fetchData
()
}
else
{
message
.
error
(
res
.
message
)
}
}
// 获取统计 用fetch改造
const
getStats
=
async
()
=>
{
loading
.
value
=
true
let
params
=
{
page
:
1
,
size
:
1
,
cmptId
:
getCId
(),
}
let
paramsList
=
[
1
,
0
].
map
(
v
=>
({
...
params
,
isPickUp
:
v
,
}))
const
requests
=
paramsList
.
map
(
v
=>
{
// 发起请求
const
url
=
isSetting
.
value
?
PLAYERS_URL
:
MARK_NO_URL
return
fetch
(
url
,
{
method
:
"POST"
,
headers
:
{
'Content-Type'
:
'application/json'
},
body
:
JSON
.
stringify
(
v
)
}).
then
(
res
=>
res
.
json
())
})
const
res
=
await
Promise
.
all
(
requests
)
loading
.
value
=
false
if
(
isSetting
.
value
)
{
OrderStatusOptions
.
value
[
1
].
total
=
res
[
0
].
data
.
total
OrderStatusOptions
.
value
[
2
].
total
=
res
[
1
].
data
.
total
}
else
{
OrderStatusOptions
.
value
[
1
].
total
=
res
[
0
].
data
.
total
OrderStatusOptions
.
value
[
2
].
total
=
res
[
1
].
data
.
total
}
OrderStatusOptions
.
value
[
0
].
total
=
OrderStatusOptions
.
value
[
2
].
total
+
OrderStatusOptions
.
value
[
1
].
total
}
// 名单导出
const
exportExcel
=
(
type
)
=>
{
const
url
=
type
===
PLAYER
?
PLAYERS_EXPORT_URL
:
MARK_NO_EXPORT_URL
window
.
location
.
href
=
url
}
// 文件上传成功
const
onChange
=
async
(
fileEvent
,
type
)
=>
{
loading
.
value
=
true
const
formData
=
new
FormData
();
formData
.
append
(
'file'
,
fileEvent
.
file
.
file
);
formData
.
append
(
'cmptId'
,
getCId
());
const
url
=
type
===
PLAYER
?
PLAYERS_IMPORT_URL
:
MARK_NO_IMPORT_URL
const
[
err
,
res
]
=
await
to
(
fetch
(
url
,
{
method
:
"POST"
,
body
:
formData
}).
then
(
res
=>
res
.
json
()))
loading
.
value
=
false
if
(
err
)
{
message
.
error
(
err
)
return
}
fileList
.
value
=
[]
if
(
res
.
code
===
200
)
{
message
.
success
(
'导入成功'
)
fetchData
()
}
else
{
message
.
error
(
res
.
message
)
}
}
// 导出
const
download
=
(
type
)
=>
{
const
url
=
type
===
PLAYER
?
PLAYERS_DOWNLOAD_URL
:
MARK_NO_DOWNLOAD_URL
window
.
location
.
href
=
url
}
// 富文本编辑器 .setContent() .getContent()
let
editor
;
/***---------------- 自助选号相关 end -----------------*/
/***---------------- 押金交互相关 start -----------------*/
// todo 保存押金配置
const
saveDeposit
=
()
=>
{
depositFormRef
.
value
?.
validate
(
async
(
errors
)
=>
{
if
(
errors
)
return
message
.
error
(
'请检查表单是否填写完整'
)
loading
.
value
=
true
const
[
err
,
res
]
=
await
to
(
fetch
(
SAVE_DEPOSIT_URL
,
{
method
:
"POST"
,
headers
:
{
'Content-Type'
:
'application/json'
},
body
:
JSON
.
stringify
(
depositForm
.
value
)
}).
then
(
res
=>
res
.
json
()))
loading
.
value
=
false
if
(
err
)
{
message
.
error
(
err
)
return
}
if
(
res
.
code
===
200
)
{
message
.
success
(
'保存成功'
)
fetchData
()
getDeposit
()
}
else
{
message
.
error
(
res
.
message
)
}
})
}
// todo 获取押金配置
const
getDeposit
=
async
()
=>
{
loading
.
value
=
true
const
[
err
,
res
]
=
await
to
(
fetch
(
GET_DEPOSIT_URL
,
{
method
:
"GET"
,
headers
:
{
'Content-Type'
:
'application/json'
}
}).
then
(
res
=>
res
.
json
()))
loading
.
value
=
false
if
(
err
)
{
message
.
error
(
err
)
return
}
if
(
res
.
code
===
200
)
{
depositForm
.
value
=
res
.
data
editor
.
setContent
(
res
.
data
.
content
)
}
else
{
message
.
error
(
res
.
message
)
}
}
// todo 批量退款
const
batchRefund
=
()
=>
{
}
// todo 触发批量退款
const
onBatchRefund
=
()
=>
{
showBatchModal
.
value
=
true
}
/***---------------- 押金交互相关 end -----------------*/
onMounted
(()
=>
{
fetchData
()
editor
=
UE
.
getEditor
(
'rich-text-container'
);
})
return
{
// 自助选号相关
updateStatus
,
updateTab
,
list
,
query
,
pagination
,
playersColumns
,
isSetting
,
showModal
,
showBatchModal
,
handleCheck
,
checkedRowKeys
,
// 文件相关
keyword
,
fetchData
,
tabIndex
,
randomAssign
,
// 公共数据
loading
,
StatusEnum
,
TabEnum
,
OrderStatusOptions
,
GpsStatusOptions
,
// 名单导出
exportExcel
,
download
,
uploadFinish
,
onChange
,
PLAYER
,
MARK_NO
,
// 押金相关
depositForm
,
depositRules
,
roadOptions
,
saveDeposit
,
getDeposit
,
batchRefund
,
depositFormRef
,
}
}
})
const
app
=
Vue
.
createApp
({
setup
()
{
return
{
locale
:
zhCN
,
dateLocale
:
dateZhCN
}
}
})
app
.
component
(
'my-app'
,
MyApp
)
app
.
use
(
naive
)
app
.
mount
(
'#app'
)
</script>
</body>
</html>
\ No newline at end of file
src/main/webapp/WEB-INF/views/cmpt/information.jsp
0 → 100644
View file @
706c5c7c
<%@ page
language=
"java"
contentType=
"text/html; charset=utf-8"
pageEncoding=
"utf-8"
%>
<%@ taglib
prefix=
"c"
uri=
"http://java.sun.com/jsp/jstl/core"
%>
<%@ taglib
prefix=
"form"
uri=
"http://www.springframework.org/tags/form"
%>
<%@ taglib
prefix=
"fmt"
uri=
"http://java.sun.com/jsp/jstl/fmt"
%>
<%@ taglib
prefix=
"fn"
uri=
"http://java.sun.com/jsp/jstl/functions"
%>
<%@ taglib
prefix=
"fns"
uri=
"/WEB-INF/tlds/fns.tld"
%>
<%@ taglib
prefix=
"fnc"
uri=
"/WEB-INF/tlds/fnc.tld"
%>
<c:set
var=
"ctx"
value=
"
${
pageContext
.
request
.
contextPath
}${
fns:
getAdminPath
()
}
"
/>
<c:set
var=
"path"
value=
"
${
pageContext
.
request
.
contextPath
}${
fns:
getPath
()
}
"
/>
<c:set
var=
"jaaproot"
value=
"
${
pageContext
.
request
.
contextPath
}
"
/>
<c:set
var=
"ctxStatic"
value=
"
${
pageContext
.
request
.
contextPath
}
/static"
/>
<!DOCTYPE html>
<html>
<head>
<meta
name=
"viewport"
content=
"width=device-width, initial-scale=1.0"
>
<title>
信息收集
</title>
<!-- ... 保留原有的 Vue 引入 ... -->
<script
src=
"${ctxStatic}/vue/vue.global.min.js"
></script>
<!-- 添加 Naive UI 的引入 -->
<!-- 会使用最新版本,你最好指定一个版本 -->
<script
src=
"${ctxStatic}/navie-ui/index.min.js"
></script>
<!-- <script nomodule
src="https://unpkg.com/ionicons@7.1.0/dist/ionicons/ionicons.js"></script> -->
<script
type=
"module"
src=
"https://unpkg.com/ionicons@7.1.0/dist/ionicons/ionicons.esm.js"
></script>
<script
nomodule
src=
"https://unpkg.com/ionicons@7.1.0/dist/ionicons/ionicons.js"
></script>
<!-- Favicon-->
<link
rel=
"shortcut icon"
href=
"https://img.geexek.com/files/home/favicon.ico"
>
<!-- 自定义css -->
<link
rel=
"stylesheet"
href=
"${ctxStatic}/css/base.css"
>
<!-- Bootstrap CSS-->
<link
rel=
"stylesheet"
href=
"${ctxStatic}/newdermon/vendor/bootstrap/css/bootstrap.min.css"
>
<!-- theme stylesheet-->
<link
rel=
"stylesheet"
href=
"${ctxStatic}/newdermon/css/style.default.css?v=
<%=
System
.
currentTimeMillis
()
%>
"
id=
"theme-stylesheet"
>
<!-- Custom stylesheet - for your changes-->
<link
rel=
"stylesheet"
href=
"${ctxStatic}/newdermon/css/custom.css?v=
<%=
System
.
currentTimeMillis
()
%>
"
>
<!-- Favicon-->
<link
rel=
"shortcut icon"
href=
"https://img.geexek.com/files/home/favicon.ico"
>
<link
rel=
"stylesheet"
href=
"${ctxStatic}/cmpt/setting.css?v=
<%=
System
.
currentTimeMillis
()
%>
"
>
<script
src=
"${ctxStatic}/newdermon/vendor/jquery/jquery.min.js"
></script>
<style>
#app
{
padding
:
0
20px
20px
20px
;
}
.layout
{
min-height
:
100vh
;
}
.carousel-img
{
width
:
100%
;
height
:
240px
;
object-fit
:
cover
;
}
[
v-cloak
]
{
display
:
none
;
}
.n-message
.n-message__icon
>*
{
position
:
absolute
;
left
:
0
;
top
:
-5px
!important
;
right
:
0
;
bottom
:
0
;
}
.n-dialog__icon
>*
{
position
:
absolute
;
left
:
0
;
top
:
-2px
!important
;
right
:
0
;
bottom
:
0
;
}
</style>
</head>
<body>
<jsp:include
page=
"../common/header.jsp"
></jsp:include>
<div
class=
"page-content d-flex align-items-stretch main-body"
>
<jsp:include
page=
"../common/menu.jsp"
></jsp:include>
<div
id=
"app"
class=
"flex-1"
v-cloak
>
<n-config-provider
:locale=
"locale"
:date-locale=
"dateLocale"
>
<n-modal-provider>
<n-message-provider>
<n-notification-provider>
<my-app></my-app>
</n-notification-provider>
</n-message-provider>
</n-modal-provider>
</n-config-provider>
</div>
</div>
<script
type=
"text/x-template"
id=
"my-app"
>
<
n
-
space
vertical
>
<
n
-
card
:
bordered
=
"false"
>
<
div
class
=
"w-full flex flex-row items-center gap-x-2"
>
<
div
style
=
"min-width: 200px"
>
<
n
-
tabs
type
=
"segment"
@
update
:
value
=
"updateTab"
:
value
=
"tabIndex"
animated
pane
-
style
=
"padding:0;"
>
<
n
-
tab
-
pane
v
-
for
=
"item in TabEnum.data"
:
name
=
"item.value"
:
tab
=
"item.name"
/>
<
/n-tabs
>
<
/div
>
<
div
class
=
"ml-auto"
v
-
if
=
"!isSetting"
>
<
n
-
input
v
-
model
:
value
=
"keyword"
placeholder
=
"请输入关键字进行搜索"
:
clearable
=
"true"
@
change
=
"fetchData"
/>
<
/div
>
<
/div
>
<
div
class
=
"w-full gap-x-2 flex flex-row items-center mt-3"
>
<
div
class
=
"flex-1"
v
-
if
=
"!isSetting"
>
<
/div
>
<
n
-
space
>
<
n
-
button
v
-
if
=
"checkedRowKeys.length"
type
=
"error"
>
批量操作
<
/n-button
>
<
/n-space
>
<
/div
>
<
/n-card
>
<!--
信息收集列表
-->
<
n
-
data
-
table
v
-
if
=
"!isSetting"
:
columns
=
"playersColumns"
:
loading
=
"loading"
:
row
-
key
=
"rowKey"
:
data
=
"list"
:
pagination
=
"pagination"
:
bordered
=
"false"
:
remote
=
"true"
@
update
:
checked
-
row
-
keys
=
"handleCheck"
/>
<!--
信息收集字段配置
-->
<
n
-
card
v
-
if
=
"isSetting"
title
=
"信息收集字段配置"
:
bordered
=
"false"
>
<
n
-
form
ref
=
"configFormRef"
:
model
=
"configs"
:
rules
=
"configRules"
label
-
placement
=
"left"
label
-
width
=
"auto"
>
<
n
-
form
-
item
label
=
"状态"
>
<
n
-
switch
:
checked
-
value
=
"1"
:
unchecked
-
value
=
"0"
v
-
model
:
value
=
"configs.status"
>
<
template
#
checked
>
开启
<
/template
>
<
template
#
unchecked
>
关闭
<
/template
>
<
/n-switch
>
<
/n-form-item
>
<
n
-
form
-
item
label
=
"审核"
>
<
n
-
switch
:
checked
-
value
=
"1"
:
unchecked
-
value
=
"0"
v
-
model
:
value
=
"configs.audit"
>
<
template
#
checked
>
开启
<
/template
>
<
template
#
unchecked
>
关闭
<
/template
>
<
/n-switch
>
<
/n-form-item
>
<
n
-
form
-
item
label
=
"描述"
>
<
n
-
input
type
=
"textarea"
v
-
model
:
value
=
"configs.description"
placeholder
=
"请输入描述信息"
/>
<
/n-form-item
>
<
n
-
form
-
item
label
=
"开始时间"
path
=
"startTime"
>
<
n
-
date
-
picker
value
-
format
=
"yyyy-MM-dd HH:mm:ss"
date
-
format
=
"yyyy-MM-dd HH:mm:ss"
:
value
=
"configs.startTime"
type
=
"datetime"
clearable
@
update
:
formatted
-
value
=
"updateStartTime"
/>
<
/n-form-item
>
<
n
-
form
-
item
label
=
"结束时间"
path
=
"endTime"
>
<
n
-
date
-
picker
value
-
format
=
"yyyy-MM-dd HH:mm:ss"
date
-
format
=
"yyyy-MM-dd HH:mm:ss"
:
value
=
"configs.endTime"
type
=
"datetime"
clearable
@
update
:
formatted
-
value
=
"updateEndTime"
/>
<
/n-form-item
>
<
/n-form
>
<
/n-card
>
<!--
可配置字段
-->
<
n
-
card
title
=
"可配置字段"
:
bordered
=
"false"
v
-
if
=
"isSetting"
>
<
div
class
=
"w-full gap-2 flex flex-row items-center flex-wrap"
>
<
n
-
tag
@
click
=
"addField(item.key)"
v
-
for
=
"item in enableFields"
:
key
=
"item.key"
type
=
"primary"
>
{{
item
.
name
}}
<
/n-tag
>
<
/div
>
<
/n-card
>
<!--
字段规则
-->
<
n
-
card
title
=
"字段规则"
:
bordered
=
"false"
v
-
if
=
"isSetting"
>
<
n
-
data
-
table
size
=
"small"
:
columns
=
"fieldColumns"
:
loading
=
"loading"
:
data
=
"configs.fields"
:
pagination
=
"false"
:
bordered
=
"true"
/>
<
/n-card
>
<!--
操作按钮
-->
<
div
class
=
"flex flex-row items-center gap-x-2 w-full"
v
-
if
=
"isSetting"
>
<
n
-
button
:
disabled
=
"loading"
:
loading
=
"loading"
:
block
=
"true"
@
click
=
"onSubmit"
type
=
"primary"
>
保存
<
/n-button
>
<
/div
>
<
/n-space
>
</script>
<script>
const
cmpt
=
JSON
.
parse
(
'${fns:toJson(cmpt)}'
);
// 枚举class
class
SuperEnum
{
constructor
(
param
)
{
const
keyObj
=
{};
const
valueObj
=
{};
const
nameObj
=
{};
if
(
!
Array
.
isArray
(
param
))
{
throw
new
TypeError
(
'param is not an array!'
);
}
param
.
forEach
((
element
)
=>
{
if
(
!
element
.
key
||
!
element
.
name
)
{
return
;
}
// 使用对象存储键值对,方便快速查找
keyObj
[
element
.
key
]
=
element
;
valueObj
[
element
.
value
]
=
element
;
nameObj
[
element
.
name
]
=
element
;
// 动态添加属性
this
[
element
.
key
]
=
element
;
this
[
element
.
name
]
=
element
;
if
(
element
.
key
!==
element
.
value
)
{
this
[
element
.
value
]
=
element
;
}
});
// 保存源数组
this
.
data
=
param
;
this
.
keyObj
=
keyObj
;
this
.
valueObj
=
valueObj
;
this
.
nameObj
=
nameObj
;
// 防止被修改
Object
.
freeze
(
this
);
}
getColorByKey
(
key
)
{
const
prop
=
this
.
keyOf
(
key
);
if
(
!
prop
)
{
const
error
=
new
Error
(
'No enum constant'
);
error
.
code
=
'ENUM_NOT_FOUND'
;
throw
error
;
}
return
prop
.
color
;
}
getData
()
{
return
this
.
data
;
}
getKeyByName
(
name
)
{
const
prop
=
this
.
nameOf
(
name
);
if
(
!
prop
)
{
const
error
=
new
Error
(
'No enum constant'
);
error
.
code
=
'ENUM_NOT_FOUND'
;
throw
error
;
}
return
prop
.
key
;
}
getNameByKey
(
key
)
{
const
prop
=
this
.
keyOf
(
key
);
if
(
!
prop
)
{
const
error
=
new
Error
(
'No enum constant'
);
error
.
code
=
'ENUM_NOT_FOUND'
;
throw
error
;
}
return
prop
.
name
;
}
getNameByValue
(
value
)
{
const
prop
=
this
.
valueOf
(
value
);
if
(
!
prop
)
{
const
error
=
new
Error
(
'No enum constant'
);
error
.
code
=
'ENUM_NOT_FOUND'
;
throw
error
;
}
return
prop
.
name
;
}
getValueByKey
(
key
)
{
const
prop
=
this
.
keyOf
(
key
);
if
(
!
prop
)
{
const
error
=
new
Error
(
'No enum constant'
);
error
.
code
=
'ENUM_NOT_FOUND'
;
throw
error
;
}
return
prop
.
value
;
}
getValueByName
(
name
)
{
const
prop
=
this
.
nameOf
(
name
);
if
(
!
prop
)
{
const
error
=
new
Error
(
'No enum constant'
);
error
.
code
=
'ENUM_NOT_FOUND'
;
throw
error
;
}
return
prop
.
value
;
}
keyOf
(
key
)
{
return
this
.
keyObj
[
key
];
}
nameOf
(
name
)
{
return
this
.
nameObj
[
name
];
}
valueOf
(
value
)
{
return
this
.
valueObj
[
value
];
}
}
// to 方法,封装try catch
const
to
=
async
(
promise
,
errorExt
,
)
=>
{
try
{
const
data
=
await
promise
const
result
=
[
null
,
data
]
return
result
}
catch
(
error
)
{
if
(
errorExt
)
{
const
parsedError
=
Object
.
assign
({},
error
,
errorExt
)
return
[
parsedError
,
undefined
]
}
return
[
error
,
undefined
]
}
}
// tab类型
const
TabEnum
=
new
SuperEnum
([
{
key
:
'SETTING'
,
name
:
'字段配置'
,
color
:
'warning'
,
value
:
1
},
{
key
:
'ORDER'
,
name
:
'信息列表'
,
color
:
'success'
,
value
:
2
},
])
// 配置固定项
const
fieldConfigs
=
[
{
key
:
"name"
,
name
:
"姓名"
,
type
:
"text"
,
required
:
true
,
disabled
:
false
,
editable
:
true
,
placeholder
:
"请输入姓名"
,
},
{
key
:
"phone"
,
name
:
"手机号"
,
type
:
"text"
,
required
:
true
,
disabled
:
false
,
editable
:
true
,
placeholder
:
"请输入手机号"
,
},
{
key
:
"email"
,
name
:
"邮箱"
,
type
:
"text"
,
required
:
true
,
disabled
:
false
,
editable
:
true
,
placeholder
:
"请输入邮箱"
,
},
{
key
:
"idCard"
,
name
:
"身份证号"
,
type
:
"text"
,
required
:
true
,
disabled
:
false
,
editable
:
true
,
placeholder
:
"请输入身份证号"
,
},
{
key
:
"avatar"
,
name
:
"头像"
,
type
:
"image"
,
required
:
true
,
disabled
:
false
,
editable
:
true
,
placeholder
:
"请上传头像"
,
},
// 备用项
{
key
:
"remark1"
,
name
:
"自定义一"
,
type
:
"image"
,
required
:
true
,
disabled
:
false
,
editable
:
true
,
placeholder
:
"请输入自定义描述文字"
,
},
]
</script>
<script>
const
{
createApp
,
defineComponent
,
reactive
,
ref
,
onMounted
,
h
,
computed
}
=
Vue
;
const
{
useMessage
,
useNotification
,
dateZhCN
,
NButton
,
NTag
,
zhCN
,
NSpace
,
NImageGroup
,
NImage
,
NInput
,
NSelect
,
NCheckbox
,
NText
}
=
naive
// 添加全局 loading 指令
const
uploadUrl
=
window
.
location
.
origin
+
'/api-common/v1/upload?folder='
+
'gk/invoice'
+
'&cmptId='
+
getCId
()
const
BASE_ECC_URL
=
"https://ecc.geexek.com"
// 人员列表
const
PLAYERS_URL
=
BASE_ECC_URL
+
'/api-pick/v1/enroll-page'
const
PLAYERS_EXPORT_URL
=
BASE_ECC_URL
+
'/api-pick/v1/export-markno-enroll?cmptId='
+
getCId
()
const
PLAYERS_IMPORT_URL
=
BASE_ECC_URL
+
'/api-pick/v1/import-mark-enroll'
const
PLAYERS_DOWNLOAD_URL
=
"https://geexekimgoss-sxk.oss-cn-hangzhou.aliyuncs.com/gk/common/markNoSelect/%E9%80%89%E5%8F%B7%E5%90%8D%E5%8D%95%E8%A1%A8%E6%A8%A1%E7%89%88v1.xlsx"
// 号码簿列表
const
MARK_NO_URL
=
BASE_ECC_URL
+
'/api-pick/v1/mark-list'
const
MARK_NO_EXPORT_URL
=
BASE_ECC_URL
+
'/api-pick/v1/export-markno-library-v1?cmptId='
+
getCId
()
const
MARK_NO_IMPORT_URL
=
BASE_ECC_URL
+
'/api-pick/v1/import-mark-library'
const
MARK_NO_DOWNLOAD_URL
=
"https://geexekimgoss-sxk.oss-cn-hangzhou.aliyuncs.com/gk/common/markNoSelect/%E5%8F%82%E8%B5%9B%E5%8F%B7%E5%85%A5%E5%BA%93%E6%A8%A1%E7%89%88v1.xlsx"
// 随机分配名单
const
RANDOM_ASSIGN_URL
=
BASE_ECC_URL
+
'/api-pick/v1/pick-up-batch?cmptId='
+
getCId
()
// TODO 保存信息收集配置
const
SAVE_INFORMATION_URL
=
""
const
GET_CONFIG_URL
=
""
const
MyApp
=
defineComponent
({
name
:
'MyApp'
,
template
:
'#my-app'
,
setup
()
{
const
message
=
useMessage
()
const
notification
=
useNotification
()
const
loading
=
ref
(
false
)
/***----------------选手名单相关 start -----------------*/
const
tabIndex
=
ref
(
1
)
const
isSetting
=
computed
(()
=>
tabIndex
.
value
===
1
)
const
PLAYER
=
"player"
const
MARK_NO
=
"markNo"
/***---------------- 信息收集字段配置 start -----------------*/
const
enableFields
=
computed
(()
=>
fieldConfigs
.
filter
(
item
=>
!
configs
.
value
.
fields
.
map
(
v
=>
v
.
key
).
includes
(
item
.
key
)))
// 配置项
const
configs
=
ref
({
status
:
1
,
// 是否开启
audit
:
0
,
// 是否审核
cmptId
:
getCId
(),
title
:
"信息收集的标题"
,
startTime
:
undefined
,
endTime
:
undefined
,
description
:
"信息收集的描述"
,
fields
:
[
{
key
:
"name"
,
name
:
"姓名"
,
type
:
"text"
,
required
:
true
,
disabled
:
false
,
editable
:
true
,
placeholder
:
"请输入姓名"
,
},
],
})
// 字段列
const
fieldColumns
=
[
{
title
:
'字段名称'
,
key
:
'name'
,
align
:
'center'
,
render
(
row
,
index
)
{
return
h
(
NInput
,
{
value
:
row
.
name
,
disabled
:
!
configs
.
value
.
fields
[
index
].
key
.
includes
(
'remark'
),
onUpdateValue
(
v
)
{
configs
.
value
.
fields
[
index
].
key
=
v
}
})
}
},
{
title
:
'字段名称'
,
key
:
'key'
,
align
:
'center'
,
render
(
row
,
index
)
{
return
h
(
NInput
,
{
value
:
row
.
key
,
disabled
:
!
configs
.
value
.
fields
[
index
].
key
.
includes
(
'remark'
),
onUpdateValue
(
v
)
{
configs
.
value
.
fields
[
index
].
name
=
v
}
})
}
},
{
title
:
'字段描述'
,
key
:
'placeholder'
,
align
:
'center'
,
render
(
row
,
index
)
{
return
h
(
NInput
,
{
value
:
row
.
placeholder
,
onUpdateValue
(
v
)
{
configs
.
value
.
fields
[
index
].
placeholder
=
v
}
})
}
},
{
title
:
'类型'
,
key
:
'type'
,
// 文本,日期,文件,图片
align
:
'center'
,
render
(
row
,
index
)
{
return
h
(
NSelect
,
{
value
:
row
.
type
,
options
:
[
{
label
:
'文本'
,
value
:
'text'
},
{
label
:
'日期'
,
value
:
'date'
},
{
label
:
'文件'
,
value
:
'file'
},
{
label
:
'图片'
,
value
:
'image'
},
],
onUpdateValue
(
v
)
{
configs
.
value
.
fields
[
index
].
type
=
v
}
})
}
},
{
title
:
'是否必填'
,
key
:
'required'
,
align
:
'center'
,
width
:
100
,
render
(
row
,
index
)
{
return
h
(
NCheckbox
,
{
checked
:
row
.
required
,
onUpdateChecked
(
v
)
{
configs
.
value
.
fields
[
index
].
required
=
v
}
})
}
},
{
title
:
'是否禁用'
,
key
:
'disabled'
,
align
:
'center'
,
width
:
100
,
render
(
row
,
index
)
{
return
h
(
NCheckbox
,
{
checked
:
row
.
disabled
,
onUpdateChecked
(
v
)
{
configs
.
value
.
fields
[
index
].
disabled
=
v
}
})
}
},
{
title
:
'是否可编辑'
,
key
:
'editable'
,
align
:
'center'
,
width
:
100
,
render
(
row
,
index
)
{
return
h
(
NCheckbox
,
{
checked
:
row
.
editable
,
onUpdateChecked
(
v
)
{
configs
.
value
.
fields
[
index
].
editable
=
v
}
})
}
},
{
title
:
'操作'
,
key
:
'actions'
,
width
:
50
,
align
:
'center'
,
render
:
(
row
,
index
)
=>
{
return
h
(
NButton
,
{
type
:
'error'
,
size
:
'small'
,
onClick
:
async
()
=>
{
configs
.
value
.
fields
.
splice
(
index
,
1
)
}
},
'移除'
)
}
}
]
// ref 信息收集表单
const
configFormRef
=
ref
()
// 信息收集配置规则
const
configRules
=
{
title
:
[{
required
:
true
,
message
:
'请输入标题'
,
trigger
:
[
'blur'
,
'change'
]
}],
}
// 勾选的行数据
const
checkedRowKeys
=
ref
([])
// 列表配置
const
playersColumns
=
[
{
type
:
'selection'
,
},
{
title
:
'姓名'
,
key
:
'name'
,
},
{
title
:
'参赛号'
,
key
:
MARK_NO
,
},
{
title
:
'手机号'
,
key
:
'phone'
,
},
{
title
:
'证件号'
,
key
:
'identityNo'
,
},
{
title
:
'操作'
,
key
:
'action'
,
width
:
200
,
fixed
:
'right'
,
align
:
'center'
,
render
:
(
row
)
=>
{
// 两个按钮,一个 编辑 一个 删除
return
h
(
NSpace
,
{},
[
h
(
NButton
,
{
type
:
'error'
,
size
:
'small'
,
onClick
:
async
()
=>
{
}
},
'发放'
),
h
(
NButton
,
{
type
:
'primary'
,
size
:
'small'
,
onClick
:
()
=>
{
}
},
'归还'
),
h
(
NButton
,
{
type
:
'primary'
,
size
:
'small'
,
onClick
:
async
()
=>
{
}
},
'退款'
),
])
}
},
]
// 分页
const
pagination
=
reactive
({
pageSize
:
20
,
page
:
1
,
pageCount
:
0
,
showSizePicker
:
true
,
itemCount
:
0
,
pageSizes
:
[
20
,
50
,
200
,
500
],
prefix
:
(
info
)
=>
"共"
+
info
.
itemCount
+
"条数据"
,
onChange
:
(
page
)
=>
{
pagination
.
page
=
page
fetchData
()
},
onUpdatePageSize
:
(
pageSize
)
=>
{
pagination
.
pageSize
=
pageSize
pagination
.
page
=
1
fetchData
()
}
})
// 查询的参数
const
query
=
reactive
({
keyword
:
undefined
,
isPickUp
:
1
,
markNo
:
undefined
,
})
const
keyword
=
ref
(
''
)
// 名单列表
const
list
=
ref
([])
/***----------------信息列表 start -----------------*/
function
handleCheck
(
rowKeys
)
{
checkedRowKeys
.
value
=
rowKeys
}
function
rowKey
(
row
)
{
return
row
.
markNo
}
/***----------------信息列表 end -----------------*/
/***----------------表单配置 start -----------------*/
// 日期处理
const
updateStartTime
=
(
val
)
=>
{
configs
.
value
.
startTime
=
val
}
// 日期处理
const
updateEndTime
=
(
val
)
=>
{
configs
.
value
.
endTime
=
val
}
// 状态tab
const
updateTab
=
(
value
)
=>
{
tabIndex
.
value
=
value
fetchData
()
}
// 获取自助选号分页列表
const
fetchData
=
async
()
=>
{
list
.
value
=
[]
loading
.
value
=
true
let
params
=
{
...
query
,
current
:
pagination
.
page
,
size
:
pagination
.
pageSize
,
cmptId
:
getCId
(),
keyword
:
keyword
.
value
,
}
// 发起请求
const
[
err
,
res
]
=
await
to
(
fetch
(
PLAYERS_URL
,
{
method
:
"POST"
,
headers
:
{
'Content-Type'
:
'application/json'
},
body
:
JSON
.
stringify
(
params
)
}).
then
(
res
=>
res
.
json
()))
loading
.
value
=
false
if
(
err
)
{
message
.
error
(
err
)
return
}
if
(
res
.
code
===
200
)
{
list
.
value
=
res
.
data
.
records
pagination
.
itemCount
=
res
.
data
.
total
// // 全部状态下不获取统计
}
else
{
message
.
error
(
res
.
message
)
}
}
/***---------------- 自助选号相关 end -----------------*/
/***---------------- 信息收集交互相关 start -----------------*/
// todo 保存信息收集配置
const
saveConfig
=
()
=>
{
configFormRef
.
value
?.
validate
(
async
(
errors
)
=>
{
if
(
errors
)
return
message
.
error
(
'请检查表单是否填写完整'
)
loading
.
value
=
true
const
[
err
,
res
]
=
await
to
(
fetch
(
SAVE_INFORMATION_URL
,
{
method
:
"POST"
,
headers
:
{
'Content-Type'
:
'application/json'
},
body
:
JSON
.
stringify
(
configs
.
value
)
}).
then
(
res
=>
res
.
json
()))
loading
.
value
=
false
if
(
err
)
{
message
.
error
(
err
)
return
}
if
(
res
.
code
===
200
)
{
message
.
success
(
'保存成功'
)
fetchData
()
getConfig
()
}
else
{
message
.
error
(
res
.
message
)
}
})
}
// todo 获取信息收集配置
const
getConfig
=
async
()
=>
{
loading
.
value
=
true
const
[
err
,
res
]
=
await
to
(
fetch
(
GET_CONFIG_URL
,
{
method
:
"GET"
,
headers
:
{
'Content-Type'
:
'application/json'
}
}).
then
(
res
=>
res
.
json
()))
loading
.
value
=
false
if
(
err
)
{
message
.
error
(
err
)
return
}
if
(
res
.
code
===
200
)
{
configs
.
value
=
res
.
data
}
else
{
message
.
error
(
res
.
message
)
}
}
// todo 添加字段
const
addField
=
(
key
)
=>
{
const
field
=
fieldConfigs
.
find
(
item
=>
item
.
key
===
key
)
configs
.
value
.
fields
.
push
(
field
)
}
/***---------------- 信息收集交互相关 end -----------------*/
onMounted
(()
=>
{
fetchData
()
})
return
{
// 自助选号相关
updateTab
,
list
,
query
,
pagination
,
playersColumns
,
isSetting
,
handleCheck
,
checkedRowKeys
,
// 文件相关
keyword
,
fetchData
,
tabIndex
,
// 公共数据
loading
,
TabEnum
,
// 名单导出
PLAYER
,
MARK_NO
,
// 配置相关
configs
,
configRules
,
saveConfig
,
getConfig
,
configFormRef
,
updateStartTime
,
updateEndTime
,
fieldColumns
,
addField
,
fieldConfigs
,
enableFields
,
}
}
})
const
app
=
Vue
.
createApp
({
setup
()
{
return
{
locale
:
zhCN
,
dateLocale
:
dateZhCN
}
}
})
app
.
component
(
'my-app'
,
MyApp
)
app
.
use
(
naive
)
app
.
mount
(
'#app'
)
</script>
</body>
</html>
\ No newline at end of file
src/main/webapp/WEB-INF/views/common/menu.jsp
View file @
706c5c7c
...
...
@@ -404,6 +404,20 @@
<span
class=
"menu-txt"
>
领物导航
</span>
</a>
</li>
<li
class=
"gpsDeposit menu-sub-item"
>
<a
href=
"/gk/gpsDeposit/index/${cmpt.cmptId}?uId=${uId}&cId=${cId}×tamp=${timestamp}&sign=${sign}"
>
<span
class=
"left-arrow"
></span>
<span
class=
"menu-txt"
>
GPS押金(ing)
</span>
</a>
</li>
<li
class=
"information menu-sub-item"
>
<a
href=
"/gk/information/index/${cmpt.cmptId}?uId=${uId}&cId=${cId}×tamp=${timestamp}&sign=${sign}"
>
<span
class=
"left-arrow"
></span>
<span
class=
"menu-txt"
>
信息收集(ing)
</span>
</a>
</li>
<li
class=
"wechat menu-sub-item"
>
<a
href=
"/gk/wechatMini/index/${cmpt.cmptId}?uId=${uId}&cId=${cId}×tamp=${timestamp}&sign=${sign}"
>
...
...
@@ -473,7 +487,7 @@
var
classes
=
[
'cmptSetting'
,
'nameList'
,
'manual'
,
'contact'
,
'manage'
,
'route'
,
'road'
,
'equip'
,
'photo'
,
'news'
,
'cert'
,
'data'
,
'banner'
,
'score'
,
'auto'
,
'scan'
,
'review'
,
'customer'
,
'rule'
,
'outter-link'
,
'sure-letter'
,
'rankSetting'
,
'service'
,
"module"
,
"swiper"
,
"bag"
,
"invoice"
,
"markNoSelect"
,
"feedback"
,
"markNoRule"
,
"gunRule"
,
"disClaimer"
,
"location"
,
"wechat"
];
'outter-link'
,
'sure-letter'
,
'rankSetting'
,
'service'
,
"module"
,
"swiper"
,
"bag"
,
"invoice"
,
"markNoSelect"
,
"feedback"
,
"markNoRule"
,
"gunRule"
,
"disClaimer"
,
"location"
,
"wechat"
,
"gpsDeposit"
,
"information"
];
let
url
=
document
.
location
.
href
;
var
done
=
false
;
for
(
var
i
in
classes
)
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment