This commit is contained in:
那些花儿
2025-09-17 17:52:09 +08:00
parent 9821aebd0a
commit 3f40ee599e
59 changed files with 3697 additions and 4029 deletions
@@ -1,93 +0,0 @@
const activity = {
template: /*language=HTML*/ `
<div class="home-activity">
<el-card shadow="never">
<div class="card-title" slot="header">最新活动</div>
<div v-if="activityOptions && activityOptions.length > 0" v-for="item in activityOptions"
:key="item.id">
<div style="width: 100%">
<div style="background-color: #fff; position: relative; margin-bottom: 10px">
<div style="display: flex; justify-content: center; align-items: center;border-bottom: 1px solid var(--border-color-lighter);padding-bottom: 8px">
<div
style="position: relative;flex-shrink: 1;width: 150px; height: 90px;margin-right: 10px; ">
<el-image :src="item.cover" alt="" fit="cover"
style="width: 100%; height: 100%; border-radius: 8px;">
<div slot="error" class="image-slot">
<i class="el-icon-picture-outline"></i>
</div>
</el-image>
<el-tag class="act-item-tag" type="danger" size="mini"
v-if="$moment().unix() > $moment(item.endDate).unix()">
已结束
</el-tag>
<el-tag class="act-item-tag" type="success" size="mini"
v-else-if="$moment().unix() < $moment(item.endDate).unix()">
进行中
</el-tag>
</div>
<div style="flex: 1;height: 90px;display: flex;flex-direction: column;justify-content: space-between;">
<div style="color: #111">
<i class="el-icon-star-on" style="color: red; font-size: 17px"></i>{{item.name}}
</div>
<div style="font-size: 12px; color: #999">
开始时间:{{$moment(item.startDate).format('MM-DD HH:mm')}}
</div>
<div style="font-size: 12px; color: #999">
结束时间:{{$moment(item.endDate).format('MM-DD HH:mm')}}
</div>
</div>
<div @click="enterActivity(item)">
<el-button size="mini" type="primary">查看<i class="el-icon-s-promotion"></i>
</el-button>
</div>
</div>
</div>
</div>
</div>
<el-empty v-if="activityOptions.length === 0" description="暂无活动"></el-empty>
</el-card>
</div>
`,
data() {
return {
activityOptions: []
}
},
methods: {
listActivity() {
this.$axios.post("/platform/home/listHomeActivity").then((resp) => {
if (resp.code === 0) {
this.activityOptions = resp.data
}
})
},
enterActivity(item) {
this.$store.dispatch("pjaxRoute", item.url)
}
},
created() {
this.listActivity()
},
style: /*language=CSS*/ `
.home-activity {
min-width: 500px;
}
.home-activity .el-card {
width: 100%;
overflow-y: auto;
}
.home-activity .el-empty {
padding: 40px 0 !important;
}
.home-activity .act-item-tag{
position: absolute;
right: 0;
bottom: 0;
z-index: 1;
}
`
}
@@ -1,76 +0,0 @@
const appModule = {
template: /*language=HTML*/ `
<div class="home-app-module">
<el-card shadow="never">
<div class="card-title" slot="header">平台入口</div>
<div style="display: flex;gap: 20px">
<template v-for="item in entranceModules">
<div :key="item.id" class="v-item-handle" @click="enterEntranceModules(item)" >
<el-image :src="item.icon" style="height: 50px;width: 50px;border-radius: 50%"></el-image>
<span class="v-item-handle-label">
{{ item.name }}
</span>
</div>
</template>
</div>
</el-card>
</div>
`,
store,
data() {
return {}
},
computed: {
entranceModules() {
return this.$store.getters.pcModules
}
},
methods: {
enterEntranceModules(item) {
this.$store.commit("setActiveMenuModuleId", item.id)
}
},
created() {},
style: /*language=CSS*/ `
.v-item-handle {
width: 110px;
height: 110px;
border: 1px solid #f3efef;
/*/ / background-color: rgb(248, 248, 248);*/
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
transition: all 500ms;
color: #0779e4;
cursor: pointer;
border-radius: 5px;
}
.v-item-handle-label {
font-size: 14px;
margin-top: 5px;
}
.v-item-handle .el-image {
transition: width 0.3s ease,
height 0.3s ease;
transform-origin: center; /* 缩放的中心点 */
}
.v-item-handle:hover .el-image {
width: 60px !important;
height: 60px !important;
}
.v-item-handle:hover .fa {
color: white !important;
}
.v-item-handle span {
transition: all 500ms;
color: #000;
font-size: 16px;
}
`
}
@@ -1,127 +0,0 @@
<!--#
layout("/layouts/platform.html"){
#-->
<style>
.el-card {
border-radius: 8px;
}
.image-slot {
display: flex;
justify-content: center;
align-items: center;
width: 100%;
height: 100%;
background: #f5f7fa;
color: #909399;
}
.el-icon-picture-outline {
font-size: 30px;
}
.el-card {
height: 100%;
}
.layout-grid-container {
display: grid;
grid-template-columns: repeat(3, minmax(100px, 1fr));
grid-template-rows: 200px 200px auto;
gap: 10px;
width: calc(100% - 0px);
height: calc(100vh - 126px);
margin: 0 auto;
overflow: hidden;
box-sizing: border-box;
}
.layout-grid-container .grid-item {
color: white;
border-radius: 8px;
}
.appModule-grid {
grid-column: 1 / 3; /* 元素1占据第1和第2列 */
grid-row: 1 / 2; /* 元素1占据第1行 */
}
.activity-grid {
grid-column: 3 / 4; /* 元素2占据第3列 */
grid-row: 1 / 3; /* 元素2跨越第1和第2行 */
}
.quickEntry-grid {
grid-column: 1 / 3; /* 元素3占据第1和第2列 */
grid-row: 2 / 3; /* 元素3占据第2行 */
}
.news-grid,
.todo-grid,
.user-grid {
grid-column: span 1; /* 每个元素占据1列 */
grid-row: 3 / 4; /* 所有元素都在第3行 */
}
</style>
<div id="app" v-cloak style="height: 100%">
<div class="layout-grid-container">
<app-module class="appModule-grid grid-item"></app-module>
<quick-entry class="quickEntry-grid grid-item"></quick-entry>
<activity class="activity-grid grid-item"></activity>
<news class="news-grid grid-item"></news>
<todo class="todo-grid grid-item"></todo>
<user-info class="user-grid grid-item"></user-info>
</div>
</div>
<script>
<!--#include("userInfo.js"){}#-->
<!--#include("todo.js"){}#-->
<!--#include("quickEntry.js"){}#-->
<!--#include("activity.js"){}#-->
<!--#include("appModule.js"){}#-->
<!--#include("news.js"){}#-->
new Vue({
el: "#app",
components: {
"icon-selector": httpVueLoader("/components/plugins/sysIconSelector/index.vue?v=" + new Date().getTime()),
"user-info": userInfo,
todo,
"quick-entry": quickEntry,
activity,
"app-module": appModule,
news: news
},
store,
data: function () {
return {
quickEntries: [],
activityOptions: [],
processInstanceOptions: []
}
},
methods: {
listQuickEntry() {
this.$axios.post("/platform/home/listQuickEntry").then((res) => {
if (res.code === 0) {
this.quickEntries = res.data
}
})
},
listActivity() {
this.$axios.post("/platform/h5/listHomeActivity").then((resp) => {
if (resp.code === 0) {
this.activityOptions = resp.data
}
})
},
enterActivity(item) {
this.$store.dispatch("pjaxRoute", item.url)
}
},
created() {
this.listQuickEntry()
this.listActivity()
}
})
</script>
<!--# } #-->
@@ -1,81 +0,0 @@
const news = {
template: /*language=HTML*/ `
<div class="home-news">
<el-tabs v-model="activeName">
<el-tab-pane v-for="(item,index) in newsData" :key="index" :label="item.label" :name="item.label" v-if="item.value.length > 0">
<div v-for="(n,i) in item.value" :key="i" @click="openUrl(n.href)">
<span v-if="n.time" class="news_time">{{ n.time }}</span>
<span class="news_text">{{ n.text }}</span>
</div>
</el-tab-pane>
</el-tabs>
</div>
`,
data() {
return {
newsData: [],
activeName: 0
}
},
methods: {
async getNews() {
const resp = await this.$axios.post("/platform/home/getNews")
if (resp.data.length > 0) {
this.activeName = resp.data[0].label
}
this.newsData = resp.data
},
openUrl(href) {
const url = this.isHttpOrHttps(href) ? href : "https://gonghui.njupt.edu.cn/" + href
window.open(url)
},
isHttpOrHttps(url) {
return /^(http:\/\/|https:\/\/)/i.test(url)
}
},
async created() {
await this.getNews()
},
style: /*language=CSS*/ `
.home-news {
background: #ffffff;
padding: 15px;
border-radius: 8px;
overflow-y: auto;
}
.home-news .el-tabs {
height: 100%;
}
.home-news .el-tabs__content {
height: calc(100% - 55px);
overflow-y: auto;
}
.home-news .el-tab-pane {
line-height: 38px;
color: black;
}
.home-news .el-tab-pane .news_time {
color: white;
padding: 4px 10px;
border-radius: 10px;
background: #1867b0;
}
.home-news .el-tab-pane div {
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
cursor: pointer;
height: 50px;
line-height: 50px;
}
.home-news .el-tab-pane .news_text:hover {
color: #1867b0;
}
`
}
@@ -1,116 +0,0 @@
const quickEntry = {
template: /*language=HTML*/ `
<div class="home-quick-entry">
<el-card shadow="never">
<div class="card-title" slot="header">快速入口</div>
<div class="quickEntries">
<div v-for="item in quickEntries" :key="item.id" @click="$store.dispatch('pjaxRoute',item.href)" class="quickEntryItem">
<svg-icon :name="item.icon" :size="40" style="color: var(--color-primary)"></svg-icon>
<span>{{item.name}}</span>
</div>
</div>
</el-card>
</div>
`,
data() {
return {
quickEntries: []
}
},
methods: {
listQuickEntry() {
this.$axios.post("/platform/home/listQuickEntry", { platform: "PC" }).then((res) => {
if (res.code === 0) {
this.quickEntries = res.data
}
})
}
},
created() {
this.listQuickEntry()
},
style: /*language=CSS*/ `
.home-quick-entry .el-card {
width: 100%;
}
.home-quick-entry .el-card .el-card__body {
overflow-x: auto;
overflow-y: auto;
height: calc(100% - 53.5px);
}
.home-quick-entry .quickEntries {
overflow-y: auto;
display: grid;
grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
gap: 10px;
}
.home-quick-entry .quickEntries .quickEntryItem img {
max-width: 50px;
}
.home-quick-entry .quickEntries .quickEntryItem {
font-size: 16px;
height: 90px;
max-height: 90px;
display: flex;
flex-direction: column;
align-items: center;
text-align: center;
padding: 10px;
transition: transform 0.3s ease-in-out,
box-shadow 0.3s ease-in-out;
background: #f3f3f3;
border-radius: 10px;
}
.home-quick-entry .quickEntries .quickEntryItem span {
margin-top: auto;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
max-width: 100%;
}
.home-quick-entry .quickEntries .quickEntryItem:hover {
cursor: pointer;
background: #f3f3f3;
border-radius: 10px;
border: 1px solid var(--color-primary);
box-shadow:
0 0 12px rgba(33, 112, 80, 0.4), /* 外发光 */
inset 0 0 8px rgba(33, 112, 80, 0.2); /* 内发光 */
background: rgba(33, 112, 80, 0.05); /* 悬浮背景微透主题色 */
}
.home-quick-entry .quickEntries .quickEntryItem:hover .svg-icon {
transform: scale(1.1); /* 图标放大10% */
transition: transform 0.3s ease;
}
.home-quick-entry .quickEntries .quickEntryItem:hover span {
color: var(--color-primary); /* 使用主题色或自定义颜色 */
}
@keyframes shake {
0% {
transform: translateX(0);
}
25% {
transform: translateX(-5px);
}
50% {
transform: translateX(5px);
}
75% {
transform: translateX(-5px);
}
100% {
transform: translateX(0);
}
}
`
}
@@ -1,85 +0,0 @@
const todo = {
template: /*language=HTML*/ `
<div class="home-todo">
<el-tabs v-model="activeName" @tab-click="handleClick">
<el-tab-pane label="待处理" name="listTodo"></el-tab-pane>
<el-tab-pane label="已处理" name="listDone"></el-tab-pane>
<el-tab-pane label="我的发起" name="listMyInitiation"></el-tab-pane>
</el-tabs>
<el-table :data="tableData" :border="false" size="small" class="mt10" height="calc(100% - 111px)">
<el-table-column label="序号" type="index"></el-table-column>
<el-table-column label="标题" prop="processInstanceName" show-overflow-tooltip></el-table-column>
<el-table-column label="发起人" prop="processInstanceInitiatorName"></el-table-column>
<el-table-column label="当前环节" prop="processInstanceNodeName" show-overflow-tooltip></el-table-column>
<el-table-column label="操作">
<template slot-scope="{row}">
<el-link type="primary" @click="openView(row)">查看</el-link>
</template>
</el-table-column>
</el-table>
<!--#include("/layouts/pagination.html"){}#-->
</div>
`,
store,
mixins: [initTableMixins],
data() {
return {
activeName: "listTodo",
pageForm: {
searchName: "",
searchKeyword: "",
pageNumber: 1,
pageSize: 10,
totalCount: 0,
pageOrderName: "",
pageOrderBy: "",
audit: false
}
}
},
methods: {
handleClick() {
this.pageData()
},
openView(row) {
if (this.activeName === "listMyInitiation") {
this.$store.dispatch("pjaxRoute", row.processInstanceUrl)
} else {
this.$store.dispatch("pjaxRoute", row.taskFormUrl)
}
},
pageData() {
this.$axios.post("/platform/home/" + this.activeName, this.pageForm).then((resp) => {
if (resp.code === 0) {
this.tableData = resp.data.list
this.pageForm.totalCount = resp.data.totalCount
}
})
}
},
created() {
this.handleClick()
},
style: /*language=CSS*/ `
.home-todo {
background: #ffffff;
padding: 15px;
border-radius: 8px;
overflow-y: auto;
color: #000000;
}
.home-todo .el-tabs {
/*height: 100%;*/
}
.home-todo .el-tabs__content {
height: calc(100% - 55px);
overflow-y: auto;
}
/*.home-todo .el-tabs__item{*/
/* color: #000000;*/
/*}*/
`
}
@@ -1,91 +0,0 @@
<!--#include("/platform/zhgh/staffmanage/member/common/info/memberInfo.js"){}#-->
const userInfo = {
template: /*language=HTML*/ `
<div class="home-user-info">
<el-card shadow="never">
<div class="card-title" slot="header">个人信息</div>
<div class="info">
<div>👨‍🏫我的姓名:{{ $store.state.user.username }}</div>
<div>🆔我的工号:{{ $store.state.user.loginname }}</div>
<div>⭕我的性别:{{ $store.state.user.sex }}</div>
<div>🟢我的单位:{{ $store.state.user.unit.name }}</div>
<div>🟤我的工会:{{ $store.state.user.union.name }}</div>
<div>📕系统角色:
<span style="font-size: 14px;color: #666;" v-for="role in $store.state.user.roles">
{{role.name}}
</span>
</div>
</div>
</el-card>
<el-dialog :visible.sync="signatureDialogVisible" title="我的签字" width="35%">
<div class="flx">
<div v-if="!showSignature" class="p10">
<el-image style="width: 100%;border: 1px dashed #000" :src="userSignatureUrl"
v-if="userSignatureUrl">
<template slot="error">获取签名失败</template>
</el-image>
<el-empty v-else description="暂无签名"></el-empty>
</div>
<div class="flx-center-center" style="flex-direction: column;">
<qrcode :options="{ width: 126 }" :value="signatureAddress" class="signature-qrcode"></qrcode>
<el-button icon="el-icon-refresh" size="small" type="primary" @click="getUserSignature(true)">
刷新
</el-button>
</div>
</div>
<el-alert title="扫描二维码可重新签名,手机上签名成功后可点击刷新查看。" type="success"></el-alert>
</el-dialog>
<el-dialog :visible.sync="memberInfoDialogVisible" title="我的信息">
<member-info :id="$store.state.user.id"></member-info>
</el-dialog>
</div>
`,
store,
data() {
return {
showSignature: false,
userSignatureUrl: null,
signatureDialogVisible: false,
signatureAddress: window.location.origin + "/platform/signature/scanPcCode?origin=user",
memberInfoDialogVisible: false
}
},
components: {
"member-info": MEMBER_INFO
},
mounted() {
},
methods: {
openSignature() {
this.signatureDialogVisible = true
this.getUserSignature()
},
getUserSignature(isRefresh = false) {
this.$axios.post("/platform/signature/get").then((res) => {
if (res.code === 0) {
if (isRefresh) {
this.$message.success("刷新成功")
} else {
if (!res.data.signature) {
this.$message.warning("未获取到签字信息")
}
}
this.userSignatureUrl = res.data.signature
}
})
},
},
style: /*language=CSS*/ `
.home-user-info .el-card {
width: 100%;
overflow: auto;
}
.home-user-info .info {
line-height: 40px;
color: black;
}
`
}
@@ -0,0 +1,34 @@
const subjectBank = {
template: /*language=HTML*/ `
<el-dialog :visible.sync="visible" title="题库" append-to-body width="700px">
</el-dialog>
`,
data() {
return {
visible: false,
category: null,
list: []
}
},
methods: {
onOpen(category) {
debugger
this.visible = true
this.category = category
this.listBank()
},
listBank() {
this.$axios.post('/platform/qsv/activity/listBank', {category: this.category}).then(res => {
if (res.code === 0) {
this.list = res.data
}
})
},
},
style: /*language=CSS*/ `
`
}
@@ -1,6 +1,7 @@
<!--#include('optionImg.js'){}#-->
<!--#include('setting.js'){}#-->
<!--#include('txtImport.js'){}#-->
<!--#include('bank.js'){}#-->
const subjectForm = {
template: /*language=HTML*/ `
@@ -193,6 +194,11 @@ const subjectForm = {
<div style="border-top: 1px solid var(--border-color-lighter);padding: 12px;text-align: right;">
<!-- <el-button @click="visible = false">取消</el-button>-->
<el-button type="primary" icon="el-icon-plus" @click="openBank">
从题库选择
</el-button>
<el-button type="primary" icon="el-icon-upload" @click="openTxtImport">
从文本导入
</el-button>
@@ -207,12 +213,14 @@ const subjectForm = {
<option-img ref="optionImgRef" @confirm="onOptionImgConfirm"></option-img>
<setting ref="settingRef" @confirm="onSettingConfirm"></setting>
<txt-import ref="txtImportRef" @confirm="onTxtImportConfirm"></txt-import>
<bank ref="bankRef" @confirm="onBankConfirm"></bank>
</div>
`,
components: {
'option-img': optionImg,
'setting': setting,
'txt-import': txtImport
'txt-import': txtImport,
'bank': subjectBank
},
data() {
return {
@@ -375,6 +383,16 @@ const subjectForm = {
this.$message.success('成功导入' + importedQuestions.length + '道题目');
},
// 打开题库
openBank(){
this.$refs.bankRef.onOpen(this.activity.category)
},
// 从题库选择
onBankConfirm(subject){
},
//保存
saveQuestionnaire() {
$
@@ -0,0 +1,72 @@
const basicForm = {
template: /*language=HTML*/ `
<el-dialog :visible.sync="dialogVisible" title="基础设置" width="70%">
<div style="overflow-y: auto">
<el-form :model="formData" ref="formRef" :rules="formRules" label-width="150px">
<el-form-item label="类型" prop="category">
<el-radio-group v-model="formData.category" size="small">
<el-radio v-for="item in dict.type.ACTIVITY_QSV_CATEGORY" :label="item.code"
:key="item.code"
border>
{{item.label}}
</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="标题" prop="title">
<el-input v-model="formData.title" placeholder="请输入标题" maxlength="50"
show-word-limit></el-input>
</el-form-item>
<el-form-item label="说明" prop="description">
<text-editor v-model="formData.description" :height="150"></text-editor>
</el-form-item>
</el-form>
</div>
<div slot="footer" class="dialog-footer">
<el-button @click="dialogVisible = false">取 消</el-button>
<el-button type="primary" @click="onSubmit">确 定</el-button>
</div>
</el-dialog>
`,
dicts: ["ACTIVITY_QSV_CATEGORY", "ACTIVITY_QSV_MODE", "ACTIVITY_QSV_REPEAT_MODE", "ACTIVITY_QSV_SCORE_MODE"],
data() {
return {
dialogVisible: false,
formData: {
category: ''
},
formRules: {
category: [{required: true, message: "请选择类型", trigger: "change"}],
title: [{required: true, message: "请输入标题", trigger: "change"}],
},
}
},
methods: {
onOpen(id) {
this.dialogVisible = true
if (id) {
$.post("/platform/qsv/bank/findOne", {id}).then((res) => {
if (res.code === 0) {
this.formData = res.data
}
})
} else {
this.formData = {}
}
},
onSubmit() {
this.$refs.formRef.validate((valid) => {
if (valid) {
$.post("/platform/qsv/bank/" + (this.formData.id ? "update" : "save"), {qsvBank: JSON.stringify(this.formData)}).then((res) => {
if (res.code === 0) {
this.$message.success(res.msg)
this.dialogVisible = false
this.$emit("refresh", null)
}
})
}
})
}
}
}
@@ -0,0 +1,100 @@
<!--#
layout("/layouts/platform.html"){
#-->
<div id="app">
<guava ref="guava">
<el-card shadow="never">
<search @search="doSearch">
<search-item label="标题">
<el-input placeholder="标题" v-model="pageForm.title" clearable></el-input>
</search-item>
</search>
</el-card>
<el-card shadow="never" class="mt10">
<table-tool label="管理列表">
<el-button @click="$refs.basicFormRef.onOpen()" size="small" type="primary" class="mr5">新增</el-button>
</table-tool>
<el-table :data="tableData" ref="tableRef" @sort-change="pageOrder">
<el-table-column label="序号" width="50" type="index" :index="indexMethod"></el-table-column>
<el-table-column label="标题" prop="title" sortable></el-table-column>
<el-table-column label="类型" prop="category" sortable width="200">
<template scope="{row}">
<dict-tag :options="dict.type.ACTIVITY_QSV_CATEGORY" :value="row.category"></dict-tag>
</template>
</el-table-column>
<el-table-column label="操作" fixed="right" width="450px">
<template scope="{row}">
<el-button size="mini" type="primary" @click="openEdit(row)">编辑</el-button>
<el-button size="mini" type="primary" @click="openSubject(row.id)">题目设置</el-button>
<el-button size="mini" type="danger" @click="onDelete(row.id)">删除</el-button>
</template>
</el-table-column>
</el-table>
<!--#include("/layouts/pagination.html"){}#-->
</el-card>
<template #edit>
<subject-form ref="subjectFormRef" @refresh="pageData"></subject-form>
</template>
</guava>
<basic-form ref="basicFormRef" @refresh="pageData"></basic-form>
</div>
<script>
<!--#include('basicForm.js'){}#-->
<!--#include('subjectForm.js'){}#-->
new Vue({
el: "#app",
dicts: ["ACTIVITY_QSV_CATEGORY"],
mixins: [initTableMixins],
components: {
"basic-form": basicForm,
"subject-form": subjectForm
},
data() {
return {
}
},
methods: {
// 编辑
openEdit(row) {
this.$refs.basicFormRef.onOpen(row.id)
},
// 题目设置
openSubject(id) {
this.$refs.guava.edit(() => {
this.$refs.subjectFormRef.onOpen(id)
})
},
// 删除
onDelete(id) {
this.$confirm("您确认删除吗, 是否继续?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
$.post("/platform/qsv/activity/delete", {id}).then((res) => {
if (res.code === 0) {
this.$message.success("删除成功")
this.pageData()
}
})
})
}
},
created() {
this.pageData()
}
})
</script>
<!--#
}
#-->
@@ -0,0 +1,551 @@
<!--#include('../activity/optionImg.js'){}#-->
<!--#include('../activity/setting.js'){}#-->
<!--#include('../activity/txtImport.js'){}#-->
const subjectForm = {
template: /*language=HTML*/ `
<div class="subject-form-dialog">
<el-form ref="form" :model="formData" :rules="formRules" label-width="120px">
<div style="min-height:50vh;overflow-y: auto">
<draggable v-model="subjects" handle=".drag-handler">
<transition-group>
<div v-for="(subject, subjectIndex) in subjects" :key="subject.id" class="subject-item">
<div class="subject-header">
<div style="display: flex; align-items: center;">
<i class="el-icon-rank drag-handler"></i>
<span style="font-weight: bold; margin-right: 10px;">第 {{subjectIndex + 1}} 题</span>
<el-input
v-model="subject.title"
placeholder="请输入题目"
style="flex: 1">
</el-input>
</div>
<div class="subject-meta">
<div>
题目类型:
<el-select
v-model="subject.type"
@change="subjectTypeChange(subject, subjectIndex)"
placeholder="请选择题目类型"
style="width: 200px;">
<el-option label="单选题" value="radio">
<i class="el-icon-circle-check subject-type-icon"></i>单选题
</el-option>
<el-option label="多选题" value="checkbox">
<i class="el-icon-check subject-type-icon"></i>多选题
</el-option>
<el-option label="填空题" value="text"
v-if="activity.category!=='QUIZ'">
<i class="el-icon-edit subject-type-icon"></i>填空题
</el-option>
<el-option label="判断题" value="judge">
<i class="el-icon-right subject-type-icon"></i>判断题
</el-option>
</el-select>
</div>
<div v-if="subject.type === 'checkbox'">
最大选择数:
<el-input-number v-model="subject.maxMulti"
placeholder="最多可选数量"></el-input-number>
</div>
<!-- <el-input-->
<!-- v-model="subject.hint"-->
<!-- placeholder="题目提示信息"-->
<!-- style="width: 200px;">-->
<!-- <template slot="prepend">提示</template>-->
<!-- </el-input>-->
<div v-if="activity.category==='QUIZ'">
题目分数:
<el-input-number
v-model="subject.score"
:min="0"
:max="100"
placeholder="分数">
<template slot="prepend">分数</template>
</el-input-number>
</div>
<div v-if="activity.category==='QUIZ' && activity.mode==='SCHEDULED'">
显示日期:
<el-date-picker
v-model="subject.displayDate"
type="date"
placeholder="显示日期"
format="yyyy-MM-dd"
value-format="yyyy-MM-dd">
</el-date-picker>
</div>
</div>
</div>
<template>
<draggable v-model="subject.options" handle=".option-drag-handle"
v-if="subject.type !== 'text'">
<transition-group>
<div v-for="(option, optionIndex) in subject.options"
:key="option.id"
class="option-item">
<i class="el-icon-rank option-drag-handle"></i>
<div class="option-content">
<el-input
v-model="option.text"
:placeholder="'选项'+optionIndex + 1">
<template slot="prepend">选项{{optionIndex + 1}}</template>
</el-input>
<!-- <el-input-->
<!-- v-model="option.hint"-->
<!-- placeholder="选项提示"-->
<!-- style="margin-top: 5px;">-->
<!-- </el-input>-->
<div v-if="option.imageUrl" style="margin-top: 10px;">
<img :src="option.imageUrl" class="image-preview" alt="">
</div>
</div>
<div class="option-tools">
<template v-if="activity.category!=='QUIZ'">
<div class="option-img-box" v-if="option.imgUrl">
<i class="el-icon-remove"
@click="removeOptionImg(subjectIndex,optionIndex)"></i>
<img :src="option.imgUrl" alt=""
@click="openOptionImg(subjectIndex,optionIndex,option)">
</div>
<i v-if="!option.imgUrl" class="el-icon-picture-outline"
style="font-size: 40px;cursor: pointer;" title="上传图片"
@click="openOptionImg(subjectIndex,optionIndex,option)"></i>
</template>
<el-switch
v-if="activity.category==='QUIZ'"
v-model="option.isCorrect"
active-text="正确答案">
</el-switch>
<el-button
type="primary"
icon="el-icon-setting"
size="mini"
@click="openSetting(subjectIndex,optionIndex,option)">
</el-button>
<el-button
type="danger"
icon="el-icon-delete"
size="mini"
@click="removeOption(subject, optionIndex)">
</el-button>
</div>
</div>
</transition-group>
</draggable>
<div class="subject-toolbar">
<div>
<el-button
v-if="subject.type !== 'text'"
type="primary"
icon="el-icon-plus"
size="small"
@click="addOption(subject)">
添加选项
</el-button>
</div>
<div>
<el-button
type="danger"
icon="el-icon-delete"
size="small"
@click="removeSubject(subjectIndex)">
删除题目
</el-button>
</div>
<!-- <div>-->
<!-- <el-switch-->
<!-- v-model="subject.required"-->
<!-- active-text="必答题">-->
<!-- </el-switch>-->
<!-- <el-switch-->
<!-- v-model="subject.showDate"-->
<!-- class="date-visible"-->
<!-- active-text="显示日期">-->
<!-- </el-switch>-->
<!-- </div>-->
</div>
</template>
<div class="meta-info">
<!-- 创建时间:{{ formatDate(subject.createTime) }}-->
<!-- <el-button-->
<!-- type="danger"-->
<!-- icon="el-icon-delete"-->
<!-- size="mini"-->
<!-- style="float: right;"-->
<!-- @click="removeSubject(index)">-->
<!-- 删除题目-->
<!-- </el-button>-->
</div>
</div>
</transition-group>
</draggable>
<el-empty description="描述文字" v-if="subjects.length===0"></el-empty>
</div>
</el-form>
<div style="border-top: 1px solid var(--border-color-lighter);padding: 12px;text-align: right;">
<!-- <el-button @click="visible = false">取消</el-button>-->
<el-button type="primary" icon="el-icon-upload" @click="openTxtImport">
从文本导入
</el-button>
<el-button type="primary" icon="el-icon-plus" @click="addSubject">
添加题目
</el-button>
<el-button type="primary" icon="el-icon-check" @click="saveQuestionnaire">
保存题目
</el-button>
</div>
<option-img ref="optionImgRef" @confirm="onOptionImgConfirm"></option-img>
<setting ref="settingRef" @confirm="onSettingConfirm"></setting>
<txt-import ref="txtImportRef" @confirm="onTxtImportConfirm"></txt-import>
</div>
`,
components: {
'option-img': optionImg,
'setting': setting,
'txt-import': txtImport
},
data() {
return {
id: null,
visible: false,
formData: {},
subjects: [],
previewDialogVisible: false,
activity: {},
formRules: {}
}
},
methods: {
onOpen(id) {
this.visible = true
if (id) {
this.id = id
$.post("/platform/qsv/bank/findOne", {id}).then((res) => {
if (res.code === 0) {
this.activity = res.data
this.subjects = res.data.subjects || []
}
})
}
},
//生成随机id
generateId() {
return Date.now() + Math.random().toString(36).substr(2, 9)
},
//添加题目
addSubject() {
this.subjects.push({
id: this.generateId(),
title: "",
hint: "",
type: "radio",
score: 0,
displayDate: "",
options: [
{
id: this.generateId(),
text: "选项1",
hint: "",
imgUrl: null,
isCorrect: false
},
{
id: this.generateId(),
text: "选项2",
hint: "",
imgUrl: null,
isCorrect: false
}
],
})
},
//题目类型切换
subjectTypeChange(subject, subjectIndex) {
if (subject.type === 'text') {
subject.options = []
}
},
//删除题目
removeSubject(index) {
this.$confirm("确认删除该题目?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
})
.then(() => {
this.subjects.splice(index, 1)
this.$message.success("删除成功")
})
.catch(() => {
})
},
//添加选项
addOption(subject) {
subject.options.push({
id: this.generateId(),
text: "选项" + subject.options.length + 1,
hint: "",
imgUrl: null,
isCorrect: false
})
},
//删除选项
removeOption(subject, optionIndex) {
subject.options.splice(optionIndex, 1)
},
//打开选项上传图片
openOptionImg(subjectIndex, optionIndex, option) {
this.$refs.optionImgRef.onOpen(option.imgUrl, {
subjectIndex,
optionIndex
})
},
//选项图片上传成功回调
onOptionImgConfirm({img, ext}) {
this.$set(this.subjects[ext.subjectIndex].options[ext.optionIndex], "imgUrl", img)
},
//删除选项图片
removeOptionImg(subjectIndex, optionIndex) {
this.$set(this.subjects[subjectIndex].options[optionIndex], "imgUrl", null)
console.log(this.subjects[subjectIndex])
},
//打开选项设置
openSetting(subjectIndex, optionIndex, option) {
this.$refs.settingRef.onOpen(option, {
subjectIndex,
optionIndex
})
},
//选项设置确认
onSettingConfirm({option, ext}) {
this.subjects[ext.subjectIndex].options[ext.optionIndex] = option
console.log(this.subjects[ext.subjectIndex].options[ext.optionIndex])
// this.$set(this.subjects[ext.subjectIndex].options[ext.optionIndex], "isCorrect", option.isCorrect)
// this.$set(this.subjects[ext.subjectIndex].options[ext.optionIndex], "hint", option.hint)
},
//从文本导入
openTxtImport() {
this.$refs.txtImportRef.visible = true;
},
//处理导入的题目
onTxtImportConfirm(importedQuestions) {
if (!importedQuestions || importedQuestions.length === 0) {
return;
}
// 计算新题目的起始序号
const startSortNum = this.subjects.length + 1;
// 更新导入题目的序号
importedQuestions.forEach((question, index) => {
question.sortNum = startSortNum + index;
});
// 将导入的题目添加到现有题目列表
this.subjects.push(...importedQuestions);
this.$message.success('成功导入' + importedQuestions.length + '道题目');
},
//保存
saveQuestionnaire() {
this.$axios.post("/platform/qsv/bank/saveSubjects", {
id: this.activity.id,
subjects: JSON.stringify(this.subjects)
}).then((res) => {
if (res.code === 0) {
this.visible = false
this.$message.success(res.msg)
this.$emit("refresh", null)
}
})
}
},
style: /*language=CSS*/ `
/*.subject-form-dialog,.subject-form-dialog .el-dialog__body {*/
/* background: rgb(248, 249, 250);*/
/*}*/
::v-deep .questionnaire-editor {
max-width: 1200px;
margin: 0 auto;
padding: 20px;
}
::v-deep .editor-header {
background: white;
padding: 20px;
border-radius: 8px;
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.05);
margin-bottom: 20px;
}
::v-deep .subject-item {
background: white;
border-radius: 8px;
padding: 25px;
margin-bottom: 20px;
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.05);
transition: all 0.3s ease;
border: 1px dashed #d9d9d9;
}
::v-deep .subject-item:hover {
box-shadow: 0 4px 20px 0 rgba(0, 0, 0, 0.1);
/*transform: translateY(-1px);*/
}
::v-deep .subject-header {
border-bottom: 1px solid #eee;
padding-bottom: 15px;
margin-bottom: 15px;
}
::v-deep .subject-toolbar {
display: flex;
justify-content: space-between;
align-items: center;
margin-top: 15px;
padding-top: 15px;
border-top: 1px solid #eee;
}
::v-deep .toolbar {
background: white;
padding: 15px;
border-radius: 8px;
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
z-index: 1000;
}
::v-deep .toolbar-btn {
margin: 5px 0;
width: 100%;
}
::v-deep .option-item {
background: #f8f9fa;
border-radius: 4px;
padding: 10px;
margin-bottom: 10px;
display: flex;
align-items: center;
}
::v-deep .option-drag-handle {
cursor: move;
margin-right: 10px;
color: #909399;
}
::v-deep .option-content {
flex-grow: 1;
margin-right: 10px;
}
::v-deep .option-tools {
display: flex;
align-items: center;
gap: 10px;
}
::v-deep .preview-dialog {
max-width: 800px;
margin: 0 auto;
}
::v-deep .date-visible {
margin-left: 20px;
}
::v-deep .subject-meta {
display: flex;
flex-wrap: wrap;
gap: 15px;
margin-top: 15px;
background: #f8f9fa;
padding: 10px;
border-radius: 4px;
}
::v-deep .image-preview {
max-width: 200px;
max-height: 200px;
margin-top: 10px;
border-radius: 4px;
border: 1px solid #dcdfe6;
}
::v-deep .drag-handler {
cursor: move;
color: #909399;
margin-right: 10px;
}
::v-deep .meta-info {
color: #909399;
font-size: 12px;
margin-top: 5px;
}
::v-deep .subject-type-icon {
margin-right: 5px;
}
::v-deep .option-img-box {
position: relative;
width: 40px;
height: 40px;
cursor: pointer;
flex-shrink: 0
}
::v-deep .option-img-box:hover .el-icon-remove {
display: block;
}
::v-deep .option-img-box img {
width: 100%;
height: 100%;
}
::v-deep .option-img-box .el-icon-remove {
position: absolute;
top: -7px;
right: -7px;
color: red;
display: none;
}
::v-deep .option-img-box .el-icon-remove:hover {
transform: scale(1.1);
}
`
}
@@ -42,18 +42,18 @@ layout("/layouts/platform_h5.html"){
<div v-else-if="videoInfo" class="video-player">
<video
ref="videoElement"
class="video-element"
:src="videoInfo.url"
controls
preload="metadata"
@loadedmetadata="onVideoLoaded"
@canplay="onVideoCanPlay"
@play="onVideoPlay"
@pause="onVideoPause"
@timeupdate="onTimeUpdate"
@ended="onVideoEnded"
@error="onVideoError"
ref="videoElement"
class="video-element"
:src="videoSrc"
controls
preload="metadata"
@loadedmetadata="onVideoLoaded"
@canplay="onVideoCanPlay"
@play="onVideoPlay"
@pause="onVideoPause"
@timeupdate="onTimeUpdate"
@ended="onVideoEnded"
@error="onVideoError"
>
您的浏览器不支持视频播放
</video>
@@ -63,227 +63,241 @@ layout("/layouts/platform_h5.html"){
</div>
<!-- 进度保存提示 -->
<van-toast v-model="showProgressToast" message="进度已保存" :duration="1000" />
<van-toast v-model="showProgressToast" message="进度已保存" :duration="1000"/>
<!-- 完成学习弹窗 -->
<van-dialog
v-model="showCompletionDialog"
title="恭喜完成学习!"
message="您已完成本视频的学习,学习记录已保存。"
show-cancel-button
cancel-button-text="继续观看"
confirm-button-text="返回课程"
@confirm="backToCourse"
v-model="showCompletionDialog"
title="恭喜完成学习!"
message="您已完成本视频的学习,学习记录已保存。"
show-cancel-button
cancel-button-text="继续观看"
confirm-button-text="返回课程"
@confirm="backToCourse"
></van-dialog>
</div>
<script>
const vue = new Vue({
el: "#app",
store,
data() {
return {
videoInfo: null,
loading: true,
videoId: null,
courseId: null,
videoTitle: '视频播放',
isPlaying: false,
progressSaveTimer: null,
showProgressToast: false,
showCompletionDialog: false,
savedProgress: 0
}
},
methods: {
pageBack(){
this.historyBack(this.clearProgressSave)
const vue = new Vue({
el: "#app",
store,
data() {
return {
videoInfo: null,
loading: true,
videoId: null,
courseId: null,
videoTitle: '视频播放',
isPlaying: false,
progressSaveTimer: null,
showProgressToast: false,
showCompletionDialog: false,
savedProgress: 0,
progressSet: false // 标记进度是否已设置,避免死循环
}
},
// 加载视频信息
async loadVideoInfo() {
if (!this.videoId) {
this.$toast.fail('缺少视频ID参数');
this.loading = false;
return;
computed: {
videoSrc() {
if (this.videoInfo && this.videoInfo.url) {
const id = this.videoInfo.url.split('id=')[1];
console.log('/platform/sys/file/videoPlay?id=' + id)
return '/platform/sys/file/videoPlay?id=' + id;
}
return null
}
},
try {
const { code, data, msg } = await this.$axios.post('/platform/h5/edu/video/detail', {
videoId: this.videoId
});
methods: {
pageBack() {
this.historyBack(this.clearProgressSave)
},
if (code === 0 && data) {
this.videoInfo = data;
this.$nextTick(() => {
this.loadWatchProgress();
// 加载视频信息
async loadVideoInfo() {
if (!this.videoId) {
this.$toast.fail('缺少视频ID参数');
this.loading = false;
return;
}
try {
const {code, data, msg} = await this.$axios.post('/platform/h5/edu/video/detail', {
videoId: this.videoId
});
} else {
this.$toast.fail(msg || '加载视频信息失败');
if (code === 0 && data) {
this.videoInfo = data;
this.$nextTick(() => {
this.loadWatchProgress();
});
} else {
this.$toast.fail(msg || '加载视频信息失败');
}
} catch (error) {
this.$toast.fail('网络错误');
}
} catch (error) {
this.$toast.fail('网络错误');
}
this.loading = false;
},
this.loading = false;
},
// 视频加载完成
onVideoLoaded() {
console.log('视频元数据加载完成');
},
// 视频加载完成
onVideoLoaded() {
console.log('视频元数据加载完成');
},
// 视频可以播放
onVideoCanPlay() {
console.log('视频可以播放');
// 视频可以播放时,设置观看进度
this.setWatchProgress();
},
// 视频可以播放
onVideoCanPlay() {
console.log('视频可以播放');
// 视频可以播放时,设置观看进度
this.setWatchProgress();
},
// 视频开始播放
onVideoPlay() {
this.isPlaying = true;
this.startProgressSave();
},
// 视频开始播放
onVideoPlay() {
this.isPlaying = true;
this.startProgressSave();
},
// 视频暂停
onVideoPause() {
this.isPlaying = false;
this.saveProgress();
},
// 时间更新
onTimeUpdate() {
console.log('时间更新')
// 可以在这里添加进度更新逻辑
},
// 视频播放结束
onVideoEnded() {
this.isPlaying = false;
this.markVideoCompleted();
},
// 视频加载错误
onVideoError() {
this.$toast.fail('视频加载失败');
},
// 加载观看进度
async loadWatchProgress() {
if (!this.videoId || !this.courseId) return;
try {
const { code, data } = await this.$axios.post('/platform/h5/edu/study/record', {
videoId: this.videoId
});
if (code === 0 && data && data.watchedDuration > 0) {
this.savedProgress = data.watchedDuration;
}
} catch (error) {
console.error('加载观看进度失败:', error);
}
},
// 设置观看进度
setWatchProgress() {
if (this.savedProgress > 0) {
const video = this.$refs.videoElement;
if (video && video.readyState >= 3) {
// 使用setTimeout确保DOM更新完成
setTimeout(() => {
try {
video.currentTime = this.savedProgress;
console.log('设置观看进度成功:', this.savedProgress);
} catch (error) {
console.error('设置观看进度失败:', error);
}
}, 100);
} else {
console.log('视频还未准备好,readyState:', video ? video.readyState : 'video不存在');
}
}
},
// 保存观看进度
async saveProgress() {
const video = this.$refs.videoElement;
if (!video || !this.videoId || !this.courseId) return;
try {
await $.post('/platform/h5/edu/study/progress/save', {
videoId: this.videoId,
courseId: this.courseId,
watchedDuration: Math.floor(video.currentTime)
});
this.showProgressToast = true;
} catch (error) {
console.error('保存进度失败:', error);
}
},
// 开始定时保存进度
startProgressSave() {
this.clearProgressSave();
this.progressSaveTimer = setInterval(() => {
// 视频暂停
onVideoPause() {
this.isPlaying = false;
this.saveProgress();
}, 10000); // 每10秒保存一次
},
},
// 清除定时保存
clearProgressSave() {
if (this.progressSaveTimer) {
clearInterval(this.progressSaveTimer);
this.progressSaveTimer = null;
}
},
// 时间更新
onTimeUpdate() {
console.log('时间更新')
// 可以在这里添加进度更新逻辑
},
// 标记视频完成
async markVideoCompleted() {
if (!this.videoId || !this.courseId) return;
// 视频播放结束
onVideoEnded() {
this.isPlaying = false;
this.markVideoCompleted();
},
try {
const { code } = await $.post('/platform/h5/edu/study/complete', {
videoId: this.videoId,
courseId: this.courseId
});
// 视频加载错误
onVideoError() {
this.$toast.fail('视频加载失败');
},
if (code === 0) {
this.showCompletionDialog = true;
// 加载观看进度
async loadWatchProgress() {
if (!this.videoId || !this.courseId) return;
try {
const {code, data} = await this.$axios.post('/platform/h5/edu/study/record', {
videoId: this.videoId
});
if (code === 0 && data && data.watchedDuration > 0) {
this.savedProgress = data.watchedDuration;
}
} catch (error) {
console.error('加载观看进度失败:', error);
}
},
// 设置观看进度
setWatchProgress() {
if (this.savedProgress > 0 && !this.progressSet) {
const video = this.$refs.videoElement;
if (video && video.readyState >= 3) {
// 使用setTimeout确保DOM更新完成
setTimeout(() => {
try {
this.progressSet = true; // 标记进度已设置,避免重复设置
video.currentTime = this.savedProgress;
console.log('设置观看进度成功:', this.savedProgress);
} catch (error) {
console.error('设置观看进度失败:', error);
}
}, 100);
} else {
console.log('视频还未准备好,readyState:', video ? video.readyState : 'video不存在');
}
}
},
// 保存观看进度
async saveProgress() {
const video = this.$refs.videoElement;
if (!video || !this.videoId || !this.courseId) return;
try {
await $.post('/platform/h5/edu/study/progress/save', {
videoId: this.videoId,
courseId: this.courseId,
watchedDuration: Math.floor(video.currentTime)
});
this.showProgressToast = true;
} catch (error) {
console.error('保存进度失败:', error);
}
},
// 开始定时保存进度
startProgressSave() {
this.clearProgressSave();
this.progressSaveTimer = setInterval(() => {
this.saveProgress();
}, 10000); // 每10秒保存一次
},
// 清除定时保存
clearProgressSave() {
if (this.progressSaveTimer) {
clearInterval(this.progressSaveTimer);
this.progressSaveTimer = null;
}
},
// 标记视频完成
async markVideoCompleted() {
if (!this.videoId || !this.courseId) return;
try {
const {code} = await $.post('/platform/h5/edu/study/complete', {
videoId: this.videoId,
courseId: this.courseId
});
if (code === 0) {
this.showCompletionDialog = true;
}
} catch (error) {
console.error('标记完成失败:', error);
}
},
// 返回课程
backToCourse() {
if (this.courseId) {
} else {
this.historyBack();
}
} catch (error) {
console.error('标记完成失败:', error);
}
},
// 返回课程
backToCourse() {
if (this.courseId) {
mounted() {
// 获取URL参数
const urlParams = new URLSearchParams(window.location.search);
this.videoId = urlParams.get('videoId');
this.courseId = urlParams.get('courseId');
this.videoTitle = decodeURIComponent(urlParams.get('title') || '视频播放');
} else {
this.historyBack();
}
this.loadVideoInfo();
},
beforeDestroy() {
// 页面销毁前保存进度
this.saveProgress();
this.clearProgressSave();
}
},
mounted() {
// 获取URL参数
const urlParams = new URLSearchParams(window.location.search);
this.videoId = urlParams.get('videoId');
this.courseId = urlParams.get('courseId');
this.videoTitle = decodeURIComponent(urlParams.get('title') || '视频播放');
this.loadVideoInfo();
},
beforeDestroy() {
// 页面销毁前保存进度
this.saveProgress();
this.clearProgressSave();
}
});
});
</script>
<!--#
@@ -156,7 +156,7 @@ layout("/layouts/platform_h5.html"){
if (this.timerInterval) {
clearInterval(this.timerInterval)
}
pjaxReplace('platform/h5/qsv')
historyBack()
},
//答题计时器
@@ -27,8 +27,8 @@ const SUGGESTION_BOX_INFO = {
</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>
<dict-tag :options="dict.type.PROCESS_TASK_SUBMIT_TYPE"
:value="task.ext.submitType"></dict-tag>
</van-cell>
<van-cell title="办理意见" v-if="!task.ext.isFirstTaskNode" class="direction-column-cell">
<div v-html="task.taskFormData.tf_opinion"></div>
@@ -20,7 +20,7 @@ layout("/layouts/platform_h5.html"){
<template v-slot="{index,row}">
<table-column label="申请人">{{row.userName}}</table-column>
<table-column label="申请时间">{{row.submitTime}}</table-column>
<table-column label="当前节点">{{row.curTaskName}}</table-column>
<table-column label="当前节点">{{row.taskName}}</table-column>
</template>
<template #actions="{index,row}">
<div class="action-btn" @click="onView(row)">
@@ -91,7 +91,7 @@ layout("/layouts/platform_h5.html"){
// 编辑
onEdit(row) {
this.$pjaxReplace("/platform/h5/suggestionBox/write?bizId=" + row.id + "&taskId=" + row.startTaskId)
this.$pjaxReplace("/platform/suggestionBox/write/h5?bizId=" + row.id + "&taskId=" + (row.startTaskId || ''))
},
// 撤回
@@ -73,7 +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")
pjaxReplace("/platform/suggestionBox/mine/h5")
}
})
}).catch(() => {
@@ -96,7 +96,7 @@ layout("/layouts/platform_h5.html"){
this.$axios.post('/platform/suggestionBox/write/submit', {data: JSON.stringify(this.formData)}).then(res => {
if (res.code === 0) {
this.$toast.success("提交成功");
pjaxReplace("/platform/h5/suggestionBox/mine")
pjaxReplace("/platform/suggestionBox/mine/h5")
}
})
}).catch(() => {
@@ -265,6 +265,11 @@ const apps = {
// 显示应用菜单弹框
showAppMenus(app, menus) {
if(app.href && menus.length === 0){
this.$pjaxReplace(app.href)
return;
}
if (!menus || menus.length === 0) {
this.$toast('该应用暂无可用功能')
return
@@ -92,7 +92,7 @@ const todo = {
</div>
<div v-else class="empty-section">
<van-empty :description="getEmptyText()"/>
<van-empty :description="getEmptyText()"></van-empty>
</div>
</van-list>
</van-pull-refresh>