This commit is contained in:
那些花儿
2025-09-10 08:46:52 +08:00
parent 5a55444209
commit ab6323a7de
31 changed files with 1884 additions and 704 deletions
@@ -19,14 +19,7 @@ const basicForm = {
></file-upload>
</el-form-item>
<el-form-item label="课程分类" prop="category">
<el-select v-model="formData.category" placeholder="请选择分类" style="width: 100%;">
<el-option label="前端开发" value="前端开发"></el-option>
<el-option label="后端开发" value="后端开发"></el-option>
<el-option label="移动开发" value="移动开发"></el-option>
<el-option label="数据库" value="数据库"></el-option>
<el-option label="运维部署" value="运维部署"></el-option>
<el-option label="人工智能" value="人工智能"></el-option>
</el-select>
<dict-select v-model="formData.category" code="TRAIN_EDU_COURSE_TYPE" style="width: 100%"></dict-select>
</el-form-item>
<el-form-item label="是否启用">
<el-switch v-model="formData.disabled" :active-value="false" :inactive-value="true"></el-switch>
@@ -161,8 +161,6 @@ const contentForm = {
</video>
</div>
</el-dialog>
</el-dialog>
`,
data() {
@@ -352,12 +350,12 @@ const contentForm = {
},
style: /*language=CSS*/ `
.edu_content_dialog .el-dialog__body {
::v-deep .edu_content_dialog .el-dialog__body {
height: calc(100vh - 155px);
overflow-y: auto;
}
.section-header {
::v-deep .section-header {
display: flex;
justify-content: space-between;
align-items: center;
@@ -365,7 +363,7 @@ const contentForm = {
padding: 20px 20px 0;
}
.video-item {
::v-deep .video-item {
background: #f8f9fa;
border: 1px solid #e9ecef;
border-radius: 8px;
@@ -374,19 +372,19 @@ const contentForm = {
transition: all 0.3s;
}
.video-item:hover {
::v-deep .video-item:hover {
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
transform: translateY(-2px);
}
.chapter-card {
::v-deep .chapter-card {
border: 1px solid #e4e7ed;
border-radius: 8px;
margin-bottom: 20px;
overflow: hidden;
}
.chapter-header {
::v-deep .chapter-header {
background: #f5f7fa;
padding: 15px 20px;
border-bottom: 1px solid #e4e7ed;
@@ -395,11 +393,11 @@ const contentForm = {
align-items: center;
}
.chapter-content {
::v-deep .chapter-content {
padding: 20px;
}
.stats-card {
::v-deep .stats-card {
color: white;
padding: 20px;
border-radius: 8px;
@@ -407,14 +405,14 @@ const contentForm = {
margin-bottom: 20px;
}
.course-cover {
::v-deep .course-cover {
width: 100px;
height: 60px;
object-fit: cover;
border-radius: 4px;
}
.duration-display {
::v-deep .duration-display {
color: #909399;
font-size: 12px;
}
@@ -2,6 +2,13 @@
layout("/layouts/platform.html"){
#-->
<style>
.course-cover{
width: 100px;
height: auto;
}
</style>
<div id="app" v-cloak>
<el-card shadow="never">
<table-tool>
@@ -9,19 +16,12 @@ layout("/layouts/platform.html"){
</table-tool>
<el-table :data="tableData" @sort-change="pageOrder" style="width: 100%">
<el-table-column type="index" width="50px" label="序号" :index="indexMethod"></el-table-column>
<el-table-column prop="title" label="课程标题" min-width="150">
<el-table-column prop="cover" label="课程封面" width="150">
<template slot-scope="scope">
<div style="display: flex; align-items: center;">
<img v-if="scope.row.cover" :src="scope.row.cover" class="course-cover"
style="margin-right: 10px;">
<div v-else
style="width: 100px; height: 60px; background: #f0f0f0; border-radius: 4px; margin-right: 10px; display: flex; align-items: center; justify-content: center; color: #999;">
无封面
</div>
<strong>{{ scope.row.title }}</strong>
</div>
<img v-if="scope.row.cover" :src="scope.row.cover" class="course-cover">
</template>
</el-table-column>
<el-table-column prop="title" label="课程标题" min-width="150"></el-table-column>
<el-table-column prop="description" label="描述" min-width="200" show-overflow-tooltip></el-table-column>
<el-table-column prop="category" label="分类" width="120">
<template slot-scope="scope">
@@ -1,137 +0,0 @@
<div id="suggestion-box-apply-form" v-cloak>
<el-form :model="formData" ref="formRef" :rules="formRules" label-width="0" label-suffix="" class="flow-task-form">
<el-descriptions :column="2" border>
<el-descriptions-item label="姓名">{{formData.userName}}</el-descriptions-item>
<el-descriptions-item label="工号">{{formData.loginName}}</el-descriptions-item>
<el-descriptions-item label="单位">{{formData.unitName}}</el-descriptions-item>
<el-descriptions-item label="工会">{{formData.unionName}}</el-descriptions-item>
<el-descriptions-item label="标题" :span="2">
<el-form-item prop="title" label="标题">
<el-input v-model="formData.title" maxlength="100" show-word-limit placeholder="请输入标题"></el-input>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="填写意见建议内容" :span="2">
<el-form-item prop="content" label="填写意见建议内容">
<el-input v-model="formData.content" type="textarea" maxlength="500" show-word-limit placeholder="请输入内容"></el-input>
</el-form-item>
</el-descriptions-item>
</el-descriptions>
</el-form>
<snaker-flow-task-form-action @task-action="handleTaskAction" @save-draft="handleSaveDraft"></snaker-flow-task-form-action>
</div>
<script>
new Vue({
el: "#suggestion-box-apply-form",
store,
data() {
return {
businessId: GetQueryString("businessId"),
instanceId: GetQueryString("instanceId"),
formData: {},
formRules: {
title: [{ required: true, message: "必填", trigger: ["change", "blur"] }],
content: [{ required: true, message: "必填", trigger: ["change", "blur"] }]
}
}
},
methods: {
handleTaskAction(val) {
console.log(val)
this.$refs.formRef.validate((valid) => {
if (valid) {
if (!this.instanceId) {
this.handleApply(val)
} else {
this.handleReApply(val)
}
}
})
},
// 提交申请
handleApply(val) {
this.$axios
.post("/flow/common/startInstanceAndExecute", {
...val,
bizData: JSON.stringify(this.formData)
})
.then((res) => {
if (res.code === 0) {
this.$message.success(res.msg)
window.GlobalBroadcastChannel.postMessage({
type: "task-complete"
})
}
})
},
// 重新提交申请
handleReApply(val) {
this.$axios
.post("/flow/common/executeTask", {
data: JSON.stringify({
processTaskId: val.taskId,
processInstanceId: val.instanceId,
submitType: val.submitType,
f_data: JSON.stringify(this.formData)
})
})
.then((res) => {
if (res.code === 0) {
this.$message.success(res.msg)
window.GlobalBroadcastChannel.postMessage({
type: "task-complete"
})
}
})
},
// 保存申请
handleSaveDraft(val) {
this.$refs.formRef.validateField(["title"], (errMsg) => {
if (errMsg) {
this.$message.warning("请填写标题")
return
}
this.$axios
.post("/flow/common/startInstance", {
...val,
bizData: JSON.stringify(this.formData)
})
.then((res) => {
if (res.code === 0) {
this.$message.success(res.msg)
}
})
})
},
// 初始化
init() {
if (this.businessId) {
this.$axios.post("/platform/suggestionBox/view/info", { id: this.businessId }).then((res) => {
if (res.code === 0) {
this.formData = res.data
}
})
} else {
const { username, loginname, id, unit, union, mobile } = this.$store.state.user
this.formData = {
userName: username,
loginName: loginname,
submitterId: id,
unitId: unit?.id,
unitName: unit?.name,
unionId: union?.id,
unionName: union?.name,
concat: mobile
}
}
}
},
created() {
this.init()
}
})
</script>
@@ -1,128 +0,0 @@
<!--#
layout("/layouts/platform.html"){
#-->
<guava ref="guava">
<div id="app">
<el-card shadow="never">
<search @search="doSearch">
<search-item label="年度">
<el-date-picker v-model="pageForm.year" type="year" value-format="yyyy" placeholder="年度" style="width: 100%"></el-date-picker>
</search-item>
<search-item label="标题">
<el-input v-model="pageForm.title" placeholder="标题" clearable></el-input>
</search-item>
</search>
</el-card>
<el-card shadow="never">
<table-tool></table-tool>
<el-table :data="tableData" @sort-change="pageOrder" style="width: 100%">
<el-table-column type="index" width="50px" label="序号" :index="indexMethod"></el-table-column>
<el-table-column prop="title" label="投稿标题"></el-table-column>
<el-table-column prop="loginName" label="投稿人工号"></el-table-column>
<el-table-column prop="userName" label="投稿人姓名"></el-table-column>
<el-table-column prop="unitName" label="投稿人单位"></el-table-column>
<el-table-column prop="unionName" label="投稿人工会"></el-table-column>
<el-table-column prop="submitTime" label="投稿时间"></el-table-column>
<el-table-column prop="taskName" label="当前节点"></el-table-column>
<el-table-column prop="instanceState" label="流程状态">
<template slot-scope="{row}">
<enum-tag :value="row.instanceState" name="ProcessInstanceStateEnum" label_key="message" size="small"></enum-tag>
</template>
</el-table-column>
<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.taskKey === 'startTask'" @click="onEdit(row)" size="mini" type="primary">编辑</el-button>
<el-button v-if="row.canRevoke" @click="onRevoke(row)" size="mini" type="danger">撤回</el-button>
<!-- <el-button v-if="row.instanceState === 10" size="mini" type="danger" @click="onWithDraw(row)">撤销</el-button>-->
<!-- v-if="row.instanceState === 30"-->
<el-button @click="onDelete(row.id)" size="mini" type="danger">删除</el-button>
</template>
</el-table-column>
</el-table>
<!--#include("/layouts/pagination.html"){}#-->
</el-card>
</div>
</guava>
<script>
new Vue({
el: "#app",
store,
mixins: [initTableMixins],
data() {
return {
pageDataUrl: "/platform/suggestionBox2/apply/pageData"
}
},
methods: {
openView(row) {
window.open("/flow/common/approval/form?" + "instanceId=" + (row.instanceId || "") + "&businessId=" + row.id + "&defineKey=XWTG")
},
onEdit(row) {
window.open(
"/flow/common/approval/form?taskId=" +
(row.taskId || "") +
"&instanceId=" +
(row.instanceId || "") +
"&businessId=" +
row.id +
"&defineKey=XWTG"
)
},
onRevoke(row) {
this.$confirm("您确定要撤回吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
this.$axios.post("/flow/common/revokeTask", { taskId: row.startTaskId }).then((res) => {
if (res.code === 0) {
this.$message.success(res.msg)
this.pageData()
}
})
})
},
onWithDraw({ instanceId }) {
this.$confirm("您确定要撤销申请吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
this.$axios.post("/flow/common/withdrawInstance", { instanceId }).then((res) => {
if (res.code === 0) {
this.$message.success(res.msg)
this.pageData()
}
})
})
},
onDelete(id) {
this.$confirm("您确定要删除吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
this.$axios.post("/platform/suggestionBox2/apply/delete", { id }).then((res) => {
if (res.code === 0) {
this.$message.success(res.msg)
this.pageData()
}
})
})
}
},
created() {
this.pageData()
}
})
</script>
<!--#
}
#-->
@@ -1,88 +0,0 @@
<div id="suggestion-box-view">
<!-- <el-form ref="formRef" label-width="0" label-suffix="" class="flow-task-form">-->
<el-descriptions :column="2" border class="flow-task-form">
<el-descriptions-item label="姓名">{{viewData.userName}}</el-descriptions-item>
<el-descriptions-item label="工号">{{viewData.loginName}}</el-descriptions-item>
<el-descriptions-item label="单位">{{viewData.unitName}}</el-descriptions-item>
<el-descriptions-item label="工会">{{viewData.unionName}}</el-descriptions-item>
<el-descriptions-item label="标题" :span="2">{{viewData.title}}</el-descriptions-item>
<el-descriptions-item label="填写意见建议内容" :span="2">{{viewData.content}}</el-descriptions-item>
</el-descriptions>
<template v-for="task in doneTasks">
<div class="task-panel mt10">
<div class="task-panel-header">{{ task.displayName }}</div>
<el-descriptions border class="flow-task-form" :column="3" :key="task.id" v-if="task.ext.isFirstTaskNode">
<el-descriptions-item label="申请用户">{{ task.ext.initiatorName }}({{task.ext.initiatorAccount}})</el-descriptions-item>
<el-descriptions-item label="申请时间">{{ task.finishTime }}</el-descriptions-item>
<el-descriptions-item label="办理结果">
<dict-tag :options="dict.type.PROCESS_TASK_SUBMIT_TYPE" :value="task.ext.submitType"></dict-tag>
</el-descriptions-item>
</el-descriptions>
<el-descriptions border class="flow-task-form" :column="3" :key="task.id" v-else>
<el-descriptions-item label="办理用户">{{ task.taskFormData.userName }}({{task.taskFormData.loginName}})</el-descriptions-item>
<el-descriptions-item label="办理时间">{{ task.finishTime }}</el-descriptions-item>
<el-descriptions-item label="办理结果">
<dict-tag :options="dict.type.PROCESS_TASK_SUBMIT_TYPE" :value="task.ext.submitType"></dict-tag>
</el-descriptions-item>
<el-descriptions-item label="办理意见" v-if="!task.ext.isFirstTaskNode">{{ task.taskFormData.opinion }}</el-descriptions-item>
</el-descriptions>
</div>
</template>
<!-- </el-form>-->
</div>
<script>
new Vue({
el: "#suggestion-box-view",
store,
dicts: ["PROCESS_TASK_SUBMIT_TYPE"],
data() {
return {
businessId: GetQueryString("businessId"),
instanceId: GetQueryString("instanceId"),
viewData: {},
doneTasks: []
}
},
methods: {
info() {
this.$axios.post("/platform/suggestionBox/view/info", { id: this.businessId }).then((res) => {
if (res.code === 0) {
this.viewData = res.data
}
})
},
getDoneTasks() {
this.$axios.post("/flow/common/doneTasks", { instanceId: this.instanceId }).then((res) => {
if (res.code === 0) {
this.doneTasks = res.data
}
})
}
},
created() {
this.info()
this.getDoneTasks()
}
})
</script>
<style>
.task-panel {
background: white;
border-radius: 4px;
overflow: hidden;
}
.task-panel-header {
background: rgb(250, 250, 250);
border: 1px solid rgb(228, 231, 237);
border-bottom: none;
padding: 12px 16px;
display: flex;
justify-content: space-between;
align-items: center;
}
</style>
@@ -1,48 +0,0 @@
<div id="suggestion-box-apply-form" v-cloak>
<el-form :model="formData" ref="formRef" :rules="formRules" label-width="0" label-suffix="" class="flow-task-form">
<el-form-item label="审批意见" prop="tf_opinion" :rules="[{required:true,message:'必填',trigger:['change','blur']}]">
<user-opinion-textarea v-model="formData.tf_opinion"></user-opinion-textarea>
</el-form-item>
</el-form>
<snaker-flow-task-form-action @task-action="handleTaskAction" @cancel="handleCancel"></snaker-flow-task-form-action>
</div>
<script>
new Vue({
el: "#suggestion-box-apply-form",
store,
data() {
return {
businessId: GetQueryString("businessId"),
formData: {},
formRules: {}
}
},
methods: {
handleTaskAction(val) {
console.log(val)
this.$axios
.post("/flow/common/executeTask", {
data: JSON.stringify({
...val,
...this.formData
})
})
.then((res) => {
if (res.code === 0) {
this.$message.success("操作成功")
// 发送完成消息
window.GlobalBroadcastChannel.postMessage({
type: "task-complete",
payload: val
})
}
})
},
handleCancel(val) {
console.log(val)
}
}
})
</script>
@@ -1,81 +0,0 @@
<!--#
layout("/layouts/platform.html"){
#-->
<guava ref="guava">
<div id="app">
<el-card shadow="never">
<search @search="doSearch">
<search-item label="年度">
<el-date-picker v-model="pageForm.year" type="year" value-format="yyyy" placeholder="年度" style="width: 100%"></el-date-picker>
</search-item>
<search-item label="标题">
<el-input v-model="pageForm.title" placeholder="标题" clearable></el-input>
</search-item>
</search>
</el-card>
<el-card shadow="never">
<table-tool>
<el-radio-group v-model="pageForm.approval" size="small" @change="doSearch">
<el-radio-button :label="true">已审核</el-radio-button>
<el-radio-button :label="false">未审核</el-radio-button>
</el-radio-group>
</table-tool>
<el-table :data="tableData" @sort-change="pageOrder" style="width: 100%">
<el-table-column type="index" width="50px" label="序号" :index="indexMethod"></el-table-column>
<el-table-column prop="title" label="投稿标题"></el-table-column>
<el-table-column prop="loginName" label="投稿人工号"></el-table-column>
<el-table-column prop="userName" label="投稿人姓名"></el-table-column>
<el-table-column prop="unitName" label="投稿人单位"></el-table-column>
<el-table-column prop="unionName" label="投稿人工会"></el-table-column>
<el-table-column prop="submitTime" label="投稿时间"></el-table-column>
<el-table-column prop="curTaskName" label="当前节点"></el-table-column>
<el-table-column prop="instanceState" label="流程状态">
<template slot-scope="{row}">
<enum-tag :value="row.instanceState" name="ProcessInstanceStateEnum" label_key="message" size="small"></enum-tag>
</template>
</el-table-column>
<el-table-column label="操作" fixed="right" width="200px">
<template slot-scope="{row}">
<el-button @click="openView(row)" size="mini" type="primary">查看</el-button>
<el-button v-if="row.canRevoke" @click="onRevoke(row)" size="mini" type="danger">撤回</el-button>
<!-- <el-button v-if="row.taskState === 10" @click="openView(row)" size="mini" type="primary">审核</el-button>-->
</template>
</el-table-column>
</el-table>
<!--#include("/layouts/pagination.html"){}#-->
</el-card>
</div>
</guava>
<script>
new Vue({
el: "#app",
store,
mixins: [initTableMixins],
data() {
return {
pageDataUrl: "/platform/suggestionBox2/xgh/pageData",
pageForm: {
approval: false
}
}
},
methods: {
openView(row) {
window.open("/flow/common/approval/form?taskId=" + row.taskId + "&instanceId=" + row.instanceId + "&businessId=" + row.businessNo)
},
onRevoke(row) {
console.log(row)
}
},
created() {
this.pageData()
}
})
</script>
<!--#
}
#-->