feat: 图片上传、编辑、首页假数据

dev-theme
wx-jincw 1 week ago
parent 2799b33955
commit ee3aa34b60

@ -0,0 +1,18 @@
import request from '@/utils/request'
// 编辑
export function update(data) {
return request({
url: '/common/editFile',
method: 'put',
data
})
}
export function fileDownload(attachId) {
return request({
url: `/file/download/${attachId}`,
method: "get",
responseType: "blob",
});
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.5 KiB

After

Width:  |  Height:  |  Size: 48 KiB

@ -0,0 +1,320 @@
<template>
<div class="file-group-upload" v-loading="loading">
<div class="file-group-upload__btns">
<el-badge
v-for="(item, index) in uploadTypes"
:key="item.key"
:value="getTypeFileCount(item.key)"
>
<el-upload
ref="upload"
class="upload-demo"
:action="action"
multiple
:file-list="item.children"
:limit="item.max"
:show-file-list="false"
:on-exceed="handleExceed"
:on-success="handleSuccess"
:before-upload="handleBeforeUpload"
:headers="headers"
:data="{ fileId: item.key }"
>
<el-button
size="small"
icon="el-icon-upload"
:disabled="readonly || loadFail"
@click="handleUpload(index)"
>
{{ item.label }}
</el-button>
</el-upload>
</el-badge>
</div>
<el-table
:data="tableFileList"
:highlight-current-row="true"
:header-row-style="{ height: '40px' }"
:row-style="{ height: '46px' }"
:cell-style="{ padding: '0px' }"
:header-cell-style="{ padding: '0px' }"
:span-method="spanMethod" border
>
<el-button v-if="loadFail" slot="empty" type="text" icon="el-icon-refresh-right" @click="getFileList"></el-button>
<el-table-column label="" type="index" width="30"></el-table-column>
<el-table-column prop="belong" label="所属类别" align="center" />
<el-table-column label="附件名" align="center">
<template slot-scope="scope">
<el-button type="text" @click="handleDownload(scope.row)">{{ scope.row.oldName }}</el-button>
</template>
</el-table-column>
<el-table-column label="预览" align="center" min-width="60">
<template slot-scope="scope">
<div class="img-box">
<el-image style="width:40px; height:40px" fit="contain" :src="getFullUrl(scope.row.attachFileUrl)" :preview-src-list="[getFullUrl(scope.row.attachFileUrl)]" />
</div>
</template>
</el-table-column>
<el-table-column label="类型" align="center" width="80">
<template slot-scope="scope">
<div>{{ scope.row.oldName.split('.')[1] }}</div>
</template>
</el-table-column>
<el-table-column v-if="!readonly" label="操作" width="80" align="center">
<template slot-scope="scope">
<el-popconfirm
title="删除后不可恢复,确定删除吗?"
@confirm="handleRemove(scope.row)"
>
<el-button slot="reference" type="text" :disabled="readonly">删除</el-button>
</el-popconfirm>
</template>
</el-table-column>
</el-table>
</div>
</template>
<script>
import { getToken } from '@/utils/auth'
import { deleteFile, getAttachListByFileIds } from '@/api/common/file.js'
import download from '@/plugins/download.js'
// mime
const FILE_MIME_MAP = {
'png': 'image/png',
'jpg': 'image/jpeg',
'jpeg': 'image/jpeg',
'ppt': 'application/vnd.ms-powerpoint',
'doc': 'application/msword',
'docx': 'application/vndopenxmlformats-officedocumentwordprocessingmldocument',
'xls': 'application/vnd.ms-excel',
'xlsx': 'application/vndopenxmlformats-officedocumentspreadsheetmlsheet'
}
export default {
name: 'FileGroupUpload',
props: {
//
uploadTypes: {
type: Array,
default: () => {
return [
{
prop: 'fileId',
label: '上传附件', //
key: '', // uuid
idFromServer: false, // ID
min: 1, //
max: 10, //
types: '', //
}
]
}
},
readonly: {
type: Boolean,
default: false
}
},
data() {
return {
loading: false,
loadFail: false,
fileList: [], //
currentActive: 0, //
action: process.env.VUE_APP_BASE_API + '/common/upload',
headers: {
Authorization: 'Bearer ' + getToken()
}
}
},
computed: {
fileKeyList() {
const fileKeyList = {};
this.fileList.forEach(item => {
if (!fileKeyList[item.key]) {
fileKeyList[item.key] = [];
}
fileKeyList[item.key].push(item);
});
return fileKeyList;
},
tableFileList() {
const list = [];
Object.keys(this.fileKeyList).forEach(key => {
list.push(...this.fileKeyList[key]);
})
return list;
}
},
watch: {
uploadTypes(newVal) {
this.getFileList();
}
},
methods: {
getFullUrl(url) {
return process.env.VUE_APP_BASE_API + url;
},
async getFileList() {
const filterUploadTypes = this.uploadTypes.filter(item => item.idFromServer);
const fileIds = filterUploadTypes.map(item => item.key);
this.loading = true;
this.loadFail = false;
try {
const { data } = await getAttachListByFileIds(fileIds.join());
if (!data) {
return;
}
const fileList = [];
filterUploadTypes.forEach(item => {
let children = data[item.key] || [];
children = children.map(child => ({
...child,
key: item.key,
prop: item.prop,
belong: item.label,
attachId: child.id,
}));
fileList.push(...children);
});
this.fileList = fileList;
} catch (error) {
this.loadFail = true;
} finally {
this.loading = false;
}
},
getTypeFileCount(key) {
return this.fileList.filter(item => item.key === key).length;
},
// ID
sendFileId() {
const fileIdMap = this.fileList.reduce((pre, cur) => {
return {
...pre,
[cur.prop]: cur.key
}
}, {});
this.$emit('fileMap', fileIdMap);
},
/**
* 上传操作
* @param {*} index 上传类型所对应的下标
*/
handleUpload(index) {
this.currentActive = index
},
/**
* 删除
* @param {*} info 文件信息
*/
async handleRemove(info) {
try {
const { code } = await deleteFile(info.attachId)
if (+code === 200) {
this.$message.success('删除成功')
this.fileList = this.fileList.filter(item => item.attachId !== info.attachId);
this.sendFileId();
}
} catch (e) {
console.error(e)
}
},
/**
* 处理文件超出个数限制
* @param {*} files 上传的文件
* @param {*} fileList 文件总列表
*/
handleExceed(files, fileList) {
this.$message.warning(`文件超出可上传的个数限制! 该类型文件最多可上传${this.uploadTypes[this.currentActive].max}`)
},
/**
* @param {*} res 上传接口返回
* @param {*} file 上传的文件
* @param {*} fileList 已经上传的文件列表
*/
handleSuccess(res, file, fileList) {
const { cmAttach } = res
const { label, key, prop } = this.uploadTypes[this.currentActive]
this.fileList.push({
...cmAttach,
prop,
belong: label,
key,
attachId: cmAttach.id
});
this.sendFileId();
},
handleBeforeUpload(file) {
const acceptTypes = this.uploadTypes[this.currentActive].types.split(',').map(item => FILE_MIME_MAP[item])
if (!acceptTypes.includes(file.type)) {
this.$message.error(`只允许上传类型为: ${this.uploadTypes[this.currentActive].types} 的文件`)
return false
} else {
return true
}
},
/**
* 点击文件名下载文件
* @param {*} info 文件信息
*/
async handleDownload(info) {
try {
download.attachId(info.attachId, info.oldName, false)
} catch (e) {
console.error(e)
}
},
spanMethod({ row, column, rowIndex, columnIndex }) {
if (columnIndex !== 1) {
return ;
}
const typeFiles = this.fileKeyList[row.key];
const firstFile = typeFiles[0];
if (row.attachId === firstFile.attachId) {
return [typeFiles.length, 1];
} else {
return [0, 0];
}
},
}
}
</script>
<style scoped lang="scss">
.file-group-upload {
margin-top: 12px;
&__btns {
margin-bottom: 12px;
display: grid;
grid-template-columns: repeat(auto-fill, 88px);
grid-auto-rows: 32px;
gap: 12px;
.el-button--small {
width: 88px;
height: 32px;
padding: 0;
display: flex;
justify-content: center;
align-items: center;
}
}
.file-name:hover {
cursor: pointer;
color: #409EFF;
}
.file-delete:hover {
color: #409EFF;
}
}
.img-box {
height: 100%;
display: flex;
justify-content: center;
align-items: center;
}
</style>

@ -4,7 +4,7 @@
<script>
import ImageViewer from './image-viewer';
import { update, fileDownload, deleteFile } from '@/api/system/file';
import { update, fileDownload } from '@/api/system/file';
import { downloadFile } from '@/utils';
export default {
@ -43,10 +43,10 @@ export default {
console.log("this.files");
console.log(this.files);
return this.files.map(val => {
if (val.attachFileurl.indexOf("http") === 0) {
return val.attachFileurl;
if (val.attachFileUrl?.indexOf("http") === 0) {
return val.attachFileUrl;
}
return process.env.VUE_APP_BASE_API + val.attachFileurl;
return process.env.VUE_APP_BASE_API + val.attachFileUrl;
});
}
},
@ -70,7 +70,7 @@ export default {
const item = this.files[index];
this.loading = true;
fileDownload(item.attachId).then((res) => {
const suffix = item.attachFileurl.substring(item.attachFileurl.lastIndexOf(".")).toLowerCase();
const suffix = item.attachFileUrl.substring(item.attachFileUrl.lastIndexOf(".")).toLowerCase();
downloadFile(res, item.oldName + suffix);
this.loading = false;
}).catch(e => {
@ -87,8 +87,7 @@ export default {
const item = this.files[index];
this.loading = true;
update({
attachId: item.attachId,
refId: item.refId,
...item,
oldName: filename,
}).then(res => {
this.loading = false;
@ -107,13 +106,12 @@ export default {
const item = this.files[index];
this.loading = true;
update({
attachId: item.attachId,
refId: item.refId,
...item,
angle: deg,
}).then(res => {
this.loading = false;
item.attachFileurl = res.data.attachFileurl;
item.url = process.env.VUE_APP_BASE_API + res.data.attachFileurl;
item.attachFileUrl = res.data.attachFileUrl;
item.url = process.env.VUE_APP_BASE_API + res.data.attachFileUrl;
// this.files[index] = res.data;
this.$emit('change', [...this.files]);
this.$refs.viewer && this.$refs.viewer.reset();

@ -1,5 +1,23 @@
import { parseTime } from './bs'
/**
* 表格时间格式化
*/
export function formatDateStr(cellValue, hasTime = false) {
var date = cellValue ? new Date(cellValue) : new Date();
var year = date.getFullYear()
var month = date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1
var day = date.getDate() < 10 ? '0' + date.getDate() : date.getDate()
if (hasTime) {
var hours = date.getHours() < 10 ? '0' + date.getHours() : date.getHours()
var minutes = date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes()
var seconds = date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds()
return year + '-' + month + '-' + day + ' ' + hours + ':' + minutes + ':' + seconds
}
return year + '-' + month + '-' + day;
}
/**
* 表格时间格式化
*/

@ -62,7 +62,7 @@ export default {
},
xAxis: [{
type: 'category',
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
data: ['04-02', '04-03', '04-04', '04-05', '04-06', '04-07', '04-08'],
axisTick: {
alignWithLabel: true
}
@ -74,21 +74,21 @@ export default {
}
}],
series: [{
name: 'pageA',
name: '访问量',
type: 'bar',
stack: 'vistors',
barWidth: '60%',
data: [79, 52, 200, 334, 390, 330, 220],
animationDuration
}, {
name: 'pageB',
name: '下载量',
type: 'bar',
stack: 'vistors',
barWidth: '60%',
data: [80, 52, 200, 334, 390, 330, 220],
animationDuration
}, {
name: 'pageC',
name: '上传量',
type: 'bar',
stack: 'vistors',
barWidth: '60%',

@ -64,7 +64,7 @@ export default {
setOptions({ expectedData, actualData } = {}) {
this.chart.setOption({
xAxis: {
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
data: ['04-02', '04-03', '04-04', '04-05', '04-06', '04-07', '04-08'],
boundaryGap: false,
axisTick: {
show: false
@ -90,10 +90,10 @@ export default {
}
},
legend: {
data: ['expected', 'actual']
data: ['上月', '当月']
},
series: [{
name: 'expected', itemStyle: {
name: '上月', itemStyle: {
normal: {
color: '#FF005A',
lineStyle: {
@ -109,7 +109,7 @@ export default {
animationEasing: 'cubicInOut'
},
{
name: 'actual',
name: '当月',
smooth: true,
type: 'line',
itemStyle: {

@ -7,9 +7,9 @@
</div>
<div class="card-panel-description">
<div class="card-panel-text">
访
访
</div>
<count-to :start-val="0" :end-val="102400" :duration="2600" class="card-panel-num" />
<count-to :start-val="0" :end-val="102" :duration="2600" class="card-panel-num" />
</div>
</div>
</el-col>
@ -22,33 +22,33 @@
<div class="card-panel-text">
消息
</div>
<count-to :start-val="0" :end-val="81212" :duration="3000" class="card-panel-num" />
<count-to :start-val="0" :end-val="34" :duration="3000" class="card-panel-num" />
</div>
</div>
</el-col>
<el-col :xs="12" :sm="12" :lg="6" class="card-panel-col">
<div class="card-panel" @click="handleSetLineChartData('purchases')">
<div class="card-panel-icon-wrapper icon-money">
<svg-icon icon-class="money" class-name="card-panel-icon" />
<svg-icon icon-class="form" class-name="card-panel-icon" />
</div>
<div class="card-panel-description">
<div class="card-panel-text">
金额
已办
</div>
<count-to :start-val="0" :end-val="9280" :duration="3200" class="card-panel-num" />
<count-to :start-val="0" :end-val="68" :duration="3200" class="card-panel-num" />
</div>
</div>
</el-col>
<el-col :xs="12" :sm="12" :lg="6" class="card-panel-col">
<div class="card-panel" @click="handleSetLineChartData('shoppings')">
<div class="card-panel-icon-wrapper icon-shopping">
<svg-icon icon-class="shopping" class-name="card-panel-icon" />
<svg-icon icon-class="upload" class-name="card-panel-icon" />
</div>
<div class="card-panel-description">
<div class="card-panel-text">
订单
图片
</div>
<count-to :start-val="0" :end-val="13600" :duration="3600" class="card-panel-num" />
<count-to :start-val="0" :end-val="65" :duration="3600" class="card-panel-num" />
</div>
</div>
</el-col>

@ -52,21 +52,21 @@ export default {
legend: {
left: 'center',
bottom: '10',
data: ['Industries', 'Technology', 'Forex', 'Gold', 'Forecasts']
data: ['互动小组', '品牌宣讲', '日常任务']
},
series: [
{
name: 'WEEKLY WRITE ARTICLES',
name: '任务类型',
type: 'pie',
roseType: 'radius',
radius: [15, 95],
center: ['50%', '38%'],
data: [
{ value: 320, name: 'Industries' },
{ value: 240, name: 'Technology' },
{ value: 149, name: 'Forex' },
{ value: 100, name: 'Gold' },
{ value: 59, name: 'Forecasts' }
{ value: 320, name: '互动小组' },
{ value: 240, name: '品牌宣讲' },
{ value: 149, name: '日常任务' },
// { value: 100, name: 'Gold' },
// { value: 59, name: 'Forecasts' }
],
animationEasing: 'cubicInOut',
animationDuration: 2600

@ -1,13 +1,13 @@
<template>
<div class="image-item" @click="$emit('goDetail')">
<img class="image" src="https://picsum.photos/200/300" alt="">
<img class="image" :src="imageUrl" alt="">
<div class="info">
<div class="info-title">图片名称</div>
<div class="info-date">2025-05-05 12:12:12</div>
<div class="info-subtitle">{{ imageName }}</div>
<div class="info-title">{{ item.imageTitle }}</div>
<div class="info-date">{{ item.uploadTime }}</div>
<div class="info-tag">
<el-tag size="small">大厅</el-tag>
<el-tag size="small" style="margin-left: 3px;">大厅</el-tag>
<el-tag size="small" style="margin-left: 3px;">大厅</el-tag>
<el-tag size="small" >公开</el-tag>
<el-tag size="small" v-if="item.keyWords" style="margin-left: 3px;">{{ item.keyWords }}</el-tag>
</div>
</div>
</div>
@ -15,7 +15,34 @@
<script>
export default {
name: 'ImageItem'
name: 'ImageItem',
props: {
item: {
type: Object,
default: () => ({})
}
},
computed: {
imageUrl() {
let url = this.item.imagePath;
if (this.item.file?.length > 0) {
url = this.item.file[0].attachFileUrl || this.item.imagePath;
}
if (url.indexOf("http") === 0) {
return url;
}
return process.env.VUE_APP_BASE_API + url;
},
imageName() {
if (this.item.file?.length > 0) {
return this.item.file[0].oldName || this.item.imageName;
}
return this.item.imageName;
}
},
methods: {
}
}
</script>
@ -35,12 +62,18 @@ export default {
.info-title {
font-size: 18px;
margin-top: 5px;
}
.info-subtitle {
font-size: 14px;
color: #999999;
}
.info-date {
margin-top: 2px;
font-size: 15px;
color: #666666;
color: #999999;
}

@ -1,10 +1,15 @@
<template>
<div class="app-container" v-loading="tableLoading">
<el-form :model="query" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="图片名称" prop="name">
<div class="app-container" >
<div class="left-content">
<div style="margin-bottom: 20px;">图片目录</div>
<el-tree :data="cates" :props="defaultProps" @node-click="handleNodeClick"></el-tree>
</div>
<div class="right-content" v-loading="tableLoading">
<el-form :model="query" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="图片标题" prop="imageTitle">
<el-input
v-model="query.cataName"
placeholder="请输入图片名称"
v-model="query.imageTitle"
placeholder="请输入图片标题"
clearable
@keyup.enter.native="handleQuery"
/>
@ -15,40 +20,105 @@
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<!-- <el-col :span="1.5">
<el-col :span="1.5">
<el-button
type="warning"
plain
icon="el-icon-download"
icon="el-icon-upload"
size="mini"
@click="handleExport"
v-hasPermi="['gallery:cata:export']"
>导出</el-button>
</el-col> -->
@click="handleUpload"
>上传</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getTableList"></right-toolbar>
</el-row>
<div class="image-list">
<ImageItem class="image-item" @goDetail="showImageViewer"></ImageItem>
<ImageItem class="image-item"></ImageItem>
<ImageItem class="image-item"></ImageItem>
<ImageItem v-for="(item, index) in tableData" :key="index" :item="item" class="image-item" @goDetail="showImageViewer($event, index)"></ImageItem>
</div>
<!-- 表格页脚 -->
<pagination
v-show="total > 0"
:total="total"
:pageSizes="[5, 10, 20, 50]"
:page.sync="page.pageNum"
:limit.sync="page.pageSize"
@pagination="getTableList"
/>
</div>
<MyImageViewer ref="previewImage" :z-index="2000"
:files="[{attachFileurl:'https://picsum.photos/200/300'}, {attachFileurl:'https://picsum.photos/200/300'}]"></MyImageViewer>
:files="images" :options="{
download: true,
print: true,
edit: true,
check: true,
}" @change="imageEditChange"></MyImageViewer>
<!-- 添加或修改部门对话框 -->
<el-dialog title="上传图片" :visible.sync="openLoad" width="600px" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="目录" prop="cataId">
<el-select v-model="form.cataId"
style="width: 100%">
<el-option v-for="item in cates" :key="item.id" :label="item.cataName" :value="item.id"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="图片标题" prop="imageTitle">
<el-input v-model="form.imageTitle" placeholder="请输入图片标题" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="拍摄时间" prop="photoTime">
<el-date-picker
v-model="form.photoTime"
style="width: 100%"
value-format="yyyy-MM-dd"
type="date"
placeholder="选择日期"
></el-date-picker>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="关键词" prop="keyWords">
<el-input v-model="form.keyWords" placeholder="请输入图片关键词" />
</el-form-item>
</el-col>
</el-row>
<el-upload
v-if="openLoad"
ref="upload"
class="avatar-uploader"
:action="uploadFileUrl"
:show-file-list="false"
:on-change="handleFileChange"
:on-success="handleFileSuccess"
:on-error="handleFileError"
:auto-upload="false"
:headers="headers"
:data="uploadData"
:limit="1" accept=".png,.jpg,.jpeg,.gif">
<img v-if="imageUrl" :src="imageUrl" class="avatar">
<i v-else class="el-icon-plus avatar-uploader-icon"></i>
</el-upload>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" v-loading="uploading" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import ImageItem from './components/ImageItem.vue';
import tableMixin from '../../../mixins/table-mixin';
import { listCata } from "@/api/gallery/cata";
import { pageListImages } from "@/api/gallery/images";
import { getToken } from "@/utils/auth";
import { formatDateStr } from "@/utils";
export default {
name: 'List',
@ -56,23 +126,150 @@ export default {
ImageItem
},
mixins: [tableMixin],
pageInfo: {
title: '图片列表',
exportUrl: '',
pageListApi: pageListImages,
},
data() {
return {
showViewer: false,
cates: [],
defaultProps: {
children: 'children',
label: 'cataName'
},
openLoad: false,
form: {
imageTitle: null,
photoTime: null,// ,
uploadTime: formatDateStr(),
isOpen: 1,
keyWords: '日常',
cataId: null,
},
rules: {
imageTitle: [{ required: true, message: '请输入图片标题', trigger: 'blur' }],
photoTime: [{ required: true, message: '请输入图片拍摄时间', trigger: 'change' }],
cataId: [{ required: true, message: '请选择图片目录', trigger: 'change' }]
},
imageUrl: '',
uploadFileUrl: process.env.VUE_APP_BASE_API + "/gallery/images/upload", //
headers: {
Authorization: "Bearer " + getToken(),
},
uploading: false,
};
},
computed: {
uploadData() {
const params = {};
Object.keys(this.form).forEach(key => {
if (this.form[key] !== null) {
params[key] = this.form[key];
}
});
return params;
},
images() {
return this.tableData.map(item => {
return item.file?.[0] || {};
});
}
},
created() {
listCata().then(res => {
const list = res.data || [];
this.cates = list;
})
},
methods: {
showImageViewer() {
imageEditChange() {
this.getTableList();
},
showImageViewer(event, index) {
console.log('showImageViewer');
this.showViewer = true;
this.$refs.previewImage.open(0);
this.$refs.previewImage.open(index);
}
},
handleNodeClick(data) {
console.log(data);
if (this.query.cataId === data.id) {
this.query.cataId = null;
} else {
this.query.cataId = data.id;
}
this.getTableList();
},
handleUpload() {
this.form = {
imageTitle: null,
photoTime: null,// ,
uploadTime: formatDateStr(),
isOpen: 1,
keyWords: '日常',
cataId: null,
};
this.imageUrl = '';
this.openLoad = true;
},
cancel() {
this.openLoad = false;
this.uploading = false;
},
submitForm() {
if (!this.imageUrl) {
this.$message.error('请选择图片');
return;
}
this.$refs['form'].validate((valid) => {
if (valid) {
this.uploading = true;
this.$refs.upload.submit();
}
});
},
handleFileChange(file) {
this.imageUrl = URL.createObjectURL(file.raw);
},
handleFileSuccess(res, file) {
this.$message.success('上传成功');
this.openLoad = false;
this.uploading = false;
this.getTableList();
},
handleFileError() {
this.$message.error('上传失败');
this.uploading = false;
},
beforeAvatarUpload(file) {
const isImg = file.type.indexOf('image/') !== -1;
if (!isImg) {
this.$message.error('只能上传图片!');
}
return isImg;
}
}
}
</script>
<style lang="scss" scoped>
.app-container {
display: flex;
}
.left-content {
width: 300px;
padding: 15px;
border: #EEEEEE 1px solid;
border-radius: 8px;
}
.right-content {
width: 0;
flex: 1;
margin-left: 10px;
}
.image-list {
display: flex;
flex-wrap: wrap;
@ -82,4 +279,28 @@ export default {
margin: 0 15px 15px 0;
}
}
.avatar-uploader ::v-deep .el-upload {
border: 1px dashed #d9d9d9;
border-radius: 6px;
cursor: pointer;
position: relative;
overflow: hidden;
}
.avatar-uploader ::v-deep .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;
}
</style>

@ -1,29 +1,142 @@
<template>
<div class="app-container">
<div class="left-container">
<!-- <el-carousel height="300px">
<el-carousel-item v-for="item in 4" :key="item">
<div></div>
<div></div>
<el-carousel height="300px">
<el-carousel-item v-for="item in cates" :key="item.id" @click="goImageList">
<div class="index-flex" @click="goImageList">
<div class="cata-name">{{ item.cataName }}</div>
<img class="single-image image-border" :src="imageUrl(item.images[0])"/>
</div>
<div class="index-flex" @click="goImageList">
<img class="double-image image-border" :src="imageUrl(item.images[1])"/>
<img class="double-image image-border" style="margin-left: 10px;" :src="imageUrl(item.images[2])"/>
</div>
</el-carousel-item>
</el-carousel> -->
</el-carousel>
<el-card style="margin-top: 50px;" >
<div slot="header" class="clearfix">
<span>我的任务</span>
<el-button style="float: right; padding: 3px 0" type="text" @click="goMoreTask"></el-button>
</div>
<el-table
ref="multipleTable"
tooltip-effect="dark"
:data="tableData"
class="w100p"
border
header-cell-class-name="duojibiaotou"
>
<el-table-column
align="center"
label="任务名称"
show-overflow-tooltip
min-width="160"
prop="taskTitle"
/>
<el-table-column label="任务类型" align="center" prop="taskType" min-width="100">
<template slot-scope="scope">
<dict-tag :options="dict.type.task_type" :value="scope.row.taskType"/>
</template>
</el-table-column>
<el-table-column label="任务状态" align="center" prop="taskStatus" min-width="100">
<template slot-scope="scope">
<dict-tag :options="dict.type.task_status" :value="scope.row.taskStatus"/>
</template>
</el-table-column>
<el-table-column
align="center"
label="状态"
show-overflow-tooltip
min-width="90"
>
<template v-slot="{ row }">
<template v-if="row.sdTaskOther && row.sdTaskOther.status === '2'">
<el-tag
type="success">已办结</el-tag>
</template>
<template v-else-if="row.sdTaskOtherFeedbackByCreate">
<el-tag v-if="row.sdTaskOtherFeedbackByCreate.status === '1'"
>已反馈</el-tag
>
<el-tag
v-else-if="row.sdTaskOtherFeedbackByCreate.status === '2'"
type="success"
>已通过</el-tag
>
<el-tag
v-else-if="row.sdTaskOtherFeedbackByCreate.status === '-1'"
type="danger"
>驳回</el-tag
>
<el-tag v-else type="info">未反馈</el-tag>
</template>
<el-tag v-else type="info">未反馈</el-tag>
</template>
</el-table-column>
</el-table>
</el-card>
</div>
<div class="right-container">
<index_v1 ></index_v1>
</div>
</div>
</template>
<script>
import { listCata } from "@/api/gallery/cata";
import { pageListImages } from "@/api/gallery/images";
import index_v1 from "./index_v1.vue";
import { pageListByUser } from "@/api/task/branch";
export default {
name: "Index",
components: {
index_v1,
},
dicts: ['task_type','task_status'],
data() {
return {
cates: [],
tableData: []
};
},
created() {
listCata().then((res) => {
this.cates = res.data || [];
this.cates.forEach((item) => {
this.$set(item, "images", []);
pageListImages({ cataId: item.id, pageNum: 1, pageSize: 3 }).then((result) => {
this.$set(item, "images", result.rows || []);
});
});
});
pageListByUser({ pageNum: 1, pageSize: 10 }).then((res) => {
this.tableData = res.rows || [];
});
},
methods: {
goMoreTask() {
this.$router.push({ path: "/task/MyTask" });
},
goImageList() {
this.$router.push({ path: "/gallery/list" });
},
imageUrl(item) {
if (!item) {
return "";
}
let url = item.imagePath;
if (item.file?.length > 0) {
url = item.file[0].attachFileUrl || item.imagePath;
}
if (url.indexOf("http") === 0) {
return url;
}
return process.env.VUE_APP_BASE_API + url;
}
}
};
</script>
@ -32,6 +145,42 @@ export default {
.app-container {
display: flex;
.index-flex {
display: flex;
padding: 5px;
height: 50%;
}
.cata-name {
display: flex;
align-items: center;
justify-content: center;
font-size: 20px;
font-weight: 500;
height: 100%;
width: 120px;
padding: 10px;
}
.image-border {
border-radius: 6px;
overflow: hidden;
}
.single-image {
flex: 1;
height: 100%;
background: #f5f5f5;
object-fit: cover;
}
.double-image {
flex: 1;
height: 100%;
background: #f5f5f5;
object-fit: cover;
}
.left-container {
width: 400px;

@ -0,0 +1,98 @@
<template>
<div class="dashboard-editor-container">
<panel-group @handleSetLineChartData="handleSetLineChartData" />
<el-row style="background:#fff;padding:16px 16px 0;margin-bottom:32px;">
<line-chart :chart-data="lineChartData" />
</el-row>
<el-row :gutter="32">
<!-- <el-col :xs="24" :sm="24" :lg="8">
<div class="chart-wrapper">
<raddar-chart />
</div>
</el-col> -->
<el-col :xs="24" :sm="24" :lg="12">
<div class="chart-wrapper">
<pie-chart />
</div>
</el-col>
<el-col :xs="24" :sm="24" :lg="12">
<div class="chart-wrapper">
<bar-chart />
</div>
</el-col>
</el-row>
</div>
</template>
<script>
import PanelGroup from './dashboard/PanelGroup'
import LineChart from './dashboard/LineChart'
import RaddarChart from './dashboard/RaddarChart'
import PieChart from './dashboard/PieChart'
import BarChart from './dashboard/BarChart'
const lineChartData = {
newVisitis: {
expectedData: [100, 120, 161, 134, 105, 160, 165],
actualData: [120, 82, 91, 154, 162, 140, 145]
},
messages: {
expectedData: [200, 192, 120, 144, 160, 130, 140],
actualData: [180, 160, 151, 106, 145, 150, 130]
},
purchases: {
expectedData: [80, 100, 121, 104, 105, 90, 100],
actualData: [120, 90, 100, 138, 142, 130, 130]
},
shoppings: {
expectedData: [130, 140, 141, 142, 145, 150, 160],
actualData: [120, 82, 91, 154, 162, 140, 130]
}
}
export default {
name: 'Index',
components: {
PanelGroup,
LineChart,
RaddarChart,
PieChart,
BarChart
},
data() {
return {
lineChartData: lineChartData.newVisitis
}
},
methods: {
handleSetLineChartData(type) {
this.lineChartData = lineChartData[type]
}
}
}
</script>
<style lang="scss" scoped>
.dashboard-editor-container {
padding: 32px;
background-color: rgb(240, 242, 245);
position: relative;
.chart-wrapper {
background: #fff;
padding: 16px 16px 0;
margin-bottom: 32px;
}
}
@media (max-width:1024px) {
.chart-wrapper {
padding: 8px;
}
}
</style>
Loading…
Cancel
Save