first commit

This commit is contained in:
2026-09-08 19:49:21 +08:00
commit ebffbab428
7320 changed files with 1477614 additions and 0 deletions
@@ -0,0 +1,312 @@
<!--#
layout("/layouts/platform.html"){
#-->
<style>
.avatar-uploader .el-upload {
border: 1px dashed #d9d9d9;
border-radius: 6px;
cursor: pointer;
position: relative;
overflow: hidden;
}
.avatar-uploader .el-upload:hover {
border-color: #409EFF;
}
.avatar-uploader-icon {
font-size: 28px;
color: #8c939d;
width: 178px;
height: 178px;
line-height: 178px;
text-align: center;
}
.avatar {
width: 178px;
height: 178px;
display: block;
}
.el-popover {
text-align: center;
}
.descriptionContainer {
}
</style>
<div id="app" v-cloak>
<guava ref="guava">
<el-card shadow="never">
<div class="btn-group tool-button mt5">
<el-input placeholder="请输入内容" v-model="pageForm.searchKeyword" clearable
@keyup.enter.native="doSearch">
<el-select v-model="pageForm.searchName" slot="prepend" placeholder="查询类型"
style="width: 120px;">
<el-option label="标题" value="tea.title"></el-option>
</el-select>
</el-input>
</div>
<div class="btn-group tool-button mt5">
<el-select v-model="pageForm.typeId" clearable>
<el-option v-for="item in videoTypeList" :label="item.typeName"
:value="item.id"></el-option>
</el-select>
</div>
<div class="btn-group tool-button mt5">
<el-button type="primary" icon="el-icon-search" @click="doSearch">搜索</el-button>
</div>
<div class="pull-right offscreen-right mt5">
<el-button type="primary" @click="openAdd">
<i class="ti-plus"></i>
新增专辑
</el-button>
</div>
</el-card>
<el-card shadow="never" class="mt10">
<table-tool label="专辑列表" :app="this"></table-tool>
<el-table :data="tableData" :size="tableSize" style="width: 100%">
<el-table-column type="index" label="序号" width="80px"></el-table-column>
<el-table-column
align="center"
header-align="center"
v-for="column in tableColumns"
show-overflow-tooltip
:label="column.label"
:prop="column.prop"
:sortable="column.sortable"
>
<template v-if="column.prop==='cover'" scope="{row}">
<el-popover
placement="top-start"
width="100"
trigger="hover">
<el-image
style="height: 100px;width: 100px"
:src="APP_DOMAIN+FILE_STREAM_PREVIEW_ADDRESS+'?id='+row.cover"
fit="cover">
<div slot="error" class="image-slot">
<i class="el-icon-picture-outline"></i>
</div>
</el-image>
<el-image
slot="reference"
style="height: 30px;width: 30px"
:src="APP_DOMAIN+FILE_STREAM_PREVIEW_ADDRESS+'?id='+row.cover"
fit="cover">
<div slot="error" class="image-slot">
<i class="el-icon-picture-outline"></i>
</div>
</el-image>
</el-popover>
</template>
</el-table-column>
<el-table-column align="center" header-align="center" label="操作" width="250">
<template scope="{row}">
<el-button size="small" @click="openView(row)">查看</el-button>
<el-button size="small" type="primary" @click="openEdit(row)">编辑</el-button>
<el-button size="small" type="danger" @click="doDelete(row.id)">删除
</el-button>
</template>
</el-table-column>
</el-table>
<!--#include("/layouts/pagination.html"){}#-->
</el-card>
<template #edit>
<el-form :model="formData" :rules="rules" ref="ruleForm" label-width="100px"
>
<el-form-item label="专辑标题" prop="title">
<el-input v-model="formData.title" maxlength="30"></el-input>
</el-form-item>
<el-form-item label="专辑类型" prop="typeId">
<el-select v-model="formData.typeId">
<el-option v-for="item in videoTypeList" :label="item.typeName"
:value="item.id"></el-option>
</el-select>
</el-form-item>
<el-form-item label="专辑简介" prop="description">
<!-- <el-input type="textarea" :rows="3" v-model="formData.description"></el-input>-->
<div id="descriptionEditor"></div>
</el-form-item>
<el-form-item label="封面图片" prop="cover">
<el-upload
class="avatar-uploader"
:action="FILE_UPLOAD_ADDRESS"
:show-file-list="false"
:on-success="handleAvatarSuccess"
:before-upload="beforeAvatarUpload">
<img v-if="formData.cover"
:src="APP_DOMAIN+FILE_STREAM_PREVIEW_ADDRESS+'?id='+formData.cover"
class="avatar">
<i v-else class="el-icon-plus avatar-uploader-icon"></i>
</el-upload>
</el-form-item>
<el-form-item class="text-right">
<el-button type="primary" @click="doHandle">确定</el-button>
<el-button @click="$refs.guava.index()">取消</el-button>
</el-form-item>
</el-form>
</template>
<template #view>
<el-form label-width="100px" label-suffix="">
<el-form-item label="专辑标题">
<span>
{{viewData.title}}
</span>
</el-form-item>
<el-form-item label="专辑类型">
<span>{{viewData.typeName}}</span>
</el-form-item>
<el-form-item label="专辑简介">
<div v-html="viewData.description" class="descriptionContainer"></div>
</el-form-item>
<el-form-item label="封面图片" prop="cover">
<file-upload :files="viewFiles" view></file-upload>
</el-form-item>
</el-form>
</template>
</guava>
</div>
<script>
<!--#include("/platform/trainEdu/include/include.js"){}#-->
let descriptionEditor = null
var vue = new Vue({
el: '#app',
mixins: [initTableMixins],
data() {
return {
viewFiles: [],
pageForm: {
searchName: 'tea.title'
},
formData: {
cover: null,
title: null,
description: null,
typeId: null
},
tableColumns: [
{prop: 'title', label: '标题'},
{prop: 'cover', label: '封面'},
{prop: 'videoCount', label: '视频数量'},
{prop: 'typeName', label: '专辑类型'},
],
rules: {
title: [{required: true, message: '请输入标题', trigger: ['change', 'blur']}],
description: [{required: true, message: '请输入简介', trigger: ['change', 'blur']}],
cover: [{required: true, message: '请上传封面图片', trigger: ['change', 'blur']}],
typeId: [{required: true, message: '请选择专辑类型', trigger: ['change', 'blur']}],
},
videoTypeList: [],
viewData: {}
}
},
methods: {
openAdd() {
this.$refs['guava'].edit()
this.$refs['ruleForm'].resetFields()
this.formData.id = undefined
this.$nextTick(() => {
$("#descriptionEditor").html("")
descriptionEditor = new wangEditor("#descriptionEditor")
descriptionEditor.config.onchange = (html) => {
this.formData.description = html
}
descriptionEditor.config.uploadImgShowBase64 = true
descriptionEditor.create()
descriptionEditor.txt.html()
})
},
async handleAvatarSuccess(res, file) {
this.$set(this.formData, 'cover', res.data.id)
await this.$refs['ruleForm'].validate()
},
beforeAvatarUpload(file) {
const allow = ['image/jpeg', 'image/png']
if (!allow.includes(file.type)) {
this.$message.error('上传头像图片只能是 JPG、PNG 格式!')
return false
}
return true
},
async doHandle() {
const valid = await this.$refs['ruleForm'].validate()
if (valid) {
const methodName = typeof this.formData.id === 'undefined' ? '/doAdd' : '/doEdit'
const resp = await $.post(loc() + methodName, this.formData)
if (resp.code === 0) {
this.notifySuccess(resp.msg)
this.doSearch()
this.$refs['guava'].index()
} else {
this.notifyError(resp.msg)
}
}
},
openView(row) {
this.viewData = {...row}
this.viewFiles = [{id: row.cover, filename: row.cover + '.jpg'}]
this.$refs.guava.view()
},
openEdit(row) {
this.$refs['guava'].edit()
this.formData = JSON.parse(JSON.stringify(row))
this.$nextTick(() => {
$("#descriptionEditor").html("")
descriptionEditor = new wangEditor("#descriptionEditor")
descriptionEditor.config.onchange = (html) => {
this.formData.description = html
}
descriptionEditor.config.uploadImgShowBase64 = true
descriptionEditor.create()
descriptionEditor.txt.html(row.description)
})
},
async doDelete(id) {
const confirm = await this.$confirm('确定删除吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
})
if (confirm === 'confirm') {
const resp = await $.post(loc() + '/doDelete', {id})
if (resp.code === 0) {
this.$notify.success(resp.msg)
this.doSearch()
}
}
},
},
async created() {
this.videoTypeList = await getVideoType()
this.pageData()
}
})
</script>
<!--#
}
#-->