..
This commit is contained in:
+4
-2
@@ -1,5 +1,6 @@
|
||||
package com.budwk.app.zhgh.dayofficework.qsv.h5controller;
|
||||
|
||||
import cn.dev33.satoken.annotation.SaCheckLogin;
|
||||
import com.budwk.app.base.page.Pagination;
|
||||
import com.budwk.app.base.param.PageForm;
|
||||
import com.budwk.app.base.result.Result;
|
||||
@@ -23,13 +24,14 @@ public class H5QsvController {
|
||||
private QsvActivityService qsvActivityService;
|
||||
|
||||
@At("")
|
||||
@Ok("beetl:/mobile/qsv/index.html")
|
||||
@Ok("beetl:/platform/zhghh5/dayofficework/qsv/index.html")
|
||||
@SaCheckLogin
|
||||
public void index() {
|
||||
|
||||
}
|
||||
|
||||
// 分页查询
|
||||
@At
|
||||
@SaCheckLogin
|
||||
public Result pageData(@Valid PageForm pageForm, @Valid String category) {
|
||||
Cnd cnd = Cnd.NEW();
|
||||
cnd.andEX("category", "=", category);
|
||||
|
||||
+13
-7
@@ -1,7 +1,9 @@
|
||||
package com.budwk.app.zhgh.dayofficework.qsv.h5controller;
|
||||
|
||||
import cn.dev33.satoken.annotation.SaCheckLogin;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.json.JSONObject;
|
||||
import com.budwk.app.base.annotation.SLog;
|
||||
import com.budwk.app.base.result.Result;
|
||||
@@ -44,26 +46,30 @@ public class H5QsvQuizController {
|
||||
private QsvQuizService qsvQuizService;
|
||||
|
||||
@At("")
|
||||
@Ok("beetl:/mobile/qsv/quiz/index.html")
|
||||
@SaCheckLogin
|
||||
@Ok("beetl:/platform/zhghh5/dayofficework/qsv/quiz/index.html")
|
||||
public void index() {
|
||||
|
||||
}
|
||||
|
||||
@At
|
||||
@Ok("beetl:/mobile/qsv/quiz/result.html")
|
||||
@SaCheckLogin
|
||||
@Ok("beetl:/platform/zhghh5/dayofficework/qsv/quiz/result.html")
|
||||
public void result() {
|
||||
|
||||
}
|
||||
|
||||
// 题目列表
|
||||
@At
|
||||
@SaCheckLogin
|
||||
public Result subjects(@Valid String activityId) {
|
||||
QsvActivity activity = dao.fetch(QsvActivity.class, activityId);
|
||||
|
||||
int count = dao.count(ActivityUserScope.class, Cnd.where("groupId", "=", activity.getGroupId())
|
||||
.and("userId", "=", SecurityUtil.getUserId()));
|
||||
if (count != 1) {
|
||||
return Result.error("您无需参加此次答题,感谢您的关注!");
|
||||
if(activity.getGroupId() != null){
|
||||
int count = dao.count(ActivityUserScope.class, Cnd.where("groupId", "=", activity.getGroupId())
|
||||
.and("userId", "=", SecurityUtil.getUserId()));
|
||||
if (count != 1) {
|
||||
return Result.error("您无需参加此次答题,感谢您的关注!");
|
||||
}
|
||||
}
|
||||
|
||||
String mode = activity.getMode();
|
||||
|
||||
+7
@@ -46,6 +46,13 @@ public class ProposalFeedbackEvaluationController {
|
||||
public void index() {
|
||||
}
|
||||
|
||||
@At(value = "/platform/h5/proposal/feedbackEvaluation",top = true)
|
||||
@Ok("beetl:/platform/zhghh5/democratic/proposal/transact/feedbackEvaluation/index.html")
|
||||
@SaCheckPermission("proposal.feedbackEvaluation")
|
||||
public void h5Index() {
|
||||
}
|
||||
|
||||
|
||||
@At
|
||||
@SaCheckPermission("proposal.feedbackEvaluation")
|
||||
@ApiOperation("分页列表")
|
||||
|
||||
+8
@@ -49,6 +49,14 @@ public class ProposalSchoolLeaderApprovalController {
|
||||
public void index() {
|
||||
}
|
||||
|
||||
|
||||
@At(value = "/platform/h5/proposal/schoolLeaderApproval",top = true)
|
||||
@Ok("beetl:/platform/zhghh5/democratic/proposal/transact/schoolLeaderApproval/index.html")
|
||||
@SaCheckPermission("proposal.schoolLeaderApproval")
|
||||
public void h5Index() {
|
||||
}
|
||||
|
||||
|
||||
@At
|
||||
@SaCheckPermission("proposal.schoolLeaderApproval")
|
||||
@ApiOperation("分页列表")
|
||||
|
||||
+5
-5
@@ -44,17 +44,17 @@ public class SuggestionBoxMineController {
|
||||
|
||||
}
|
||||
|
||||
@At(value = "/platform/h5/suggestionBox/mine",top = true)
|
||||
@At(value = "/platform/h5/suggestionBox/mine", top = true)
|
||||
@Ok("beetl:/platform/zhghh5/democratic/suggestionBox/mine/index.html")
|
||||
@SaCheckLogin
|
||||
public void h5Index(){
|
||||
public void h5Index() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
@At
|
||||
@SaCheckPermission("suggestionBox.mine")
|
||||
public Result pageData(Integer pageNumber, Integer pageSize, String title, Integer year) {
|
||||
public Result pageData(Integer pageNumber, Integer pageSize, String searchKeyword, Integer year) {
|
||||
Sql sql = Sqls.create("""
|
||||
SELECT
|
||||
info.id,
|
||||
@@ -89,8 +89,8 @@ public class SuggestionBoxMineController {
|
||||
""");
|
||||
Cnd cnd = Cnd.NEW();
|
||||
cnd.and("info.createdBy", "=", SecurityUtil.getUserId());
|
||||
if (StrUtil.isNotBlank(title)) {
|
||||
cnd.where().andLike("info.title", title);
|
||||
if (StrUtil.isNotBlank(searchKeyword)) {
|
||||
cnd.where().andLike("info.title", searchKeyword);
|
||||
}
|
||||
cnd.andEX("YEAR(info.submitTime)", "=", year);
|
||||
cnd.desc("info.submitTime");
|
||||
|
||||
+15
-5
@@ -1,10 +1,11 @@
|
||||
package com.budwk.app.zhgh.democratic.suggestionBox.controller;
|
||||
|
||||
import cn.dev33.satoken.annotation.SaCheckLogin;
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.budwk.app.base.page.Pagination;
|
||||
import com.budwk.app.base.result.Result;
|
||||
import com.budwk.app.flow.engine.FlowEngine;
|
||||
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
|
||||
import com.budwk.app.zhgh.democratic.suggestionBox.service.SuggestionBoxService;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
@@ -36,15 +37,22 @@ public class SuggestionBoxQueryController {
|
||||
|
||||
@At("")
|
||||
@Ok("beetl:/platform/zhgh/democratic/suggestionBox/query/index.html")
|
||||
@SaCheckLogin
|
||||
@SaCheckPermission("suggestionBox.query")
|
||||
public void index() {
|
||||
|
||||
}
|
||||
|
||||
@At(value = "/platform/h5/suggestionBox/query", top = true)
|
||||
@Ok("beetl:/platform/zhghh5/democratic/suggestionBox/query/index.html")
|
||||
@SaCheckPermission("suggestionBox.query")
|
||||
public void h5Index() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
@At
|
||||
@SaCheckLogin
|
||||
public Result pageData(Integer pageNumber, Integer pageSize, String title, Integer year) {
|
||||
@SaCheckPermission("suggestionBox.query")
|
||||
public Result pageData(Integer pageNumber, Integer pageSize, String searchKeyword, Integer year) {
|
||||
Sql sql = Sqls.create("""
|
||||
SELECT
|
||||
info.id,
|
||||
@@ -79,7 +87,9 @@ public class SuggestionBoxQueryController {
|
||||
""");
|
||||
Cnd cnd = Cnd.NEW();
|
||||
cnd.andEX("YEAR(info.submitTime)", "=", year);
|
||||
cnd.and(Cnd.likeEX("info.title", title));
|
||||
if (StrUtil.isNotBlank(searchKeyword)) {
|
||||
cnd.where().andLike("info.title", searchKeyword);
|
||||
}
|
||||
cnd.desc("info.submitTime");
|
||||
sql.setCondition(cnd);
|
||||
Pagination<NutMap> pagination = suggestionBoxService.listPageMap(pageNumber, pageSize, sql);
|
||||
|
||||
+17
-5
@@ -1,6 +1,7 @@
|
||||
package com.budwk.app.zhgh.democratic.suggestionBox.controller;
|
||||
|
||||
import cn.dev33.satoken.annotation.SaCheckLogin;
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.budwk.app.base.page.Pagination;
|
||||
import com.budwk.app.base.param.PageForm;
|
||||
@@ -35,14 +36,22 @@ public class SuggestionXghController {
|
||||
|
||||
@At("")
|
||||
@Ok("beetl:/platform/zhgh/democratic/suggestionBox/xgh/index.html")
|
||||
@SaCheckLogin
|
||||
@SaCheckPermission("suggestionBox.xgh")
|
||||
public void index() {
|
||||
|
||||
}
|
||||
|
||||
@At(value = "/platform/h5/suggestionBox/xgh",top = true)
|
||||
@Ok("beetl:/platform/zhghh5/democratic/suggestionBox/xgh/index.html")
|
||||
@SaCheckPermission("suggestionBox.xgh")
|
||||
public void h5Index() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
@At
|
||||
@SaCheckLogin
|
||||
public Result pageData(PageForm pageForm, String taskId, String title, Integer year, boolean approval) {
|
||||
@SaCheckPermission("suggestionBox.xgh")
|
||||
public Result pageData(PageForm pageForm, String taskId, String searchKeyword, Integer year, boolean approval) {
|
||||
Sql sql = Sqls.create("""
|
||||
SELECT
|
||||
info.id,
|
||||
@@ -88,7 +97,10 @@ public class SuggestionXghController {
|
||||
}
|
||||
|
||||
cnd.andEX("YEAR(info.submitTime)", "=", year);
|
||||
cnd.and(Cnd.likeEX("info.title", title));
|
||||
|
||||
if (StrUtil.isNotBlank(searchKeyword)) {
|
||||
cnd.where().andLike("info.title", searchKeyword);
|
||||
}
|
||||
|
||||
if (StrUtil.isAllBlank(pageForm.getPageOrderName(), pageForm.getPageOrderBy())) {
|
||||
cnd.desc("info.submitTime");
|
||||
@@ -103,7 +115,7 @@ public class SuggestionXghController {
|
||||
}
|
||||
|
||||
@At
|
||||
@SaCheckLogin
|
||||
@SaCheckPermission("suggestionBox.xgh")
|
||||
@ApiOperation("查询任务")
|
||||
public Result queryTask(@Valid @Param("taskId") String taskId) {
|
||||
Sql sql = Sqls.create("""
|
||||
|
||||
@@ -219,10 +219,22 @@ body {
|
||||
}
|
||||
|
||||
.form-container .van-cell-group__title {
|
||||
padding: 12px 16px 8px;
|
||||
font-size: 15px;
|
||||
color: #323233;
|
||||
font-weight: bold;
|
||||
color: var(--color-black);
|
||||
font-weight: 600;
|
||||
padding: 10px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.form-container .van-cell-group__title::before{
|
||||
content: "";
|
||||
width: 5px;
|
||||
background: var(--color-primary);
|
||||
display: inline-block;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
.form-container .van-field__label {
|
||||
@@ -256,3 +268,32 @@ body {
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
/***************************查看详情CSS********************************/
|
||||
.detail-container {
|
||||
background: #f9f9f9
|
||||
}
|
||||
|
||||
.detail-container .van-cell-group__title{
|
||||
font-size: 15px;
|
||||
color: var(--color-black);
|
||||
font-weight: 600;
|
||||
padding: 10px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.detail-container .van-cell-group__title::before{
|
||||
content: "";
|
||||
width: 5px;
|
||||
background: var(--color-primary);
|
||||
display: inline-block;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
.detail-container .direction-column-cell{
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
<title>智慧工会</title>
|
||||
|
||||
<link rel="stylesheet" href="${base!}/assets/platform/plugins/vant/index.css"/>
|
||||
<link rel="stylesheet" href="${base!}/assets/platform/css/h5.css"/>
|
||||
<link rel="stylesheet" href="${base!}/assets/platform/css/common.css"/>
|
||||
<link rel="stylesheet" href="${base!}/assets/platform/css/h5.css"/>
|
||||
<link rel="stylesheet" href="https://cdn.staticfile.net/animate.css/4.1.1/animate.css"/>
|
||||
<link rel="stylesheet" href="${base!}/assets/platform/fonts/font-awesome.min.css"/>
|
||||
|
||||
|
||||
@@ -396,13 +396,13 @@ const subjectForm = {
|
||||
/* background: rgb(248, 249, 250);*/
|
||||
/*}*/
|
||||
|
||||
.questionnaire-editor {
|
||||
::v-deep .questionnaire-editor {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.editor-header {
|
||||
::v-deep .editor-header {
|
||||
background: white;
|
||||
padding: 20px;
|
||||
border-radius: 8px;
|
||||
@@ -410,7 +410,7 @@ const subjectForm = {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.subject-item {
|
||||
::v-deep .subject-item {
|
||||
background: white;
|
||||
border-radius: 8px;
|
||||
padding: 25px;
|
||||
@@ -420,18 +420,18 @@ const subjectForm = {
|
||||
border: 1px dashed #d9d9d9;
|
||||
}
|
||||
|
||||
.subject-item:hover {
|
||||
::v-deep .subject-item:hover {
|
||||
box-shadow: 0 4px 20px 0 rgba(0, 0, 0, 0.1);
|
||||
/*transform: translateY(-1px);*/
|
||||
}
|
||||
|
||||
.subject-header {
|
||||
::v-deep .subject-header {
|
||||
border-bottom: 1px solid #eee;
|
||||
padding-bottom: 15px;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.subject-toolbar {
|
||||
::v-deep .subject-toolbar {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
@@ -440,7 +440,7 @@ const subjectForm = {
|
||||
border-top: 1px solid #eee;
|
||||
}
|
||||
|
||||
.toolbar {
|
||||
::v-deep .toolbar {
|
||||
background: white;
|
||||
padding: 15px;
|
||||
border-radius: 8px;
|
||||
@@ -448,12 +448,12 @@ const subjectForm = {
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
.toolbar-btn {
|
||||
::v-deep .toolbar-btn {
|
||||
margin: 5px 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.option-item {
|
||||
::v-deep .option-item {
|
||||
background: #f8f9fa;
|
||||
border-radius: 4px;
|
||||
padding: 10px;
|
||||
@@ -462,33 +462,33 @@ const subjectForm = {
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.option-drag-handle {
|
||||
::v-deep .option-drag-handle {
|
||||
cursor: move;
|
||||
margin-right: 10px;
|
||||
color: #909399;
|
||||
}
|
||||
|
||||
.option-content {
|
||||
::v-deep .option-content {
|
||||
flex-grow: 1;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.option-tools {
|
||||
::v-deep .option-tools {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.preview-dialog {
|
||||
::v-deep .preview-dialog {
|
||||
max-width: 800px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.date-visible {
|
||||
::v-deep .date-visible {
|
||||
margin-left: 20px;
|
||||
}
|
||||
|
||||
.subject-meta {
|
||||
::v-deep .subject-meta {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 15px;
|
||||
@@ -498,7 +498,7 @@ const subjectForm = {
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.image-preview {
|
||||
::v-deep .image-preview {
|
||||
max-width: 200px;
|
||||
max-height: 200px;
|
||||
margin-top: 10px;
|
||||
@@ -506,24 +506,24 @@ const subjectForm = {
|
||||
border: 1px solid #dcdfe6;
|
||||
}
|
||||
|
||||
.drag-handler {
|
||||
::v-deep .drag-handler {
|
||||
cursor: move;
|
||||
color: #909399;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.meta-info {
|
||||
::v-deep .meta-info {
|
||||
color: #909399;
|
||||
font-size: 12px;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
.subject-type-icon {
|
||||
::v-deep .subject-type-icon {
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
|
||||
.option-img-box {
|
||||
::v-deep .option-img-box {
|
||||
position: relative;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
@@ -531,16 +531,16 @@ const subjectForm = {
|
||||
flex-shrink: 0
|
||||
}
|
||||
|
||||
.option-img-box:hover .el-icon-remove {
|
||||
::v-deep .option-img-box:hover .el-icon-remove {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.option-img-box img {
|
||||
::v-deep .option-img-box img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.option-img-box .el-icon-remove {
|
||||
::v-deep .option-img-box .el-icon-remove {
|
||||
position: absolute;
|
||||
top: -7px;
|
||||
right: -7px;
|
||||
@@ -548,7 +548,7 @@ const subjectForm = {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.option-img-box .el-icon-remove:hover {
|
||||
::v-deep .option-img-box .el-icon-remove:hover {
|
||||
transform: scale(1.1);
|
||||
}
|
||||
|
||||
|
||||
@@ -314,11 +314,11 @@ E.先进性"
|
||||
}
|
||||
},
|
||||
style: /*language=CSS*/ `
|
||||
.txt-import-dialog .el-dialog__body {
|
||||
::v-deep .txt-import-dialog .el-dialog__body {
|
||||
padding: 10px 20px;
|
||||
}
|
||||
|
||||
.txt-import-container {
|
||||
::v-deep .txt-import-container {
|
||||
display: flex;
|
||||
height: 80vh;
|
||||
border-radius: 4px;
|
||||
@@ -327,7 +327,7 @@ E.先进性"
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.txt-import-panel-header {
|
||||
::v-deep .txt-import-panel-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
@@ -337,7 +337,7 @@ E.先进性"
|
||||
height: 32px; /* 统一高度 */
|
||||
}
|
||||
|
||||
.txt-import-left-panel {
|
||||
::v-deep .txt-import-left-panel {
|
||||
width: 50%;
|
||||
padding: 20px;
|
||||
border-right: 1px solid #ebeef5;
|
||||
@@ -345,7 +345,7 @@ E.先进性"
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.txt-import-right-panel {
|
||||
::v-deep .txt-import-right-panel {
|
||||
width: 50%;
|
||||
padding: 20px;
|
||||
background-color: #fff; /* 改为白色背景 */
|
||||
@@ -354,22 +354,22 @@ E.先进性"
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.txt-import-title {
|
||||
::v-deep .txt-import-title {
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
color: #303133;
|
||||
}
|
||||
|
||||
.txt-import-format-tip {
|
||||
::v-deep .txt-import-format-tip {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.txt-import-format-tooltip {
|
||||
::v-deep .txt-import-format-tooltip {
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
.txt-import-input-area {
|
||||
::v-deep .txt-import-input-area {
|
||||
flex: 1;
|
||||
position: relative;
|
||||
margin-bottom: 15px;
|
||||
@@ -379,7 +379,7 @@ E.先进性"
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
.txt-import-textarea {
|
||||
::v-deep .txt-import-textarea {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 15px;
|
||||
@@ -394,25 +394,25 @@ E.先进性"
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.txt-import-textarea:focus {
|
||||
::v-deep .txt-import-textarea:focus {
|
||||
box-shadow: 0 0 0 2px rgba(24,103,176,0.2);
|
||||
}
|
||||
|
||||
.txt-import-action-buttons {
|
||||
::v-deep .txt-import-action-buttons {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
margin-top: 10px;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.txt-import-stats {
|
||||
::v-deep .txt-import-stats {
|
||||
color: #1867b0;
|
||||
font-size: 13px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.txt-import-result-display {
|
||||
::v-deep .txt-import-result-display {
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
background-color: #f9fafc; /* 只在结果显示区域使用浅灰色背景 */
|
||||
@@ -421,7 +421,7 @@ E.先进性"
|
||||
border: 1px solid #ebeef5;
|
||||
}
|
||||
|
||||
.txt-import-no-questions {
|
||||
::v-deep .txt-import-no-questions {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@@ -431,7 +431,7 @@ E.先进性"
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.txt-import-question-item {
|
||||
::v-deep .txt-import-question-item {
|
||||
background-color: #fff;
|
||||
margin-bottom: 15px;
|
||||
padding: 15px;
|
||||
@@ -441,12 +441,12 @@ E.先进性"
|
||||
border-left: 3px solid #67c23a;
|
||||
}
|
||||
|
||||
.txt-import-question-item:hover {
|
||||
::v-deep .txt-import-question-item:hover {
|
||||
box-shadow: 0 4px 12px 0 rgba(0,0,0,0.1);
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
.txt-import-question-title {
|
||||
::v-deep .txt-import-question-title {
|
||||
font-size: 15px;
|
||||
font-weight: bold;
|
||||
margin-bottom: 12px;
|
||||
@@ -454,7 +454,7 @@ E.先进性"
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.txt-import-question-number {
|
||||
::v-deep .txt-import-question-number {
|
||||
display: inline-block;
|
||||
width: 25px;
|
||||
height: 25px;
|
||||
@@ -467,11 +467,11 @@ E.先进性"
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.txt-import-options {
|
||||
::v-deep .txt-import-options {
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.txt-import-option-item {
|
||||
::v-deep .txt-import-option-item {
|
||||
margin-bottom: 8px;
|
||||
padding: 8px 12px;
|
||||
background-color: #f5f7fa;
|
||||
@@ -483,27 +483,27 @@ E.先进性"
|
||||
transition: all 0.2s;
|
||||
}
|
||||
|
||||
.txt-import-option-item:hover {
|
||||
::v-deep .txt-import-option-item:hover {
|
||||
background-color: #ebeef5;
|
||||
}
|
||||
|
||||
.txt-import-option-item.txt-import-correct {
|
||||
::v-deep .txt-import-option-item.txt-import-correct {
|
||||
background-color: #f0f9eb;
|
||||
color: #67c23a;
|
||||
border-left: 3px solid #67c23a;
|
||||
}
|
||||
|
||||
.txt-import-option-text {
|
||||
::v-deep .txt-import-option-text {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.txt-import-correct-mark {
|
||||
::v-deep .txt-import-correct-mark {
|
||||
color: #67c23a;
|
||||
font-weight: bold;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.txt-import-question-meta {
|
||||
::v-deep .txt-import-question-meta {
|
||||
margin-top: 12px;
|
||||
padding-top: 12px;
|
||||
border-top: 1px dashed #ebeef5;
|
||||
@@ -511,12 +511,12 @@ E.先进性"
|
||||
color: #909399;
|
||||
}
|
||||
|
||||
.txt-import-dialog-footer {
|
||||
::v-deep .txt-import-dialog-footer {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.txt-import-no-options {
|
||||
::v-deep .txt-import-no-options {
|
||||
padding: 10px;
|
||||
color: #f56c6c;
|
||||
font-style: italic;
|
||||
|
||||
+1
-1
@@ -66,7 +66,7 @@ layout("/layouts/platform.html"){
|
||||
<el-table-column label="操作" fixed="right" width="300px">
|
||||
<template slot-scope="{row}">
|
||||
<el-button @click="openView(row)" size="mini" type="primary">查看</el-button>
|
||||
<el-button v-if="row.taskState === 10" @click="openAudit(row)" size="mini" type="primary">答复
|
||||
<el-button v-if="row.taskState === 10" @click="openAudit(row)" size="mini" type="primary">评价
|
||||
</el-button>
|
||||
<el-button v-if="row.canRevoke" @click="onRevoke(row)" size="mini" type="danger">撤回
|
||||
</el-button>
|
||||
|
||||
@@ -10,7 +10,7 @@ layout("/layouts/platform.html"){
|
||||
style="width: 100%"></el-date-picker>
|
||||
</search-item>
|
||||
<search-item label="标题">
|
||||
<el-input v-model="pageForm.title" placeholder="标题" clearable></el-input>
|
||||
<el-input v-model="pageForm.searchKeyword" placeholder="标题" clearable></el-input>
|
||||
</search-item>
|
||||
</search>
|
||||
</el-card>
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
<!--#
|
||||
layout("/layouts/platform_h5.html"){
|
||||
#-->
|
||||
|
||||
<div id="app" v-cloak>
|
||||
<van-nav-bar @click-left="historyBack" left-arrow left-text="返回" title="问卷列表" placeholder fixed></van-nav-bar>
|
||||
|
||||
<van-sticky offset-top="46px">
|
||||
<van-tabs v-model="pageForm.category" @change="doSearch">
|
||||
<van-tab v-for="item in dict.type.ACTIVITY_QSV_CATEGORY" :name="item.code" :title="item.label"
|
||||
:key="item.code"></van-tab>
|
||||
</van-tabs>
|
||||
</van-sticky>
|
||||
|
||||
<table-list api="/platform/h5/qsv/pageData" :page_form.sync="pageForm" ref="tableListRef" title="title"
|
||||
@ready="doSearch">
|
||||
<!-- <template #header="{index,row}"></template>-->
|
||||
<template v-slot="{index,row}">
|
||||
<table-column label="开始时间">{{row.startTime}}</table-column>
|
||||
<table-column label="结束时间">{{row.endTime}}</table-column>
|
||||
</template>
|
||||
<template #actions="{index,row}">
|
||||
<div class="action-btn" @click="onEnter(row)">
|
||||
<i class="fa fa-eye"></i>
|
||||
<span>查看</span>
|
||||
</div>
|
||||
</template>
|
||||
</table-list>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
const vue = new Vue({
|
||||
el: "#app",
|
||||
dicts: ['ACTIVITY_QSV_CATEGORY'],
|
||||
store,
|
||||
data() {
|
||||
return {
|
||||
pageForm: {
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
totalCount: 0,
|
||||
category: "QUIZ"
|
||||
},
|
||||
categoryPaths: {
|
||||
QUIZ: "/platform/h5/qsv/quiz",
|
||||
SURVEY: "/platform/h5/qsv/survey",
|
||||
VOTE: "/platform/h5/qsv/vote"
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
historyBack,
|
||||
|
||||
doSearch() {
|
||||
this.$nextTick(() => {
|
||||
this.pageForm.pageNumber = 1
|
||||
this.pageForm.totalCount = 0
|
||||
this.$refs.tableListRef.doSearch()
|
||||
})
|
||||
},
|
||||
|
||||
async onEnter(item) {
|
||||
debugger
|
||||
if (item.groupId) {
|
||||
const {
|
||||
code,
|
||||
data
|
||||
} = await $.get('/platform/activity/basic/scope/getScopeUser', {activityGroupId: item.groupId})
|
||||
if (code === 0 && data === 0) {
|
||||
this.$toast.fail("您没有权限参与")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
const {startTime, endTime} = item
|
||||
if (this.$moment(startTime).unix() > this.$moment().unix()) {
|
||||
this.$toast("未开始")
|
||||
return
|
||||
}
|
||||
|
||||
const path = this.categoryPaths[item.category]
|
||||
if (path) {
|
||||
pjaxReplace(path + "?id=" + item.id)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
|
||||
<!--#
|
||||
}
|
||||
#-->
|
||||
@@ -0,0 +1,406 @@
|
||||
<!--#
|
||||
layout("/layouts/platform_h5.html"){
|
||||
#-->
|
||||
|
||||
<div id="app" v-cloak>
|
||||
<van-nav-bar @click-left="historyBack" left-arrow left-text="返回" title="问卷列表" placeholder fixed></van-nav-bar>
|
||||
|
||||
<div class="container" :style="{'padding-bottom': answerRecord.isFinish ? 0 : '84px'}">
|
||||
<van-sticky offset-top="46px">
|
||||
<!--开启计时 未完成 活动未结束-->
|
||||
<div class="timer" v-if="activity.timeLimit > 0 && !answerRecord.isFinish && !isEnd">⏰{{ remainingTime }}s
|
||||
</div>
|
||||
<h2 class="title">{{ activity.title }}</h2>
|
||||
</van-sticky>
|
||||
|
||||
<div v-if="!answerRecord.isFinish">
|
||||
<div v-for="(subject, index) in subjects" :key="index" class="subject">
|
||||
<p>{{index+1}}、{{ subject.title }}</p>
|
||||
<div class="tag">
|
||||
<van-tag v-if="subject.type === 'checkbox'" type="primary" size="large">多选</van-tag>
|
||||
<van-tag v-if="subject.type === 'radio'" type="primary" size="large">单选</van-tag>
|
||||
<van-tag v-if="subject.score" type="primary" size="large">{{subject.score}}分</van-tag>
|
||||
</div>
|
||||
|
||||
<van-checkbox-group v-model="subject.userSelectOptionIds" :ref="'subject'+subject.id">
|
||||
<van-cell-group>
|
||||
<van-cell
|
||||
v-for="(option,index) in subject.options"
|
||||
clickable
|
||||
:key="option.id"
|
||||
:title="option.text"
|
||||
@click="cellToggle(subject,option.id)"
|
||||
>
|
||||
<template #icon>
|
||||
<van-checkbox
|
||||
:name="option.id"
|
||||
:ref="'option'+option.id"
|
||||
:disabled="answerRecord.isFinish"
|
||||
:shape="subject.type==='checkbox' ? 'square' : 'round'"
|
||||
style="margin-right: 10px"
|
||||
></van-checkbox>
|
||||
</template>
|
||||
</van-cell>
|
||||
</van-cell-group>
|
||||
</van-checkbox-group>
|
||||
</div>
|
||||
<div class="button-control" v-if="!answerRecord.isFinish">
|
||||
<van-button type="info" @click="onSubmit" block :disabled="isEnd">{{isEnd ? '已结束' : '提交'}}
|
||||
</van-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
const vue = new Vue({
|
||||
el: "#app",
|
||||
store,
|
||||
data() {
|
||||
return {
|
||||
list: [],
|
||||
id: GetQueryString("id"),
|
||||
H5JumpTo: GetQueryString("H5JumpTo"),
|
||||
subjects: [],
|
||||
activity: {},
|
||||
isFinished: false,
|
||||
answerRecord: {},
|
||||
answerRecordId: null,
|
||||
//历史记录
|
||||
historyScores: [],
|
||||
//答题用时
|
||||
answerTime: 0
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
isEnd() {
|
||||
if (this.activity) {
|
||||
return this.$moment().unix() > this.$moment(this.activity.endTime).unix()
|
||||
}
|
||||
return true
|
||||
},
|
||||
remainingTime() {
|
||||
if (this.activity && this.activity.timeLimit > 0) {
|
||||
return this.activity.timeLimit * 60 - this.answerTime
|
||||
}
|
||||
return 0
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
//获取活动、题目
|
||||
listSubjects() {
|
||||
this.$axios.post("/platform/h5/qsv/quiz/subjects", {activityId: this.id}).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.activity = res.data.activity
|
||||
this.subjects = res.data.subjects
|
||||
this.answerRecordId = res.data.answerRecordId
|
||||
// this.checkGroupPermission()
|
||||
if (!this.H5JumpTo && this.activity.repeatable && res.data.repeatTips) {
|
||||
// 如果是可重复答题,第二次答题进来弹出提示
|
||||
vant.Dialog.confirm({
|
||||
title: '温馨提示',
|
||||
message: '您已完成本次答题,是否要重新答题?',
|
||||
confirmButtonText: '重新答题',
|
||||
cancelButtonText: '查看答题记录',
|
||||
}).then(() => {
|
||||
this.getAnswerRecord()
|
||||
}).catch(() => {
|
||||
pjaxReplace("/platform/h5/qsv/quiz/result?answerRecordId=" + this.answerRecordId)
|
||||
// pjaxReplace("/mobile/index")
|
||||
});
|
||||
} else {
|
||||
this.getAnswerRecord()
|
||||
}
|
||||
} else {
|
||||
vant.Dialog.alert({
|
||||
title: '温馨提示',
|
||||
message: res.msg,
|
||||
}).then(() => {
|
||||
pjaxReplace("/mobile/index")
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
//获取回答记录
|
||||
getAnswerRecord() {
|
||||
this.$axios.post("/platform/h5/qsv/quiz/answerRecord", {answerRecordId: this.answerRecordId}).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.answerRecord = res.data
|
||||
|
||||
if (this.answerRecord.isFinish || this.$moment().unix() > this.$moment(this.activity.endTime)) {
|
||||
pjaxReplace("/platform/h5/qsv/quiz/result?answerRecordId=" + this.answerRecordId)
|
||||
}
|
||||
|
||||
this.initAnswer()
|
||||
this.checkTimer()
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
//答案回显
|
||||
initAnswer() {
|
||||
this.subjects.forEach((subject, subjectIndex) => {
|
||||
if (subject.type === "radio") {
|
||||
this.$refs["subject" + subject.id][0].toggleAll(false)
|
||||
}
|
||||
if (this.answerRecord.optionIds) {
|
||||
this.answerRecord.optionIds[subjectIndex].forEach((optionId) => {
|
||||
this.$refs["option" + optionId][0].toggle()
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
historyBack() {
|
||||
if (this.timerInterval) {
|
||||
clearInterval(this.timerInterval)
|
||||
}
|
||||
pjaxReplace('platform/h5/qsv')
|
||||
},
|
||||
|
||||
//答题计时器
|
||||
checkTimer() {
|
||||
if (this.timerInterval) {
|
||||
clearInterval(this.timerInterval)
|
||||
}
|
||||
|
||||
//开启计时
|
||||
const startInterval = () => {
|
||||
this.timerInterval = setInterval(() => {
|
||||
this.answerTime++
|
||||
if (this.activity.timeLimit > 0 && this.answerTime >= this.activity.timeLimit * 60) {
|
||||
clearInterval(this.timerInterval)
|
||||
|
||||
this.$dialog.alert({
|
||||
title: "提示",
|
||||
message: "答题时间到,请刷新页面重新答题",
|
||||
}).then(() => {
|
||||
window.location.reload()
|
||||
})
|
||||
|
||||
// const loading = this.$toast.loading({
|
||||
// message: "答题时间到,自动提交中",
|
||||
// forbidClick: true
|
||||
// })
|
||||
// setTimeout(() => {
|
||||
// this.autoSubmit(loading)
|
||||
// }, 1500)
|
||||
}
|
||||
}, 1000)
|
||||
}
|
||||
|
||||
if (!this.isEnd && !this.answerRecord.isFinish) {
|
||||
if (this.activity.timeLimit > 0) {
|
||||
this.$dialog
|
||||
.alert({
|
||||
title: "提示",
|
||||
message: "本次答题时间" + this.activity.timeLimit + "分钟,点击确认开始答题"
|
||||
})
|
||||
.then(() => {
|
||||
startInterval()
|
||||
})
|
||||
} else {
|
||||
startInterval()
|
||||
}
|
||||
}
|
||||
|
||||
// if (this.activity.timeLimit > 0 && !this.isEnd) {
|
||||
// if (!this.answerRecord.isFinish) {
|
||||
// this.$dialog
|
||||
// .alert({
|
||||
// title: "提示",
|
||||
// message: "本次答题时间" + this.activity.timeLimit + "分钟,点击确认开始答题"
|
||||
// })
|
||||
// .then(() => {
|
||||
// this.remainingTime = this.activity.timeLimit * 60
|
||||
// this.timerInterval = setInterval(() => {
|
||||
// if (this.remainingTime > 0) {
|
||||
// this.remainingTime--
|
||||
// } else {
|
||||
// clearInterval(this.timerInterval)
|
||||
// const loading = this.$toast.loading({
|
||||
// message: "答题时间到,自动提交中",
|
||||
// forbidClick: true
|
||||
// })
|
||||
// this.autoSubmit(loading)
|
||||
// }
|
||||
// }, 1000)
|
||||
// })
|
||||
// }
|
||||
// }
|
||||
},
|
||||
|
||||
historyScore() {
|
||||
this.$axios.post("/platform/h5/qsv/quiz/historyScore", {activityId: this.activityId}).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.historyScores = res.data
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
//选项点击
|
||||
cellToggle(subject, optionId) {
|
||||
if (this.answerRecord.isFinish) {
|
||||
return
|
||||
}
|
||||
|
||||
if (subject.type === "radio") {
|
||||
this.$refs["subject" + subject.id][0].toggleAll(false)
|
||||
}
|
||||
this.$refs["option" + optionId][0].toggle()
|
||||
},
|
||||
|
||||
//手动提交
|
||||
onSubmit() {
|
||||
if (this.isEnd) {
|
||||
this.$toast("调查已结束")
|
||||
return
|
||||
}
|
||||
|
||||
//提示那些题没有作答
|
||||
for (let i = 0; i < this.subjects.length; i++) {
|
||||
let subject = this.subjects[i]
|
||||
//["radio", "checkbox"].includes(subject.type) &&
|
||||
if (!subject.userSelectOptionIds || subject.userSelectOptionIds.length === 0) {
|
||||
this.$toast.fail("第" + (i + 1) + "题未做答")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if (this.timerInterval) {
|
||||
clearInterval(this.timerInterval)
|
||||
}
|
||||
|
||||
this.autoSubmit()
|
||||
},
|
||||
|
||||
//自动提交
|
||||
autoSubmit(loading = null) {
|
||||
this.$axios.post("/platform/h5/qsv/quiz/submitAnswer", {
|
||||
answer: JSON.stringify({
|
||||
activityId: this.id,
|
||||
answerRecordId: this.answerRecordId,
|
||||
subjects: this.subjects.map((subject) => {
|
||||
return {
|
||||
id: subject.id,
|
||||
userSelectOptionIds: ["checkbox", "radio"].includes(subject.type) ? subject.userSelectOptionIds : []
|
||||
}
|
||||
}),
|
||||
answerTime: this.answerTime
|
||||
})
|
||||
})
|
||||
.then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.$toast.success(res.msg)
|
||||
pjaxReplace("/platform/h5/qsv/quiz/result?answerRecordId=" + this.answerRecordId)
|
||||
}
|
||||
})
|
||||
.always(() => {
|
||||
if (loading) {
|
||||
loading.clear()
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
// async checkGroupPermission() {
|
||||
// const groupId = this.activity.groupId
|
||||
// if (groupId) {
|
||||
// const { code, data } = await this.$axios.post("/open/common/checkGroupPermission", { groupId })
|
||||
// if (code === 0) {
|
||||
// if (!data) {
|
||||
// this.$dialog
|
||||
// .alert({
|
||||
// title: "提示",
|
||||
// message: "您没有权限参与"
|
||||
// })
|
||||
// .then(() => {
|
||||
// location.back()
|
||||
// })
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
},
|
||||
created() {
|
||||
if (this.timerInterval) {
|
||||
clearInterval(this.timerInterval)
|
||||
}
|
||||
if (this.id) {
|
||||
this.listSubjects()
|
||||
}
|
||||
},
|
||||
style: /*language=CSS*/ `
|
||||
.container {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
::v-deep .container .title {
|
||||
text-align: center;
|
||||
padding: 20px;
|
||||
background: #ffffff;
|
||||
margin: 0 0 10px 0 !important;
|
||||
color: var(--color-primary);
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.container .card {
|
||||
padding: 10px;
|
||||
background: #ffffff;
|
||||
}
|
||||
|
||||
.subject {
|
||||
background: #fff;
|
||||
padding: 15px;
|
||||
margin-bottom: 15px;
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.subject p {
|
||||
font-size: 16px;
|
||||
margin: 20px 0 10px 0;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.subject .tag {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
::v-deep .timer {
|
||||
text-align: center;
|
||||
font-size: 18px;
|
||||
background: #fff;
|
||||
padding: 10px 0;
|
||||
}
|
||||
|
||||
.submit-button {
|
||||
width: 100%;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.result {
|
||||
text-align: center;
|
||||
font-size: 20px;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.button-control {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
padding: 20px;
|
||||
display: flex;
|
||||
column-gap: 20px;
|
||||
background: #fff;
|
||||
}
|
||||
`
|
||||
})
|
||||
</script>
|
||||
|
||||
|
||||
<!--#
|
||||
}
|
||||
#-->
|
||||
@@ -0,0 +1,359 @@
|
||||
<!--#
|
||||
layout("/layouts/platform_h5.html"){
|
||||
#-->
|
||||
|
||||
<div id="app" v-cloak>
|
||||
<van-nav-bar @click-left="historyBack" left-arrow left-text="返回" title="问卷列表" placeholder fixed></van-nav-bar>
|
||||
|
||||
<div class="container" :style="{'padding-bottom': answerRecord.isFinish ? 0 : '84px'}">
|
||||
<van-sticky offset-top="46px">
|
||||
<h2 class="title">{{ activity.title }}</h2>
|
||||
<div class="score-form">
|
||||
<div class="score-form-total">
|
||||
<div class="score-font-style">{{totalScore}}</div>
|
||||
<i class="score-underline"></i>
|
||||
</div>
|
||||
</div>
|
||||
</van-sticky>
|
||||
|
||||
<div>
|
||||
<div v-for="(subject, index) in subjects" :key="index" class="subject">
|
||||
<p>{{index+1}}、{{ subject.title }}</p>
|
||||
<div class="tag">
|
||||
<van-tag v-if="subject.type === 'checkbox'" type="primary" size="large">多选</van-tag>
|
||||
<van-tag v-if="subject.type === 'radio'" type="primary" size="large">单选</van-tag>
|
||||
<van-tag v-if="subject.score" type="primary" size="large">{{subject.score}}分</van-tag>
|
||||
</div>
|
||||
|
||||
<van-checkbox-group v-model="subject.userSelectOptionIds" :ref="'subject'+subject.id">
|
||||
<van-cell-group>
|
||||
<van-cell
|
||||
v-for="(option,index) in subject.options"
|
||||
clickable
|
||||
:key="option.id"
|
||||
:title="option.text"
|
||||
>
|
||||
<template #title>
|
||||
<span :style="{color : option.isCorrect ? 'green' : ''}">{{option.text}}</span>
|
||||
</template>
|
||||
<template #icon>
|
||||
<van-checkbox
|
||||
:name="option.id"
|
||||
:ref="'option'+option.id"
|
||||
:disabled="answerRecord.isFinish"
|
||||
style="margin-right: 10px"
|
||||
></van-checkbox>
|
||||
</template>
|
||||
</van-cell>
|
||||
</van-cell-group>
|
||||
</van-checkbox-group>
|
||||
|
||||
<div class="answer-container">
|
||||
<div v-if="answerRecord.extJson?.[subject.id]?.isCorrect" class="correct-answer">
|
||||
<van-icon name="passed"></van-icon>
|
||||
回答正确
|
||||
</div>
|
||||
<div v-else-if="answerRecord.extJson?.[subject.id]" class="incorrect-answer">
|
||||
<van-icon name="close"></van-icon>
|
||||
回答错误
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="button-control">
|
||||
<van-button v-if="canAgainQuestion" type="primary" @click="againQuestion" block>重新答题</van-button>
|
||||
<van-button type="primary" @click="openHistory" block>查看全部答题记录</van-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<van-action-sheet v-model="historyShow" title="历史记录" >
|
||||
<div class="history-list">
|
||||
<div v-for="item in historyList" class="history-item">
|
||||
<div class="history-header">
|
||||
<span>{{ item.date }}</span>
|
||||
<van-tag v-if="item.isHighestScore" type="danger" class="tag">最高分</van-tag>
|
||||
<van-tag v-if="item.isLatestScore" type="primary" class="tag">最新得分</van-tag>
|
||||
</div>
|
||||
<div class="history-info">答题分数:{{ item.totalScore }}</div>
|
||||
<div class="history-info">答题用时:{{ item.answerTime | formatSeconds }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</van-action-sheet>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<script>
|
||||
const vue = new Vue({
|
||||
el: "#app",
|
||||
data() {
|
||||
return {
|
||||
answerRecordId: GetQueryString("answerRecordId"),
|
||||
answerRecord: {},
|
||||
subjects: [],
|
||||
activity: {},
|
||||
list: [],
|
||||
historyShow: false,
|
||||
historyList: [],
|
||||
canAgainQuestion: false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
totalScore() {
|
||||
if (!this.answerRecord || !this.answerRecord.extJson) {
|
||||
return 0
|
||||
}
|
||||
let totalScore = 0
|
||||
for (const key in this.answerRecord.extJson) {
|
||||
if (this.answerRecord.extJson.hasOwnProperty(key)) {
|
||||
totalScore += this.answerRecord.extJson[key].score || 0
|
||||
}
|
||||
}
|
||||
return totalScore
|
||||
}
|
||||
},
|
||||
filters: {
|
||||
formatSeconds(seconds) {
|
||||
if (seconds) {
|
||||
const minutes = Math.floor(seconds / 60) // 获取总分钟数
|
||||
const remainingSeconds = seconds % 60 // 获取剩余秒数
|
||||
// 格式化输出,确保秒数始终为两位数
|
||||
return minutes + "分钟" + String(remainingSeconds).padStart(2, "0") + "秒"
|
||||
}
|
||||
return null
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
/**
|
||||
* 重新答题
|
||||
*/
|
||||
againQuestion() {
|
||||
vant.Dialog.confirm({
|
||||
title: '温馨提示',
|
||||
message: '确定要重新答题吗?',
|
||||
}).then(() => {
|
||||
pjaxReplace('/platform/h5/qsv/quiz?id=' + this.activity.id + "&H5JumpTo=true")
|
||||
}).catch(() => {
|
||||
// on cancel
|
||||
});
|
||||
},
|
||||
getAnswerResult() {
|
||||
this.$axios.post("/platform/h5/qsv/quiz/answerResult", { answerRecordId: this.answerRecordId }).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.subjects = res.data.subjects
|
||||
this.activity = res.data.activity
|
||||
this.getAnswerRecord()
|
||||
this.getHistoryQuestion()
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
//获取回答记录
|
||||
getAnswerRecord() {
|
||||
this.$axios.post("/platform/h5/qsv/quiz/answerRecord", { answerRecordId: this.answerRecordId }).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.answerRecord = res.data
|
||||
this.initAnswer()
|
||||
}
|
||||
})
|
||||
},
|
||||
//答案回显
|
||||
initAnswer() {
|
||||
this.subjects.forEach((subject, subjectIndex) => {
|
||||
const answer = this.answerRecord.extJson[subject.id]
|
||||
if (["radio", "checkbox"].includes(subject.type)) {
|
||||
this.$nextTick(() => {
|
||||
this.$refs["subject" + subject.id][0].toggleAll(false)
|
||||
})
|
||||
answer?.optionIds.forEach((optionId) => {
|
||||
this.$nextTick(() => {
|
||||
this.$refs["option" + optionId][0].toggle()
|
||||
})
|
||||
})
|
||||
} else if (subject.type === "text") {
|
||||
subject.userFillContent = answer?.text
|
||||
}
|
||||
})
|
||||
},
|
||||
historyBack() {
|
||||
pjaxReplace('/platform/h5/qsv')
|
||||
},
|
||||
openHistory() {
|
||||
this.historyShow = true
|
||||
},
|
||||
getHistoryQuestion() {
|
||||
this.$axios.post("/platform/h5/qsv/quiz/historyScore", { activityId: this.activity.id }).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.historyList = res.data
|
||||
if (this.activity.maxAttempts > res.data.length) {
|
||||
this.canAgainQuestion = true
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.getAnswerResult()
|
||||
},
|
||||
style: /*language=CSS*/ `
|
||||
.container {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
::v-deep .container .title {
|
||||
text-align: center;
|
||||
padding: 20px;
|
||||
margin: 0 !important;
|
||||
background: #ffffff;
|
||||
color: var(--color-primary);
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.container .score {
|
||||
}
|
||||
|
||||
.container .card {
|
||||
padding: 10px;
|
||||
background: #ffffff;
|
||||
}
|
||||
|
||||
.subject {
|
||||
background: #fff;
|
||||
padding: 15px;
|
||||
margin-bottom: 15px;
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.subject p {
|
||||
font-size: 16px;
|
||||
margin: 20px 0 10px 0;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.subject .tag {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
::v-deep .score-form {
|
||||
background: #ffffff;
|
||||
display: flex;
|
||||
margin-bottom: 10px;
|
||||
border-top: 1px solid #f1f1f1;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
::v-deep .score-form-total {
|
||||
flex: 1;
|
||||
background: #fff;
|
||||
display: flex;
|
||||
padding: 10px 20px 10px 0;
|
||||
flex-direction: column;
|
||||
align-items: flex-end;
|
||||
}
|
||||
|
||||
::v-deep .score-text-news {
|
||||
flex: 1;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
::v-deep .score-font-style {
|
||||
font-size: 32px;
|
||||
color: #ff6a00;
|
||||
word-break: keep-all;
|
||||
line-height: 38px;
|
||||
min-width: 47px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
::v-deep .score-underline {
|
||||
background: url(//image.wjx.cn/images/newimg/score-form/score-underline@2x.png) no-repeat center;
|
||||
background-size: 47px 16px;
|
||||
display: inline-block;
|
||||
height: 16px;
|
||||
width: 47px;
|
||||
margin-top: 7px;
|
||||
}
|
||||
|
||||
.van-checkbox__icon--checked .van-icon {
|
||||
color: #fff !important;
|
||||
background-color: var(--color-primary) !important;
|
||||
border-color: var(--color-primary) !important;
|
||||
}
|
||||
|
||||
.van-checkbox__icon--disabled .van-icon {
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.answer-container {
|
||||
padding: 16px;
|
||||
}
|
||||
.correct-answer {
|
||||
color: green;
|
||||
}
|
||||
.incorrect-answer {
|
||||
color: red;
|
||||
}
|
||||
|
||||
.button-control {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
padding: 20px;
|
||||
display: flex;
|
||||
column-gap: 20px;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
::v-deep .history-list {
|
||||
background: #f1f1f1;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
::v-deep .history-item {
|
||||
background: #ffffff;
|
||||
border-radius: 12px;
|
||||
padding: 16px;
|
||||
margin: 20px 10px;
|
||||
box-shadow:
|
||||
8px 8px 16px #d9d9d9,
|
||||
-8px -8px 16px #ffffff;
|
||||
transition: transform 0.2s ease-in-out;
|
||||
}
|
||||
|
||||
::v-deep .history-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
::v-deep .history-header span {
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
::v-deep .history-header .tag {
|
||||
margin-left: 8px;
|
||||
color: #fff;
|
||||
padding: 2px 5px;
|
||||
}
|
||||
|
||||
::v-deep .history-info {
|
||||
font-size: 14px;
|
||||
color: #555;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
`
|
||||
})
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
<!--#
|
||||
}
|
||||
#-->
|
||||
@@ -2,82 +2,129 @@ const PROPOSAL_INFO = {
|
||||
name: "ProposalInfo",
|
||||
template: /*language=HTML*/ `
|
||||
<van-action-sheet v-model="visible" title="查看详情">
|
||||
<div class="process-title">基本信息</div>
|
||||
<van-cell-group>
|
||||
<van-cell title="提案名称">
|
||||
<div style="font-weight:bold;">
|
||||
{{ viewData.name }}
|
||||
</div>
|
||||
</van-cell>
|
||||
<van-cell title="提案编号">{{ viewData.code }}</van-cell>
|
||||
<van-cell title="提案人">{{ viewData.createUserName }}</van-cell>
|
||||
<van-cell title="提案时间">{{ viewData.createTime }}</van-cell>
|
||||
<van-cell title="教代会届次">{{ viewData.fullName }}</van-cell>
|
||||
<van-cell title="提案人单位">{{ viewData.unitName }}</van-cell>
|
||||
<van-cell :title="viewData.mannerCode!=='W03'?'代表团名称':'委员会名称'">
|
||||
{{ viewData.mannerCode !== 'W03' ? viewData.delegationName : viewData.committeeName }}
|
||||
</van-cell>
|
||||
<van-cell title="提案类别">
|
||||
{{viewData.typeName}}
|
||||
</van-cell>
|
||||
<van-cell title="立案结果">
|
||||
<dict-tag :options="dict.type.PROPOSAL_CASE_FILING_RESULT"
|
||||
:value="viewData.caseFilingResult"></dict-tag>
|
||||
</van-cell>
|
||||
<van-cell title="提案摘要">
|
||||
<div slot="label" class="font-size1 van-color-text-primary break-all" style="white-space: normal;">
|
||||
<div class="detail-container">
|
||||
<van-cell-group title="基本信息">
|
||||
<van-cell title="提案名称">
|
||||
<div style="font-weight:bold;">
|
||||
{{ viewData.name }}
|
||||
</div>
|
||||
</van-cell>
|
||||
<van-cell title="提案编号">{{ viewData.code }}</van-cell>
|
||||
<van-cell title="提案人">{{ viewData.createUserName }}</van-cell>
|
||||
<van-cell title="提案时间">{{ viewData.createTime }}</van-cell>
|
||||
<van-cell title="教代会届次">{{ viewData.fullName }}</van-cell>
|
||||
<van-cell title="提案人单位">{{ viewData.unitName }}</van-cell>
|
||||
<van-cell :title="viewData.mannerCode!=='W03'?'代表团名称':'委员会名称'">
|
||||
{{ viewData.mannerCode !== 'W03' ? viewData.delegationName : viewData.committeeName }}
|
||||
</van-cell>
|
||||
<van-cell title="提案类别">
|
||||
{{viewData.typeName}}
|
||||
</van-cell>
|
||||
<van-cell title="立案结果">
|
||||
<dict-tag :options="dict.type.PROPOSAL_CASE_FILING_RESULT"
|
||||
:value="viewData.caseFilingResult"></dict-tag>
|
||||
</van-cell>
|
||||
<van-cell title="提案摘要" class="direction-column-cell">
|
||||
<div v-html="viewData.excerpt"></div>
|
||||
</div>
|
||||
</van-cell>
|
||||
<van-cell title="提案内容">
|
||||
<div slot="label" class="font-size1 van-color-text-primary break-all" style="white-space: normal;">
|
||||
</van-cell>
|
||||
<van-cell title="提案内容" class="direction-column-cell">
|
||||
<div v-html="viewData.brief"></div>
|
||||
</div>
|
||||
</van-cell>
|
||||
<van-cell title="可行性分析">
|
||||
<div slot="label" class="font-size1 van-color-text-primary break-all">
|
||||
</van-cell>
|
||||
<van-cell title="可行性分析" class="direction-column-cell">
|
||||
<div v-html="viewData.measures"></div>
|
||||
</div>
|
||||
</van-cell>
|
||||
<!-- <van-cell title="附件">
|
||||
<div slot="label">
|
||||
{{viewData.files}}
|
||||
</div>
|
||||
</van-cell>-->
|
||||
<!-- <van-cell title="签字">-->
|
||||
<!-- <div slot="label">-->
|
||||
<!-- <van-image :src="viewData.signature"-->
|
||||
<!-- style="width: 100%;height: 150px;border: 1px dashed"></van-image>-->
|
||||
<!-- </div>-->
|
||||
<!-- </van-cell>-->
|
||||
</van-cell-group>
|
||||
</van-cell>
|
||||
<!-- <van-cell title="附件">
|
||||
<div slot="label">
|
||||
{{viewData.files}}
|
||||
</div>
|
||||
</van-cell>-->
|
||||
<!-- <van-cell title="签字">-->
|
||||
<!-- <div slot="label">-->
|
||||
<!-- <van-image :src="viewData.signature"-->
|
||||
<!-- style="width: 100%;height: 150px;border: 1px dashed"></van-image>-->
|
||||
<!-- </div>-->
|
||||
<!-- </van-cell>-->
|
||||
</van-cell-group>
|
||||
|
||||
<div class="process-title">
|
||||
附议人信息
|
||||
<template v-for="task in doneTasks">
|
||||
<van-cell-group :title="task.displayName" v-if="task.ext.isFirstTaskNode">
|
||||
<van-cell title="申请用户">{{ task.ext.initiatorName }}({{task.ext.initiatorAccount}})
|
||||
</van-cell>
|
||||
<van-cell title="申请时间">{{ task.finishTime }}</van-cell>
|
||||
<van-cell title="办理结果">
|
||||
<dict-tag :options="dict.type.PROCESS_TASK_SUBMIT_TYPE"
|
||||
:value="task.ext.submitType"></dict-tag>
|
||||
</van-cell>
|
||||
</van-cell-group>
|
||||
|
||||
<!--邀请附议人-->
|
||||
<van-cell-group :title="task.displayName"
|
||||
v-else-if="task.taskName === '85b7b9bd-d706-48cb-99a1-ef1370fb1819'">
|
||||
<van-cell title="办理用户">{{ task.taskFormData.userName }}({{task.taskFormData.loginName}})
|
||||
</van-cell>
|
||||
<van-cell title="办理时间">{{ task.finishTime }}</van-cell>
|
||||
<van-cell title="附议人" v-if="task.taskName === '85b7b9bd-d706-48cb-99a1-ef1370fb1819'" class="direction-column-cell">
|
||||
<el-table :data="task?.taskFormData?.seconder">
|
||||
<el-table-column label="姓名" prop="userName"></el-table-column>
|
||||
<el-table-column label="工号" prop="loginName"></el-table-column>
|
||||
<el-table-column label="性别" prop="sex"></el-table-column>
|
||||
<el-table-column label="单位" prop="unitName" show-overflow-tooltip></el-table-column>
|
||||
<el-table-column label="分工会" prop="unionName" show-overflow-tooltip></el-table-column>
|
||||
<el-table-column label="代表团" prop="delegationName" show-overflow-tooltip></el-table-column>
|
||||
</el-table>
|
||||
<!-- <table>-->
|
||||
<!-- <thead>-->
|
||||
<!-- <tr>-->
|
||||
<!-- <th>姓名</th>-->
|
||||
<!-- <th>工号</th>-->
|
||||
<!-- <th>性别</th>-->
|
||||
<!-- <th>单位</th>-->
|
||||
<!-- <th>分工会</th>-->
|
||||
<!-- <th>代表团</th>-->
|
||||
<!-- </tr>-->
|
||||
<!-- </thead>-->
|
||||
<!-- <tbody>-->
|
||||
<!-- <tr v-for="item in task?.taskFormData?.seconder">-->
|
||||
<!-- <td>{{item.userName}}</td>-->
|
||||
<!-- <td>{{item.loginName}}</td>-->
|
||||
<!-- <td>{{item.sex}}</td>-->
|
||||
<!-- <td>{{item.unitName}}</td>-->
|
||||
<!-- <td>{{item.unionName}}</td>-->
|
||||
<!-- <td>{{item.delegationName}}</td>-->
|
||||
<!-- </tr>-->
|
||||
<!-- </tbody>-->
|
||||
<!-- </table>-->
|
||||
</van-cell>
|
||||
</van-cell-group>
|
||||
|
||||
<!--提案委员会立案-->
|
||||
<van-cell-group :title="task.displayName"
|
||||
v-else-if="task.taskName === '9846ab38-40c5-4093-bafc-a9b3b443338b'">
|
||||
<van-cell title="办理用户">{{ task.taskFormData.userName }}({{task.taskFormData.loginName}})
|
||||
</van-cell>
|
||||
<van-cell title="办理时间">{{ task.finishTime }}</van-cell>
|
||||
<van-cell title="立案结果">
|
||||
<dict-tag :options="dict.type.PROPOSAL_CASE_FILING_RESULT"
|
||||
:value="task.ext.caseFilingResult"></dict-tag>
|
||||
</van-cell>
|
||||
<van-cell title="主办单位">{{ task.ext.tf_hostUnitName }}</van-cell>
|
||||
<van-cell title="协办单位">{{ task?.ext?.tf_helpUnitNames.join('、') }}</van-cell>
|
||||
</van-cell-group>
|
||||
|
||||
<van-cell-group :title="task.displayName" v-else>
|
||||
<van-cell title="办理用户">{{ task.taskFormData.userName }}({{task.taskFormData.loginName}})
|
||||
</van-cell>
|
||||
<van-cell title="办理时间">{{ task.finishTime }}</van-cell>
|
||||
<van-cell title="办理结果">
|
||||
<dict-tag :options="dict.type.PROPOSAL_CASE_FILING_RESULT"
|
||||
:value="task.ext.caseFilingResult"></dict-tag>
|
||||
</van-cell>
|
||||
<van-cell title="办理意见" v-if="!task.ext.isFirstTaskNode" class="direction-column-cell">
|
||||
<div v-html="task.taskFormData.tf_opinion"></div>
|
||||
</van-cell>
|
||||
</van-cell-group>
|
||||
</template>
|
||||
</div>
|
||||
<van-cell-group>
|
||||
<van-cell title="提案名称" v-for="item in viewData.seconders">
|
||||
<template slot="title">
|
||||
<span class="font-size1">{{item.createVariable.userName}}</span>
|
||||
<span class="margin-left10 font-size1 van-color-text-regular">/ {{item.createVariable.loginName}}</span>
|
||||
</template>
|
||||
<template slot="label">
|
||||
<span class="font-size0 van-color-text-assist">{{item.createVariable.unitName}}</span>
|
||||
</template>
|
||||
<template>
|
||||
<span class="font-size2 van-color-text-placeholder bold">
|
||||
<span v-if="item.extVariable && item.extVariable.bpmTaskApprovalType">
|
||||
<van-tag size="mini" type="success"
|
||||
v-if="item.extVariable.bpmTaskApprovalType==='PASS'">同意</van-tag>
|
||||
<van-tag size="mini" type="danger" v-if="item.extVariable.bpmTaskApprovalType==='REJECT'">拒绝</van-tag>
|
||||
</span>
|
||||
<span v-else>
|
||||
<van-tag size="mini">未附议</van-tag>
|
||||
</span>
|
||||
</span>
|
||||
</template>
|
||||
</van-cell>
|
||||
</van-cell-group>
|
||||
|
||||
<slot></slot>
|
||||
</van-action-sheet>
|
||||
@@ -86,7 +133,6 @@ const PROPOSAL_INFO = {
|
||||
data() {
|
||||
return {
|
||||
visible:false,
|
||||
|
||||
viewData: {},
|
||||
doneTasks: [],
|
||||
row: null,
|
||||
@@ -131,4 +177,4 @@ const PROPOSAL_INFO = {
|
||||
})
|
||||
},
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
+14
@@ -161,6 +161,20 @@ layout("/layouts/platform_h5.html"){
|
||||
}
|
||||
},
|
||||
|
||||
onRevoke(row){
|
||||
this.$dialog.confirm({
|
||||
title: "提示",
|
||||
message: "您确定要撤回吗?"
|
||||
}).then(() => {
|
||||
this.$axios.post("/flow/common/revokeTask", {taskId: row.taskId}).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.$toast.success(res.msg)
|
||||
this.doSearch()
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
doSearch() {
|
||||
this.$nextTick(() => {
|
||||
this.pageForm.pageNumber = 1
|
||||
|
||||
+224
@@ -0,0 +1,224 @@
|
||||
<!--#
|
||||
layout("/layouts/platform_h5.html"){
|
||||
#-->
|
||||
<div id="app" v-cloak>
|
||||
<van-nav-bar @click-left="historyBack" left-arrow left-text="返回" title="反馈评价" placeholder fixed></van-nav-bar>
|
||||
<van-sticky offset-top="46px">
|
||||
<van-search
|
||||
v-model="pageForm.name"
|
||||
:show-action="false"
|
||||
:reverse-color="false"
|
||||
input-align="left"
|
||||
placeholder="请输入提案名称搜索"
|
||||
@search="doSearch"
|
||||
></van-search>
|
||||
<van-dropdown-menu :close-on-click-outside="false" :close-on-click-overlay="false">
|
||||
<van-dropdown-item v-model="pageForm.sessionId" :options="sessionOptions" :multiple="false"
|
||||
@change="doSearch"></van-dropdown-item>
|
||||
</van-dropdown-menu>
|
||||
<van-tabs v-model="pageForm.approvalText"
|
||||
@change="(val)=>{this.pageForm.approval = val==='1';this.doSearch();}">
|
||||
<van-tab title="已评价" name="1"></van-tab>
|
||||
<van-tab title="未评价" name="0"></van-tab>
|
||||
</van-tabs>
|
||||
</van-sticky>
|
||||
|
||||
<table-list api="/platform/proposal/feedbackEvaluation/pageData" :page_form.sync="pageForm" @ready="onReady"
|
||||
ref="tableListRef"
|
||||
title="name">
|
||||
<template v-slot="{index,row}">
|
||||
<table-column label="提案编号">{{row.code}}</table-column>
|
||||
<table-column label="提案类别">{{row.typeName}}</table-column>
|
||||
<table-column label="提案人">{{row.createUserName}}</table-column>
|
||||
<table-column label="代表团">{{row.delegationName}}</table-column>
|
||||
<table-column label="当前节点">{{row.taskName}}</table-column>
|
||||
</template>
|
||||
<template #actions="{index,row}">
|
||||
<div class="action-btn" @click="onView(row)">
|
||||
<i class="fa fa-eye"></i>
|
||||
<span>查看</span>
|
||||
</div>
|
||||
<div class="action-btn" v-if="row.taskState === 10" @click="onApproval(row)">
|
||||
<i class="fa fa-edit"></i>
|
||||
<span>评价</span>
|
||||
</div>
|
||||
<div class="action-btn delete" v-if="row.canRevoke" @click="onRevoke(row)">
|
||||
<i class="fa fa-reply"></i>
|
||||
<span>撤回</span>
|
||||
</div>
|
||||
</template>
|
||||
</table-list>
|
||||
|
||||
<proposal-info ref="proposalInfoRef">
|
||||
<div v-if="showApprovalForm">
|
||||
<div class="process-title">{{formData.taskName}}</div>
|
||||
<van-form ref="formRef">
|
||||
<van-field
|
||||
v-model="formData.tf_feedback_name"
|
||||
name="tf_feedback_name"
|
||||
label="满意度"
|
||||
placeholder="请选择满意度"
|
||||
:rules="[{ required: true, message: '请选择满意度' }]"
|
||||
required
|
||||
is-link
|
||||
@click="showFeedBackPicker = true"
|
||||
></van-field>
|
||||
<van-popup v-model="showFeedBackPicker" position="bottom">
|
||||
<van-picker
|
||||
show-toolbar
|
||||
:columns="dict.type.PROPOSAL_FEEDBACK.map(item => ({text: item.label, value: item.code}))"
|
||||
@confirm="onFeedBackConfirm"
|
||||
@cancel="showFeedBackPicker = false"
|
||||
></van-picker>
|
||||
</van-popup>
|
||||
|
||||
<van-field
|
||||
v-model="formData.tf_opinion"
|
||||
name="tf_opinion"
|
||||
label="审批意见"
|
||||
placeholder="请输入审批意见"
|
||||
:rules="[{ required: true, message: '请填写审批意见' }]"
|
||||
required
|
||||
maxlength="100"
|
||||
show-word-limit
|
||||
></van-field>
|
||||
</van-form>
|
||||
<div style="display: flex; justify-content: space-between; column-gap: 10px; padding: 10px">
|
||||
<van-button type="danger" block @click="$refs.proposalInfoRef.onClose()">取消</van-button>
|
||||
<van-button type="primary" block @click="handleTaskAction(1)">提交</van-button>
|
||||
</div>
|
||||
</div>
|
||||
</proposal-info>
|
||||
|
||||
</div>
|
||||
<script>
|
||||
<!--#include("../../common/info.js"){}#-->
|
||||
|
||||
const vue = new Vue({
|
||||
el: "#app",
|
||||
dicts: ["PROPOSAL_FEEDBACK"],
|
||||
store,
|
||||
data() {
|
||||
return {
|
||||
pageForm: {
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
totalCount: 0,
|
||||
name: null,
|
||||
sessionId: null,
|
||||
approvalText: "0",
|
||||
approval: false
|
||||
},
|
||||
|
||||
sessionOptions: [],
|
||||
formData: {},
|
||||
showApprovalForm: false,
|
||||
|
||||
showFeedBackPicker: false
|
||||
}
|
||||
},
|
||||
components: {
|
||||
"proposal-info": PROPOSAL_INFO
|
||||
},
|
||||
methods: {
|
||||
onReady() {
|
||||
this.listSession()
|
||||
},
|
||||
listSession() {
|
||||
this.$axios.post("/platform/proposal/common/listSession").then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.sessionOptions = [
|
||||
{
|
||||
text: "全部届次",
|
||||
value: null
|
||||
}
|
||||
].concat(res.data.map((v) => ({text: v.fullName, value: v.id})))
|
||||
if (this.sessionOptions.length > 0) {
|
||||
this.pageForm.sessionId = this.sessionOptions[0].value
|
||||
this.doSearch()
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
onView(row) {
|
||||
this.showApprovalForm = false
|
||||
this.$refs.proposalInfoRef.onOpen(row)
|
||||
},
|
||||
|
||||
onApproval(row) {
|
||||
this.showApprovalForm = true
|
||||
this.$refs.proposalInfoRef.onOpen(row)
|
||||
this.formData = {
|
||||
processTaskId: row.taskId,
|
||||
taskName: row.curTaskName
|
||||
}
|
||||
},
|
||||
|
||||
onFeedBackConfirm({value, text}) {
|
||||
this.formData.tf_feedback_name = text
|
||||
this.formData.tf_feedback = value
|
||||
this.showFeedBackPicker = false
|
||||
},
|
||||
|
||||
async handleTaskAction(val) {
|
||||
try {
|
||||
await this.$refs.formRef.validate();
|
||||
this.$dialog.confirm({
|
||||
title: "提示",
|
||||
message: "您确定要提交吗?"
|
||||
}).then(async () => {
|
||||
const formData = {
|
||||
...this.formData,
|
||||
submitType: val
|
||||
}
|
||||
// 不满意
|
||||
if (this.formData.tf_feedback === 'DISSATISFIED') {
|
||||
const caseInfo = await this.getCaseInfo(this.formData.instanceId)
|
||||
formData.tf_hostUnitId = caseInfo.tf_hostUnitId
|
||||
}
|
||||
|
||||
this.$axios.post("/flow/common/executeTask", {
|
||||
data: JSON.stringify(formData)
|
||||
}).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.$refs.proposalInfoRef.onClose()
|
||||
this.$toast.success(res.msg)
|
||||
this.doSearch()
|
||||
}
|
||||
})
|
||||
}).catch(() => {
|
||||
|
||||
})
|
||||
} catch (error) {
|
||||
|
||||
}
|
||||
},
|
||||
|
||||
onRevoke(row) {
|
||||
this.$dialog.confirm({
|
||||
title: "提示",
|
||||
message: "您确定要撤回吗?"
|
||||
}).then(() => {
|
||||
this.$axios.post("/flow/common/revokeTask", {taskId: row.taskId}).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.$toast.success(res.msg)
|
||||
this.doSearch()
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
doSearch() {
|
||||
this.$nextTick(() => {
|
||||
this.pageForm.pageNumber = 1
|
||||
this.pageForm.totalCount = 0
|
||||
this.$refs.tableListRef.doSearch()
|
||||
})
|
||||
},
|
||||
}
|
||||
})
|
||||
</script>
|
||||
<!--#
|
||||
}
|
||||
#-->
|
||||
+189
@@ -0,0 +1,189 @@
|
||||
<!--#
|
||||
layout("/layouts/platform_h5.html"){
|
||||
#-->
|
||||
<div id="app" v-cloak>
|
||||
<van-nav-bar @click-left="historyBack" left-arrow left-text="返回" title="分管校领导审批" placeholder fixed></van-nav-bar>
|
||||
<van-sticky offset-top="46px">
|
||||
<van-search
|
||||
v-model="pageForm.name"
|
||||
:show-action="false"
|
||||
:reverse-color="false"
|
||||
input-align="left"
|
||||
placeholder="请输入提案名称搜索"
|
||||
@search="doSearch"
|
||||
></van-search>
|
||||
<van-dropdown-menu :close-on-click-outside="false" :close-on-click-overlay="false">
|
||||
<van-dropdown-item v-model="pageForm.sessionId" :options="sessionOptions" :multiple="false"
|
||||
@change="doSearch"></van-dropdown-item>
|
||||
</van-dropdown-menu>
|
||||
<van-tabs v-model="pageForm.approvalText"
|
||||
@change="(val)=>{this.pageForm.approval = val==='1';this.doSearch();}">
|
||||
<van-tab title="已审核" name="1"></van-tab>
|
||||
<van-tab title="未审核" name="0"></van-tab>
|
||||
</van-tabs>
|
||||
</van-sticky>
|
||||
|
||||
<table-list api="/platform/proposal/schoolLeaderApproval/pageData" :page_form.sync="pageForm" @ready="onReady"
|
||||
ref="tableListRef"
|
||||
title="name">
|
||||
<template v-slot="{index,row}">
|
||||
<table-column label="提案编号">{{row.code}}</table-column>
|
||||
<table-column label="提案类别">{{row.typeName}}</table-column>
|
||||
<table-column label="提案人">{{row.createUserName}}</table-column>
|
||||
<table-column label="代表团">{{row.delegationName}}</table-column>
|
||||
<table-column label="当前节点">{{row.taskName}}</table-column>
|
||||
</template>
|
||||
<template #actions="{index,row}">
|
||||
<div class="action-btn" @click="onView(row)">
|
||||
<i class="fa fa-eye"></i>
|
||||
<span>查看</span>
|
||||
</div>
|
||||
<div class="action-btn" v-if="row.taskState === 10" @click="onApproval(row)">
|
||||
<i class="fa fa-edit"></i>
|
||||
<span>审核</span>
|
||||
</div>
|
||||
<div class="action-btn delete" v-if="row.canRevoke" @click="onRevoke(row)">
|
||||
<i class="fa fa-reply"></i>
|
||||
<span>撤回</span>
|
||||
</div>
|
||||
</template>
|
||||
</table-list>
|
||||
|
||||
<proposal-info ref="proposalInfoRef">
|
||||
<div v-if="showApprovalForm">
|
||||
<div class="process-title">{{formData.taskName}}</div>
|
||||
<van-form ref="formRef">
|
||||
<van-field
|
||||
v-model="formData.tf_opinion"
|
||||
name="tf_opinion"
|
||||
label="审批意见"
|
||||
placeholder="请输入审批意见"
|
||||
:rules="[{ required: true, message: '请填写审批意见' }]"
|
||||
required
|
||||
maxlength="100"
|
||||
show-word-limit
|
||||
></van-field>
|
||||
</van-form>
|
||||
<div style="display: flex; justify-content: space-between; column-gap: 10px; padding: 10px">
|
||||
<van-button type="danger" block @click="handleTaskAction(4)">退回答复</van-button>
|
||||
<van-button type="primary" block @click="handleTaskAction(1)">同意答复</van-button>
|
||||
</div>
|
||||
</div>
|
||||
</proposal-info>
|
||||
|
||||
</div>
|
||||
<script>
|
||||
<!--#include("../../common/info.js"){}#-->
|
||||
|
||||
const vue = new Vue({
|
||||
el: "#app",
|
||||
store,
|
||||
data() {
|
||||
return {
|
||||
pageForm: {
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
totalCount: 0,
|
||||
name: null,
|
||||
sessionId: null,
|
||||
approvalText: "0",
|
||||
approval: false
|
||||
},
|
||||
|
||||
sessionOptions: [],
|
||||
formData: {},
|
||||
showApprovalForm: false
|
||||
}
|
||||
},
|
||||
components: {
|
||||
"proposal-info": PROPOSAL_INFO
|
||||
},
|
||||
methods: {
|
||||
onReady() {
|
||||
this.listSession()
|
||||
},
|
||||
listSession() {
|
||||
this.$axios.post("/platform/proposal/common/listSession").then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.sessionOptions = [
|
||||
{
|
||||
text: "全部届次",
|
||||
value: null
|
||||
}
|
||||
].concat(res.data.map((v) => ({text: v.fullName, value: v.id})))
|
||||
if (this.sessionOptions.length > 0) {
|
||||
this.pageForm.sessionId = this.sessionOptions[0].value
|
||||
this.doSearch()
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
onView(row) {
|
||||
this.showApprovalForm = false
|
||||
this.$refs.proposalInfoRef.onOpen(row)
|
||||
},
|
||||
|
||||
onApproval(row) {
|
||||
this.showApprovalForm = true
|
||||
this.$refs.proposalInfoRef.onOpen(row)
|
||||
this.formData = {
|
||||
processTaskId: row.taskId,
|
||||
taskName: row.curTaskName
|
||||
}
|
||||
},
|
||||
|
||||
async handleTaskAction(val) {
|
||||
try {
|
||||
await this.$refs.formRef.validate();
|
||||
this.$dialog.confirm({
|
||||
title: "提示",
|
||||
message: "您确定要提交吗?"
|
||||
}).then(() => {
|
||||
this.$axios.post("/flow/common/executeTask", {
|
||||
data: JSON.stringify({
|
||||
...this.formData,
|
||||
submitType: val
|
||||
})
|
||||
}).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.$refs.proposalInfoRef.onClose()
|
||||
this.$toast.success(res.msg)
|
||||
this.doSearch()
|
||||
}
|
||||
})
|
||||
}).catch(() => {
|
||||
|
||||
})
|
||||
} catch (error) {
|
||||
|
||||
}
|
||||
},
|
||||
|
||||
onRevoke(row){
|
||||
this.$dialog.confirm({
|
||||
title: "提示",
|
||||
message: "您确定要撤回吗?"
|
||||
}).then(() => {
|
||||
this.$axios.post("/flow/common/revokeTask", {taskId: row.taskId}).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.$toast.success(res.msg)
|
||||
this.doSearch()
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
doSearch() {
|
||||
this.$nextTick(() => {
|
||||
this.pageForm.pageNumber = 1
|
||||
this.pageForm.totalCount = 0
|
||||
this.$refs.tableListRef.doSearch()
|
||||
})
|
||||
},
|
||||
}
|
||||
})
|
||||
</script>
|
||||
<!--#
|
||||
}
|
||||
#-->
|
||||
+14
@@ -242,6 +242,20 @@ layout("/layouts/platform_h5.html"){
|
||||
}
|
||||
},
|
||||
|
||||
onRevoke(row){
|
||||
this.$dialog.confirm({
|
||||
title: "提示",
|
||||
message: "您确定要撤回吗?"
|
||||
}).then(() => {
|
||||
this.$axios.post("/flow/common/revokeTask", {taskId: row.taskId}).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.$toast.success(res.msg)
|
||||
this.doSearch()
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
doSearch() {
|
||||
this.$nextTick(() => {
|
||||
this.pageForm.pageNumber = 1
|
||||
|
||||
@@ -1,878 +0,0 @@
|
||||
<!--#
|
||||
layout("/layouts/platform_h5.html"){
|
||||
#-->
|
||||
|
||||
<style>
|
||||
:root {
|
||||
--primary-color: rgb(0, 78, 100);
|
||||
--primary-light: rgba(0, 78, 100, 0.1);
|
||||
--secondary-color: #37A6BD;
|
||||
--text-color: #333333;
|
||||
--text-secondary: #666666;
|
||||
--text-light: #999999;
|
||||
--bg-color: #f5f7fa;
|
||||
--card-bg: #ffffff;
|
||||
--border-color: #eeeeee;
|
||||
--success-color: #07c160;
|
||||
--warning-color: #ff976a;
|
||||
}
|
||||
|
||||
#app {
|
||||
min-height: 100vh;
|
||||
background-color: var(--bg-color);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
/* 筛选区域样式 */
|
||||
.filter-section {
|
||||
background-color: var(--card-bg);
|
||||
padding: 12px 16px;
|
||||
margin-bottom: 10px;
|
||||
overflow: hidden;
|
||||
transition: max-height 0.3s ease;
|
||||
}
|
||||
|
||||
.filter-section.collapsed {
|
||||
max-height: 84px;
|
||||
}
|
||||
|
||||
.filter-section.expanded {
|
||||
max-height: 500px;
|
||||
}
|
||||
|
||||
.filter-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.filter-title {
|
||||
font-size: 15px;
|
||||
font-weight: 500;
|
||||
color: var(--text-color);
|
||||
}
|
||||
|
||||
.filter-toggle {
|
||||
color: var(--text-secondary);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.filter-toggle .van-icon {
|
||||
transition: transform 0.3s;
|
||||
margin-left: 4px;
|
||||
}
|
||||
|
||||
.filter-toggle .van-icon.rotate {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
|
||||
.filter-content {
|
||||
transition: opacity 0.3s;
|
||||
}
|
||||
|
||||
.filter-content.hidden {
|
||||
opacity: 0;
|
||||
height: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.filter-row {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.filter-row:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.filter-label {
|
||||
font-size: 13px;
|
||||
color: var(--text-secondary);
|
||||
margin-right: 10px;
|
||||
min-width: 60px;
|
||||
padding-top: 4px;
|
||||
}
|
||||
|
||||
.filter-options {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.filter-tag {
|
||||
padding: 4px 10px;
|
||||
border-radius: 16px;
|
||||
font-size: 12px;
|
||||
margin-right: 8px;
|
||||
margin-bottom: 6px;
|
||||
background-color: var(--bg-color);
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
.filter-tag.active {
|
||||
background-color: var(--primary-light);
|
||||
color: var(--primary-color);
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.filter-search {
|
||||
padding: 8px 0;
|
||||
}
|
||||
|
||||
.filter-search .van-search {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.filter-search .van-search__content {
|
||||
background-color: var(--bg-color);
|
||||
}
|
||||
|
||||
.suggestion-list {
|
||||
padding: 16px;
|
||||
background-color: var(--bg-color);
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.van-pull-refresh, .van-list {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.suggestion-card {
|
||||
background-color: var(--card-bg);
|
||||
border-radius: 12px;
|
||||
margin-bottom: 16px;
|
||||
padding: 16px;
|
||||
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.04);
|
||||
border: 1px solid rgba(0, 0, 0, 0.02);
|
||||
}
|
||||
|
||||
.suggestion-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.suggestion-title {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: var(--text-color);
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.suggestion-status {
|
||||
font-size: 12px;
|
||||
padding: 3px 8px;
|
||||
border-radius: 12px;
|
||||
margin-left: 10px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.status-pending {
|
||||
background-color: #e6f7ff;
|
||||
color: #1890ff;
|
||||
}
|
||||
|
||||
.status-processing {
|
||||
background-color: #fff7e6;
|
||||
color: #fa8c16;
|
||||
}
|
||||
|
||||
.status-completed {
|
||||
background-color: #f6ffed;
|
||||
color: #52c41a;
|
||||
}
|
||||
|
||||
.suggestion-content {
|
||||
font-size: 14px;
|
||||
color: var(--text-secondary);
|
||||
line-height: 1.6;
|
||||
margin-bottom: 16px;
|
||||
overflow: hidden;
|
||||
background-color: var(--bg-color);
|
||||
padding: 10px;
|
||||
border-radius: 8px;
|
||||
word-break: break-all;
|
||||
white-space: pre-line;
|
||||
max-height: 3.2em;
|
||||
text-overflow: ellipsis;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.suggestion-submitter {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 13px;
|
||||
color: var(--text-secondary);
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.suggestion-submitter .van-icon {
|
||||
margin-right: 5px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.suggestion-unit {
|
||||
margin-left: 15px;
|
||||
}
|
||||
|
||||
.suggestion-footer {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
font-size: 13px;
|
||||
color: var(--text-light);
|
||||
border-top: 1px solid #f5f5f5;
|
||||
padding-top: 12px;
|
||||
}
|
||||
|
||||
.suggestion-time {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.suggestion-time .van-icon {
|
||||
font-size: 14px;
|
||||
margin-right: 4px;
|
||||
}
|
||||
|
||||
.suggestion-action {
|
||||
color: var(--primary-color);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.suggestion-action .van-icon {
|
||||
font-size: 14px;
|
||||
margin-left: 2px;
|
||||
}
|
||||
|
||||
.empty-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 64px 16px;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.empty-icon {
|
||||
font-size: 64px;
|
||||
color: #ddd;
|
||||
margin-bottom: 16px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.empty-text {
|
||||
font-size: 15px;
|
||||
color: var(--text-light);
|
||||
text-align: center;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
/* 详情弹窗样式 */
|
||||
.detail-popup {
|
||||
padding: 24px;
|
||||
max-height: 80vh;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.detail-header {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.detail-title {
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
margin-bottom: 10px;
|
||||
color: var(--text-color);
|
||||
}
|
||||
|
||||
.detail-meta {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
color: var(--text-light);
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.detail-section {
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.detail-label {
|
||||
color: var(--text-secondary);
|
||||
margin-bottom: 8px;
|
||||
font-weight: 500;
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
.detail-content {
|
||||
color: var(--text-color);
|
||||
line-height: 1.8;
|
||||
font-size: 15px;
|
||||
white-space: pre-wrap;
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
.submitter-info {
|
||||
background-color: var(--bg-color);
|
||||
border-radius: 8px;
|
||||
padding: 12px 15px;
|
||||
}
|
||||
|
||||
.info-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 8px;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.info-item:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.info-label {
|
||||
color: var(--text-secondary);
|
||||
width: 80px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.info-value {
|
||||
color: var(--text-color);
|
||||
flex: 1;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.detail-reply {
|
||||
background-color: #f9f9f9;
|
||||
padding: 16px;
|
||||
border-radius: 8px;
|
||||
border-left: 4px solid var(--primary-color);
|
||||
}
|
||||
|
||||
.detail-attachments {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.attachment-item {
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
margin-right: 10px;
|
||||
margin-bottom: 10px;
|
||||
border-radius: 6px;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.attachment-image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.reply-form {
|
||||
margin-top: 16px;
|
||||
}
|
||||
|
||||
.reply-textarea {
|
||||
box-sizing: border-box;
|
||||
padding: 12px;
|
||||
border: 1px solid var(--border-color);
|
||||
border-radius: 8px;
|
||||
width: 100%;
|
||||
height: 100px;
|
||||
font-size: 14px;
|
||||
background-color: var(--card-bg);
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.reply-attachments {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.reply-actions {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.no-reply {
|
||||
padding: 20px 0;
|
||||
text-align: center;
|
||||
background-color: var(--bg-color);
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.no-reply-icon {
|
||||
font-size: 36px;
|
||||
color: #ccc;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.no-reply-text {
|
||||
font-size: 14px;
|
||||
color: var(--text-light);
|
||||
}
|
||||
|
||||
.van-button--primary {
|
||||
background-color: var(--primary-color);
|
||||
border-color: var(--primary-color);
|
||||
}
|
||||
|
||||
/* 下拉刷新和上拉加载样式 */
|
||||
.van-pull-refresh__track {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.van-list {
|
||||
min-height: 100%;
|
||||
}
|
||||
|
||||
/* 统计面板 */
|
||||
.stats-panel {
|
||||
background-color: var(--card-bg);
|
||||
padding: 16px;
|
||||
margin-bottom: 10px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.stats-item {
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.stats-value {
|
||||
font-size: 20px;
|
||||
font-weight: bold;
|
||||
color: var(--primary-color);
|
||||
}
|
||||
|
||||
.stats-label {
|
||||
font-size: 12px;
|
||||
color: var(--text-secondary);
|
||||
margin-top: 4px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div id="app" v-cloak>
|
||||
<van-nav-bar title="意见箱管理" left-arrow @click-left="history.go(-1)" fixed placeholder></van-nav-bar>
|
||||
|
||||
<!-- 统计面板 -->
|
||||
<div class="stats-panel">
|
||||
<div class="stats-item">
|
||||
<div class="stats-value">{{ stats.total }}</div>
|
||||
<div class="stats-label">总意见数</div>
|
||||
</div>
|
||||
<div class="stats-item">
|
||||
<div class="stats-value">{{ stats.pending }}</div>
|
||||
<div class="stats-label">待回复</div>
|
||||
</div>
|
||||
<div class="stats-item">
|
||||
<div class="stats-value">{{ stats.replied }}</div>
|
||||
<div class="stats-label">已回复</div>
|
||||
</div>
|
||||
<div class="stats-item">
|
||||
<div class="stats-value">{{ stats.today }}</div>
|
||||
<div class="stats-label">今日新增</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 筛选区域 -->
|
||||
<div class="filter-section" :class="filters.isCollapsed ? 'collapsed' : 'expanded'">
|
||||
<div class="filter-header">
|
||||
<div class="filter-title">筛选条件</div>
|
||||
<div class="filter-toggle" @click="toggleFilterCollapse">
|
||||
<span>{{ filters.isCollapsed ? '展开' : '收起' }}</span>
|
||||
<van-icon :name="filters.isCollapsed ? 'arrow-down' : 'arrow-up'"
|
||||
:class="{ rotate: !filters.isCollapsed }"></van-icon>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="filter-search">
|
||||
<van-search v-model="filters.keyword" placeholder="搜索意见标题、内容或提交人"
|
||||
@search="onSearch"></van-search>
|
||||
</div>
|
||||
|
||||
<div class="filter-content" :class="{ hidden: filters.isCollapsed }">
|
||||
<div class="filter-row">
|
||||
<div class="filter-label">状态</div>
|
||||
<div class="filter-options">
|
||||
<div class="filter-tag" :class="{ active: filters.status === '' }" @click="setFilter('status', '')">
|
||||
全部
|
||||
</div>
|
||||
<div class="filter-tag" :class="{ active: filters.status === '0' }"
|
||||
@click="setFilter('status', '0')">
|
||||
待回复
|
||||
</div>
|
||||
<div class="filter-tag" :class="{ active: filters.status === '1' }"
|
||||
@click="setFilter('status', '1')">
|
||||
已回复
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="filter-row">
|
||||
<div class="filter-label">时间</div>
|
||||
<div class="filter-options">
|
||||
<div class="filter-tag" :class="{ active: filters.time === '' }" @click="setFilter('time', '')">全部
|
||||
</div>
|
||||
<div class="filter-tag" :class="{ active: filters.time === 'today' }"
|
||||
@click="setFilter('time', 'today')">今日
|
||||
</div>
|
||||
<div class="filter-tag" :class="{ active: filters.time === 'week' }"
|
||||
@click="setFilter('time', 'week')">
|
||||
本周
|
||||
</div>
|
||||
<div class="filter-tag" :class="{ active: filters.time === 'month' }"
|
||||
@click="setFilter('time', 'month')">本月
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 内容区域 -->
|
||||
<div class="suggestion-list">
|
||||
<!-- 下拉刷新和上拉加载更多 -->
|
||||
<van-pull-refresh v-model="refreshing" @refresh="onRefresh">
|
||||
<van-list
|
||||
v-model="loading"
|
||||
:finished="finished"
|
||||
finished-text="没有更多了"
|
||||
@load="loadMore"
|
||||
>
|
||||
<!-- 空状态 -->
|
||||
<div class="empty-list" v-if="suggestions.length === 0 && !loading">
|
||||
<van-icon name="comment-circle-o" class="empty-icon"></van-icon>
|
||||
<div class="empty-text">暂无符合条件的意见</div>
|
||||
</div>
|
||||
|
||||
<!-- 意见列表 -->
|
||||
<div class="suggestion-card" v-for="(item, index) in suggestions" :key="item.id"
|
||||
@click="showDetail(item)">
|
||||
<div class="suggestion-header">
|
||||
<div class="suggestion-title">{{ item.title || '意见反馈' }}</div>
|
||||
<div class="suggestion-status" :class="getStatusClass(item.isReply)">
|
||||
{{ getStatusText(item.isReply) }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="suggestion-submitter">
|
||||
<van-icon name="contact"/>
|
||||
<span>{{ item.submitterName }}</span>
|
||||
<span class="suggestion-unit">{{ item.submitterUnitName }}</span>
|
||||
</div>
|
||||
<div class="suggestion-content">{{ item.content }}</div>
|
||||
<div class="suggestion-footer">
|
||||
<div class="suggestion-time">
|
||||
<van-icon name="clock-o"/>
|
||||
<span>{{ formatDate(item.submitTime) }}</span>
|
||||
</div>
|
||||
<div class="suggestion-action">
|
||||
{{ item.reply ? '查看详情' : '去回复' }}
|
||||
<van-icon name="arrow"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</van-list>
|
||||
</van-pull-refresh>
|
||||
</div>
|
||||
|
||||
<!-- 详情弹出层 -->
|
||||
<van-popup v-model="showDetailPopup" round closeable position="bottom">
|
||||
<div class="detail-popup" v-if="currentSuggestion">
|
||||
<div class="detail-header">
|
||||
<div class="detail-title">{{ currentSuggestion.title || '意见反馈' }}</div>
|
||||
<div class="detail-meta">
|
||||
<span>{{ formatDate(currentSuggestion.submitTime) }}</span>
|
||||
<span :class="getStatusClass(currentSuggestion.isReply)">{{ getStatusText(currentSuggestion.isReply) }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="detail-section">
|
||||
<div class="detail-label">提交人信息</div>
|
||||
<div class="submitter-info">
|
||||
<div class="info-item">
|
||||
<span class="info-label">姓名:</span>
|
||||
<span class="info-value">{{ currentSuggestion.submitterName || '未填写' }}</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<span class="info-label">工号:</span>
|
||||
<span class="info-value">{{ currentSuggestion.submitterLoginName || '未填写' }}</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<span class="info-label">单位:</span>
|
||||
<span class="info-value">{{ currentSuggestion.submitterUnitName || '未填写' }}</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<span class="info-label">联系方式:</span>
|
||||
<span class="info-value">{{ currentSuggestion.concat || '未填写' }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="detail-section">
|
||||
<div class="detail-label">意见内容</div>
|
||||
<div class="detail-content">{{ currentSuggestion.content }}</div>
|
||||
</div>
|
||||
|
||||
<div class="detail-section"
|
||||
v-if="currentSuggestion.attachments && currentSuggestion.attachments.length > 0">
|
||||
<div class="detail-label">附件</div>
|
||||
<div class="detail-attachments">
|
||||
<div class="attachment-item" v-for="(file, idx) in currentSuggestion.attachments" :key="idx"
|
||||
@click.stop="previewImage(file.url, idx)">
|
||||
<img :src="file.url" class="attachment-image">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="detail-section" v-if="currentSuggestion.reply">
|
||||
<div class="detail-label">已回复内容</div>
|
||||
<div class="detail-reply detail-content">{{ currentSuggestion.reply }}</div>
|
||||
<div class="detail-meta" style="margin-top: 10px;">
|
||||
回复时间:{{ formatDate(currentSuggestion.replyTime) }}
|
||||
</div>
|
||||
<div v-if="currentSuggestion.replyAttachments && currentSuggestion.replyAttachments.length > 0"
|
||||
style="margin-top: 12px;">
|
||||
<div class="detail-label">回复附件</div>
|
||||
<div class="detail-attachments">
|
||||
<div class="attachment-item" v-for="(file, idx) in currentSuggestion.replyAttachments"
|
||||
:key="idx" @click.stop="previewImage(file.url, idx, 'reply')">
|
||||
<img :src="file.url" class="attachment-image">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="detail-section">
|
||||
<div class="detail-label">{{ currentSuggestion.isReply ? '修改回复' : '回复意见' }}</div>
|
||||
<div class="reply-form">
|
||||
<textarea class="reply-textarea" v-model="currentSuggestion.replyContent"
|
||||
placeholder="请输入回复内容..."></textarea>
|
||||
|
||||
<!-- <div class="reply-attachments">-->
|
||||
<!-- <vant-file-upload :files.sync="formData.replyAttachments" :max="15"></vant-file-upload>-->
|
||||
<!-- </div>-->
|
||||
|
||||
<div class="reply-actions">
|
||||
<van-button style="border-radius: 10px" block type="info" :color="themeColor"
|
||||
@click="submitReply">提交回复
|
||||
</van-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</van-popup>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
new Vue({
|
||||
el: '#app',
|
||||
data() {
|
||||
return {
|
||||
refreshing: false,
|
||||
loading: false,
|
||||
finished: false,
|
||||
showDetailPopup: false,
|
||||
currentSuggestion: null,
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
suggestions: [],
|
||||
replyContent: '',
|
||||
replyAttachments: [],
|
||||
filters: {
|
||||
status: '', // 状态筛选
|
||||
time: '', // 时间筛选
|
||||
keyword: '', // 关键词搜索
|
||||
isCollapsed: true // 筛选区域是否折叠
|
||||
},
|
||||
stats: {
|
||||
total: 0,
|
||||
pending: 0,
|
||||
replied: 0,
|
||||
today: 0
|
||||
},
|
||||
formData: {}
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.loadStats();
|
||||
this.loadData();
|
||||
},
|
||||
methods: {
|
||||
// 加载统计数据
|
||||
loadStats() {
|
||||
$.post('/platform/suggestionBox/admin/getStats').done((res) => {
|
||||
if (res.code === 0 && res.data) {
|
||||
this.stats = {
|
||||
total: res.data.total || 0,
|
||||
pending: res.data.pending || 0,
|
||||
replied: res.data.replied || 0,
|
||||
today: res.data.today || 0
|
||||
};
|
||||
}
|
||||
}).fail(() => {
|
||||
this.$toast.fail('统计数据加载失败');
|
||||
});
|
||||
},
|
||||
|
||||
// 加载意见数据
|
||||
loadData() {
|
||||
this.loading = true;
|
||||
$.post('/platform/suggestionBox/admin/pageData', {
|
||||
pageNumber: this.pageNumber,
|
||||
pageSize: this.pageSize,
|
||||
status: this.filters.status,
|
||||
timeRange: this.filters.time,
|
||||
keyword: this.filters.keyword
|
||||
}).done((res) => {
|
||||
if (res.code === 0 && res.data) {
|
||||
if (this.pageNumber === 1) {
|
||||
this.suggestions = res.data.list || [];
|
||||
} else {
|
||||
this.suggestions = this.suggestions.concat(res.data.list || []);
|
||||
}
|
||||
|
||||
this.finished = !res.data.list || res.data.list.length < this.pageSize;
|
||||
} else {
|
||||
this.finished = true;
|
||||
}
|
||||
this.loading = false;
|
||||
this.refreshing = false;
|
||||
}).fail(() => {
|
||||
this.loading = false;
|
||||
this.refreshing = false;
|
||||
this.finished = true;
|
||||
});
|
||||
},
|
||||
|
||||
// 下拉刷新
|
||||
onRefresh() {
|
||||
this.pageNumber = 1;
|
||||
this.finished = false;
|
||||
this.loadStats();
|
||||
this.loadData();
|
||||
},
|
||||
|
||||
// 上拉加载更多
|
||||
loadMore() {
|
||||
this.pageNumber++;
|
||||
this.loadData();
|
||||
},
|
||||
|
||||
// 设置筛选条件
|
||||
setFilter(type, value) {
|
||||
this.filters[type] = value;
|
||||
this.pageNumber = 1;
|
||||
this.finished = false;
|
||||
this.loadData();
|
||||
},
|
||||
|
||||
// 搜索
|
||||
onSearch() {
|
||||
this.pageNumber = 1;
|
||||
this.finished = false;
|
||||
this.loadData();
|
||||
},
|
||||
|
||||
// 查看详情
|
||||
showDetail(suggestion) {
|
||||
if (suggestion.attachments && typeof suggestion.attachments === 'string') {
|
||||
try{
|
||||
suggestion.attachments = JSON.parse(suggestion.attachments);
|
||||
}catch (e){
|
||||
suggestion.attachments = [];
|
||||
}
|
||||
}
|
||||
console.log(suggestion)
|
||||
this.currentSuggestion = suggestion;
|
||||
this.showDetailPopup = true;
|
||||
},
|
||||
|
||||
// 提交回复
|
||||
submitReply() {
|
||||
if (!this.currentSuggestion.replyContent || !this.currentSuggestion.replyContent.trim()) {
|
||||
this.$toast('请输入回复内容');
|
||||
return;
|
||||
}
|
||||
|
||||
this.$dialog.confirm({
|
||||
title: '确认提交',
|
||||
message: '确定提交此回复内容吗?'
|
||||
}).then(() => {
|
||||
// 提交回复
|
||||
$.post('/platform/suggestionBox/admin/reply', {
|
||||
reply: JSON.stringify(this.currentSuggestion)
|
||||
}).done((res) => {
|
||||
if (res.code === 0) {
|
||||
this.$toast.success('回复成功');
|
||||
this.showDetailPopup = false;
|
||||
this.loadStats();
|
||||
this.pageData();
|
||||
} else {
|
||||
this.$toast.fail(res.msg || '回复失败');
|
||||
}
|
||||
}).fail(() => {
|
||||
this.$toast.fail('网络错误,请重试');
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
// 获取状态class
|
||||
getStatusClass(isReply) {
|
||||
if (!isReply || isReply === 0) return 'status-pending';
|
||||
if (isReply === 1) return 'status-processing';
|
||||
return 'status-completed';
|
||||
},
|
||||
|
||||
// 获取状态文本
|
||||
getStatusText(isReply) {
|
||||
if (!isReply || isReply === 0) return '待回复';
|
||||
if (isReply === 1) return '已回复';
|
||||
return '已处理';
|
||||
},
|
||||
|
||||
// 格式化日期
|
||||
formatDate(dateStr) {
|
||||
if (!dateStr) return '';
|
||||
const date = new Date(dateStr);
|
||||
return date.getFullYear() + '-' + String(date.getMonth() + 1).padStart(2, '0') + '-' + String(date.getDate()).padStart(2, '0');
|
||||
},
|
||||
|
||||
// 预览图片
|
||||
previewImage(url, index, type = 'submission') {
|
||||
if (!url) return;
|
||||
|
||||
// 创建图片查看器
|
||||
const urls = type === 'reply'
|
||||
? this.currentSuggestion.replyAttachments.map(file => file.url)
|
||||
: this.currentSuggestion.attachments.map(file => file.url);
|
||||
|
||||
this.$imagePreview({
|
||||
images: urls,
|
||||
startPosition: index
|
||||
});
|
||||
},
|
||||
|
||||
// 切换筛选区域折叠状态
|
||||
toggleFilterCollapse() {
|
||||
this.filters.isCollapsed = !this.filters.isCollapsed;
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<!--#}#-->
|
||||
@@ -1,538 +0,0 @@
|
||||
<!--#
|
||||
layout("/layouts/platform_h5.html"){
|
||||
#-->
|
||||
|
||||
<div id="app" v-cloak>
|
||||
<van-nav-bar title="意见箱" fixed placeholder></van-nav-bar>
|
||||
|
||||
<!-- 顶部Banner区域 -->
|
||||
<div class="banner-section">
|
||||
<div class="banner-content">
|
||||
<div class="banner-text">
|
||||
<h2>我们重视您的意见</h2>
|
||||
<p>每一条建议都将认真对待</p>
|
||||
</div>
|
||||
<div class="banner-image">
|
||||
<img src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxMjggMTI4Ij48cGF0aCBkPSJNMTI1LjYgMTAyLjdsLTE5LTE2LjhtLTQuNy0yMy43bDExLjUtNi44TTU3LjQgMTZsMTEuNSAxMS43TTMxLjIgNTMuOGwyMy42IDcuOSIgc3R5bGU9ImZpbGw6bm9uZTtzdHJva2U6I2ZmZjtzdHJva2UtbGluZWNhcDpyb3VuZDtzdHJva2UtbWl0ZXJsaW1pdDoxMDtvcGFjaXR5Oi40Ii8+PHBhdGggZD0iTTY0LjEgMzEuN0w0NyA0OS45Yy0zIDMuMi0zLjEgOC4xLS4xIDExLjJsMjQuNCAyNWMzIDMuMSA3LjkgMy4yIDExIC4xTDk5IDY5YzMtMy4yIDMuMS04LjEuMS0xMS4yTDc0LjcgMzIuOGMtMyAzLjEtNy45IDMuMS0xMC42LTEuMXoiIHN0eWxlPSJmaWxsOiNmZmY7c3Ryb2tlOiNmZmY7c3Ryb2tlLW1pdGVybGltaXQ6MTAiLz48cGF0aCBkPSJNMTA4LjkgOTUuN2wtMTUuOC0xMi0xMi4yIDEzIDE0LjQgMTMuN2MuMyAyLjUgMi4zIDQuNSA0LjggNC41aDEzLjdjMi43IDAgNC45LTIuMiA0LjktNC45VjkzLjVjMC0yLjgtMi4xLTUtNC45LTV2OC40cy4xLTEuMi00LjkgMi44LjEtMyAuMS0zeiIgc3R5bGU9ImZpbGw6I2ZmZjtzdHJva2U6I2ZmZjtzdHJva2UtbGluZWNhcDpyb3VuZDtzdHJva2UtbWl0ZXJsaW1pdDoxMCIvPjwvc3ZnPg==" alt="Feedback">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 功能卡片区域 -->
|
||||
<div class="cards-container">
|
||||
<!-- 提交意见 -->
|
||||
<div class="feature-card" @click="goToSubmitPage">
|
||||
<div class="card-icon submit-icon">
|
||||
<van-icon name="edit" />
|
||||
</div>
|
||||
<div class="card-info">
|
||||
<h3>提交意见</h3>
|
||||
<p>分享您的想法和建议</p>
|
||||
</div>
|
||||
<div class="card-arrow">
|
||||
<van-icon name="arrow" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 我的意见 -->
|
||||
<div class="feature-card" @click="goToMyOpinionsPage">
|
||||
<div class="card-icon my-icon">
|
||||
<van-icon name="records" />
|
||||
</div>
|
||||
<div class="card-info">
|
||||
<h3>我的意见</h3>
|
||||
<p>查看您提交的所有意见</p>
|
||||
</div>
|
||||
<div class="card-arrow">
|
||||
<van-icon name="arrow" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 意见管理(管理员) -->
|
||||
<div class="feature-card" v-if="isAdmin" @click="goToAllOpinionsPage">
|
||||
<div class="card-icon admin-icon">
|
||||
<van-icon name="manager" />
|
||||
</div>
|
||||
<div class="card-info">
|
||||
<h3>意见管理</h3>
|
||||
<p>管理所有用户提交的意见</p>
|
||||
</div>
|
||||
<div class="card-arrow">
|
||||
<van-icon name="arrow" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 使用指南 -->
|
||||
<div class="guide-container" v-if="!isAdmin">
|
||||
<div class="guide-header">
|
||||
<h3>使用指南</h3>
|
||||
</div>
|
||||
<div class="guide-steps">
|
||||
<div class="guide-step">
|
||||
<div class="step-number">1</div>
|
||||
<div class="step-content">
|
||||
<h4>提交意见</h4>
|
||||
<p>点击"提交意见"按钮,填写您的意见和建议</p>
|
||||
</div>
|
||||
<div class="step-icon">
|
||||
<van-icon name="edit" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="step-divider"></div>
|
||||
<div class="guide-step">
|
||||
<div class="step-number">2</div>
|
||||
<div class="step-content">
|
||||
<h4>等待处理</h4>
|
||||
<p>我们将在3个工作日内处理您的意见</p>
|
||||
</div>
|
||||
<div class="step-icon">
|
||||
<van-icon name="underway-o" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="step-divider"></div>
|
||||
<div class="guide-step">
|
||||
<div class="step-number">3</div>
|
||||
<div class="step-content">
|
||||
<h4>查看回复</h4>
|
||||
<p>在"我的意见"中查看官方回复</p>
|
||||
</div>
|
||||
<div class="step-icon">
|
||||
<van-icon name="comment-o" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 常见问题 -->
|
||||
<div class="faq-container" v-if="!isAdmin">
|
||||
<div class="faq-header">
|
||||
<h3>常见问题</h3>
|
||||
<span class="faq-subtitle">解答您的疑惑</span>
|
||||
</div>
|
||||
<div class="faq-list">
|
||||
<div class="faq-item" :class="{'faq-active': activeFaq === 1}" @click="toggleFaq(1)">
|
||||
<div class="faq-question">
|
||||
<span class="faq-icon"><van-icon name="question-o" /></span>
|
||||
<span>如何提交带附件的意见?</span>
|
||||
<span class="faq-arrow"><van-icon name="arrow-down" /></span>
|
||||
</div>
|
||||
<div class="faq-answer" v-show="activeFaq === 1">
|
||||
<p>在提交意见表单中,您可以上传最多3个文件作为附件,支持图片格式。点击附件上传区域,选择您要上传的文件即可。</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="faq-item" :class="{'faq-active': activeFaq === 2}" @click="toggleFaq(2)">
|
||||
<div class="faq-question">
|
||||
<span class="faq-icon"><van-icon name="question-o" /></span>
|
||||
<span>意见提交后多久能收到回复?</span>
|
||||
<span class="faq-arrow"><van-icon name="arrow-down" /></span>
|
||||
</div>
|
||||
<div class="faq-answer" v-show="activeFaq === 2">
|
||||
<p>我们会在3个工作日内处理您的意见,紧急问题会优先处理。您可以随时在"我的意见"中查看处理进度。</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="faq-item" :class="{'faq-active': activeFaq === 3}" @click="toggleFaq(3)">
|
||||
<div class="faq-question">
|
||||
<span class="faq-icon"><van-icon name="question-o" /></span>
|
||||
<span>我可以修改已提交的意见吗?</span>
|
||||
<span class="faq-arrow"><van-icon name="arrow-down" /></span>
|
||||
</div>
|
||||
<div class="faq-answer" v-show="activeFaq === 3">
|
||||
<p>提交后的意见暂不支持修改,如有补充,请重新提交并说明这是对之前意见的补充。我们会将相关意见关联处理。</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
:root {
|
||||
--primary-color: rgb(0, 78, 100);
|
||||
--primary-light: rgba(0, 78, 100, 0.1);
|
||||
--secondary-color: #37A6BD;
|
||||
--text-color: #333333;
|
||||
--text-secondary: #666666;
|
||||
--text-light: #999999;
|
||||
--bg-color: #f6f6f6;
|
||||
--card-bg: #ffffff;
|
||||
--border-color: #eeeeee;
|
||||
--success-color: #07c160;
|
||||
--warning-color: #ff976a;
|
||||
}
|
||||
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', Helvetica, Segoe UI, Arial, Roboto, 'PingFang SC', 'miui', 'Hiragino Sans GB', 'Microsoft Yahei', sans-serif;
|
||||
background-color: var(--bg-color);
|
||||
color: var(--text-color);
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.page-container {
|
||||
padding-bottom: 50px;
|
||||
}
|
||||
|
||||
/* 顶部Banner */
|
||||
.banner-section {
|
||||
padding: 0;
|
||||
height: 180px;
|
||||
background: linear-gradient(135deg, var(--primary-color) 0%, var(--secondary-color) 100%);
|
||||
position: relative;
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
.banner-curve {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.banner-content {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 24px 20px 0;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.banner-text {
|
||||
color: white;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.banner-text h2 {
|
||||
font-size: 24px;
|
||||
font-weight: 600;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.banner-text p {
|
||||
font-size: 14px;
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
.banner-image {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.banner-image img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
/* 功能卡片 */
|
||||
.cards-container {
|
||||
padding: 20px 16px 16px;
|
||||
margin-top: -20px;
|
||||
position: relative;
|
||||
z-index: 10;
|
||||
background-color: var(--bg-color);
|
||||
border-radius: 20px 20px 0 0;
|
||||
}
|
||||
|
||||
.feature-card {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
background: var(--card-bg);
|
||||
border-radius: 12px;
|
||||
padding: 16px;
|
||||
margin-bottom: 12px;
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.feature-card:active {
|
||||
transform: scale(0.98);
|
||||
}
|
||||
|
||||
.card-icon {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
border-radius: 12px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
margin-right: 16px;
|
||||
}
|
||||
|
||||
.card-icon .van-icon {
|
||||
font-size: 24px;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.submit-icon {
|
||||
background: linear-gradient(135deg, #1989fa 0%, #39b9f9 100%);
|
||||
}
|
||||
|
||||
.my-icon {
|
||||
background: linear-gradient(135deg, #07c160 0%, #10d878 100%);
|
||||
}
|
||||
|
||||
.admin-icon {
|
||||
background: linear-gradient(135deg, #ff6b6b 0%, #ffaa7f 100%);
|
||||
}
|
||||
|
||||
.card-info {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.card-info h3 {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
margin-bottom: 4px;
|
||||
color: var(--text-color);
|
||||
}
|
||||
|
||||
.card-info p {
|
||||
font-size: 13px;
|
||||
color: var(--text-light);
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.card-arrow {
|
||||
color: #ccc;
|
||||
}
|
||||
|
||||
/* 使用指南 */
|
||||
.guide-container {
|
||||
padding: 0 16px 16px;
|
||||
}
|
||||
|
||||
.guide-header {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.guide-header h3 {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: var(--text-color);
|
||||
}
|
||||
|
||||
.guide-steps {
|
||||
background: var(--card-bg);
|
||||
border-radius: 12px;
|
||||
padding: 16px;
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
.guide-step {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.step-number {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
border-radius: 50%;
|
||||
background: var(--primary-color);
|
||||
color: white;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
font-weight: 600;
|
||||
margin-right: 16px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.step-content {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.step-content h4 {
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
margin-bottom: 4px;
|
||||
color: var(--text-color);
|
||||
}
|
||||
|
||||
.step-content p {
|
||||
font-size: 13px;
|
||||
color: var(--text-secondary);
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.step-icon {
|
||||
margin-left: 12px;
|
||||
color: var(--primary-color);
|
||||
}
|
||||
|
||||
.step-divider {
|
||||
height: 24px;
|
||||
width: 1px;
|
||||
background: #e8e8e8;
|
||||
margin: 8px 0 8px 15px;
|
||||
}
|
||||
|
||||
/* 常见问题 */
|
||||
.faq-container {
|
||||
padding: 0 16px 16px;
|
||||
}
|
||||
|
||||
.faq-header {
|
||||
margin-bottom: 16px;
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
}
|
||||
|
||||
.faq-header h3 {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: var(--text-color);
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.faq-subtitle {
|
||||
font-size: 12px;
|
||||
color: var(--text-light);
|
||||
}
|
||||
|
||||
.faq-list {
|
||||
background: var(--card-bg);
|
||||
border-radius: 12px;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
.faq-item {
|
||||
border-bottom: 1px solid var(--border-color);
|
||||
}
|
||||
|
||||
.faq-item:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.faq-question {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 16px;
|
||||
cursor: pointer;
|
||||
transition: background-color 0.3s ease;
|
||||
}
|
||||
|
||||
.faq-active .faq-question {
|
||||
background-color: var(--primary-light);
|
||||
}
|
||||
|
||||
.faq-icon {
|
||||
color: var(--primary-color);
|
||||
margin-right: 12px;
|
||||
}
|
||||
|
||||
.faq-arrow {
|
||||
margin-left: auto;
|
||||
color: var(--text-light);
|
||||
transition: transform 0.3s ease;
|
||||
}
|
||||
|
||||
.faq-active .faq-arrow .van-icon {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
|
||||
.faq-answer {
|
||||
padding: 0 16px 16px 44px;
|
||||
color: var(--text-secondary);
|
||||
font-size: 13px;
|
||||
line-height: 1.6;
|
||||
border-top: 1px dashed var(--border-color);
|
||||
background-color: rgba(0, 0, 0, 0.02);
|
||||
}
|
||||
|
||||
/* 弹窗样式 */
|
||||
.popup-title {
|
||||
text-align: center;
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
padding: 16px 0;
|
||||
border-bottom: 1px solid #ebedf0;
|
||||
}
|
||||
|
||||
.popup-content {
|
||||
padding: 16px;
|
||||
max-height: calc(100% - 60px);
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.suggestion-content {
|
||||
font-size: 14px;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.suggestion-title {
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
margin-bottom: 6px;
|
||||
color: var(--text-color);
|
||||
}
|
||||
|
||||
.suggestion-meta {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
color: var(--text-light);
|
||||
}
|
||||
|
||||
.attachment-list {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
new Vue({
|
||||
el: '#app',
|
||||
data: function() {
|
||||
return {
|
||||
isAdmin: true, // 控制是否为管理员
|
||||
allSuggestions: [],
|
||||
user: 'user1',
|
||||
activeFaq: null,
|
||||
totalSuggestions: 0,
|
||||
respondedPercent: 0,
|
||||
recentSuggestions: []
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
userSuggestions: function() {
|
||||
return this.allSuggestions.filter(function(item) {
|
||||
return item.user === this.user;
|
||||
}.bind(this));
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
goToSubmitPage: function() {
|
||||
window.location.href = '/platform/suggestionBox/h5/write';
|
||||
},
|
||||
goToMyOpinionsPage: function() {
|
||||
window.location.href = '/platform/suggestionBox/h5/mine';
|
||||
},
|
||||
goToAllOpinionsPage: function() {
|
||||
window.location.href = '/platform/suggestionBox/admin/h5';
|
||||
},
|
||||
toggleFaq: function(id) {
|
||||
this.activeFaq = this.activeFaq === id ? null : id;
|
||||
},
|
||||
loadStats: function() {
|
||||
// 模拟加载统计数据
|
||||
this.totalSuggestions = 25;
|
||||
this.respondedPercent = 80;
|
||||
this.recentSuggestions = [1, 2, 3];
|
||||
}
|
||||
},
|
||||
created: function() {
|
||||
// 初始化数据
|
||||
if (this.isAdmin) {
|
||||
this.loadStats();
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<!--#
|
||||
}
|
||||
#-->
|
||||
@@ -0,0 +1,91 @@
|
||||
const SUGGESTION_BOX_INFO = {
|
||||
template: /*language=HTML*/ `
|
||||
<van-action-sheet v-model="visible" title="查看详情">
|
||||
<div class="detail-container">
|
||||
<van-cell-group title="基本信息">
|
||||
<van-cell title="姓名">{{viewData.userName}}</van-cell>
|
||||
<van-cell title="工号">{{viewData.loginName}}</van-cell>
|
||||
<van-cell title="单位">{{viewData.unitName}}</van-cell>
|
||||
<van-cell title="工会">{{viewData.unionName}}</van-cell>
|
||||
<van-cell title="标题">{{viewData.title}}</van-cell>
|
||||
<van-cell title="意见建议内容" class="direction-column-cell">{{viewData.content}}</van-cell>
|
||||
</van-cell-group>
|
||||
|
||||
<template v-for="task in doneTasks">
|
||||
<van-cell-group :title="task.displayName" v-if="task.ext.isFirstTaskNode">
|
||||
<van-cell title="申请用户">{{ task.ext.initiatorName }}({{task.ext.initiatorAccount}})
|
||||
</van-cell>
|
||||
<van-cell title="申请时间">{{ task.finishTime }}</van-cell>
|
||||
<van-cell title="办理结果">
|
||||
<dict-tag :options="dict.type.PROCESS_TASK_SUBMIT_TYPE"
|
||||
:value="task.ext.submitType"></dict-tag>
|
||||
</van-cell>
|
||||
</van-cell-group>
|
||||
|
||||
<van-cell-group :title="task.displayName" v-else>
|
||||
<van-cell title="办理用户">{{ task.taskFormData.userName }}({{task.taskFormData.loginName}})
|
||||
</van-cell>
|
||||
<van-cell title="办理时间">{{ task.finishTime }}</van-cell>
|
||||
<van-cell title="办理结果">
|
||||
<dict-tag :options="dict.type.PROPOSAL_CASE_FILING_RESULT"
|
||||
:value="task.ext.caseFilingResult"></dict-tag>
|
||||
</van-cell>
|
||||
<van-cell title="办理意见" v-if="!task.ext.isFirstTaskNode" class="direction-column-cell">
|
||||
<div v-html="task.taskFormData.tf_opinion"></div>
|
||||
</van-cell>
|
||||
</van-cell-group>
|
||||
</template>
|
||||
</div>
|
||||
<slot></slot>
|
||||
</van-action-sheet>
|
||||
`,
|
||||
dicts: ["PROCESS_TASK_SUBMIT_TYPE"],
|
||||
data(){
|
||||
return{
|
||||
visible: false,
|
||||
viewData: {},
|
||||
doneTasks: [],
|
||||
row: null,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 打开
|
||||
onOpen(row) {
|
||||
this.row = row
|
||||
this.visible = true
|
||||
this.getInfo()
|
||||
this.getDoneTasks()
|
||||
},
|
||||
|
||||
// 关闭
|
||||
onClose(){
|
||||
this.visible = false
|
||||
},
|
||||
|
||||
// 获取申请信息
|
||||
getInfo() {
|
||||
this.$axios.post('/platform/suggestionBox/common/info', {id: this.row.id}).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.viewData = res.data || {}
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
// 查看提案
|
||||
openView(id) {
|
||||
this.$nextTick(() => {
|
||||
this.$refs.infoDialogRef.onOpen(id)
|
||||
})
|
||||
},
|
||||
|
||||
// 获取已办任务审批记录
|
||||
getDoneTasks() {
|
||||
this.$axios.post("/flow/common/doneTasks", {bizId: this.row.id}).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.doneTasks = res.data
|
||||
}
|
||||
})
|
||||
},
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,542 +0,0 @@
|
||||
<!--#
|
||||
layout("/layouts/platform_h5.html"){
|
||||
#-->
|
||||
|
||||
<style>
|
||||
:root {
|
||||
--primary-color: rgb(0, 78, 100);
|
||||
--primary-light: rgba(0, 78, 100, 0.1);
|
||||
--secondary-color: #37a6bd;
|
||||
--text-color: #333333;
|
||||
--text-secondary: #666666;
|
||||
--text-light: #999999;
|
||||
--bg-color: #f5f7fa;
|
||||
--card-bg: #ffffff;
|
||||
--border-color: #eeeeee;
|
||||
--success-color: #07c160;
|
||||
--warning-color: #ff976a;
|
||||
}
|
||||
|
||||
#app {
|
||||
min-height: 100vh;
|
||||
background-color: var(--bg-color);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
/* 页面样式 */
|
||||
.suggestion-list {
|
||||
padding: 16px;
|
||||
background-color: var(--bg-color);
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.van-pull-refresh,
|
||||
.van-list {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.suggestion-card {
|
||||
background-color: var(--card-bg);
|
||||
border-radius: 12px;
|
||||
margin-bottom: 16px;
|
||||
padding: 16px;
|
||||
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.04);
|
||||
transition: all 0.2s ease;
|
||||
border: 1px solid rgba(0, 0, 0, 0.02);
|
||||
}
|
||||
|
||||
.suggestion-card:active {
|
||||
transform: scale(0.98);
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
|
||||
}
|
||||
|
||||
.suggestion-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.suggestion-title {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: var(--text-color);
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.suggestion-status {
|
||||
font-size: 12px;
|
||||
padding: 3px 8px;
|
||||
border-radius: 12px;
|
||||
margin-left: 10px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.status-pending {
|
||||
background-color: #e6f7ff;
|
||||
color: #1890ff;
|
||||
}
|
||||
|
||||
.status-processing {
|
||||
background-color: #fff7e6;
|
||||
color: #fa8c16;
|
||||
}
|
||||
|
||||
.status-completed {
|
||||
background-color: #f6ffed;
|
||||
color: #52c41a;
|
||||
}
|
||||
|
||||
.suggestion-content {
|
||||
font-size: 14px;
|
||||
color: var(--text-secondary);
|
||||
line-height: 1.6;
|
||||
margin-bottom: 16px;
|
||||
overflow: hidden;
|
||||
background-color: var(--bg-color);
|
||||
padding: 10px;
|
||||
border-radius: 8px;
|
||||
word-break: break-all;
|
||||
white-space: pre-line;
|
||||
max-height: 3.2em;
|
||||
text-overflow: ellipsis;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.suggestion-footer {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
font-size: 13px;
|
||||
color: var(--text-light);
|
||||
border-top: 1px solid #f5f5f5;
|
||||
padding-top: 12px;
|
||||
}
|
||||
|
||||
.suggestion-time {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.suggestion-time .van-icon {
|
||||
font-size: 14px;
|
||||
margin-right: 4px;
|
||||
}
|
||||
|
||||
.suggestion-action {
|
||||
color: var(--primary-color);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.suggestion-action .van-icon {
|
||||
font-size: 14px;
|
||||
margin-left: 2px;
|
||||
}
|
||||
|
||||
.empty-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 64px 16px;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.empty-icon {
|
||||
font-size: 64px;
|
||||
color: #ddd;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.empty-text {
|
||||
font-size: 15px;
|
||||
color: var(--text-light);
|
||||
text-align: center;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
/* 详情弹窗样式 */
|
||||
.detail-popup {
|
||||
padding: 24px;
|
||||
max-height: 80vh;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.detail-header {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.detail-title {
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
margin-bottom: 10px;
|
||||
color: var(--text-color);
|
||||
}
|
||||
|
||||
.detail-meta {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
color: var(--text-light);
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.detail-section {
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.detail-label {
|
||||
color: var(--text-secondary);
|
||||
margin-bottom: 8px;
|
||||
font-weight: 500;
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
.detail-content {
|
||||
color: var(--text-color);
|
||||
line-height: 1.8;
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
.detail-reply {
|
||||
background-color: #f9f9f9;
|
||||
padding: 16px;
|
||||
border-radius: 8px;
|
||||
border-left: 4px solid var(--primary-color);
|
||||
}
|
||||
|
||||
.detail-attachments {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.attachment-item {
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
margin-right: 10px;
|
||||
margin-bottom: 10px;
|
||||
border-radius: 6px;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.attachment-image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.loader {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.van-button--primary {
|
||||
background-color: var(--primary-color);
|
||||
border-color: var(--primary-color);
|
||||
}
|
||||
|
||||
/* 下拉刷新和上拉加载样式 */
|
||||
.van-pull-refresh__track {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.van-list {
|
||||
min-height: 100%;
|
||||
}
|
||||
|
||||
.no-reply {
|
||||
padding: 20px 0;
|
||||
text-align: center;
|
||||
background-color: var(--bg-color);
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.no-reply-icon {
|
||||
font-size: 36px;
|
||||
color: #ccc;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.no-reply-text {
|
||||
font-size: 14px;
|
||||
color: var(--text-light);
|
||||
}
|
||||
|
||||
.submitter-info {
|
||||
background-color: var(--bg-color);
|
||||
border-radius: 8px;
|
||||
padding: 12px 15px;
|
||||
}
|
||||
|
||||
.info-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 8px;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.info-item:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.info-label {
|
||||
color: var(--text-secondary);
|
||||
width: 80px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.info-value {
|
||||
color: var(--text-color);
|
||||
flex: 1;
|
||||
font-size: 14px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div id="app" v-cloak>
|
||||
<van-nav-bar title="我的意见建议" left-arrow @click-left="history.go(-1)" fixed placeholder></van-nav-bar>
|
||||
|
||||
<!-- 内容区域 -->
|
||||
<div class="suggestion-list">
|
||||
<!-- 下拉刷新和上拉加载更多 -->
|
||||
<van-pull-refresh v-model="refreshing" @refresh="onRefresh">
|
||||
<van-list v-model="loading" :finished="finished" finished-text="没有更多了" @load="loadMore">
|
||||
<!-- 空状态 -->
|
||||
<div class="empty-list" v-if="suggestions.length === 0 && !loading">
|
||||
<van-icon name="comment-circle-o" class="empty-icon" />
|
||||
<div class="empty-text">您还没有提交过意见</div>
|
||||
<van-button type="primary" size="normal" round @click="goToSubmitPage">去提交意见</van-button>
|
||||
</div>
|
||||
|
||||
<!-- 意见列表 -->
|
||||
<div class="suggestion-card" v-for="(item, index) in suggestions" :key="item.id" @click="showDetail(item)">
|
||||
<div class="suggestion-header">
|
||||
<div class="suggestion-title">{{ item.title || '意见反馈' }}</div>
|
||||
<div class="suggestion-status" :class="getStatusClass(item.isReply)">{{ item.node_name }}</div>
|
||||
</div>
|
||||
<div class="suggestion-content">{{ item.content }}</div>
|
||||
<div class="suggestion-footer">
|
||||
<div class="suggestion-time">
|
||||
<van-icon name="clock-o" />
|
||||
<span>{{ formatDate(item.submitTime) }}</span>
|
||||
</div>
|
||||
<div style="display: flex; column-gap: 10px">
|
||||
<div class="suggestion-action">
|
||||
查看详情
|
||||
<van-icon name="arrow" />
|
||||
</div>
|
||||
<div class="suggestion-action" v-if="item.flow_status==='1'" @click.stop="onRevoke(item)">
|
||||
撤销
|
||||
<van-icon name="arrow" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</van-list>
|
||||
</van-pull-refresh>
|
||||
</div>
|
||||
|
||||
<!-- 详情弹出层 -->
|
||||
<van-popup v-model="showDetailPopup" round closeable position="bottom" :style="{ height: '80%' }">
|
||||
<div class="detail-popup" v-if="currentSuggestion">
|
||||
<div class="detail-header">
|
||||
<div class="detail-title">{{ currentSuggestion.title || '意见反馈' }}</div>
|
||||
<div class="detail-meta">
|
||||
<span>{{ formatDate(currentSuggestion.submitTime) }}</span>
|
||||
<span :class="getStatusClass(currentSuggestion.isReply)">{{ getStatusText(currentSuggestion.isReply) }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="detail-section">
|
||||
<div class="detail-label">提交人信息</div>
|
||||
<div class="submitter-info">
|
||||
<div class="info-item">
|
||||
<span class="info-label">姓名:</span>
|
||||
<span class="info-value">{{ currentSuggestion.submitterName || '未填写' }}</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<span class="info-label">工号:</span>
|
||||
<span class="info-value">{{ currentSuggestion.submitterLoginName || '未填写' }}</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<span class="info-label">单位:</span>
|
||||
<span class="info-value">{{ currentSuggestion.submitterUnitName || '未填写' }}</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<span class="info-label">联系方式:</span>
|
||||
<span class="info-value">{{ currentSuggestion.concat || '未填写' }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="detail-section">
|
||||
<div class="detail-label">意见内容</div>
|
||||
<div class="detail-content">{{ currentSuggestion.content }}</div>
|
||||
</div>
|
||||
|
||||
<div class="detail-section" v-if="currentSuggestion.attachments && currentSuggestion.attachments.length > 0">
|
||||
<div class="detail-label">附件</div>
|
||||
<div class="detail-attachments">
|
||||
<div
|
||||
class="attachment-item"
|
||||
v-for="(file, idx) in currentSuggestion.attachments"
|
||||
:key="idx"
|
||||
@click.stop="previewImage(file.url, idx)"
|
||||
>
|
||||
<img :src="file.url" class="attachment-image" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="detail-section" v-if="currentSuggestion.isReply">
|
||||
<div class="detail-label">回复</div>
|
||||
<div class="detail-reply detail-content">{{ currentSuggestion.replyContent }}</div>
|
||||
</div>
|
||||
|
||||
<div v-else class="detail-section">
|
||||
<div class="detail-label">回复</div>
|
||||
<div class="no-reply">
|
||||
<van-icon name="chat-o" class="no-reply-icon" />
|
||||
<div class="no-reply-text">暂无回复,请耐心等待</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</van-popup>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
new Vue({
|
||||
el: "#app",
|
||||
data() {
|
||||
return {
|
||||
refreshing: false,
|
||||
loading: false,
|
||||
finished: false,
|
||||
showDetailPopup: false,
|
||||
currentSuggestion: null,
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
suggestions: []
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.loadData()
|
||||
},
|
||||
methods: {
|
||||
loadData() {
|
||||
this.loading = true
|
||||
$.post("/platform/suggestionBox/pageData", {
|
||||
pageNumber: this.pageNumber,
|
||||
pageSize: this.pageSize
|
||||
})
|
||||
.done((res) => {
|
||||
if (res.code === 0 && res.data) {
|
||||
if (this.pageNumber === 1) {
|
||||
this.suggestions = res.data.list || []
|
||||
} else {
|
||||
this.suggestions = this.suggestions.concat(res.data.list || [])
|
||||
}
|
||||
|
||||
this.finished = !res.data.list || res.data.list.length < this.pageSize
|
||||
} else {
|
||||
this.finished = true
|
||||
}
|
||||
this.loading = false
|
||||
this.refreshing = false
|
||||
})
|
||||
.fail(() => {
|
||||
this.loading = false
|
||||
this.refreshing = false
|
||||
this.finished = true
|
||||
})
|
||||
},
|
||||
|
||||
// 下拉刷新
|
||||
onRefresh() {
|
||||
this.pageNumber = 1
|
||||
this.finished = false
|
||||
this.loadData()
|
||||
},
|
||||
|
||||
// 上拉加载更多
|
||||
loadMore() {
|
||||
this.pageNumber++
|
||||
this.loadData()
|
||||
},
|
||||
|
||||
// 查看详情
|
||||
showDetail(suggestion) {
|
||||
if (suggestion.attachments && typeof suggestion.attachments === "string") {
|
||||
try {
|
||||
suggestion.attachments = JSON.parse(suggestion.attachments)
|
||||
} catch (e) {
|
||||
suggestion.attachments = []
|
||||
}
|
||||
}
|
||||
this.currentSuggestion = suggestion
|
||||
this.showDetailPopup = true
|
||||
},
|
||||
|
||||
// 获取状态class
|
||||
getStatusClass(isReply) {
|
||||
if (!isReply || isReply === 0) return "status-pending"
|
||||
if (isReply === 1) return "status-processing"
|
||||
return "status-completed"
|
||||
},
|
||||
|
||||
// 获取状态文本
|
||||
getStatusText(isReply) {
|
||||
if (!isReply || isReply === 0) return "待处理"
|
||||
if (isReply === 1) return "处理中"
|
||||
return "已处理"
|
||||
},
|
||||
|
||||
// 格式化日期
|
||||
formatDate(dateStr) {
|
||||
if (!dateStr) return ""
|
||||
const date = new Date(dateStr)
|
||||
return date.getFullYear() + "-" + String(date.getMonth() + 1).padStart(2, "0") + "-" + String(date.getDate()).padStart(2, "0")
|
||||
},
|
||||
|
||||
// 前往提交意见页面
|
||||
goToSubmitPage() {
|
||||
window.location.href = "/platform/suggestionBox/h5/write"
|
||||
},
|
||||
|
||||
// 预览图片
|
||||
previewImage(url, index) {
|
||||
if (!url) return
|
||||
|
||||
// 创建图片查看器
|
||||
const urls = this.currentSuggestion.attachments.map((file) => file.url)
|
||||
this.$imagePreview({
|
||||
images: urls,
|
||||
startPosition: index
|
||||
})
|
||||
},
|
||||
|
||||
// 撤销
|
||||
onRevoke(item) {
|
||||
this.$dialog
|
||||
.confirm({
|
||||
title: "提示",
|
||||
message: "您确认要撤销吗?"
|
||||
})
|
||||
.then(() => {})
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<!--#}#-->
|
||||
+22
-137
@@ -2,120 +2,9 @@
|
||||
layout("/layouts/platform_h5.html"){
|
||||
#-->
|
||||
|
||||
<style>
|
||||
/*.list-container {*/
|
||||
/* padding: 0;*/
|
||||
/*}*/
|
||||
/*.list-item {*/
|
||||
/* background-color: #fff;*/
|
||||
/* border-bottom: 1px solid #eaecef;*/
|
||||
/* padding: 16px;*/
|
||||
/* position: relative;*/
|
||||
/* margin-bottom: 10px;*/
|
||||
/*}*/
|
||||
/*.list-item:last-child {*/
|
||||
/* border-bottom: none;*/
|
||||
/*}*/
|
||||
/*.item-header {*/
|
||||
/* display: flex;*/
|
||||
/* justify-content: space-between;*/
|
||||
/* align-items: flex-start;*/
|
||||
/* margin-bottom: 10px;*/
|
||||
/*}*/
|
||||
/*.item-title {*/
|
||||
/* font-size: 16px;*/
|
||||
/* font-weight: 500;*/
|
||||
/* color: #1f2f3d;*/
|
||||
/* overflow: hidden;*/
|
||||
/* text-overflow: ellipsis;*/
|
||||
/* white-space: nowrap;*/
|
||||
/* flex: 1;*/
|
||||
/* padding-right: 10px;*/
|
||||
/*}*/
|
||||
/*.item-meta {*/
|
||||
/* display: flex;*/
|
||||
/* color: #606266;*/
|
||||
/* font-size: 14px;*/
|
||||
/* margin-bottom: 5px;*/
|
||||
/* padding: 4px 0;*/
|
||||
/*}*/
|
||||
/*.meta-item {*/
|
||||
/* display: flex;*/
|
||||
/* align-items: center;*/
|
||||
/* gap: 8px;*/
|
||||
/* width: 100%;*/
|
||||
/*}*/
|
||||
/*.meta-item i {*/
|
||||
/* font-size: 14px;*/
|
||||
/* color: #909399;*/
|
||||
/* width: 16px;*/
|
||||
/* text-align: center;*/
|
||||
/*}*/
|
||||
/*.item-content {*/
|
||||
/* color: #606266;*/
|
||||
/* font-size: 14px;*/
|
||||
/* overflow: hidden;*/
|
||||
/* text-overflow: ellipsis;*/
|
||||
/* display: -webkit-box;*/
|
||||
/* -webkit-line-clamp: 2;*/
|
||||
/* -webkit-box-orient: vertical;*/
|
||||
/* line-height: 1.5;*/
|
||||
/*}*/
|
||||
/*.item-footer {*/
|
||||
/* display: flex;*/
|
||||
/* justify-content: space-between;*/
|
||||
/* margin-top: 12px;*/
|
||||
/* padding-top: 8px;*/
|
||||
/* border-top: 1px dashed #eaecef;*/
|
||||
/* color: #909399;*/
|
||||
/* font-size: 13px;*/
|
||||
/*}*/
|
||||
/*.item-actions {*/
|
||||
/* display: flex;*/
|
||||
/* justify-content: space-around;*/
|
||||
/* margin-top: 15px;*/
|
||||
/* padding-top: 12px;*/
|
||||
/* border-top: 1px solid #eaecef;*/
|
||||
/*}*/
|
||||
/*.action-btn {*/
|
||||
/* display: flex;*/
|
||||
/* align-items: center;*/
|
||||
/* justify-content: end;*/
|
||||
/* font-size: 14px;*/
|
||||
/* color: var(--color-primary);*/
|
||||
/* padding: 4px 0;*/
|
||||
/* flex: 1;*/
|
||||
/*}*/
|
||||
/*.action-btn i {*/
|
||||
/* margin-right: 6px;*/
|
||||
/* font-size: 16px;*/
|
||||
/*}*/
|
||||
/*.action-btn.delete {*/
|
||||
/* color: #f56c6c;*/
|
||||
/*}*/
|
||||
/*.action-btn.review {*/
|
||||
/* color: #67c23a;*/
|
||||
/*}*/
|
||||
/*.empty-state {*/
|
||||
/* text-align: center;*/
|
||||
/* padding: 60px 20px;*/
|
||||
/* color: #909399;*/
|
||||
/*}*/
|
||||
/*.empty-state i {*/
|
||||
/* font-size: 60px;*/
|
||||
/* margin-bottom: 16px;*/
|
||||
/* color: #dcdee0;*/
|
||||
/*}*/
|
||||
/*.empty-state p {*/
|
||||
/* margin-top: 10px;*/
|
||||
/* font-size: 14px;*/
|
||||
/*}*/
|
||||
</style>
|
||||
|
||||
<div id="app" v-cloak>
|
||||
<van-nav-bar @click-left="historyBack" left-arrow left-text="返回" title="我的建言献策" placeholder
|
||||
fixed></van-nav-bar>
|
||||
|
||||
<van-sticky offset-top="46px">
|
||||
<van-search
|
||||
v-model="pageForm.searchKeyword"
|
||||
@@ -127,10 +16,9 @@ layout("/layouts/platform_h5.html"){
|
||||
></van-search>
|
||||
</van-sticky>
|
||||
|
||||
<table-list api="/platform/proposal/mine/pageData" :page_form.sync="pageForm">
|
||||
<table-list api="/platform/suggestionBox/mine/pageData" :page_form.sync="pageForm" @ready="onReady" ref="tableListRef" title="title">
|
||||
<template v-slot="{index,row}">
|
||||
<table-column label="申请人">{{row.userName}}</table-column>
|
||||
<table-column label="所属单位">{{row.unitName}}</table-column>
|
||||
<table-column label="申请时间">{{row.submitTime}}</table-column>
|
||||
<table-column label="当前节点">{{row.taskName}}</table-column>
|
||||
</template>
|
||||
@@ -155,12 +43,20 @@ layout("/layouts/platform_h5.html"){
|
||||
</div>
|
||||
</template>
|
||||
</table-list>
|
||||
|
||||
<suggestion-box-info ref="suggestionBoxInfoRef"></suggestion-box-info>
|
||||
|
||||
</div>
|
||||
|
||||
<script>
|
||||
<!--#include('../info.js'){}#-->
|
||||
|
||||
new Vue({
|
||||
el: '#app',
|
||||
store,
|
||||
components: {
|
||||
'suggestion-box-info': SUGGESTION_BOX_INFO
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
pageForm: {
|
||||
@@ -174,35 +70,28 @@ layout("/layouts/platform_h5.html"){
|
||||
},
|
||||
methods: {
|
||||
historyBack,
|
||||
doSearch() {
|
||||
this.pageForm.pageNumber = 1
|
||||
this.pageForm.totalCount = 0
|
||||
this.tableData = []
|
||||
this.pageData()
|
||||
|
||||
onReady(){
|
||||
this.doSearch()
|
||||
},
|
||||
pageData() {
|
||||
$.post('/platform/suggestionBox/mine/pageData', this.pageForm).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.tableData = this.tableData.concat(res.data.list)
|
||||
this.pageForm.totalCount = res.data.totalCount
|
||||
if (this.tableData.length >= this.pageForm.totalCount) {
|
||||
this.tableFinished = true
|
||||
} else {
|
||||
this.pageForm.pageNumber++
|
||||
}
|
||||
this.tableLoading = false
|
||||
}
|
||||
|
||||
doSearch() {
|
||||
this.$nextTick(() => {
|
||||
this.pageForm.pageNumber = 1
|
||||
this.pageForm.totalCount = 0
|
||||
this.$refs.tableListRef.doSearch()
|
||||
})
|
||||
},
|
||||
|
||||
// 查看详情
|
||||
onView(item) {
|
||||
|
||||
onView(row) {
|
||||
this.showApprovalForm = false
|
||||
this.$refs.suggestionBoxInfoRef.onOpen(row)
|
||||
},
|
||||
|
||||
// 编辑
|
||||
onEdit(row) {
|
||||
|
||||
this.$pjaxReplace("/platform/h5/suggestionBox/write?bizId=" + row.id + "&taskId=" + row.startTaskId)
|
||||
},
|
||||
|
||||
// 撤回
|
||||
@@ -221,7 +110,6 @@ layout("/layouts/platform_h5.html"){
|
||||
});
|
||||
},
|
||||
|
||||
//
|
||||
onDelete(id) {
|
||||
this.$dialog.confirm({
|
||||
title: '提示',
|
||||
@@ -236,9 +124,6 @@ layout("/layouts/platform_h5.html"){
|
||||
}).catch(() => {
|
||||
});
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.pageData()
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
<!--#
|
||||
layout("/layouts/platform_h5.html"){
|
||||
#-->
|
||||
|
||||
<div id="app" v-cloak>
|
||||
<van-nav-bar @click-left="historyBack" left-arrow left-text="返回" title="建言献策查询" placeholder
|
||||
fixed></van-nav-bar>
|
||||
<van-sticky offset-top="46px">
|
||||
<van-search
|
||||
v-model="pageForm.searchKeyword"
|
||||
:show-action="false"
|
||||
:reverse-color="false"
|
||||
input-align="left"
|
||||
placeholder="请输入关键字搜索"
|
||||
@search="doSearch"
|
||||
></van-search>
|
||||
</van-sticky>
|
||||
|
||||
<table-list api="/platform/suggestionBox/query/pageData" :page_form.sync="pageForm" @ready="onReady"
|
||||
ref="tableListRef" title="title">
|
||||
<template v-slot="{index,row}">
|
||||
<table-column label="申请人">{{row.userName}}</table-column>
|
||||
<table-column label="申请时间">{{row.submitTime}}</table-column>
|
||||
<table-column label="当前节点">{{row.taskName}}</table-column>
|
||||
</template>
|
||||
<template #actions="{index,row}">
|
||||
<div class="action-btn" @click="onView(row)">
|
||||
<i class="fa fa-eye"></i>
|
||||
<span>查看</span>
|
||||
</div>
|
||||
</template>
|
||||
</table-list>
|
||||
|
||||
<suggestion-box-info ref="suggestionBoxInfoRef"></suggestion-box-info>
|
||||
|
||||
</div>
|
||||
|
||||
<script>
|
||||
<!--#include('../info.js'){}#-->
|
||||
|
||||
new Vue({
|
||||
el: '#app',
|
||||
store,
|
||||
components: {
|
||||
'suggestion-box-info': SUGGESTION_BOX_INFO
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
pageForm: {
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
totalCount: 0,
|
||||
searchKeyword: "",
|
||||
},
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
historyBack,
|
||||
|
||||
onReady() {
|
||||
this.doSearch()
|
||||
},
|
||||
|
||||
doSearch() {
|
||||
this.$nextTick(() => {
|
||||
this.pageForm.pageNumber = 1
|
||||
this.pageForm.totalCount = 0
|
||||
this.$refs.tableListRef.doSearch()
|
||||
})
|
||||
},
|
||||
|
||||
// 查看详情
|
||||
onView(row) {
|
||||
this.showApprovalForm = false
|
||||
this.$refs.suggestionBoxInfoRef.onOpen(row)
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<!--#
|
||||
}
|
||||
#-->
|
||||
@@ -1,363 +0,0 @@
|
||||
<!--#
|
||||
layout("/layouts/platform_h5.html"){
|
||||
#-->
|
||||
|
||||
<style>
|
||||
.task-form-container {
|
||||
padding: 16px;
|
||||
background-color: #f5f7fa;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
.card {
|
||||
background-color: #fff;
|
||||
border-radius: 12px;
|
||||
margin-bottom: 16px;
|
||||
padding: 16px;
|
||||
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.04);
|
||||
}
|
||||
|
||||
.card-title {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
margin-bottom: 16px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.card-title::before {
|
||||
content: "";
|
||||
display: inline-block;
|
||||
width: 4px;
|
||||
height: 16px;
|
||||
background-color: rgb(0, 78, 100);
|
||||
margin-right: 8px;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
.info-item {
|
||||
display: flex;
|
||||
margin-bottom: 12px;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.info-label {
|
||||
color: #666;
|
||||
width: 80px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.info-value {
|
||||
color: #333;
|
||||
flex: 1;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.content-box {
|
||||
background-color: #f9f9f9;
|
||||
padding: 12px;
|
||||
border-radius: 8px;
|
||||
margin-top: 8px;
|
||||
white-space: pre-line;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.status-tag {
|
||||
display: inline-block;
|
||||
padding: 2px 8px;
|
||||
border-radius: 12px;
|
||||
font-size: 12px;
|
||||
margin-left: 8px;
|
||||
}
|
||||
|
||||
.status-pending {
|
||||
background-color: #e6f7ff;
|
||||
color: #1890ff;
|
||||
}
|
||||
|
||||
.status-processing {
|
||||
background-color: #fff7e6;
|
||||
color: #fa8c16;
|
||||
}
|
||||
|
||||
.status-completed {
|
||||
background-color: #f6ffed;
|
||||
color: #52c41a;
|
||||
}
|
||||
|
||||
.timeline {
|
||||
padding: 8px 0;
|
||||
}
|
||||
|
||||
.reply-form {
|
||||
margin-top: 16px;
|
||||
}
|
||||
|
||||
.reply-textarea {
|
||||
width: 100%;
|
||||
height: 120px;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 8px;
|
||||
padding: 12px;
|
||||
margin-bottom: 16px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.btn-container {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div id="app" v-cloak>
|
||||
<van-nav-bar title="意见箱处理" left-arrow @click-left="goBack" fixed placeholder></van-nav-bar>
|
||||
|
||||
<div class="task-form-container">
|
||||
<!-- 加载状态 -->
|
||||
<van-empty v-if="loading" description="加载中...">
|
||||
<template #image>
|
||||
<van-loading type="spinner" size="36" />
|
||||
</template>
|
||||
</van-empty>
|
||||
|
||||
<template v-else>
|
||||
<!-- 业务表单数据 -->
|
||||
<div class="card">
|
||||
<div class="card-title">基本信息</div>
|
||||
<div class="info-item">
|
||||
<span class="info-label">提交人:</span>
|
||||
<span class="info-value">{{ suggestionData.submitterName }}</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<span class="info-label">工号:</span>
|
||||
<span class="info-value">{{ suggestionData.submitterLoginName }}</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<span class="info-label">单位:</span>
|
||||
<span class="info-value">{{ suggestionData.submitterUnitName }}</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<span class="info-label">联系方式:</span>
|
||||
<span class="info-value">{{ suggestionData.concat }}</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<span class="info-label">提交时间:</span>
|
||||
<span class="info-value">{{ formatDate(suggestionData.submitTime) }}</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<span class="info-label">标题:</span>
|
||||
<span class="info-value">{{ suggestionData.title || '无标题' }}</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<span class="info-label">内容:</span>
|
||||
</div>
|
||||
<div class="content-box">{{ suggestionData.content }}</div>
|
||||
</div>
|
||||
|
||||
<!-- 流程信息 -->
|
||||
<div class="card">
|
||||
<div class="card-title">
|
||||
流程信息
|
||||
<span class="status-tag" :class="getStatusClass()">{{ getStatusText() }}</span>
|
||||
</div>
|
||||
<div class="timeline">
|
||||
<van-steps direction="vertical" :active="flowHistory.length - 1">
|
||||
<van-step v-for="(item, index) in flowHistory" :key="index">
|
||||
<h3>{{ item.taskName }}</h3>
|
||||
<p>处理人: {{ item.assigneeName || '系统' }}</p>
|
||||
<p>开始时间: {{ formatDate(item.startTime) }}</p>
|
||||
<p v-if="item.endTime">完成时间: {{ formatDate(item.endTime) }}</p>
|
||||
<p v-if="item.comment">处理意见: {{ item.comment }}</p>
|
||||
</van-step>
|
||||
</van-steps>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 回复表单 -->
|
||||
<div class="card" v-if="!taskCompleted && currentTask">
|
||||
<div class="card-title">处理意见</div>
|
||||
<div class="reply-form">
|
||||
<textarea v-model="replyForm.replyContent" class="reply-textarea"
|
||||
placeholder="请输入回复内容"></textarea>
|
||||
<div class="btn-container">
|
||||
<van-button type="primary" block round @click="submitReply">提交回复</van-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 已回复信息 -->
|
||||
<div class="card" v-if="suggestionData.isReply">
|
||||
<div class="card-title">回复信息</div>
|
||||
<div class="info-item">
|
||||
<span class="info-label">回复人:</span>
|
||||
<span class="info-value">{{ suggestionData.replyUserName }}</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<span class="info-label">回复时间:</span>
|
||||
<span class="info-value">{{ formatDate(suggestionData.replyTime) }}</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<span class="info-label">回复内容:</span>
|
||||
</div>
|
||||
<div class="content-box">{{ suggestionData.replyContent }}</div>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
new Vue({
|
||||
el: "#app",
|
||||
data() {
|
||||
return {
|
||||
loading: true,
|
||||
taskId: "",
|
||||
businessKey: "",
|
||||
processInstanceId: "",
|
||||
suggestionData: {},
|
||||
flowHistory: [],
|
||||
currentTask: null,
|
||||
taskCompleted: false,
|
||||
replyForm: {
|
||||
id: "",
|
||||
replyContent: ""
|
||||
}
|
||||
}
|
||||
},
|
||||
created() {
|
||||
// 获取URL参数
|
||||
this.taskId = GetQueryString("taskId")
|
||||
this.businessKey = GetQueryString("businessKey")
|
||||
this.processInstanceId = GetQueryString("processInstanceId")
|
||||
|
||||
// 加载数据
|
||||
this.loadData()
|
||||
},
|
||||
methods: {
|
||||
goBack() {
|
||||
history.back()
|
||||
},
|
||||
|
||||
// 加载数据
|
||||
async loadData() {
|
||||
this.loading = true
|
||||
try {
|
||||
// 1. 获取业务数据
|
||||
await this.loadSuggestionData()
|
||||
|
||||
// 2. 获取流程历史
|
||||
await this.loadFlowHistory()
|
||||
|
||||
// 3. 获取当前任务信息
|
||||
if (this.taskId) {
|
||||
await this.loadTaskInfo()
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("加载数据失败:", error)
|
||||
this.$toast.fail("加载数据失败")
|
||||
} finally {
|
||||
this.loading = false
|
||||
}
|
||||
},
|
||||
|
||||
// 加载意见箱数据
|
||||
async loadSuggestionData() {
|
||||
if (!this.businessKey) return
|
||||
|
||||
const {
|
||||
code,
|
||||
data
|
||||
} = await $.post("/platform/suggestionBox/admin/getSuggestionById", { id: this.businessKey })
|
||||
if (code === 0 && data) {
|
||||
this.suggestionData = data
|
||||
this.replyForm.id = data.id
|
||||
}
|
||||
},
|
||||
|
||||
// 加载流程历史
|
||||
async loadFlowHistory() {
|
||||
if (!this.processInstanceId) return
|
||||
|
||||
const {
|
||||
code,
|
||||
data
|
||||
} = await $.post("/platform/workflow/task/getProcessHistory", { processInstanceId: this.processInstanceId })
|
||||
if (code === 0 && data) {
|
||||
this.flowHistory = data
|
||||
}
|
||||
},
|
||||
|
||||
// 加载任务信息
|
||||
async loadTaskInfo() {
|
||||
const { code, data } = await $.post("/platform/workflow/task/getTaskInfo", { taskId: this.taskId })
|
||||
if (code === 0 && data) {
|
||||
this.currentTask = data
|
||||
this.taskCompleted = data.endTime != null
|
||||
}
|
||||
},
|
||||
|
||||
// 提交回复
|
||||
async submitReply() {
|
||||
if (!this.replyForm.replyContent.trim()) {
|
||||
this.$toast("请输入回复内容")
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
// 保存业务数据并完成任务
|
||||
const result = await $.post("/platform/suggestionBox/admin/reply", {
|
||||
reply: JSON.stringify(this.replyForm),
|
||||
taskId: this.taskId
|
||||
})
|
||||
|
||||
if (result.code === 0) {
|
||||
this.$toast.success("处理成功")
|
||||
// 重新加载数据
|
||||
setTimeout(() => {
|
||||
this.loadData()
|
||||
}, 1000)
|
||||
} else {
|
||||
this.$toast.fail(result.msg || "处理失败")
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("提交回复失败:", error)
|
||||
this.$toast.fail("提交回复失败")
|
||||
}
|
||||
},
|
||||
|
||||
// 获取状态样式
|
||||
getStatusClass() {
|
||||
if (this.flowHistory.length === 0) return "status-pending"
|
||||
|
||||
const lastTask = this.flowHistory[this.flowHistory.length - 1]
|
||||
if (!lastTask.endTime) return "status-processing"
|
||||
return "status-completed"
|
||||
},
|
||||
|
||||
// 获取状态文本
|
||||
getStatusText() {
|
||||
if (this.flowHistory.length === 0) return "未开始"
|
||||
|
||||
const lastTask = this.flowHistory[this.flowHistory.length - 1]
|
||||
if (!lastTask.endTime) return "处理中"
|
||||
return "已完成"
|
||||
},
|
||||
|
||||
// 格式化日期
|
||||
formatDate(dateStr) {
|
||||
if (!dateStr) return ""
|
||||
const date = new Date(dateStr)
|
||||
return date.getFullYear() + "-" +
|
||||
String(date.getMonth() + 1).padStart(2, "0") + "-" +
|
||||
String(date.getDate()).padStart(2, "0") + " " +
|
||||
String(date.getHours()).padStart(2, "0") + ":" +
|
||||
String(date.getMinutes()).padStart(2, "0")
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<!--#
|
||||
}
|
||||
#-->
|
||||
@@ -1,294 +0,0 @@
|
||||
<!--#
|
||||
layout("/layouts/platform_h5.html"){
|
||||
#-->
|
||||
|
||||
<style>
|
||||
.form-container {
|
||||
background-color: #f6f6f6;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.form-section {
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.section-title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 12px 16px;
|
||||
background: #fff;
|
||||
border-bottom: 1px solid #f6f6f6;
|
||||
}
|
||||
|
||||
.dot {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
background-color: rgb(0, 78, 100);
|
||||
border-radius: 50%;
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.section-title span {
|
||||
color: #333;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.input-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
border-bottom: 1px solid #f5f5f5;
|
||||
padding: 12px 16px;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.input-label {
|
||||
width: 80px;
|
||||
color: #333;
|
||||
padding: 8px 8px 8px 0;
|
||||
}
|
||||
|
||||
.input-control {
|
||||
flex: 1;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.input-control input {
|
||||
width: 100%;
|
||||
border: none;
|
||||
outline: none;
|
||||
text-align: right;
|
||||
color: #666;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.textarea-container {
|
||||
padding: 10px 16px;
|
||||
background: #fff;
|
||||
border-bottom: 1px solid #f5f5f5;
|
||||
}
|
||||
|
||||
.textarea-container textarea {
|
||||
width: 100%;
|
||||
height: 120px;
|
||||
border: none;
|
||||
outline: none;
|
||||
resize: none;
|
||||
font-size: 14px;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.word-count {
|
||||
text-align: right;
|
||||
font-size: 12px;
|
||||
color: #999;
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
.upload-area {
|
||||
padding: 16px;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.upload-grid {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.upload-item,
|
||||
.upload-btn {
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
margin-right: 8px;
|
||||
margin-bottom: 8px;
|
||||
border-radius: 4px;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.upload-btn {
|
||||
background: #f5f5f5;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.uploaded-image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.delete-btn {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
color: #fff;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: 0 0 0 4px;
|
||||
}
|
||||
|
||||
.submit-area {
|
||||
padding: 20px 16px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div id="app" v-cloak>
|
||||
<van-sticky>
|
||||
<van-nav-bar title="我要提意见" left-arrow left-text="返回" @click-left="history.go(-1)"></van-nav-bar>
|
||||
</van-sticky>
|
||||
|
||||
<div class="form-container">
|
||||
<div class="form-section">
|
||||
<div class="section-title">
|
||||
<div class="dot"></div>
|
||||
<span>填写人信息</span>
|
||||
</div>
|
||||
<div class="input-row">
|
||||
<div class="input-label">姓名</div>
|
||||
<div class="input-control">
|
||||
<input type="text" v-model="formData.submitterName" placeholder="请输入姓名" readonly />
|
||||
</div>
|
||||
</div>
|
||||
<div class="input-row">
|
||||
<div class="input-label">工号</div>
|
||||
<div class="input-control">
|
||||
<input type="text" v-model="formData.submitterLoginName" placeholder="请输入工号" readonly />
|
||||
</div>
|
||||
</div>
|
||||
<div class="input-row">
|
||||
<div class="input-label">手机号码</div>
|
||||
<div class="input-control">
|
||||
<input type="tel" v-model="formData.concat" placeholder="请输入手机号码" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="input-row">
|
||||
<div class="input-label">所在单位</div>
|
||||
<div class="input-control">
|
||||
<input type="text" v-model="formData.submitterUnitName" placeholder="请输入所在单位" readonly />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-section">
|
||||
<div class="section-title">
|
||||
<div class="dot"></div>
|
||||
<span>填写标题</span>
|
||||
</div>
|
||||
<div class="input-row">
|
||||
<div class="input-label">标题</div>
|
||||
<div class="input-control">
|
||||
<input type="text" v-model="formData.title" placeholder="请输入意见标题" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-section">
|
||||
<div class="section-title">
|
||||
<div class="dot"></div>
|
||||
<span>填写意见建议内容</span>
|
||||
</div>
|
||||
<div class="textarea-container">
|
||||
<textarea v-model="formData.content" placeholder="请描述您要填写的意见建议内容..."></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-section">
|
||||
<div class="section-title">
|
||||
<div class="dot"></div>
|
||||
<span>照片上传</span>
|
||||
</div>
|
||||
|
||||
<div class="upload-area">
|
||||
<!-- <vant-file-upload :files.sync="formData.attachments" :max="15"></vant-file-upload>-->
|
||||
<!-- <div class="upload-grid">-->
|
||||
<!-- <div class="upload-item" v-for="(item, index) in formData.fileList" :key="index">-->
|
||||
<!-- <img :src="item.content || item.url" class="uploaded-image">-->
|
||||
<!-- <div class="delete-btn" @click="deleteImage(index)">-->
|
||||
<!-- <van-icon name="cross" />-->
|
||||
<!-- </div>-->
|
||||
<!-- </div>-->
|
||||
<!-- <div class="upload-btn" v-if="formData.fileList.length < 3" @click="triggerUpload">-->
|
||||
<!-- <input type="file" ref="fileInput" style="display:none" accept="image/*" @change="onFileChange" multiple>-->
|
||||
<!-- <van-icon name="plus" size="24" />-->
|
||||
<!-- </div>-->
|
||||
<!-- </div>-->
|
||||
</div>
|
||||
</div>
|
||||
<div class="submit-area">
|
||||
<van-button @click="submitForm" style="border-radius: 10px" block type="info">提 交</van-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
new Vue({
|
||||
el: "#app",
|
||||
data() {
|
||||
return {
|
||||
formData: {
|
||||
name: "",
|
||||
mobile: "",
|
||||
idCard: "",
|
||||
department: "",
|
||||
content: "",
|
||||
address: "",
|
||||
fileList: []
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
goBack() {
|
||||
history.back()
|
||||
},
|
||||
|
||||
async submitForm() {
|
||||
if (!this.formData.concat.trim()) {
|
||||
this.$toast("请输入手机号码")
|
||||
return
|
||||
}
|
||||
//正则验证
|
||||
if (!/^1[3-9]\d{9}$/.test(this.formData.concat)) {
|
||||
this.$toast("请输入正确的手机号码")
|
||||
return
|
||||
}
|
||||
if (!this.formData.content.trim()) {
|
||||
this.$toast("请输入投诉内容")
|
||||
return
|
||||
}
|
||||
this.$dialog
|
||||
.confirm({
|
||||
title: "提示",
|
||||
message: "您确定要提交吗?"
|
||||
})
|
||||
.then(async () => {
|
||||
const { code, data, msg } = await $.post("/platform/suggestionBox/submit", { suggestion: JSON.stringify(this.formData) })
|
||||
if (code === 0) {
|
||||
this.$toast.success("提交成功")
|
||||
setTimeout(() => {
|
||||
// history.back()
|
||||
}, 200)
|
||||
} else {
|
||||
this.$toast(msg)
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
created() {
|
||||
const id = GetQueryString("id")
|
||||
if (!id) {
|
||||
this.$set(this.formData, "submitterId", "${@auth.getPrincipalProperty('id')}")
|
||||
this.$set(this.formData, "submitterName", "${@auth.getPrincipalProperty('username')}")
|
||||
this.$set(this.formData, "submitterLoginName", "${@auth.getPrincipalProperty('loginname')}")
|
||||
this.$set(this.formData, "submitterUnitId", "${@auth.getPrincipalProperty('unitid')}")
|
||||
this.$set(this.formData, "submitterUnitName", "${@auth.getPrincipalProperty('unit').getName()}")
|
||||
this.$set(this.formData, "submitterUnionId", "${@auth.getPrincipalProperty('union').getId()}")
|
||||
this.$set(this.formData, "submitterUnionName", "${@auth.getPrincipalProperty('union').getName()}")
|
||||
this.$set(this.formData, "concat", "${@auth.getPrincipalProperty('mobile')}")
|
||||
console.log(this.formData)
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
<!--#}#-->
|
||||
@@ -3,8 +3,7 @@ layout("/layouts/platform_h5.html"){
|
||||
#-->
|
||||
|
||||
<div id="app" v-cloak>
|
||||
<van-nav-bar title="填写建言献策" left-text="返回" left-arrow @click-left="historyBack" placeholder
|
||||
fixed></van-nav-bar>
|
||||
<van-nav-bar title="填写建言献策" left-text="返回" left-arrow @click-left="historyBack" placeholder fixed></van-nav-bar>
|
||||
<div class="form-container">
|
||||
<van-form ref="formRef">
|
||||
<van-cell-group title="基本信息">
|
||||
@@ -39,7 +38,7 @@ layout("/layouts/platform_h5.html"){
|
||||
<div class="form-actions">
|
||||
<van-button plain type="info" @click="onSave">保存</van-button>
|
||||
<van-button type="primary" @click="onSubmit" v-if="!taskId">提交</van-button>
|
||||
<van-button type="primary" @click="onSubmitAgain" v-else>提交</van-button>
|
||||
<van-button type="primary" @click="onFinishTask" v-else>提交</van-button>
|
||||
</div>
|
||||
</van-form>
|
||||
</div>
|
||||
@@ -74,6 +73,7 @@ layout("/layouts/platform_h5.html"){
|
||||
this.$axios.post('/platform/suggestionBox/write/save', {data: JSON.stringify(this.formData)}).then(res => {
|
||||
if (res.code === 0) {
|
||||
this.$toast.success("保存成功");
|
||||
pjaxReplace("/platform/h5/suggestionBox/mine")
|
||||
}
|
||||
})
|
||||
}).catch(() => {
|
||||
@@ -95,7 +95,8 @@ layout("/layouts/platform_h5.html"){
|
||||
}).then(() => {
|
||||
this.$axios.post('/platform/suggestionBox/write/submit', {data: JSON.stringify(this.formData)}).then(res => {
|
||||
if (res.code === 0) {
|
||||
this.$toast.success("保存成功");
|
||||
this.$toast.success("提交成功");
|
||||
pjaxReplace("/platform/h5/suggestionBox/mine")
|
||||
}
|
||||
})
|
||||
}).catch(() => {
|
||||
@@ -121,7 +122,7 @@ layout("/layouts/platform_h5.html"){
|
||||
}).then(res => {
|
||||
if (res.code === 0) {
|
||||
this.$toast.success("提交成功");
|
||||
window.location.href = '/platform/suggestionBox/mine';
|
||||
pjaxReplace("/platform/h5/suggestionBox/mine")
|
||||
}
|
||||
})
|
||||
}).catch(() => {
|
||||
|
||||
@@ -0,0 +1,176 @@
|
||||
<!--#
|
||||
layout("/layouts/platform_h5.html"){
|
||||
#-->
|
||||
|
||||
<div id="app" v-cloak>
|
||||
<van-nav-bar @click-left="historyBack" left-arrow left-text="返回" title="建言献策审核" placeholder
|
||||
fixed></van-nav-bar>
|
||||
<van-sticky offset-top="46px">
|
||||
<van-search
|
||||
v-model="pageForm.searchKeyword"
|
||||
:show-action="false"
|
||||
:reverse-color="false"
|
||||
input-align="left"
|
||||
placeholder="请输入关键字搜索"
|
||||
@search="doSearch"
|
||||
></van-search>
|
||||
<van-tabs v-model="pageForm.approvalText"
|
||||
@change="(val)=>{this.pageForm.approval = val==='1';this.doSearch();}">
|
||||
<van-tab title="已审核" name="1"></van-tab>
|
||||
<van-tab title="未审核" name="0"></van-tab>
|
||||
</van-tabs>
|
||||
</van-sticky>
|
||||
|
||||
<table-list api="/platform/suggestionBox/xgh/pageData" :page_form.sync="pageForm" @ready="onReady"
|
||||
ref="tableListRef" title="title">
|
||||
<template v-slot="{index,row}">
|
||||
<table-column label="申请人">{{row.userName}}</table-column>
|
||||
<table-column label="申请时间">{{row.submitTime}}</table-column>
|
||||
<table-column label="当前节点">{{row.taskName}}</table-column>
|
||||
</template>
|
||||
<template #actions="{index,row}">
|
||||
<div class="action-btn" @click="onView(row)">
|
||||
<i class="fa fa-eye"></i>
|
||||
<span>查看</span>
|
||||
</div>
|
||||
<div class="action-btn" v-if="row.taskState === 10" @click="onApproval(row)">
|
||||
<i class="fa fa-edit"></i>
|
||||
<span>审核</span>
|
||||
</div>
|
||||
<div class="action-btn delete" v-if="row.canRevoke" @click="onRevoke(item)">
|
||||
<i class="fa fa-undo"></i>
|
||||
<span>撤回</span>
|
||||
</div>
|
||||
</template>
|
||||
</table-list>
|
||||
|
||||
<suggestion-box-info ref="suggestionBoxInfoRef">
|
||||
<div v-if="showApprovalForm">
|
||||
<div class="process-title">{{formData.taskName}}</div>
|
||||
<van-form ref="formRef">
|
||||
<van-field
|
||||
v-model="formData.tf_opinion"
|
||||
name="tf_opinion"
|
||||
label="审批意见"
|
||||
placeholder="请输入审批意见"
|
||||
:rules="[{ required: true, message: '请填写审批意见' }]"
|
||||
required
|
||||
maxlength="100"
|
||||
show-word-limit
|
||||
></van-field>
|
||||
</van-form>
|
||||
<div style="display: flex; justify-content: space-between; column-gap: 10px; padding: 10px">
|
||||
<van-button type="danger" block @click="handleTaskAction(6)">退回</van-button>
|
||||
<van-button type="danger" block @click="handleTaskAction(2)">拒绝</van-button>
|
||||
<van-button type="primary" block @click="handleTaskAction(1)">同意</van-button>
|
||||
</div>
|
||||
</div>
|
||||
</suggestion-box-info>
|
||||
|
||||
</div>
|
||||
|
||||
<script>
|
||||
<!--#include('../info.js'){}#-->
|
||||
|
||||
new Vue({
|
||||
el: '#app',
|
||||
store,
|
||||
components: {
|
||||
'suggestion-box-info': SUGGESTION_BOX_INFO
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
pageForm: {
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
totalCount: 0,
|
||||
searchKeyword: "",
|
||||
sessionId: null,
|
||||
approvalText: "0",
|
||||
approval: false
|
||||
},
|
||||
|
||||
formData: {},
|
||||
showApprovalForm: false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
historyBack,
|
||||
|
||||
onReady() {
|
||||
this.doSearch()
|
||||
},
|
||||
|
||||
doSearch() {
|
||||
this.$nextTick(() => {
|
||||
this.pageForm.pageNumber = 1
|
||||
this.pageForm.totalCount = 0
|
||||
this.$refs.tableListRef.doSearch()
|
||||
})
|
||||
},
|
||||
|
||||
// 查看详情
|
||||
onView(row) {
|
||||
this.showApprovalForm = false
|
||||
this.$refs.suggestionBoxInfoRef.onOpen(row)
|
||||
},
|
||||
|
||||
onApproval(row) {
|
||||
this.showApprovalForm = true
|
||||
this.$refs.suggestionBoxInfoRef.onOpen(row)
|
||||
this.formData = {
|
||||
processTaskId: row.taskId,
|
||||
taskName: row.curTaskName
|
||||
}
|
||||
},
|
||||
|
||||
async handleTaskAction(val) {
|
||||
try {
|
||||
await this.$refs.formRef.validate();
|
||||
this.$dialog.confirm({
|
||||
title: "提示",
|
||||
message: "您确定要提交吗?"
|
||||
}).then(() => {
|
||||
this.$axios.post("/flow/common/executeTask", {
|
||||
data: JSON.stringify({
|
||||
...this.formData,
|
||||
submitType: val
|
||||
})
|
||||
}).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.$refs.suggestionBoxInfoRef.onClose()
|
||||
this.$toast.success(res.msg)
|
||||
this.doSearch()
|
||||
}
|
||||
})
|
||||
}).catch(() => {
|
||||
|
||||
})
|
||||
} catch (error) {
|
||||
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
// 撤回
|
||||
onRevoke(row) {
|
||||
this.$dialog.confirm({
|
||||
title: '提示',
|
||||
message: '您确定要撤回吗?',
|
||||
}).then(() => {
|
||||
this.$axios.post('/flow/common/revokeTask', {taskId: row.startTaskId}).then(res => {
|
||||
if (res.code === 0) {
|
||||
this.$toast.success('撤回成功');
|
||||
this.doSearch();
|
||||
}
|
||||
})
|
||||
}).catch(() => {
|
||||
});
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<!--#
|
||||
}
|
||||
#-->
|
||||
Reference in New Issue
Block a user