2025-05-17
This commit is contained in:
@@ -1 +1,3 @@
|
||||
VUE_APP_API_BASE_URL=http://agent.admin.haodian.cn/api
|
||||
VUE_APP_API_BASE_URL=/api
|
||||
URL = http://agent.admin.haodian.cn
|
||||
PORT = 8100
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
import request from '@/utils/request';
|
||||
|
||||
export async function pageBrand(params) {
|
||||
const res = await request.get('/common/autoBrand', {
|
||||
params
|
||||
});
|
||||
return res.data;
|
||||
}
|
||||
|
||||
export async function pageSeries(params) {
|
||||
const res = await request.get('/common/autoSeries', {
|
||||
params
|
||||
});
|
||||
return res.data;
|
||||
}
|
||||
|
||||
export async function pageAutoCar(params) {
|
||||
const res = await request.get('/common/autoCar', {
|
||||
params
|
||||
});
|
||||
return res.data;
|
||||
}
|
||||
@@ -0,0 +1,214 @@
|
||||
<template>
|
||||
<div class="car-model-selector">
|
||||
<el-form-item label="品牌">
|
||||
<el-select
|
||||
v-model="form.brandId"
|
||||
filterable
|
||||
clearable
|
||||
placeholder="请输入品牌名称搜索"
|
||||
:loading="brandLoading"
|
||||
@change="handleBrandChange"
|
||||
@filter-change="handleBrandFilter"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in brandList"
|
||||
:key="item.id"
|
||||
:label="item.name"
|
||||
:value="item.id"
|
||||
/>
|
||||
</el-select>
|
||||
<template v-if="type !== 'brand'">
|
||||
-
|
||||
<el-select
|
||||
v-model="form.seriesId"
|
||||
placeholder="请选择车系"
|
||||
clearable
|
||||
:disabled="!form.brandId"
|
||||
:loading="seriesLoading"
|
||||
@change="handleSeriesChange"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in seriesList"
|
||||
:key="item.id"
|
||||
:label="item.name"
|
||||
:value="item.id"
|
||||
/>
|
||||
</el-select>
|
||||
</template>
|
||||
<template v-if="!type">
|
||||
-
|
||||
<el-select
|
||||
v-model="form.modelId"
|
||||
placeholder="请选择车型"
|
||||
clearable
|
||||
:disabled="!form.seriesId"
|
||||
:loading="modelLoading"
|
||||
@change="handleModelChange"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in modelList"
|
||||
:key="item.id"
|
||||
:label="item.name"
|
||||
:value="item.id"
|
||||
/>
|
||||
</el-select>
|
||||
</template>
|
||||
</el-form-item>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { pageBrand, pageSeries, pageAutoCar } from '@/api/auto';
|
||||
|
||||
export default {
|
||||
name: 'CarModelSelector',
|
||||
props: {
|
||||
modelValue: {
|
||||
type: Object,
|
||||
default: () => ({
|
||||
brandId: null,
|
||||
seriesId: null,
|
||||
modelId: null
|
||||
})
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
validator: (type) => {
|
||||
return !type || ['brandSeries', 'brand'].includes(type);
|
||||
}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
form: {
|
||||
brandId: null,
|
||||
seriesId: null,
|
||||
modelId: null
|
||||
},
|
||||
brandList: [],
|
||||
seriesList: [],
|
||||
modelList: [],
|
||||
brandLoading: false,
|
||||
seriesLoading: false,
|
||||
modelLoading: false,
|
||||
brandFilter: ''
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
modelValue: {
|
||||
deep: true,
|
||||
handler(newVal) {
|
||||
this.form = { ...newVal };
|
||||
this.syncFormWithProps();
|
||||
}
|
||||
},
|
||||
'$props.modelValue': {
|
||||
handler() {
|
||||
this.syncFormWithProps();
|
||||
}
|
||||
},
|
||||
'form.brandId'(val) {
|
||||
this.emitValue();
|
||||
if (!val) {
|
||||
this.seriesList = [];
|
||||
this.modelList = [];
|
||||
this.form.seriesId = null;
|
||||
this.form.modelId = null;
|
||||
}
|
||||
},
|
||||
'form.seriesId'(val) {
|
||||
this.emitValue();
|
||||
if (!val) this.modelList = this.form.modelId = null;
|
||||
},
|
||||
'form.modelId': {
|
||||
handler() {
|
||||
this.emitValue();
|
||||
},
|
||||
immediate: true
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.loadBrands();
|
||||
this.syncFormWithProps();
|
||||
},
|
||||
methods: {
|
||||
async loadBrands(filter = '') {
|
||||
this.brandLoading = true;
|
||||
try {
|
||||
const res = await pageBrand({ nameLike: filter });
|
||||
this.brandList = res;
|
||||
} catch (error) {
|
||||
this.$message.error('品牌加载失败');
|
||||
} finally {
|
||||
this.brandLoading = false;
|
||||
}
|
||||
},
|
||||
|
||||
async loadSeriesList(brandId) {
|
||||
this.seriesLoading = true;
|
||||
try {
|
||||
const res = await pageSeries({ brandId });
|
||||
this.seriesList = res;
|
||||
this.form.seriesId = null;
|
||||
} catch (error) {
|
||||
this.$message.error('车系加载失败');
|
||||
} finally {
|
||||
this.seriesLoading = false;
|
||||
}
|
||||
},
|
||||
|
||||
async loadModelList(seriesId) {
|
||||
this.modelLoading = true;
|
||||
try {
|
||||
const res = await pageAutoCar({ seriesId });
|
||||
this.modelList = res;
|
||||
this.form.modelId = null;
|
||||
} catch (error) {
|
||||
this.$message.error('车型加载失败');
|
||||
} finally {
|
||||
this.modelLoading = false;
|
||||
}
|
||||
},
|
||||
|
||||
handleBrandChange(brandId) {
|
||||
if (brandId) this.loadSeriesList(brandId);
|
||||
},
|
||||
|
||||
handleSeriesChange(seriesId) {
|
||||
if (seriesId) this.loadModelList(seriesId);
|
||||
},
|
||||
handleModelChange() {},
|
||||
handleBrandFilter(filter) {
|
||||
this.brandFilter = filter;
|
||||
this.loadBrands(filter);
|
||||
},
|
||||
|
||||
emitValue() {
|
||||
this.$emit('update:modelValue', {
|
||||
brandId: this.form.brandId,
|
||||
seriesId: this.form.seriesId,
|
||||
modelId: this.form.modelId
|
||||
});
|
||||
},
|
||||
|
||||
syncFormWithProps() {
|
||||
// 重置所有数据
|
||||
this.brandList = [];
|
||||
this.seriesList = [];
|
||||
this.modelList = [];
|
||||
|
||||
const { brandId, seriesId, modelId } = this.modelValue;
|
||||
this.form = { brandId, seriesId, modelId };
|
||||
|
||||
if (brandId) {
|
||||
this.loadSeriesList(brandId);
|
||||
if (seriesId) {
|
||||
this.loadModelList(seriesId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
@@ -39,6 +39,11 @@
|
||||
class="ele-fluid"
|
||||
/>
|
||||
</el-form-item>
|
||||
<car-model-selector
|
||||
type="brandSeries"
|
||||
v-model="form.selectedCar"
|
||||
@update:modelValue="handleCarChange"
|
||||
/>
|
||||
<el-form-item label="有效期:" prop="dateRange">
|
||||
<el-date-picker
|
||||
v-model="form.dateRange"
|
||||
@@ -108,11 +113,13 @@
|
||||
import { listDictionaryData } from '@/api/system/dictionary-data';
|
||||
import UploadImg from '@/components/UploadImg/index.vue';
|
||||
import RegionsSelect from '@/components/RegionsSelect/index.vue';
|
||||
import CarModelSelector from '@/components/CarSelector/index.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
UploadImg,
|
||||
RegionsSelect
|
||||
RegionsSelect,
|
||||
CarModelSelector
|
||||
},
|
||||
props: {
|
||||
// 弹窗是否打开
|
||||
@@ -133,7 +140,12 @@
|
||||
secondLevelClues: '',
|
||||
firstLevelDeal: '',
|
||||
secondLevelDeal: '',
|
||||
crowdProfiling: []
|
||||
crowdProfiling: [],
|
||||
selectedCar: {
|
||||
brandId: null,
|
||||
seriesId: null,
|
||||
modelId: null
|
||||
}
|
||||
};
|
||||
return {
|
||||
editVersion: false,
|
||||
@@ -185,10 +197,6 @@
|
||||
});
|
||||
},
|
||||
methods: {
|
||||
/* 添加海报描述 */
|
||||
addShareTitle() {
|
||||
this.form.shareTitle.push('');
|
||||
},
|
||||
/* 保存编辑 */
|
||||
save() {
|
||||
this.$refs.form.validate((valid) => {
|
||||
@@ -213,6 +221,9 @@
|
||||
});
|
||||
});
|
||||
},
|
||||
handleCarChange(carInfo) {
|
||||
this.form.selectedCar = carInfo;
|
||||
},
|
||||
/* 更新visible */
|
||||
updateVisible(value) {
|
||||
this.$emit('update:visible', value);
|
||||
|
||||
@@ -13,6 +13,14 @@
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :md="24" :sm="24">
|
||||
<car-model-selector
|
||||
type="brandSeries"
|
||||
v-model="this.where.selectedCar"
|
||||
@update:modelValue="handleCarChange"
|
||||
:key="componentKey"
|
||||
/>
|
||||
</el-col>
|
||||
<el-col :md="6" :sm="12">
|
||||
<div class="ele-form-actions">
|
||||
<el-button
|
||||
@@ -107,14 +115,20 @@
|
||||
updateProductStatus
|
||||
} from '@/api/car/product';
|
||||
import edit from './components/edit.vue';
|
||||
import CarModelSelector from '@/components/CarSelector/index.vue';
|
||||
|
||||
export default {
|
||||
name: 'carProduct',
|
||||
components: { edit },
|
||||
components: { CarModelSelector, edit },
|
||||
data() {
|
||||
return {
|
||||
where: {
|
||||
title: ''
|
||||
title: '',
|
||||
selectedCar: {
|
||||
brandId: '',
|
||||
seriesId: '',
|
||||
modelId: ''
|
||||
}
|
||||
},
|
||||
// 门店数据
|
||||
organizationList: [],
|
||||
@@ -186,12 +200,11 @@
|
||||
showEditDraw: false,
|
||||
showEditVisitTag: false,
|
||||
// 是否显示二维码弹窗
|
||||
showCode: false
|
||||
showCode: false,
|
||||
componentKey: 0
|
||||
};
|
||||
},
|
||||
created() {
|
||||
//this.organizationQuery();
|
||||
},
|
||||
created() {},
|
||||
methods: {
|
||||
edit(row) {
|
||||
this.current = row;
|
||||
@@ -259,7 +272,18 @@
|
||||
},
|
||||
/* 重置搜索 */
|
||||
reset() {
|
||||
this.where = {};
|
||||
this.where = {
|
||||
selectedCar: {
|
||||
brandId: null,
|
||||
seriesId: null,
|
||||
modelId: null
|
||||
}
|
||||
};
|
||||
// 更新 key 强制组件重新渲染
|
||||
this.componentKey = Date.now();
|
||||
},
|
||||
handleCarChange(carInfo) {
|
||||
this.where.selectedCar = carInfo;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -2,6 +2,16 @@ const CompressionWebpackPlugin = require('compression-webpack-plugin');
|
||||
const { transformElementScss } = require('ele-admin/lib/utils/dynamic-theme');
|
||||
|
||||
module.exports = {
|
||||
devServer: {
|
||||
port: process.env.PORT || 8100,
|
||||
proxy: {
|
||||
'/api': {
|
||||
target: process.env.URL,
|
||||
changeOrigin: true,
|
||||
pathRewrite: { '^/api/common': '/common' } //路由重写调用公共方法
|
||||
}
|
||||
}
|
||||
},
|
||||
productionSourceMap: false,
|
||||
transpileDependencies: ['element-ui', 'ele-admin', 'vue-i18n'],
|
||||
configureWebpack: {
|
||||
|
||||
+1
-1
@@ -1,2 +1,2 @@
|
||||
VUE_APP_NAME=Ele Admin
|
||||
VUE_APP_NAME=易客来
|
||||
VUE_APP_API_BASE_URL=https://v2.eleadmin.com/api
|
||||
|
||||
@@ -1 +1,4 @@
|
||||
VUE_APP_API_BASE_URL=http://agent.admin.haodian.cn/api
|
||||
VUE_APP_NAME=易客来
|
||||
VUE_APP_API_BASE_URL=/pingan
|
||||
URL = http://agent.admin.haodian.cn
|
||||
PORT = 8200
|
||||
|
||||
@@ -24,3 +24,25 @@ export async function getCaptcha() {
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取短信验证码
|
||||
*/
|
||||
export async function getCode(data) {
|
||||
const res = await request.get('/login/code', data);
|
||||
if (res.data.code === 0) {
|
||||
return res.data.data;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
|
||||
/**
|
||||
* 注册
|
||||
*/
|
||||
export async function register(data) {
|
||||
const res = await request.post('/register', data);
|
||||
if (res.data.code === 0) {
|
||||
return res.data.data;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
<template>
|
||||
<div class="copyright">Copyright © 2022 好店云(厦门)科技有限公司</div>
|
||||
</template>
|
||||
<style lang="scss" scoped>
|
||||
/* 底部版权 */
|
||||
.copyright {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
color: #eee;
|
||||
text-align: center;
|
||||
padding: 50px 0;
|
||||
z-index: 100;
|
||||
}
|
||||
</style>
|
||||
@@ -18,7 +18,7 @@ export const HIDE_FOOTERS = [
|
||||
export const REPEATABLE_TABS = [];
|
||||
|
||||
// 不需要登录的路由
|
||||
export const WHITE_LIST = ['/login', '/forget'];
|
||||
export const WHITE_LIST = ['/login', '/register'];
|
||||
|
||||
// 开启 KeepAlive 后仍然不需要缓存的路由地址
|
||||
export const KEEP_ALIVE_EXCLUDES = [];
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
<el-dropdown @command="onUserDropClick">
|
||||
<div class="ele-admin-header-avatar">
|
||||
<el-avatar :src="loginUser.avatar" />
|
||||
<span class="hidden-xs-only">{{ loginUser.nickname }}</span>
|
||||
<span class="hidden-xs-only">{{ loginUser.username }}</span>
|
||||
<i class="el-icon-arrow-down"></i>
|
||||
</div>
|
||||
<template v-slot:dropdown>
|
||||
@@ -34,9 +34,6 @@
|
||||
<el-dropdown-item command="profile" icon="el-icon-user">
|
||||
{{ $t('layout.header.profile') }}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item command="password" icon="el-icon-key">
|
||||
{{ $t('layout.header.password') }}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item
|
||||
command="logout"
|
||||
icon="el-icon-switch-button"
|
||||
@@ -61,14 +58,14 @@
|
||||
|
||||
<script>
|
||||
// import HeaderNotice from './header-notice.vue';
|
||||
import PasswordModal from './password-modal.vue';
|
||||
// import PasswordModal from './password-modal.vue';
|
||||
import SettingDrawer from './setting-drawer.vue';
|
||||
// import I18nIcon from './i18n-icon.vue';
|
||||
import { logout } from '@/utils/page-tab-util';
|
||||
|
||||
export default {
|
||||
// components: { HeaderNotice, PasswordModal, SettingDrawer, I18nIcon },
|
||||
components: { PasswordModal, SettingDrawer },
|
||||
components: { SettingDrawer },
|
||||
props: {
|
||||
// 是否是全屏
|
||||
fullscreen: Boolean
|
||||
|
||||
@@ -13,10 +13,15 @@ export const routes = [
|
||||
component: () => import('@/views/login/index.vue'),
|
||||
meta: { title: '登录' }
|
||||
},
|
||||
// {
|
||||
// path: '/forget',
|
||||
// component: () => import('@/views/forget/index.vue'),
|
||||
// meta: { title: '忘记密码' }
|
||||
// },
|
||||
{
|
||||
path: '/forget',
|
||||
component: () => import('@/views/forget/index.vue'),
|
||||
meta: { title: '忘记密码' }
|
||||
path: '/register',
|
||||
component: () => import('@/views/register/index.vue'),
|
||||
meta: { title: '账号绑定' }
|
||||
},
|
||||
// 404
|
||||
{
|
||||
|
||||
@@ -1,73 +0,0 @@
|
||||
<template>
|
||||
<el-card shadow="never" header="热门搜索">
|
||||
<v-chart
|
||||
ref="hotSearchChart"
|
||||
style="height: 303px"
|
||||
:option="hotSearchChartOption"
|
||||
/>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { use } from 'echarts/core';
|
||||
import { CanvasRenderer } from 'echarts/renderers';
|
||||
import { TooltipComponent } from 'echarts/components';
|
||||
import VChart from 'vue-echarts';
|
||||
import 'echarts-wordcloud';
|
||||
import { wordCloudColor } from 'ele-admin';
|
||||
import { getWordCloudList } from '@/api/dashboard/analysis';
|
||||
import { echartsMixin } from '@/utils/echarts-mixin';
|
||||
|
||||
use([CanvasRenderer, TooltipComponent]);
|
||||
|
||||
export default {
|
||||
components: { VChart },
|
||||
mixins: [echartsMixin(['hotSearchChart'])],
|
||||
data() {
|
||||
return {
|
||||
// 词云图表配置
|
||||
hotSearchChartOption: {}
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.getWordCloudData();
|
||||
},
|
||||
methods: {
|
||||
/* 获取词云数据 */
|
||||
getWordCloudData() {
|
||||
getWordCloudList()
|
||||
.then((data) => {
|
||||
this.hotSearchChartOption = {
|
||||
tooltip: {
|
||||
show: true,
|
||||
confine: true,
|
||||
borderWidth: 1
|
||||
},
|
||||
series: [
|
||||
{
|
||||
type: 'wordCloud',
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
sizeRange: [12, 24],
|
||||
gridSize: 6,
|
||||
textStyle: {
|
||||
color: wordCloudColor
|
||||
},
|
||||
emphasis: {
|
||||
textStyle: {
|
||||
shadowBlur: 8,
|
||||
shadowColor: 'rgba(0, 0, 0, .15)'
|
||||
}
|
||||
},
|
||||
data: data
|
||||
}
|
||||
]
|
||||
};
|
||||
})
|
||||
.catch((e) => {
|
||||
this.$message.error(e.message);
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@@ -1,210 +0,0 @@
|
||||
<template>
|
||||
<el-card shadow="never" body-style="padding: 0;">
|
||||
<div class="ele-cell demo-monitor-tool">
|
||||
<div class="ele-cell-content">
|
||||
<el-tabs
|
||||
v-model="saleSearch.type"
|
||||
class="demo-monitor-tabs"
|
||||
@tab-click="onSaleTypeChange"
|
||||
>
|
||||
<el-tab-pane label="销售额" name="saleroom" />
|
||||
<el-tab-pane label="访问量" name="visits" />
|
||||
</el-tabs>
|
||||
</div>
|
||||
<div :class="['ele-inline-block', { 'hidden-xs-only': styleResponsive }]">
|
||||
<el-radio-group v-model="saleSearch.dateType" size="small">
|
||||
<el-radio-button :label="0">今天</el-radio-button>
|
||||
<el-radio-button :label="1">本周</el-radio-button>
|
||||
<el-radio-button :label="2">本月</el-radio-button>
|
||||
<el-radio-button :label="3">本年</el-radio-button>
|
||||
</el-radio-group>
|
||||
</div>
|
||||
<div
|
||||
:class="['ele-inline-block', { 'hidden-sm-and-down': styleResponsive }]"
|
||||
style="width: 260px; margin-left: 10px"
|
||||
>
|
||||
<el-date-picker
|
||||
unlink-panels
|
||||
type="daterange"
|
||||
class="ele-fluid"
|
||||
end-placeholder="结束日期"
|
||||
start-placeholder="开始日期"
|
||||
v-model="saleSearch.datetime"
|
||||
range-separator="至"
|
||||
size="small"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<el-divider />
|
||||
<el-row>
|
||||
<el-col v-bind="styleResponsive ? { lg: 18, md: 16 } : { span: 18 }">
|
||||
<div class="demo-monitor-title">
|
||||
<span v-if="saleSearch.type === 'saleroom'">销售额趋势</span>
|
||||
<span v-else>访问量趋势</span>
|
||||
</div>
|
||||
<v-chart
|
||||
ref="saleChart"
|
||||
style="height: 285px"
|
||||
:option="saleChartOption"
|
||||
/>
|
||||
</el-col>
|
||||
<el-col v-bind="styleResponsive ? { lg: 6, md: 8 } : { span: 6 }">
|
||||
<div class="demo-monitor-title" style="display: flex">
|
||||
<div>门店</div>
|
||||
<div>
|
||||
<span v-if="saleSearch.type === 'saleroom'">销售额</span>
|
||||
<span v-else>访问量</span>
|
||||
</div>
|
||||
<div>排名</div>
|
||||
</div>
|
||||
<div
|
||||
v-for="(item, index) in saleroomRankData"
|
||||
:key="index"
|
||||
class="demo-monitor-rank-item ele-cell"
|
||||
style="margin-bottom: 15px"
|
||||
>
|
||||
<el-tag
|
||||
size="mini"
|
||||
type="info"
|
||||
:effect="index < 3 ? 'dark' : 'light'"
|
||||
:color="index < 3 ? '#314659' : 'hsla(0, 0%, 60%, .2)'"
|
||||
style="border-color: transparent"
|
||||
class="ele-tag-round"
|
||||
>
|
||||
{{ index + 1 }}
|
||||
</el-tag>
|
||||
<div class="ele-cell-content">{{ item.name }}</div>
|
||||
<div class="ele-text-secondary">{{ item.value }}</div>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { use } from 'echarts/core';
|
||||
import { CanvasRenderer } from 'echarts/renderers';
|
||||
import { BarChart } from 'echarts/charts';
|
||||
import { GridComponent, TooltipComponent } from 'echarts/components';
|
||||
import VChart from 'vue-echarts';
|
||||
import { getSaleroomList } from '@/api/dashboard/analysis';
|
||||
import { echartsMixin } from '@/utils/echarts-mixin';
|
||||
|
||||
use([CanvasRenderer, BarChart, GridComponent, TooltipComponent]);
|
||||
|
||||
export default {
|
||||
components: { VChart },
|
||||
mixins: [echartsMixin(['saleChart'])],
|
||||
data() {
|
||||
return {
|
||||
// 销售量搜索参数
|
||||
saleSearch: {
|
||||
type: 'saleroom',
|
||||
dateType: 0,
|
||||
datetime: ''
|
||||
},
|
||||
// 销售量趋势数据
|
||||
saleroomData1: [],
|
||||
// 访问量趋势数据
|
||||
saleroomData2: [],
|
||||
// 门店排名数据
|
||||
saleroomRankData: [
|
||||
{ name: '工专路 1 号店', value: '323,234' },
|
||||
{ name: '工专路 2 号店', value: '323,234' },
|
||||
{ name: '工专路 3 号店', value: '323,234' },
|
||||
{ name: '工专路 4 号店', value: '323,234' },
|
||||
{ name: '工专路 5 号店', value: '323,234' },
|
||||
{ name: '工专路 6 号店', value: '323,234' },
|
||||
{ name: '工专路 7 号店', value: '323,234' }
|
||||
],
|
||||
// 销售额柱状图配置
|
||||
saleChartOption: {}
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
// 是否开启响应式布局
|
||||
styleResponsive() {
|
||||
return this.$store.state.theme.styleResponsive;
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.getSaleroomData();
|
||||
},
|
||||
methods: {
|
||||
/* 获取销售量数据 */
|
||||
getSaleroomData() {
|
||||
getSaleroomList()
|
||||
.then((data) => {
|
||||
this.saleroomData1 = data.list1;
|
||||
this.saleroomData2 = data.list2;
|
||||
this.onSaleTypeChange();
|
||||
})
|
||||
.catch((e) => {
|
||||
this.$message.error(e.message);
|
||||
});
|
||||
},
|
||||
|
||||
/* 销售量tab选择改变事件 */
|
||||
onSaleTypeChange() {
|
||||
const isSale = this.saleSearch.type === 'saleroom';
|
||||
const data = isSale ? this.saleroomData1 : this.saleroomData2;
|
||||
this.saleChartOption = {
|
||||
tooltip: {
|
||||
trigger: 'axis'
|
||||
},
|
||||
xAxis: [
|
||||
{
|
||||
type: 'category',
|
||||
data: data.map((d) => d.month)
|
||||
}
|
||||
],
|
||||
yAxis: [
|
||||
{
|
||||
type: 'value'
|
||||
}
|
||||
],
|
||||
series: [
|
||||
{
|
||||
type: 'bar',
|
||||
data: data.map((d) => d.value)
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
/* 销售额、访问量工具栏 */
|
||||
.demo-monitor-tool {
|
||||
padding: 0 20px;
|
||||
|
||||
.demo-monitor-tabs {
|
||||
height: 51px;
|
||||
}
|
||||
|
||||
:deep(.el-tabs__item) {
|
||||
height: 51px;
|
||||
line-height: 51px;
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
:deep(.el-tabs__nav-wrap:after) {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
/* 小标题 */
|
||||
.demo-monitor-title {
|
||||
padding: 0 20px;
|
||||
margin: 15px 0 5px 0;
|
||||
}
|
||||
|
||||
/* 排名 item */
|
||||
.demo-monitor-rank-item {
|
||||
padding: 0 20px;
|
||||
line-height: 20px;
|
||||
margin-top: 18px;
|
||||
}
|
||||
</style>
|
||||
@@ -1,243 +0,0 @@
|
||||
<!-- 统计卡片 -->
|
||||
<template>
|
||||
<el-row :gutter="15">
|
||||
<el-col v-bind="styleResponsive ? { lg: 6, md: 12 } : { span: 6 }">
|
||||
<el-card class="analysis-chart-card" shadow="never">
|
||||
<template v-slot:header>
|
||||
<div class="ele-cell">
|
||||
<div class="ele-cell-content">总销售额</div>
|
||||
<el-tooltip content="指标说明" placement="top">
|
||||
<i
|
||||
class="el-icon-_question ele-text-placeholder"
|
||||
style="cursor: pointer"
|
||||
>
|
||||
</i>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
</template>
|
||||
<div class="analysis-chart-card-num ele-text-heading">¥ 126,560</div>
|
||||
<div class="analysis-chart-card-content" style="padding-top: 18px">
|
||||
<span class="ele-action">
|
||||
<span>周同比12%</span>
|
||||
<i class="el-icon-caret-top ele-text-danger"></i>
|
||||
</span>
|
||||
<span class="ele-action">
|
||||
<span>日同比11%</span>
|
||||
<i class="el-icon-caret-bottom ele-text-success"></i>
|
||||
</span>
|
||||
</div>
|
||||
<el-divider />
|
||||
<div class="analysis-chart-card-text">日销售额 ¥12,423</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col v-bind="styleResponsive ? { lg: 6, md: 12 } : { span: 6 }">
|
||||
<el-card class="analysis-chart-card" shadow="never">
|
||||
<template v-slot:header>
|
||||
<div class="ele-cell">
|
||||
<div class="ele-cell-content">访问量</div>
|
||||
<el-tag size="mini" type="danger">日</el-tag>
|
||||
</div>
|
||||
</template>
|
||||
<div class="analysis-chart-card-num ele-text-heading">8,846</div>
|
||||
<div class="analysis-chart-card-content">
|
||||
<v-chart
|
||||
ref="visitChart"
|
||||
style="height: 40px"
|
||||
:option="visitChartOption"
|
||||
/>
|
||||
</div>
|
||||
<el-divider />
|
||||
<div class="analysis-chart-card-text">日访问量 1,234</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col v-bind="styleResponsive ? { lg: 6, md: 12 } : { span: 6 }">
|
||||
<el-card class="analysis-chart-card" shadow="never">
|
||||
<template v-slot:header>
|
||||
<div class="ele-cell">
|
||||
<div class="ele-cell-content">支付笔数</div>
|
||||
<el-tag size="mini">月</el-tag>
|
||||
</div>
|
||||
</template>
|
||||
<div class="analysis-chart-card-num ele-text-heading">6,560</div>
|
||||
<div class="analysis-chart-card-content">
|
||||
<v-chart
|
||||
ref="payNumChart"
|
||||
style="height: 40px"
|
||||
:option="payNumChartOption"
|
||||
/>
|
||||
</div>
|
||||
<el-divider />
|
||||
<div class="analysis-chart-card-text">转化率 60%</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col v-bind="styleResponsive ? { lg: 6, md: 12 } : { span: 6 }">
|
||||
<el-card class="analysis-chart-card" shadow="never">
|
||||
<template v-slot:header>
|
||||
<div class="ele-cell">
|
||||
<div class="ele-cell-content">运营活动效果</div>
|
||||
<el-tag size="mini" type="success">周</el-tag>
|
||||
</div>
|
||||
</template>
|
||||
<div class="analysis-chart-card-num ele-text-heading">78%</div>
|
||||
<div class="analysis-chart-card-content" style="padding-top: 25px">
|
||||
<el-progress
|
||||
:percentage="78"
|
||||
:show-text="false"
|
||||
:stroke-width="10"
|
||||
color="#13c2c2"
|
||||
/>
|
||||
</div>
|
||||
<el-divider />
|
||||
<div class="analysis-chart-card-text">
|
||||
<span class="ele-action">
|
||||
<span>周同比12%</span>
|
||||
<i class="el-icon-caret-top ele-text-danger"></i>
|
||||
</span>
|
||||
<span class="ele-action">
|
||||
<span>日同比11%</span>
|
||||
<i class="el-icon-caret-bottom ele-text-success"></i>
|
||||
</span>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { use } from 'echarts/core';
|
||||
import { CanvasRenderer } from 'echarts/renderers';
|
||||
import { LineChart, BarChart } from 'echarts/charts';
|
||||
import { GridComponent, TooltipComponent } from 'echarts/components';
|
||||
import VChart from 'vue-echarts';
|
||||
import { getPayNumList } from '@/api/dashboard/analysis';
|
||||
import { echartsMixin } from '@/utils/echarts-mixin';
|
||||
|
||||
use([CanvasRenderer, LineChart, BarChart, GridComponent, TooltipComponent]);
|
||||
|
||||
export default {
|
||||
components: { VChart },
|
||||
mixins: [echartsMixin(['visitChart', 'payNumChart'])],
|
||||
data() {
|
||||
return {
|
||||
// 访问量折线图配置
|
||||
visitChartOption: {},
|
||||
// 支付笔数柱状图配置
|
||||
payNumChartOption: {}
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
// 是否开启响应式布局
|
||||
styleResponsive() {
|
||||
return this.$store.state.theme.styleResponsive;
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.getPayNumData();
|
||||
},
|
||||
methods: {
|
||||
/* 获取数据 */
|
||||
getPayNumData() {
|
||||
getPayNumList()
|
||||
.then((data) => {
|
||||
this.visitChartOption = {
|
||||
color: '#975fe5',
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
formatter:
|
||||
'<i class="ele-chart-dot" style="background: #975fe5;"></i>{b0}: {c0}'
|
||||
},
|
||||
grid: {
|
||||
top: 10,
|
||||
bottom: 0,
|
||||
left: 0,
|
||||
right: 0
|
||||
},
|
||||
xAxis: [
|
||||
{
|
||||
show: false,
|
||||
type: 'category',
|
||||
boundaryGap: false,
|
||||
data: data.map((d) => d.date)
|
||||
}
|
||||
],
|
||||
yAxis: [
|
||||
{
|
||||
show: false,
|
||||
type: 'value',
|
||||
splitLine: {
|
||||
show: false
|
||||
}
|
||||
}
|
||||
],
|
||||
series: [
|
||||
{
|
||||
type: 'line',
|
||||
smooth: true,
|
||||
symbol: 'none',
|
||||
areaStyle: {
|
||||
opacity: 0.5
|
||||
},
|
||||
data: data.map((d) => d.value)
|
||||
}
|
||||
]
|
||||
};
|
||||
//
|
||||
this.payNumChartOption = {
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
formatter:
|
||||
'<i class="ele-chart-dot" style="background: #5b8ff9;"></i>{b0}: {c0}'
|
||||
},
|
||||
grid: {
|
||||
top: 10,
|
||||
bottom: 0,
|
||||
left: 0,
|
||||
right: 0
|
||||
},
|
||||
xAxis: [
|
||||
{
|
||||
show: false,
|
||||
type: 'category',
|
||||
data: data.map((d) => d.date)
|
||||
}
|
||||
],
|
||||
yAxis: [
|
||||
{
|
||||
show: false,
|
||||
type: 'value',
|
||||
splitLine: {
|
||||
show: false
|
||||
}
|
||||
}
|
||||
],
|
||||
series: [
|
||||
{
|
||||
type: 'bar',
|
||||
data: data.map((d) => d.value)
|
||||
}
|
||||
]
|
||||
};
|
||||
})
|
||||
.catch((e) => {
|
||||
this.$message.error(e.message);
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.analysis-chart-card-num {
|
||||
font-size: 30px;
|
||||
}
|
||||
|
||||
.analysis-chart-card-content {
|
||||
height: 40px;
|
||||
box-sizing: border-box;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.analysis-chart-card-text {
|
||||
padding-top: 12px;
|
||||
}
|
||||
</style>
|
||||
@@ -1,103 +0,0 @@
|
||||
<template>
|
||||
<el-card
|
||||
shadow="never"
|
||||
header="最近1小时访问情况"
|
||||
body-style="padding: 14px 5px 0 0;"
|
||||
>
|
||||
<v-chart
|
||||
ref="visitHourChart"
|
||||
style="height: 323px"
|
||||
:option="visitHourChartOption"
|
||||
/>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { use } from 'echarts/core';
|
||||
import { CanvasRenderer } from 'echarts/renderers';
|
||||
import { LineChart } from 'echarts/charts';
|
||||
import {
|
||||
GridComponent,
|
||||
TooltipComponent,
|
||||
LegendComponent
|
||||
} from 'echarts/components';
|
||||
import VChart from 'vue-echarts';
|
||||
import { getVisitHourList } from '@/api/dashboard/analysis';
|
||||
import { echartsMixin } from '@/utils/echarts-mixin';
|
||||
|
||||
use([
|
||||
CanvasRenderer,
|
||||
LineChart,
|
||||
GridComponent,
|
||||
TooltipComponent,
|
||||
LegendComponent
|
||||
]);
|
||||
|
||||
export default {
|
||||
components: { VChart },
|
||||
mixins: [echartsMixin(['visitHourChart'])],
|
||||
data() {
|
||||
return {
|
||||
// 最近1小时访问情况折线图配置
|
||||
visitHourChartOption: {}
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.getVisitHourData();
|
||||
},
|
||||
methods: {
|
||||
/* 获取最近1小时访问情况数据 */
|
||||
getVisitHourData() {
|
||||
getVisitHourList()
|
||||
.then((data) => {
|
||||
this.visitHourChartOption = {
|
||||
tooltip: {
|
||||
trigger: 'axis'
|
||||
},
|
||||
legend: {
|
||||
data: ['浏览量', '访问量'],
|
||||
right: 20
|
||||
},
|
||||
xAxis: [
|
||||
{
|
||||
type: 'category',
|
||||
boundaryGap: false,
|
||||
data: data.map((d) => d.time)
|
||||
}
|
||||
],
|
||||
yAxis: [
|
||||
{
|
||||
type: 'value'
|
||||
}
|
||||
],
|
||||
series: [
|
||||
{
|
||||
name: '浏览量',
|
||||
type: 'line',
|
||||
smooth: true,
|
||||
symbol: 'none',
|
||||
areaStyle: {
|
||||
opacity: 0.5
|
||||
},
|
||||
data: data.map((d) => d.views)
|
||||
},
|
||||
{
|
||||
name: '访问量',
|
||||
type: 'line',
|
||||
smooth: true,
|
||||
symbol: 'none',
|
||||
areaStyle: {
|
||||
opacity: 0.5
|
||||
},
|
||||
data: data.map((d) => d.visits)
|
||||
}
|
||||
]
|
||||
};
|
||||
})
|
||||
.catch((e) => {
|
||||
this.$message.error(e.message);
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@@ -1,37 +0,0 @@
|
||||
<template>
|
||||
<div class="ele-body ele-body-card">
|
||||
<statistics-card />
|
||||
<sale-card />
|
||||
<el-row :gutter="15">
|
||||
<el-col v-bind="styleResponsive ? { lg: 18, md: 16 } : { span: 18 }">
|
||||
<visit-hour />
|
||||
</el-col>
|
||||
<el-col v-bind="styleResponsive ? { lg: 6, md: 8 } : { span: 6 }">
|
||||
<hot-search />
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import StatisticsCard from './components/statistics-card.vue';
|
||||
import SaleCard from './components/sale-card.vue';
|
||||
import VisitHour from './components/visit-hour.vue';
|
||||
import HotSearch from './components/hot-search.vue';
|
||||
|
||||
export default {
|
||||
name: 'DashboardAnalysis',
|
||||
components: {
|
||||
StatisticsCard,
|
||||
SaleCard,
|
||||
VisitHour,
|
||||
HotSearch
|
||||
},
|
||||
computed: {
|
||||
// 是否开启响应式布局
|
||||
styleResponsive() {
|
||||
return this.$store.state.theme.styleResponsive;
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@@ -1,71 +0,0 @@
|
||||
<template>
|
||||
<el-card shadow="never" header="浏览器分布" body-style="padding: 0 10px;">
|
||||
<v-chart
|
||||
ref="browserChart"
|
||||
style="height: 240px"
|
||||
:option="browserChartOption"
|
||||
/>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { use } from 'echarts/core';
|
||||
import { CanvasRenderer } from 'echarts/renderers';
|
||||
import { PieChart } from 'echarts/charts';
|
||||
import { TooltipComponent, LegendComponent } from 'echarts/components';
|
||||
import VChart from 'vue-echarts';
|
||||
import { getBrowserCountList } from '@/api/dashboard/monitor';
|
||||
import { echartsMixin } from '@/utils/echarts-mixin';
|
||||
|
||||
use([CanvasRenderer, PieChart, TooltipComponent, LegendComponent]);
|
||||
|
||||
export default {
|
||||
components: { VChart },
|
||||
mixins: [echartsMixin(['browserChart'])],
|
||||
data() {
|
||||
return {
|
||||
// 浏览器分布饼图配置
|
||||
browserChartOption: {}
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.getBrowserCountData();
|
||||
},
|
||||
methods: {
|
||||
/* 获取用户浏览器分布数据 */
|
||||
getBrowserCountData() {
|
||||
getBrowserCountList()
|
||||
.then((data) => {
|
||||
this.browserChartOption = {
|
||||
tooltip: {
|
||||
trigger: 'item',
|
||||
confine: true,
|
||||
borderWidth: 1
|
||||
},
|
||||
legend: {
|
||||
bottom: 5,
|
||||
itemWidth: 10,
|
||||
itemHeight: 10,
|
||||
icon: 'circle',
|
||||
data: data.map((d) => d.name)
|
||||
},
|
||||
series: [
|
||||
{
|
||||
type: 'pie',
|
||||
radius: ['45%', '70%'],
|
||||
center: ['50%', '43%'],
|
||||
label: {
|
||||
show: false
|
||||
},
|
||||
data: data
|
||||
}
|
||||
]
|
||||
};
|
||||
})
|
||||
.catch((e) => {
|
||||
this.$message.error(e.message);
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@@ -1,149 +0,0 @@
|
||||
<template>
|
||||
<el-card shadow="never" header="用户分布">
|
||||
<el-row>
|
||||
<el-col v-bind="styleResponsive ? { sm: 18 } : { span: 18 }">
|
||||
<v-chart
|
||||
ref="userCountMapChart"
|
||||
style="height: 444px"
|
||||
:option="userCountMapOption"
|
||||
/>
|
||||
</el-col>
|
||||
<el-col v-bind="styleResponsive ? { sm: 6 } : { span: 6 }">
|
||||
<div style="padding: 10px 5px 0 0">
|
||||
<div
|
||||
v-for="(item, index) in userCountDataRank"
|
||||
:key="index"
|
||||
class="monitor-user-count-item ele-cell"
|
||||
>
|
||||
<div>{{ item.name }}</div>
|
||||
<div class="ele-cell-content">
|
||||
<el-progress
|
||||
:stroke-width="10"
|
||||
:show-text="false"
|
||||
:percentage="item.percent"
|
||||
/>
|
||||
</div>
|
||||
<div>{{ item.value }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { use, registerMap } from 'echarts/core';
|
||||
import { CanvasRenderer } from 'echarts/renderers';
|
||||
import { MapChart } from 'echarts/charts';
|
||||
import {
|
||||
VisualMapComponent,
|
||||
GeoComponent,
|
||||
TooltipComponent
|
||||
} from 'echarts/components';
|
||||
import VChart from 'vue-echarts';
|
||||
import { getChinaMapData, getUserCountList } from '@/api/dashboard/monitor';
|
||||
import { echartsMixin } from '@/utils/echarts-mixin';
|
||||
|
||||
use([
|
||||
CanvasRenderer,
|
||||
MapChart,
|
||||
VisualMapComponent,
|
||||
GeoComponent,
|
||||
TooltipComponent
|
||||
]);
|
||||
|
||||
export default {
|
||||
components: { VChart },
|
||||
mixins: [echartsMixin(['userCountMapChart'])],
|
||||
data() {
|
||||
return {
|
||||
// 用户分布地图配置
|
||||
userCountMapOption: {},
|
||||
// 用户分布前10名
|
||||
userCountDataRank: []
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
// 是否开启响应式布局
|
||||
styleResponsive() {
|
||||
return this.$store.state.theme.styleResponsive;
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.registerChinaMap();
|
||||
},
|
||||
methods: {
|
||||
/* 获取中国地图数据并注册地图 */
|
||||
registerChinaMap() {
|
||||
getChinaMapData()
|
||||
.then((data) => {
|
||||
registerMap('china', data);
|
||||
this.getUserCountData();
|
||||
})
|
||||
.catch((e) => {
|
||||
this.$message.error(e.message);
|
||||
});
|
||||
},
|
||||
/* 获取用户分布数据 */
|
||||
getUserCountData() {
|
||||
getUserCountList()
|
||||
.then((data) => {
|
||||
const temp = data.sort((a, b) => b.value - a.value);
|
||||
const min = temp[temp.length - 1].value || 0;
|
||||
const max = temp[0].value || 1;
|
||||
//
|
||||
const list = temp.length > 10 ? temp.slice(0, 15) : temp;
|
||||
this.userCountDataRank = list.map((d) => {
|
||||
return {
|
||||
name: d.name,
|
||||
value: d.value,
|
||||
percent: (d.value / max) * 100
|
||||
};
|
||||
});
|
||||
//
|
||||
this.userCountMapOption = {
|
||||
tooltip: {
|
||||
trigger: 'item',
|
||||
borderWidth: 1
|
||||
},
|
||||
visualMap: {
|
||||
min: min,
|
||||
max: max,
|
||||
text: ['高', '低'],
|
||||
calculable: true
|
||||
},
|
||||
series: [
|
||||
{
|
||||
name: '用户数',
|
||||
label: {
|
||||
show: true
|
||||
},
|
||||
type: 'map',
|
||||
map: 'china',
|
||||
data: data
|
||||
}
|
||||
]
|
||||
};
|
||||
})
|
||||
.catch((e) => {
|
||||
this.$message.error(e.message);
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
/* 人数分布排名 */
|
||||
.monitor-user-count-item {
|
||||
margin-bottom: 8px;
|
||||
|
||||
:deep(.el-progress-bar__outer) {
|
||||
background: none;
|
||||
}
|
||||
|
||||
.ele-cell-content {
|
||||
padding-right: 10px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,93 +0,0 @@
|
||||
<template>
|
||||
<el-card shadow="never" header="在线人数">
|
||||
<div
|
||||
:class="[
|
||||
'monitor-online-num-card',
|
||||
{ 'monitor-online-num-responsive': styleResponsive }
|
||||
]"
|
||||
>
|
||||
<div class="monitor-online-num-text">{{ currentTime }}</div>
|
||||
<div class="monitor-online-num-title ele-text-heading">
|
||||
<vue-count-up :end-val="onlineNum" />
|
||||
</div>
|
||||
<div class="monitor-online-num-text">在线总人数</div>
|
||||
<ele-dot :text="updateTimeText" />
|
||||
</div>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import VueCountUp from 'vue-countup-v2';
|
||||
|
||||
export default {
|
||||
components: { VueCountUp },
|
||||
data() {
|
||||
return {
|
||||
// 在线总人数倒计时
|
||||
updateTime: 10,
|
||||
// 当前时间
|
||||
currentTime: '20:58:22',
|
||||
// 在线人数
|
||||
onlineNum: 228,
|
||||
// 在线人数更新定时器
|
||||
onlineNumTimer: null
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
// 在线人数倒计时文字
|
||||
updateTimeText() {
|
||||
return this.updateTime + ' 秒后更新';
|
||||
},
|
||||
// 是否开启响应式布局
|
||||
styleResponsive() {
|
||||
return this.$store.state.theme.styleResponsive;
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.startUpdateOnlineNum();
|
||||
},
|
||||
methods: {
|
||||
/* 在线人数更新倒计时 */
|
||||
startUpdateOnlineNum() {
|
||||
this.currentTime = this.$util.toDateString(new Date(), 'HH:mm:ss');
|
||||
this.onlineNumTimer = setInterval(() => {
|
||||
this.currentTime = this.$util.toDateString(new Date(), 'HH:mm:ss');
|
||||
if (this.updateTime === 1) {
|
||||
this.updateTime = 10;
|
||||
this.onlineNum = 100 + Math.round(Math.random() * 900);
|
||||
} else {
|
||||
this.updateTime--;
|
||||
}
|
||||
}, 1000);
|
||||
}
|
||||
},
|
||||
beforeDestroy() {
|
||||
// 销毁定时器
|
||||
if (this.onlineNumTimer) {
|
||||
clearInterval(this.onlineNumTimer);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.monitor-online-num-card {
|
||||
text-align: center;
|
||||
padding: 5px 0;
|
||||
}
|
||||
|
||||
.monitor-online-num-text {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.monitor-online-num-title {
|
||||
font-size: 48px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 1200px) {
|
||||
.monitor-online-num-responsive.monitor-online-num-card {
|
||||
padding: 42px 0;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,163 +0,0 @@
|
||||
<!-- 统计卡片 -->
|
||||
<template>
|
||||
<el-row :gutter="15">
|
||||
<el-col v-bind="styleResponsive ? { md: 6, sm: 12 } : { span: 6 }">
|
||||
<el-card shadow="never" class="monitor-count-card">
|
||||
<el-tag size="large" class="ele-tag-round">
|
||||
<i class="el-icon-s-custom"></i>
|
||||
</el-tag>
|
||||
<div class="monitor-count-card-num ele-text-heading">21.2 k</div>
|
||||
<div class="monitor-count-card-text ele-text-secondary">
|
||||
总访问人数
|
||||
</div>
|
||||
<ele-avatar-list :data="visitUsers" :size="22" :max="4" />
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col v-bind="styleResponsive ? { md: 6, sm: 12 } : { span: 6 }">
|
||||
<el-card shadow="never" class="monitor-count-card">
|
||||
<el-tag size="large" type="warning" class="ele-tag-round">
|
||||
<i class="el-icon-_sent"></i>
|
||||
</el-tag>
|
||||
<div class="monitor-count-card-num ele-text-heading">1.6 k</div>
|
||||
<div class="monitor-count-card-text ele-text-secondary">
|
||||
点击量 (近30天)
|
||||
</div>
|
||||
<div class="monitor-count-card-trend ele-text-success">
|
||||
<i class="el-icon-arrow-up"></i>
|
||||
<span>110.5%</span>
|
||||
</div>
|
||||
<el-tooltip content="指标说明" placement="top">
|
||||
<i
|
||||
class="el-icon-_question ele-text-placeholder monitor-count-card-tips"
|
||||
>
|
||||
</i>
|
||||
</el-tooltip>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col v-bind="styleResponsive ? { md: 6, sm: 12 } : { span: 6 }">
|
||||
<el-card shadow="never" class="monitor-count-card">
|
||||
<el-tag size="large" type="danger" class="ele-tag-round">
|
||||
<i class="el-icon-s-flag"></i>
|
||||
</el-tag>
|
||||
<div class="monitor-count-card-num ele-text-heading">826.0</div>
|
||||
<div class="monitor-count-card-text ele-text-secondary">
|
||||
到达量 (近30天)
|
||||
</div>
|
||||
<div class="monitor-count-card-trend ele-text-danger">
|
||||
<i class="el-icon-arrow-down"></i>
|
||||
<span>15.5%</span>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col v-bind="styleResponsive ? { md: 6, sm: 12 } : { span: 6 }">
|
||||
<el-card shadow="never" class="monitor-count-card">
|
||||
<el-tag size="large" type="success" class="ele-tag-round">
|
||||
<i class="el-icon-_flash-solid"></i>
|
||||
</el-tag>
|
||||
<div class="monitor-count-card-num ele-text-heading">28.8 %</div>
|
||||
<div class="monitor-count-card-text">转化率 (近30天)</div>
|
||||
<div class="monitor-count-card-trend ele-text-success">
|
||||
<i class="el-icon-arrow-up"></i>
|
||||
<span>65.8%</span>
|
||||
</div>
|
||||
<el-tooltip content="指标说明" placement="top">
|
||||
<i
|
||||
class="el-icon-_question ele-text-placeholder monitor-count-card-tips"
|
||||
>
|
||||
</i>
|
||||
</el-tooltip>
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
// 访问人数
|
||||
visitUsers: [
|
||||
{
|
||||
name: 'SunSmile',
|
||||
avatar:
|
||||
'https://cdn.eleadmin.com/20200609/c184eef391ae48dba87e3057e70238fb.jpg'
|
||||
},
|
||||
{
|
||||
name: '你的名字很好听',
|
||||
avatar:
|
||||
'https://cdn.eleadmin.com/20200609/b6a811873e704db49db994053a5019b2.jpg'
|
||||
},
|
||||
{
|
||||
name: '全村人的希望',
|
||||
avatar:
|
||||
'https://cdn.eleadmin.com/20200609/948344a2a77c47a7a7b332fe12ff749a.jpg'
|
||||
},
|
||||
{
|
||||
name: 'Jasmine',
|
||||
avatar:
|
||||
'https://cdn.eleadmin.com/20200609/f6bc05af944a4f738b54128717952107.jpg'
|
||||
},
|
||||
{
|
||||
name: '酷酷的大叔',
|
||||
avatar:
|
||||
'https://cdn.eleadmin.com/20200609/2d98970a51b34b6b859339c96b240dcd.jpg'
|
||||
},
|
||||
{
|
||||
name: '管理员',
|
||||
avatar: 'https://cdn.eleadmin.com/20200610/avatar.jpg'
|
||||
}
|
||||
]
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
// 是否开启响应式布局
|
||||
styleResponsive() {
|
||||
return this.$store.state.theme.styleResponsive;
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.monitor-count-card {
|
||||
:deep(.el-card__body) {
|
||||
padding-top: 18px;
|
||||
text-align: center;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
:deep(.el-tag) {
|
||||
border-color: transparent;
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
.monitor-count-card-num {
|
||||
font-weight: 500;
|
||||
font-size: 32px;
|
||||
margin-top: 12px;
|
||||
}
|
||||
|
||||
.monitor-count-card-text {
|
||||
font-size: 12px;
|
||||
margin: 10px 0;
|
||||
}
|
||||
|
||||
.monitor-count-card-trend {
|
||||
font-weight: 600;
|
||||
padding: 6px 0;
|
||||
|
||||
& > i {
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
margin-right: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
.monitor-count-card-tips {
|
||||
position: absolute;
|
||||
top: 15px;
|
||||
right: 15px;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,266 +0,0 @@
|
||||
<template>
|
||||
<el-row :gutter="15">
|
||||
<el-col v-bind="styleResponsive ? { lg: 8 } : { span: 8 }">
|
||||
<el-card shadow="never" header="用户评价">
|
||||
<div class="ele-cell ele-cell-align-bottom">
|
||||
<div class="ele-text-heading" style="font-size: 48px">4.5</div>
|
||||
<div class="ele-cell-content" style="padding-bottom: 8px">
|
||||
<el-rate
|
||||
v-model="userRate"
|
||||
disabled
|
||||
show-score
|
||||
text-color="#F7BA2A"
|
||||
score-template="很棒"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ele-cell" style="margin: 15px 0">
|
||||
<div style="font-size: 29px" class="ele-text-placeholder">-0%</div>
|
||||
<div class="ele-cell-content ele-text-small ele-text-secondary">
|
||||
当前没有评价波动
|
||||
</div>
|
||||
</div>
|
||||
<div class="ele-cell">
|
||||
<div class="ele-cell-content">
|
||||
<el-progress :percentage="60" :show-text="false" status="success" />
|
||||
</div>
|
||||
<div
|
||||
style="width: 80px; white-space: nowrap"
|
||||
class="ele-text-secondary"
|
||||
>
|
||||
<span><s></s><i class="el-icon-star-on"></i></span>
|
||||
<span> 5 : 368人</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ele-cell">
|
||||
<div class="ele-cell-content">
|
||||
<el-progress :percentage="40" :show-text="false" />
|
||||
</div>
|
||||
<div
|
||||
style="width: 80px; white-space: nowrap"
|
||||
class="ele-text-secondary"
|
||||
>
|
||||
<span><s></s><i class="el-icon-star-on"></i></span>
|
||||
<span> 4 : 256人</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ele-cell">
|
||||
<div class="ele-cell-content">
|
||||
<el-progress :percentage="20" :show-text="false" status="warning" />
|
||||
</div>
|
||||
<div
|
||||
style="width: 80px; white-space: nowrap"
|
||||
class="ele-text-secondary"
|
||||
>
|
||||
<span><s></s><i class="el-icon-star-on"></i></span>
|
||||
<span> 3 : 49人</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ele-cell">
|
||||
<div class="ele-cell-content">
|
||||
<el-progress
|
||||
:percentage="10"
|
||||
:show-text="false"
|
||||
status="exception"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
style="width: 80px; white-space: nowrap"
|
||||
class="ele-text-secondary"
|
||||
>
|
||||
<span><s></s><i class="el-icon-star-on"></i></span>
|
||||
<span> 2 : 14人</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ele-cell">
|
||||
<div class="ele-cell-content">
|
||||
<el-progress :percentage="0" :show-text="false" />
|
||||
</div>
|
||||
<div
|
||||
style="width: 80px; white-space: nowrap"
|
||||
class="ele-text-secondary"
|
||||
>
|
||||
<span><s></s><i class="el-icon-star-on"></i></span>
|
||||
<span> 1 : 0人</span>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col v-bind="styleResponsive ? { lg: 8, md: 12 } : { span: 8 }">
|
||||
<el-card shadow="never" header="用户满意度">
|
||||
<div class="ele-cell" style="margin: 15px 0">
|
||||
<div
|
||||
class="ele-cell-content ele-text-center ele-text-heading"
|
||||
style="font-size: 24px"
|
||||
>
|
||||
856
|
||||
</div>
|
||||
<div class="ele-cell-content ele-text-center">
|
||||
<div class="monitor-face-smile">
|
||||
<span></span>
|
||||
</div>
|
||||
<div class="ele-text-secondary" style="margin-top: 5px">
|
||||
正面评论
|
||||
</div>
|
||||
</div>
|
||||
<h2 class="ele-cell-content ele-text-success ele-text-center">
|
||||
82%
|
||||
</h2>
|
||||
</div>
|
||||
<el-divider />
|
||||
<div class="ele-cell" style="margin: 15px 0 12px 0">
|
||||
<div
|
||||
class="ele-cell-content ele-text-center ele-text-heading"
|
||||
style="font-size: 24px"
|
||||
>
|
||||
60
|
||||
</div>
|
||||
<div class="ele-cell-content ele-text-center">
|
||||
<div class="monitor-face-cry">
|
||||
<span></span>
|
||||
</div>
|
||||
<div class="ele-text-secondary" style="margin-top: 5px">
|
||||
负面评论
|
||||
</div>
|
||||
</div>
|
||||
<h2 class="ele-cell-content ele-text-danger ele-text-center">9%</h2>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col v-bind="styleResponsive ? { lg: 8, md: 12 } : { span: 8 }">
|
||||
<el-card shadow="never" header="用户活跃度">
|
||||
<div class="ele-cell" style="padding: 35px 0; justify-content: center">
|
||||
<div class="monitor-progress-group">
|
||||
<el-progress
|
||||
type="circle"
|
||||
:percentage="70"
|
||||
status="success"
|
||||
:show-text="false"
|
||||
:width="140"
|
||||
/>
|
||||
<el-progress
|
||||
type="circle"
|
||||
:percentage="60"
|
||||
:show-text="false"
|
||||
:width="115"
|
||||
:stroke-width="5"
|
||||
/>
|
||||
<el-progress
|
||||
type="circle"
|
||||
:percentage="35"
|
||||
status="exception"
|
||||
:show-text="false"
|
||||
:width="90"
|
||||
:stroke-width="4"
|
||||
/>
|
||||
</div>
|
||||
<div class="monitor-progress-legends" style="padding-left: 12px">
|
||||
<div class="ele-text-small">
|
||||
<ele-dot :ripple="false" text="活跃率: 70%" />
|
||||
</div>
|
||||
<div class="ele-text-small">
|
||||
<ele-dot type="success" :ripple="false" text="留存率: 60%" />
|
||||
</div>
|
||||
<div class="ele-text-small">
|
||||
<ele-dot type="danger" :ripple="false" text="跳出率: 35%" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
// 用户评分
|
||||
userRate: 4.5
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
// 是否开启响应式布局
|
||||
styleResponsive() {
|
||||
return this.$store.state.theme.styleResponsive;
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
/* 笑脸、哭脸 */
|
||||
.monitor-face-smile,
|
||||
.monitor-face-cry {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
display: inline-block;
|
||||
background-color: #fbd971;
|
||||
border-radius: 50%;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.monitor-face-smile > span,
|
||||
.monitor-face-smile:before,
|
||||
.monitor-face-smile:after,
|
||||
.monitor-face-cry > span,
|
||||
.monitor-face-cry:before,
|
||||
.monitor-face-cry:after {
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
border-radius: 50%;
|
||||
transform: rotate(225deg);
|
||||
border: 3px solid #f0c419;
|
||||
border-right-color: transparent !important;
|
||||
border-bottom-color: transparent !important;
|
||||
position: absolute;
|
||||
bottom: 8px;
|
||||
left: 11px;
|
||||
}
|
||||
|
||||
.monitor-face-smile:before,
|
||||
.monitor-face-smile:after,
|
||||
.monitor-face-cry:before,
|
||||
.monitor-face-cry:after {
|
||||
content: '';
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
left: 8px;
|
||||
top: 14px;
|
||||
border-color: #f29c1f;
|
||||
transform: rotate(45deg);
|
||||
}
|
||||
|
||||
.monitor-face-smile:after,
|
||||
.monitor-face-cry:after {
|
||||
left: auto;
|
||||
right: 8px;
|
||||
}
|
||||
|
||||
.monitor-face-cry > span {
|
||||
transform: rotate(45deg);
|
||||
bottom: -6px;
|
||||
}
|
||||
|
||||
/* 圆形进度条组合 */
|
||||
.monitor-progress-group {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
|
||||
.el-progress:not(:first-child) {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
margin-top: -1px;
|
||||
}
|
||||
|
||||
:deep(.el-progress-circle__track) {
|
||||
stroke: hsla(0deg, 0%, 60%, 0.15);
|
||||
}
|
||||
}
|
||||
|
||||
.monitor-progress-legends > div + div {
|
||||
margin-top: 8px;
|
||||
}
|
||||
</style>
|
||||
@@ -1,50 +0,0 @@
|
||||
<template>
|
||||
<div class="ele-body ele-body-card">
|
||||
<statistics-card />
|
||||
<el-row :gutter="15">
|
||||
<el-col v-bind="styleResponsive ? { lg: 18 } : { span: 18 }">
|
||||
<map-card />
|
||||
</el-col>
|
||||
<el-col v-bind="styleResponsive ? { lg: 6 } : { span: 6 }">
|
||||
<el-row :gutter="15">
|
||||
<el-col
|
||||
v-bind="styleResponsive ? { lg: 24, md: 12, sm: 24 } : { span: 24 }"
|
||||
>
|
||||
<online-num />
|
||||
</el-col>
|
||||
<el-col
|
||||
v-bind="styleResponsive ? { lg: 24, md: 12, sm: 24 } : { span: 24 }"
|
||||
>
|
||||
<browser-card />
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<user-rate />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import StatisticsCard from './components/statistics-card.vue';
|
||||
import MapCard from './components/map-card.vue';
|
||||
import OnlineNum from './components/online-num.vue';
|
||||
import BrowserCard from './components/browser-card.vue';
|
||||
import UserRate from './components/user-rate.vue';
|
||||
|
||||
export default {
|
||||
name: 'DashboardMonitor',
|
||||
components: {
|
||||
StatisticsCard,
|
||||
MapCard,
|
||||
OnlineNum,
|
||||
BrowserCard,
|
||||
UserRate
|
||||
},
|
||||
computed: {
|
||||
// 是否开启响应式布局
|
||||
styleResponsive() {
|
||||
return this.$store.state.theme.styleResponsive;
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@@ -1,128 +0,0 @@
|
||||
<template>
|
||||
<el-card shadow="never" body-style="padding: 6px 0;">
|
||||
<template v-slot:header>
|
||||
<span>{{ title }}</span>
|
||||
<more-icon @remove="onRemove" @edit="onEdit" />
|
||||
</template>
|
||||
<el-scrollbar
|
||||
style="height: 326px"
|
||||
wrapStyle="overflow-x: hidden;"
|
||||
viewStyle="padding: 14px 10px;"
|
||||
>
|
||||
<el-timeline :reverse="false" class="ele-timeline ele-timeline-act">
|
||||
<el-timeline-item
|
||||
v-for="(item, index) in activities"
|
||||
:key="index"
|
||||
:timestamp="item.timestamp"
|
||||
:type="item.type"
|
||||
>
|
||||
{{ item.title }}
|
||||
</el-timeline-item>
|
||||
</el-timeline>
|
||||
</el-scrollbar>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import MoreIcon from './more-icon.vue';
|
||||
|
||||
export default {
|
||||
components: { MoreIcon },
|
||||
props: {
|
||||
title: String
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
activities: []
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.queryActivities();
|
||||
},
|
||||
methods: {
|
||||
queryActivities() {
|
||||
this.activities = [
|
||||
{
|
||||
title: 'SunSmile 解决了bug 登录提示操作失败',
|
||||
timestamp: '20:30'
|
||||
},
|
||||
{
|
||||
title: 'Jasmine 解决了bug 按钮颜色与设计不符',
|
||||
timestamp: '19:30'
|
||||
},
|
||||
{
|
||||
title: '项目经理 指派了任务 解决项目一的bug',
|
||||
timestamp: '18:30',
|
||||
type: 'primary'
|
||||
},
|
||||
{
|
||||
title: '项目经理 指派了任务 解决项目二的bug',
|
||||
timestamp: '17:30',
|
||||
type: 'primary'
|
||||
},
|
||||
{
|
||||
title: '项目经理 指派了任务 解决项目三的bug',
|
||||
timestamp: '16:30',
|
||||
type: 'primary'
|
||||
},
|
||||
{
|
||||
title: '项目经理 指派了任务 解决项目四的bug',
|
||||
timestamp: '15:30'
|
||||
},
|
||||
{
|
||||
title: '项目经理 指派了任务 解决项目五的bug',
|
||||
timestamp: '14:30'
|
||||
},
|
||||
{
|
||||
title: '项目经理 指派了任务 解决项目六的bug',
|
||||
timestamp: '12:30'
|
||||
},
|
||||
{
|
||||
title: '项目经理 指派了任务 解决项目七的bug',
|
||||
timestamp: '11:30',
|
||||
type: 'primary'
|
||||
},
|
||||
{
|
||||
title: '项目经理 指派了任务 解决项目八的bug',
|
||||
timestamp: '10:30'
|
||||
},
|
||||
{
|
||||
title: '项目经理 指派了任务 解决项目九的bug',
|
||||
timestamp: '09:30'
|
||||
},
|
||||
{
|
||||
title: '项目经理 指派了任务 解决项目十的bug',
|
||||
timestamp: '08:30'
|
||||
}
|
||||
];
|
||||
},
|
||||
onRemove() {
|
||||
this.$emit('remove');
|
||||
},
|
||||
onEdit() {
|
||||
this.$emit('edit');
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.ele-timeline-act {
|
||||
padding-left: 50px;
|
||||
|
||||
:deep(.el-timeline-item__timestamp) {
|
||||
margin: 0;
|
||||
position: absolute;
|
||||
top: 3px;
|
||||
left: -45px;
|
||||
}
|
||||
|
||||
:deep(.el-timeline-item) {
|
||||
padding-bottom: 19px;
|
||||
|
||||
&:last-child {
|
||||
padding-bottom: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,70 +0,0 @@
|
||||
<template>
|
||||
<el-card shadow="never">
|
||||
<template v-slot:header>
|
||||
<span>{{ title }}</span>
|
||||
<more-icon @remove="onRemove" @edit="onEdit" />
|
||||
</template>
|
||||
<div class="workplace-goal-wrap">
|
||||
<div class="workplace-goal-group">
|
||||
<el-progress
|
||||
:width="170"
|
||||
:percentage="80"
|
||||
type="dashboard"
|
||||
:format="() => ''"
|
||||
/>
|
||||
<div class="workplace-goal-content">
|
||||
<el-tag size="large" class="ele-tag-round">
|
||||
<i class="el-icon-s-data"></i>
|
||||
</el-tag>
|
||||
<div class="workplace-goal-num ele-text-heading">285</div>
|
||||
</div>
|
||||
<div class="workplace-goal-text">恭喜, 本月目标已达标!</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import MoreIcon from './more-icon.vue';
|
||||
|
||||
export default {
|
||||
components: { MoreIcon },
|
||||
props: {
|
||||
title: String
|
||||
},
|
||||
methods: {
|
||||
onRemove() {
|
||||
this.$emit('remove');
|
||||
},
|
||||
onEdit() {
|
||||
this.$emit('edit');
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.workplace-goal-wrap {
|
||||
height: 304px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.workplace-goal-group {
|
||||
text-align: center;
|
||||
position: relative;
|
||||
|
||||
.workplace-goal-content {
|
||||
position: absolute;
|
||||
top: 48px;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.workplace-goal-num {
|
||||
font-size: 40px;
|
||||
margin-top: 15px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,143 +0,0 @@
|
||||
<!-- 快捷方式 -->
|
||||
<template>
|
||||
<vue-draggable
|
||||
tag="el-row"
|
||||
v-model="data"
|
||||
:component-data="{ props: { gutter: 15 } }"
|
||||
:animation="300"
|
||||
:set-data="() => void 0"
|
||||
@end="onEnd"
|
||||
>
|
||||
<el-col
|
||||
v-for="item in data"
|
||||
:key="item.url"
|
||||
v-bind="styleResponsive ? { lg: 3, md: 6, sm: 6, xs: 12 } : { span: 3 }"
|
||||
>
|
||||
<el-card shadow="hover" body-style="padding: 0;">
|
||||
<router-link :to="item.url" class="app-link-block">
|
||||
<i
|
||||
:class="['app-link-icon', item.icon]"
|
||||
:style="{ color: item.color }"
|
||||
>
|
||||
</i>
|
||||
<div class="app-link-title">{{ item.title }}</div>
|
||||
</router-link>
|
||||
</el-card>
|
||||
</el-col>
|
||||
</vue-draggable>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import VueDraggable from 'vuedraggable';
|
||||
|
||||
export default {
|
||||
components: { VueDraggable },
|
||||
data() {
|
||||
// 默认布局
|
||||
const defaultData = [
|
||||
{
|
||||
icon: 'el-icon-user',
|
||||
title: '用户',
|
||||
url: '/system/user'
|
||||
},
|
||||
{
|
||||
icon: 'el-icon-data-line',
|
||||
title: '分析',
|
||||
url: '/dashboard/analysis',
|
||||
color: '#95de64'
|
||||
},
|
||||
{
|
||||
icon: 'el-icon-shopping-cart-2',
|
||||
title: '商品',
|
||||
url: '/list/card/project',
|
||||
color: '#ff9c6e'
|
||||
},
|
||||
{
|
||||
icon: 'el-icon-tickets',
|
||||
title: '订单',
|
||||
url: '/list/basic',
|
||||
color: '#b37feb'
|
||||
},
|
||||
{
|
||||
icon: 'el-icon-bank-card',
|
||||
title: '票据',
|
||||
url: '/list/advanced',
|
||||
color: '#ffd666'
|
||||
},
|
||||
{
|
||||
icon: 'el-icon-message',
|
||||
title: '消息',
|
||||
url: '/user/message',
|
||||
color: '#5cdbd3'
|
||||
},
|
||||
{
|
||||
icon: 'el-icon-discount',
|
||||
title: '标签',
|
||||
url: '/extension/tag',
|
||||
color: '#ff85c0'
|
||||
},
|
||||
{
|
||||
icon: 'el-icon-s-operation',
|
||||
title: '配置',
|
||||
url: '/user/profile',
|
||||
color: '#ffc069'
|
||||
}
|
||||
];
|
||||
// 获取缓存顺序
|
||||
const cache = (() => {
|
||||
const str = localStorage.getItem('workplace-links');
|
||||
try {
|
||||
return str ? JSON.parse(str) : null;
|
||||
} catch (e) {
|
||||
return null;
|
||||
}
|
||||
})();
|
||||
return {
|
||||
defaultData,
|
||||
data: [...(cache ?? defaultData)]
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
// 是否开启响应式布局
|
||||
styleResponsive() {
|
||||
return this.$store.state.theme.styleResponsive;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
/* 排序改变 */
|
||||
onEnd() {
|
||||
this.cacheData();
|
||||
},
|
||||
/* 重置布局 */
|
||||
reset() {
|
||||
this.data = [...this.defaultData];
|
||||
this.cacheData();
|
||||
},
|
||||
/* 缓存布局 */
|
||||
cacheData() {
|
||||
localStorage.setItem('workplace-links', JSON.stringify(this.data));
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.app-link-block {
|
||||
display: block;
|
||||
color: inherit;
|
||||
padding: 15px 0;
|
||||
text-align: center;
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
|
||||
.app-link-icon {
|
||||
color: #69c0ff;
|
||||
font-size: 30px;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
.app-link-title {
|
||||
margin-top: 8px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,41 +0,0 @@
|
||||
<template>
|
||||
<el-dropdown class="card-more-icon" @command="onCommand">
|
||||
<i class="el-icon-more ele-text-secondary"></i>
|
||||
<template v-slot:dropdown>
|
||||
<el-dropdown-menu>
|
||||
<el-dropdown-item icon="el-icon-edit" command="edit">
|
||||
编辑
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item icon="el-icon-circle-close" command="remove">
|
||||
删除
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
</el-dropdown>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
methods: {
|
||||
onCommand(command) {
|
||||
this.$emit(command);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.card-more-icon {
|
||||
padding: 0 8px 0 0;
|
||||
position: absolute;
|
||||
right: 8px;
|
||||
top: 50%;
|
||||
margin-top: -8px;
|
||||
cursor: pointer;
|
||||
|
||||
.el-icon-more {
|
||||
transform: rotate(90deg);
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,115 +0,0 @@
|
||||
<!-- 用户信息 -->
|
||||
<template>
|
||||
<el-card shadow="never" body-style="padding: 20px;">
|
||||
<div
|
||||
:class="[
|
||||
'ele-cell',
|
||||
'workplace-user-card',
|
||||
{ 'workplace-user-responsive': styleResponsive }
|
||||
]"
|
||||
>
|
||||
<div class="ele-cell-content ele-cell">
|
||||
<el-avatar :size="68" :src="loginUser.avatar" />
|
||||
<div class="ele-cell-content">
|
||||
<h4 class="ele-elip">
|
||||
早安, {{ loginUser.nickname }} , 开始您一天的工作吧!
|
||||
</h4>
|
||||
<div class="ele-text-secondary ele-elip" style="margin-top: 8px">
|
||||
<i class="el-icon-heavy-rain"></i>
|
||||
<em>今日阴转小雨, 22℃ - 32℃ , 出门记得带伞哦。</em>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="workplace-count-group">
|
||||
<div class="workplace-count-item">
|
||||
<div class="workplace-count-header">
|
||||
<el-tag size="small" class="ele-tag-round">
|
||||
<i class="el-icon-menu"></i>
|
||||
</el-tag>
|
||||
<span class="workplace-count-name">项目数</span>
|
||||
</div>
|
||||
<div class="workplace-count-num ele-text-heading">3</div>
|
||||
</div>
|
||||
<div class="workplace-count-item">
|
||||
<div class="workplace-count-header">
|
||||
<el-tag type="warning" size="small" class="ele-tag-round">
|
||||
<i class="el-icon-finished"></i>
|
||||
</el-tag>
|
||||
<span class="workplace-count-name">待办项</span>
|
||||
</div>
|
||||
<div class="workplace-count-num ele-text-heading">6 / 24</div>
|
||||
</div>
|
||||
<div class="workplace-count-item">
|
||||
<div class="workplace-count-header">
|
||||
<el-tag type="success" size="small" class="ele-tag-round">
|
||||
<i class="el-icon-bell"></i>
|
||||
</el-tag>
|
||||
<span class="workplace-count-name">消息</span>
|
||||
</div>
|
||||
<div class="workplace-count-num ele-text-heading">1,689</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
computed: {
|
||||
// 当前登录用户信息
|
||||
loginUser() {
|
||||
return this.$store.state.user.info;
|
||||
},
|
||||
// 是否开启响应式布局
|
||||
styleResponsive() {
|
||||
return this.$store.state.theme.styleResponsive;
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.workplace-user-card {
|
||||
.ele-cell-content {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.workplace-count-group {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.workplace-count-item {
|
||||
padding: 0 5px 0 25px;
|
||||
box-sizing: border-box;
|
||||
display: inline-block;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.workplace-count-name {
|
||||
padding-left: 8px;
|
||||
}
|
||||
|
||||
.workplace-count-num {
|
||||
font-size: 24px;
|
||||
margin-top: 6px;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 992px) {
|
||||
.workplace-user-responsive .workplace-count-item {
|
||||
padding: 0 5px 0 10px;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 768px) {
|
||||
.workplace-user-responsive.workplace-user-card {
|
||||
display: block;
|
||||
|
||||
.workplace-count-group {
|
||||
display: block;
|
||||
margin-top: 15px;
|
||||
text-align: right;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,156 +0,0 @@
|
||||
<template>
|
||||
<el-card
|
||||
shadow="never"
|
||||
body-style="padding: 11px;"
|
||||
class="workplace-table-card"
|
||||
>
|
||||
<template v-slot:header>
|
||||
<span>{{ title }}</span>
|
||||
<more-icon @remove="onRemove" @edit="onEdit" />
|
||||
</template>
|
||||
<el-table :data="projectList" :height="316">
|
||||
<el-table-column type="index" width="35" min-width="35" align="right" />
|
||||
<el-table-column label="项目名称" min-width="110" show-overflow-tooltip>
|
||||
<template v-slot="{ row }">
|
||||
<el-link type="primary" :underline="false">
|
||||
{{ row.projectName }}
|
||||
</el-link>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
label="开始时间"
|
||||
prop="startDate"
|
||||
width="95"
|
||||
min-width="80"
|
||||
align="center"
|
||||
show-overflow-tooltip
|
||||
/>
|
||||
<el-table-column
|
||||
prop="endDate"
|
||||
label="结束时间"
|
||||
width="95"
|
||||
min-width="80"
|
||||
align="center"
|
||||
show-overflow-tooltip
|
||||
/>
|
||||
<el-table-column
|
||||
label="状态"
|
||||
width="70"
|
||||
min-width="60"
|
||||
align="center"
|
||||
show-overflow-tooltip
|
||||
>
|
||||
<template v-slot="{ row }">
|
||||
<span
|
||||
:class="
|
||||
[
|
||||
'ele-text-success',
|
||||
'ele-text-danger',
|
||||
'ele-text-warning',
|
||||
'ele-text-info ele-text-delete'
|
||||
][row.status]
|
||||
"
|
||||
>
|
||||
{{ ['进行中', '已延期', '未开始', '已结束'][row.status] }}
|
||||
</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="进度" width="160" min-width="100" align="center">
|
||||
<template v-slot="{ row }">
|
||||
<el-progress :percentage="row.progress" class="ele-text-small" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import MoreIcon from './more-icon.vue';
|
||||
|
||||
export default {
|
||||
components: { MoreIcon },
|
||||
props: {
|
||||
title: String
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
projectList: []
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.queryProjectList();
|
||||
},
|
||||
methods: {
|
||||
queryProjectList() {
|
||||
this.projectList = [
|
||||
{
|
||||
id: 1,
|
||||
projectName: '项目0000001',
|
||||
status: 0,
|
||||
startDate: '2020-03-01',
|
||||
endDate: '2020-06-01',
|
||||
progress: 30
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
projectName: '项目0000002',
|
||||
status: 0,
|
||||
startDate: '2020-03-01',
|
||||
endDate: '2020-08-01',
|
||||
progress: 10
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
projectName: '项目0000003',
|
||||
status: 1,
|
||||
startDate: '2020-01-01',
|
||||
endDate: '2020-05-01',
|
||||
progress: 60
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
projectName: '项目0000004',
|
||||
status: 1,
|
||||
startDate: '2020-06-01',
|
||||
endDate: '2020-10-01',
|
||||
progress: 0
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
projectName: '项目0000005',
|
||||
status: 2,
|
||||
startDate: '2020-01-01',
|
||||
endDate: '2020-03-01',
|
||||
progress: 100
|
||||
},
|
||||
{
|
||||
id: 6,
|
||||
projectName: '项目0000006',
|
||||
status: 3,
|
||||
startDate: '2020-01-01',
|
||||
endDate: '2020-03-01',
|
||||
progress: 100
|
||||
}
|
||||
];
|
||||
},
|
||||
onRemove() {
|
||||
this.$emit('remove');
|
||||
},
|
||||
onEdit() {
|
||||
this.$emit('edit');
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.workplace-table-card {
|
||||
:deep(.el-table tbody > .el-table__row:last-child td) {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
:deep(.el-table:before) {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,156 +0,0 @@
|
||||
<template>
|
||||
<el-card
|
||||
shadow="never"
|
||||
body-style="padding: 0;height: 338px;overflow: hidden;"
|
||||
class="workplace-table-card"
|
||||
>
|
||||
<template v-slot:header>
|
||||
<span>{{ title }}</span>
|
||||
<more-icon @remove="onRemove" @edit="onEdit" />
|
||||
</template>
|
||||
<table class="ele-table" style="table-layout: fixed">
|
||||
<colgroup>
|
||||
<col width="38" />
|
||||
<col width="65" />
|
||||
<col />
|
||||
<col width="70" />
|
||||
</colgroup>
|
||||
<thead>
|
||||
<tr style="background: none">
|
||||
<th></th>
|
||||
<th>优先级</th>
|
||||
<th class="ele-elip">任务名称</th>
|
||||
<th style="text-align: center">状态</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<vue-draggable
|
||||
tag="tbody"
|
||||
:animation="300"
|
||||
v-model="taskList"
|
||||
handle=".sort-handle"
|
||||
:set-data="() => void 0"
|
||||
>
|
||||
<tr v-for="d in taskList" :key="d.id">
|
||||
<td style="text-align: center">
|
||||
<i class="sort-handle el-icon-_nav ele-text-placeholder"></i>
|
||||
</td>
|
||||
<td>
|
||||
<el-tag
|
||||
size="mini"
|
||||
class="ele-tag-round"
|
||||
:type="['danger', 'warning', 'primary'][d.priority - 1]"
|
||||
>
|
||||
{{ d.priority }}
|
||||
</el-tag>
|
||||
</td>
|
||||
<td class="ele-elip">
|
||||
<el-link type="primary" :underline="false" class="ele-inline">
|
||||
{{ d.taskName }}
|
||||
</el-link>
|
||||
</td>
|
||||
<td style="text-align: center">
|
||||
<span
|
||||
:class="
|
||||
['ele-text-warning', 'ele-text-success', 'ele-text-info'][
|
||||
d.status
|
||||
]
|
||||
"
|
||||
>
|
||||
{{ ['未开始', '进行中', '已完成'][d.status] }}
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
</vue-draggable>
|
||||
</table>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import VueDraggable from 'vuedraggable';
|
||||
import MoreIcon from './more-icon.vue';
|
||||
|
||||
export default {
|
||||
components: { VueDraggable, MoreIcon },
|
||||
props: {
|
||||
title: String
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
taskList: []
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.queryTaskList();
|
||||
},
|
||||
methods: {
|
||||
queryTaskList() {
|
||||
this.taskList = [
|
||||
{
|
||||
id: 1,
|
||||
priority: 1,
|
||||
taskName: '解决项目一的bug',
|
||||
status: 0
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
priority: 2,
|
||||
taskName: '解决项目二的bug',
|
||||
status: 0
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
priority: 2,
|
||||
taskName: '解决项目三的bug',
|
||||
status: 1
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
priority: 3,
|
||||
taskName: '解决项目四的bug',
|
||||
status: 1
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
priority: 3,
|
||||
taskName: '解决项目五的bug',
|
||||
status: 2
|
||||
},
|
||||
{
|
||||
id: 6,
|
||||
priority: 3,
|
||||
taskName: '解决项目六的bug',
|
||||
status: 2
|
||||
}
|
||||
];
|
||||
},
|
||||
onRemove() {
|
||||
this.$emit('remove');
|
||||
},
|
||||
onEdit() {
|
||||
this.$emit('edit');
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.ele-table tbody > tr:last-child td {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.ele-table {
|
||||
td {
|
||||
padding-top: 11px;
|
||||
padding-bottom: 11px;
|
||||
}
|
||||
|
||||
tr.sortable-chosen {
|
||||
background: hsla(0, 0%, 60%, 0.1);
|
||||
}
|
||||
}
|
||||
|
||||
.workplace-table-card .sort-handle {
|
||||
cursor: move;
|
||||
font-size: 18px;
|
||||
}
|
||||
</style>
|
||||
@@ -1,102 +0,0 @@
|
||||
<template>
|
||||
<el-card shadow="never" body-style="padding: 2px 0;">
|
||||
<template v-slot:header>
|
||||
<span>{{ title }}</span>
|
||||
<more-icon @remove="onRemove" @edit="onEdit" />
|
||||
</template>
|
||||
<div
|
||||
v-for="(item, index) in userList"
|
||||
:key="index"
|
||||
class="ele-cell user-list-item"
|
||||
>
|
||||
<el-avatar :size="40" :src="item.avatar" />
|
||||
<div class="ele-cell-content" style="overflow: hidden">
|
||||
<div class="ele-cell-title ele-elip">{{ item.name }}</div>
|
||||
<div class="ele-cell-desc ele-elip">{{ item.introduction }}</div>
|
||||
</div>
|
||||
<el-tag size="mini" :type="['success', 'danger'][item.status]">
|
||||
{{ ['在线', '离线'][item.status] }}
|
||||
</el-tag>
|
||||
</div>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import MoreIcon from './more-icon.vue';
|
||||
|
||||
export default {
|
||||
components: { MoreIcon },
|
||||
props: {
|
||||
title: String
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
userList: []
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.queryUserList();
|
||||
},
|
||||
methods: {
|
||||
queryUserList() {
|
||||
this.userList = [
|
||||
{
|
||||
name: 'SunSmile',
|
||||
introduction: 'UI设计师、交互专家',
|
||||
status: 0,
|
||||
avatar:
|
||||
'https://cdn.eleadmin.com/20200609/c184eef391ae48dba87e3057e70238fb.jpg'
|
||||
},
|
||||
{
|
||||
name: '你的名字很好听',
|
||||
introduction: '前端工程师',
|
||||
status: 0,
|
||||
avatar:
|
||||
'https://cdn.eleadmin.com/20200609/b6a811873e704db49db994053a5019b2.jpg'
|
||||
},
|
||||
{
|
||||
name: '全村人的希望',
|
||||
introduction: '前端工程师',
|
||||
status: 0,
|
||||
avatar:
|
||||
'https://cdn.eleadmin.com/20200609/948344a2a77c47a7a7b332fe12ff749a.jpg'
|
||||
},
|
||||
{
|
||||
name: 'Jasmine',
|
||||
introduction: '产品经理、项目经理',
|
||||
status: 1,
|
||||
avatar:
|
||||
'https://cdn.eleadmin.com/20200609/f6bc05af944a4f738b54128717952107.jpg'
|
||||
},
|
||||
{
|
||||
name: '酷酷的大叔',
|
||||
introduction: '组长、后端工程师',
|
||||
status: 1,
|
||||
avatar:
|
||||
'https://cdn.eleadmin.com/20200609/2d98970a51b34b6b859339c96b240dcd.jpg'
|
||||
}
|
||||
];
|
||||
},
|
||||
onRemove() {
|
||||
this.$emit('remove');
|
||||
},
|
||||
onEdit() {
|
||||
this.$emit('edit');
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.user-list-item {
|
||||
padding: 13px 18px;
|
||||
|
||||
& + .user-list-item {
|
||||
border-top: 1px solid hsla(0, 0%, 60%, 0.15);
|
||||
}
|
||||
|
||||
.ele-cell-desc {
|
||||
margin-top: 2px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,237 +0,0 @@
|
||||
<template>
|
||||
<div class="ele-body ele-body-card">
|
||||
<profile-card />
|
||||
<link-card ref="linkCard" />
|
||||
<vue-draggable
|
||||
tag="el-row"
|
||||
v-model="data"
|
||||
handle=".el-card__header"
|
||||
:component-data="{ props: { gutter: 15 } }"
|
||||
:animation="300"
|
||||
:set-data="() => void 0"
|
||||
@end="onEnd"
|
||||
>
|
||||
<el-col
|
||||
v-for="(d, i) in data"
|
||||
:key="d.name"
|
||||
v-bind="styleResponsive ? { md: d.md, sm: d.sm } : { span: d.md }"
|
||||
>
|
||||
<component
|
||||
:is="d.name"
|
||||
:title="d.title"
|
||||
@remove="onRemove(i)"
|
||||
@edit="onEdit(i)"
|
||||
/>
|
||||
</el-col>
|
||||
</vue-draggable>
|
||||
<el-card shadow="never" body-style="padding: 0;">
|
||||
<div class="ele-cell" style="line-height: 42px">
|
||||
<div
|
||||
class="ele-cell-content ele-text-primary workplace-bottom-btn"
|
||||
@click="add"
|
||||
>
|
||||
<i class="el-icon-circle-plus-outline"></i> 添加视图
|
||||
</div>
|
||||
<el-divider direction="vertical" />
|
||||
<div
|
||||
class="ele-cell-content ele-text-primary workplace-bottom-btn"
|
||||
@click="reset"
|
||||
>
|
||||
<i class="el-icon-refresh-left"></i> 重置布局
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
<!-- 编辑弹窗 -->
|
||||
<ele-modal width="680px" :visible.sync="visible" title="未添加的视图">
|
||||
<el-row :gutter="15" style="margin-bottom: -15px">
|
||||
<el-col v-for="item in notAddedData" :key="item.name" :md="8" :sm="24">
|
||||
<div
|
||||
class="workplace-card-item ele-border-lighter"
|
||||
@click="addView(item)"
|
||||
>
|
||||
<div class="workplace-card-header ele-border-lighter">
|
||||
{{ item.title }}
|
||||
</div>
|
||||
<div class="workplace-card-body ele-text-placeholder">
|
||||
<i class="el-icon-plus"></i>
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<ele-empty v-if="!notAddedData.length" text="已添加所有视图" />
|
||||
</ele-modal>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import VueDraggable from 'vuedraggable';
|
||||
import ProfileCard from './components/profile-card.vue';
|
||||
import LinkCard from './components/link-card.vue';
|
||||
import ActivitiesCard from './components/activities-card.vue';
|
||||
import TaskCard from './components/task-card.vue';
|
||||
import GoalCard from './components/goal-card.vue';
|
||||
import ProjectCard from './components/project-card.vue';
|
||||
import UserList from './components/user-list.vue';
|
||||
|
||||
export default {
|
||||
name: 'DashboardWorkplace',
|
||||
components: {
|
||||
VueDraggable,
|
||||
ProfileCard,
|
||||
LinkCard,
|
||||
ActivitiesCard,
|
||||
TaskCard,
|
||||
GoalCard,
|
||||
ProjectCard,
|
||||
UserList
|
||||
},
|
||||
data() {
|
||||
// 默认布局
|
||||
const defaultData = [
|
||||
{
|
||||
name: 'activities-card',
|
||||
title: '最新动态',
|
||||
md: 8,
|
||||
sm: 24
|
||||
},
|
||||
{
|
||||
name: 'task-card',
|
||||
title: '我的任务',
|
||||
md: 8,
|
||||
sm: 24
|
||||
},
|
||||
{
|
||||
name: 'goal-card',
|
||||
title: '本月目标',
|
||||
md: 8,
|
||||
sm: 24
|
||||
},
|
||||
{
|
||||
name: 'project-card',
|
||||
title: '项目进度',
|
||||
md: 16,
|
||||
sm: 24
|
||||
},
|
||||
{
|
||||
name: 'user-list',
|
||||
title: '小组成员',
|
||||
md: 8,
|
||||
sm: 24
|
||||
}
|
||||
];
|
||||
// 获取缓存布局
|
||||
const cache = (() => {
|
||||
const str = localStorage.getItem('workplace-layout');
|
||||
try {
|
||||
return str ? JSON.parse(str) : null;
|
||||
} catch (e) {
|
||||
return null;
|
||||
}
|
||||
})();
|
||||
return {
|
||||
defaultData,
|
||||
data: [...(cache ?? defaultData)],
|
||||
visible: false
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
// 未添加的数据
|
||||
notAddedData() {
|
||||
return this.defaultData.filter(
|
||||
(d) => !this.data.some((t) => t.name === d.name)
|
||||
);
|
||||
},
|
||||
// 是否开启响应式布局
|
||||
styleResponsive() {
|
||||
return this.$store.state.theme.styleResponsive;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
/* 添加 */
|
||||
add() {
|
||||
this.visible = true;
|
||||
},
|
||||
/* 重置布局 */
|
||||
reset() {
|
||||
this.data = [...this.defaultData];
|
||||
this.cacheData();
|
||||
this.$refs.linkCard.reset();
|
||||
this.$message.success('已重置');
|
||||
},
|
||||
/* 缓存布局 */
|
||||
cacheData() {
|
||||
localStorage.setItem('workplace-layout', JSON.stringify(this.data));
|
||||
},
|
||||
/* 删除视图 */
|
||||
onRemove(index) {
|
||||
this.data = this.data.filter((_d, i) => i !== index);
|
||||
this.cacheData();
|
||||
},
|
||||
/* 编辑视图 */
|
||||
onEdit(index) {
|
||||
console.log('index:', index);
|
||||
this.$message.info('点击了编辑');
|
||||
},
|
||||
/* 添加视图 */
|
||||
addView(item) {
|
||||
this.data.push(item);
|
||||
this.cacheData();
|
||||
this.$message.success('已添加');
|
||||
},
|
||||
/* 排序改变 */
|
||||
onEnd() {
|
||||
this.cacheData();
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.ele-body {
|
||||
:deep(.el-card__header) {
|
||||
cursor: move;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
:deep(.el-row > .el-col.sortable-chosen > .el-card) {
|
||||
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
}
|
||||
|
||||
.workplace-bottom-btn {
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
transition: background-color 0.2s;
|
||||
|
||||
&:hover {
|
||||
background: hsla(0, 0%, 60%, 0.05);
|
||||
}
|
||||
}
|
||||
|
||||
/* 添加弹窗 */
|
||||
.workplace-card-item {
|
||||
margin-bottom: 15px;
|
||||
border-width: 1px;
|
||||
border-style: solid;
|
||||
border-radius: 4px;
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
transition: box-shadow 0.3s;
|
||||
|
||||
&:hover {
|
||||
box-shadow: 0 4px 12px 0 rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
|
||||
.workplace-card-header {
|
||||
border-bottom-width: 1px;
|
||||
border-bottom-style: solid;
|
||||
padding: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
.workplace-card-body {
|
||||
font-size: 24px;
|
||||
padding: 40px 10px;
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
@@ -1,150 +0,0 @@
|
||||
<template>
|
||||
<div class="ele-body" style="padding-bottom: 71px">
|
||||
<el-card shadow="never">
|
||||
<el-row :gutter="15">
|
||||
<el-col v-bind="styleResponsive ? { md: 12 } : { span: 12 }">
|
||||
<!-- 未选择的班级数据表格 -->
|
||||
<ele-pro-table
|
||||
:datasource="unChooseClass"
|
||||
:columns="columns"
|
||||
sub-title="未选班级:"
|
||||
height="535px"
|
||||
emptyText="已全部选择"
|
||||
:toolkit="[]"
|
||||
layout="total, prev, pager, next, jumper"
|
||||
>
|
||||
<template v-slot:toolkit>
|
||||
<el-button size="mini" class="ele-btn-icon" @click="addAll">
|
||||
全部添加
|
||||
</el-button>
|
||||
</template>
|
||||
<template v-slot:action="{ row }">
|
||||
<el-button size="mini" @click="add(row)">添加</el-button>
|
||||
</template>
|
||||
</ele-pro-table>
|
||||
</el-col>
|
||||
<el-col v-bind="styleResponsive ? { md: 12 } : { span: 12 }">
|
||||
<!-- 已选择的班级数据表格 -->
|
||||
<ele-pro-table
|
||||
:datasource="chooseClasses"
|
||||
:columns="columns"
|
||||
sub-title="已选班级:"
|
||||
height="535px"
|
||||
emptyText="未选择班级"
|
||||
:toolkit="[]"
|
||||
layout="total, prev, pager, next, jumper"
|
||||
>
|
||||
<template v-slot:toolkit>
|
||||
<el-button
|
||||
size="mini"
|
||||
type="danger"
|
||||
plain
|
||||
class="ele-btn-icon"
|
||||
@click="removeAll"
|
||||
>
|
||||
全部移除
|
||||
</el-button>
|
||||
</template>
|
||||
<template v-slot:action="{ row }">
|
||||
<el-button type="danger" plain size="mini" @click="remove(row)">
|
||||
移除
|
||||
</el-button>
|
||||
</template>
|
||||
</ele-pro-table>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getAllClasses } from '@/api/example/choose';
|
||||
|
||||
export default {
|
||||
name: 'ExampleChoose',
|
||||
data() {
|
||||
return {
|
||||
// 加载状态
|
||||
loading: false,
|
||||
// 全部实训班级
|
||||
classes: [],
|
||||
// 已选择的班级数据
|
||||
chooseClasses: [],
|
||||
// 表格列配置
|
||||
columns: [
|
||||
{
|
||||
columnKey: 'action',
|
||||
label: '操作',
|
||||
width: 100,
|
||||
align: 'center',
|
||||
slot: 'action'
|
||||
},
|
||||
{
|
||||
prop: 'classesName',
|
||||
label: '班级名称',
|
||||
showOverflowTooltip: true,
|
||||
minWidth: 110,
|
||||
sortable: 'custom'
|
||||
},
|
||||
{
|
||||
prop: 'major',
|
||||
label: '专业',
|
||||
showOverflowTooltip: true,
|
||||
minWidth: 110,
|
||||
sortable: 'custom'
|
||||
},
|
||||
{
|
||||
prop: 'college',
|
||||
label: '学院',
|
||||
showOverflowTooltip: true,
|
||||
minWidth: 110,
|
||||
sortable: 'custom'
|
||||
}
|
||||
]
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
/* 未选择的班级数据 */
|
||||
unChooseClass() {
|
||||
return this.classes.filter((d) => this.chooseClasses.indexOf(d) === -1);
|
||||
},
|
||||
// 是否开启响应式布局
|
||||
styleResponsive() {
|
||||
return this.$store.state.theme.styleResponsive;
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.query();
|
||||
},
|
||||
methods: {
|
||||
/* 获取全部实训班级 */
|
||||
query() {
|
||||
getAllClasses()
|
||||
.then((data) => {
|
||||
this.classes = data;
|
||||
})
|
||||
.catch((e) => {
|
||||
this.$message.error(e.message);
|
||||
});
|
||||
},
|
||||
/* 添加 */
|
||||
add(row) {
|
||||
this.chooseClasses.push(row);
|
||||
},
|
||||
/* 移除 */
|
||||
remove(row) {
|
||||
this.chooseClasses.splice(this.chooseClasses.indexOf(row), 1);
|
||||
},
|
||||
/* 添加全部 */
|
||||
addAll() {
|
||||
this.unChooseClass.forEach((d) => {
|
||||
this.chooseClasses.push(d);
|
||||
});
|
||||
},
|
||||
/* 移除所有 */
|
||||
removeAll() {
|
||||
this.chooseClasses.splice(0, this.chooseClasses.length);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@@ -1,341 +0,0 @@
|
||||
<template>
|
||||
<ele-modal
|
||||
top="5vh"
|
||||
width="1100px"
|
||||
:visible="visible"
|
||||
title="卷内文件调整"
|
||||
custom-class="demo-file-sort-dialog"
|
||||
@update:visible="updateVisible"
|
||||
>
|
||||
<el-row :gutter="15">
|
||||
<el-col v-bind="styleResponsive ? { md: 8 } : { span: 8 }">
|
||||
<ele-pro-table
|
||||
ref="docTable"
|
||||
sub-title="案卷列表"
|
||||
:datasource="documents"
|
||||
:columns="columns1"
|
||||
highlight-current-row
|
||||
height="400px"
|
||||
:toolkit="[]"
|
||||
:need-page="false"
|
||||
:current.sync="current"
|
||||
class="demo-file-sort-table"
|
||||
:tool-style="{ lineHeight: '28px' }"
|
||||
@done="onDocTbDone"
|
||||
>
|
||||
</ele-pro-table>
|
||||
</el-col>
|
||||
<el-col v-bind="styleResponsive ? { md: 8 } : { span: 8 }">
|
||||
<ele-pro-table
|
||||
ref="fileTable"
|
||||
:loading="loading"
|
||||
sub-title="卷内列表"
|
||||
:datasource="data1"
|
||||
:columns="columns2"
|
||||
height="400px"
|
||||
:selection.sync="selection1"
|
||||
:need-page="false"
|
||||
:toolkit="[]"
|
||||
>
|
||||
<template v-slot:toolkit>
|
||||
<el-button
|
||||
type="primary"
|
||||
icon="el-icon-top"
|
||||
class="ele-btn-icon"
|
||||
size="mini"
|
||||
@click="moveUp"
|
||||
>
|
||||
上移
|
||||
</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
icon="el-icon-bottom"
|
||||
class="ele-btn-icon"
|
||||
size="mini"
|
||||
@click="moveDown"
|
||||
>
|
||||
下移
|
||||
</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
icon="el-icon-top-right"
|
||||
class="ele-btn-icon"
|
||||
size="mini"
|
||||
@click="moveOut"
|
||||
>
|
||||
调出
|
||||
</el-button>
|
||||
</template>
|
||||
</ele-pro-table>
|
||||
</el-col>
|
||||
<el-col v-bind="styleResponsive ? { md: 8 } : { span: 8 }">
|
||||
<ele-pro-table
|
||||
:loading="loading"
|
||||
sub-title="未归档列表"
|
||||
:datasource="data2"
|
||||
:columns="columns2"
|
||||
height="400px"
|
||||
:selection.sync="selection2"
|
||||
:need-page="false"
|
||||
:toolkit="[]"
|
||||
>
|
||||
<template v-slot:toolkit>
|
||||
<el-button
|
||||
type="primary"
|
||||
icon="el-icon-top-left"
|
||||
class="ele-btn-icon"
|
||||
size="mini"
|
||||
@click="moveIn"
|
||||
>
|
||||
调入
|
||||
</el-button>
|
||||
</template>
|
||||
</ele-pro-table>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<template v-slot:footer>
|
||||
<div>
|
||||
<el-button @click="close">取消</el-button>
|
||||
<el-button type="primary" @click="save">保存</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</ele-modal>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getArchiveList } from '@/api/example/document';
|
||||
|
||||
export default {
|
||||
props: {
|
||||
// 弹窗是否打开
|
||||
visible: Boolean,
|
||||
// 案卷列表
|
||||
documents: {
|
||||
type: Array,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
// 加载loading
|
||||
loading: true,
|
||||
// 案卷表格列配置
|
||||
columns1: [
|
||||
{
|
||||
prop: 'title',
|
||||
label: '案卷题名',
|
||||
width: 110,
|
||||
showOverflowTooltip: true
|
||||
},
|
||||
{
|
||||
prop: 'piece_no',
|
||||
label: '案卷档号',
|
||||
showOverflowTooltip: true
|
||||
}
|
||||
],
|
||||
// 卷内表格列配置
|
||||
columns2: [
|
||||
{
|
||||
columnKey: 'selection',
|
||||
type: 'selection',
|
||||
width: 45,
|
||||
align: 'center'
|
||||
},
|
||||
{
|
||||
prop: 'title',
|
||||
label: '文件题名',
|
||||
width: 110,
|
||||
showOverflowTooltip: true
|
||||
},
|
||||
{
|
||||
prop: 'archive_no',
|
||||
label: '文件档号',
|
||||
showOverflowTooltip: true
|
||||
}
|
||||
],
|
||||
// 案卷下的全部文件列表
|
||||
data: [],
|
||||
// 选中案卷
|
||||
current: null,
|
||||
// 卷内列表选中数据
|
||||
selection1: [],
|
||||
// 未归档列表选中数据
|
||||
selection2: []
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
// 选中案卷的卷内文件
|
||||
data1() {
|
||||
if (!this.current) {
|
||||
return [];
|
||||
}
|
||||
return this.data.filter((d) => d.piece_no === this.current.piece_no);
|
||||
},
|
||||
// 未归档的卷内文件
|
||||
data2() {
|
||||
return this.data.filter((d) => !d.piece_no);
|
||||
},
|
||||
// 是否开启响应式布局
|
||||
styleResponsive() {
|
||||
return this.$store.state.theme.styleResponsive;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
onDocTbDone() {
|
||||
if (this.documents.length) {
|
||||
this.$refs.docTable.setCurrentRow(this.documents[0]);
|
||||
}
|
||||
},
|
||||
/* 查询所选案卷的卷内文件 */
|
||||
query() {
|
||||
this.loading = true;
|
||||
getArchiveList({
|
||||
pieceNoIn: this.documents.map((d) => d.piece_no)
|
||||
})
|
||||
.then((data) => {
|
||||
this.loading = false;
|
||||
this.data = data;
|
||||
})
|
||||
.catch((e) => {
|
||||
this.loading = false;
|
||||
this.$message.error(e.message);
|
||||
});
|
||||
},
|
||||
/* 上移 */
|
||||
moveUp() {
|
||||
if (!this.selection1.length) {
|
||||
this.$message.error('请选择一条数据');
|
||||
return;
|
||||
}
|
||||
if (this.selection1.length > 1) {
|
||||
this.$message.error('只能选择一条数据');
|
||||
return;
|
||||
}
|
||||
if (this.data1.indexOf(this.selection1[0]) === 0) {
|
||||
return;
|
||||
}
|
||||
const index = this.data.indexOf(this.selection1[0]);
|
||||
const temp = this.data[index - 1];
|
||||
this.$set(this.data, index - 1, this.selection1[0]);
|
||||
this.$set(this.data, index, temp);
|
||||
this.$nextTick(() => {
|
||||
this.$refs.fileTable.toggleRowSelection(this.data[index - 1], true);
|
||||
});
|
||||
},
|
||||
/* 下移 */
|
||||
moveDown() {
|
||||
if (!this.selection1.length) {
|
||||
this.$message.error('请选择一条数据');
|
||||
return;
|
||||
}
|
||||
if (this.selection1.length > 1) {
|
||||
this.$message.error('只能选择一条数据');
|
||||
return;
|
||||
}
|
||||
if (this.data1.indexOf(this.selection1[0]) === this.data1.length - 1) {
|
||||
return;
|
||||
}
|
||||
const index = this.data.indexOf(this.selection1[0]);
|
||||
const temp = this.data[index + 1];
|
||||
this.$set(this.data, index + 1, this.selection1[0]);
|
||||
this.$set(this.data, index, temp);
|
||||
this.$nextTick(() => {
|
||||
this.$refs.fileTable.toggleRowSelection(this.data[index + 1], true);
|
||||
});
|
||||
},
|
||||
/* 调出 */
|
||||
moveOut() {
|
||||
if (!this.selection1.length) {
|
||||
this.$message.error('请至少选择一条数据');
|
||||
return;
|
||||
}
|
||||
this.selection1.forEach((d) => {
|
||||
d.piece_no = '';
|
||||
});
|
||||
},
|
||||
/* 调入 */
|
||||
moveIn() {
|
||||
if (!this.current) {
|
||||
return;
|
||||
}
|
||||
if (!this.selection2.length) {
|
||||
this.$message.error('请至少选择一条数据');
|
||||
return;
|
||||
}
|
||||
this.selection2.forEach((d) => {
|
||||
d.piece_no = this.current.piece_no;
|
||||
});
|
||||
},
|
||||
/* 保存 */
|
||||
save() {
|
||||
const result = this.data.map((d) => {
|
||||
return {
|
||||
archive_no: d.archive_no,
|
||||
piece_no: d.piece_no
|
||||
};
|
||||
});
|
||||
console.log(result);
|
||||
this.updateVisible(false);
|
||||
},
|
||||
/* 关闭弹窗 */
|
||||
close() {
|
||||
this.updateVisible(false);
|
||||
},
|
||||
/* 更新visible */
|
||||
updateVisible(value) {
|
||||
this.$emit('update:visible', value);
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
visible(visible) {
|
||||
if (visible) {
|
||||
this.query();
|
||||
} else {
|
||||
this.data = [];
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
:deep(.demo-file-sort-dialog) {
|
||||
margin-bottom: 5vh;
|
||||
|
||||
.el-dialog__body {
|
||||
padding-top: 15px;
|
||||
padding-bottom: 0;
|
||||
|
||||
& > .el-row > .el-col {
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.demo-file-sort-table {
|
||||
:deep(.el-table__row) {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
:deep(.el-table__row > td:last-child) {
|
||||
&:after {
|
||||
content: '\e6e0';
|
||||
font-family: element-icons !important;
|
||||
font-style: normal;
|
||||
font-variant: normal;
|
||||
text-transform: none;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
line-height: 1;
|
||||
position: absolute;
|
||||
right: 10px;
|
||||
top: 50%;
|
||||
margin-top: -7px;
|
||||
}
|
||||
|
||||
.cell {
|
||||
padding-right: 20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,164 +0,0 @@
|
||||
<template>
|
||||
<div class="ele-body">
|
||||
<el-card shadow="never">
|
||||
<ele-pro-table
|
||||
ref="table"
|
||||
:columns="columns"
|
||||
:datasource="datasource"
|
||||
:selection.sync="selection"
|
||||
:show-summary="true"
|
||||
:summary-method="getSummaries"
|
||||
:height="fixedHeight ? 'calc(100vh - 344px)' : void 0"
|
||||
>
|
||||
<template v-slot:toolbar>
|
||||
<el-button
|
||||
size="small"
|
||||
type="primary"
|
||||
icon="el-icon-sort"
|
||||
class="ele-btn-icon"
|
||||
@click="openFileSortDialog"
|
||||
>
|
||||
卷内文件调整
|
||||
</el-button>
|
||||
<span> 固定高度 </span>
|
||||
<el-switch v-model="fixedHeight" @change="destroyTable" />
|
||||
</template>
|
||||
</ele-pro-table>
|
||||
</el-card>
|
||||
<!-- 卷内文件调整弹窗 -->
|
||||
<file-sort :visible.sync="showFileSort" :documents="fileSortChoose" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import FileSort from './components/file-sort.vue';
|
||||
import { getPieceList } from '@/api/example/document';
|
||||
|
||||
export default {
|
||||
name: 'ExampleDocument',
|
||||
components: { FileSort },
|
||||
data() {
|
||||
return {
|
||||
// 表格列配置
|
||||
columns: [
|
||||
{
|
||||
columnKey: 'selection',
|
||||
type: 'selection',
|
||||
width: 45,
|
||||
align: 'center',
|
||||
fixed: 'left'
|
||||
},
|
||||
{
|
||||
columnKey: 'index',
|
||||
type: 'index',
|
||||
width: 45,
|
||||
align: 'center',
|
||||
fixed: 'left'
|
||||
},
|
||||
{
|
||||
prop: 'piece_no',
|
||||
label: '案卷档号',
|
||||
width: 215,
|
||||
minWidth: 110,
|
||||
showOverflowTooltip: true
|
||||
},
|
||||
{
|
||||
prop: 'title',
|
||||
label: '案卷题名',
|
||||
minWidth: 110,
|
||||
showOverflowTooltip: true
|
||||
},
|
||||
{
|
||||
prop: 'year',
|
||||
label: '年度',
|
||||
minWidth: 110,
|
||||
showOverflowTooltip: true
|
||||
},
|
||||
{
|
||||
prop: 'retention',
|
||||
label: '保管期限',
|
||||
minWidth: 110,
|
||||
showOverflowTooltip: true
|
||||
},
|
||||
{
|
||||
prop: 'secret',
|
||||
label: '密级',
|
||||
minWidth: 110,
|
||||
showOverflowTooltip: true
|
||||
},
|
||||
{
|
||||
prop: 'type',
|
||||
label: '档案类别',
|
||||
minWidth: 110,
|
||||
showOverflowTooltip: true
|
||||
},
|
||||
{
|
||||
prop: 'carrier',
|
||||
label: '载体规格',
|
||||
minWidth: 110,
|
||||
showOverflowTooltip: true
|
||||
},
|
||||
{
|
||||
prop: 'amount',
|
||||
label: '件数',
|
||||
minWidth: 110,
|
||||
showOverflowTooltip: true
|
||||
}
|
||||
],
|
||||
// 是否显示卷内文件调整弹窗
|
||||
showFileSort: false,
|
||||
// 列表选中数据
|
||||
selection: [],
|
||||
// 选中的案卷
|
||||
fileSortChoose: [],
|
||||
// 表格固定高度
|
||||
fixedHeight: false
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
/* 列表数据源 */
|
||||
datasource({ page, limit, where, order }) {
|
||||
return getPieceList({ ...where, ...order, page, limit });
|
||||
},
|
||||
/* 打开卷内文件调整弹窗 */
|
||||
openFileSortDialog() {
|
||||
if (this.selection.length < 2) {
|
||||
this.$message.error('请至少选择两条数据');
|
||||
return;
|
||||
}
|
||||
// 实际项目用这一行
|
||||
/*this.fileSortChoose = this.selection.map(d => {
|
||||
return { ...d };
|
||||
});*/
|
||||
// 演示强制选前三个演示
|
||||
this.fileSortChoose = this.$refs.table.tableData.slice(0, 3);
|
||||
this.showFileSort = true;
|
||||
},
|
||||
/* 表格合计行 */
|
||||
getSummaries({ columns, data }) {
|
||||
const sums = [];
|
||||
columns.forEach((column, index) => {
|
||||
if (index === 2) {
|
||||
sums[index] = '合计';
|
||||
} else if (column.property === 'amount') {
|
||||
sums[index] = data
|
||||
.map((item) => Number(item[column.property]))
|
||||
.reduce((prev, curr) => {
|
||||
const value = Number(curr);
|
||||
if (!isNaN(value)) {
|
||||
return prev + curr;
|
||||
} else {
|
||||
return prev;
|
||||
}
|
||||
}, 0);
|
||||
}
|
||||
});
|
||||
return sums;
|
||||
},
|
||||
/* 销毁表格 */
|
||||
destroyTable() {
|
||||
this.$refs.table.reRenderTable();
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@@ -1,134 +0,0 @@
|
||||
<template>
|
||||
<div class="ele-body">
|
||||
<el-card shadow="never" header="修改菜单徽章数据">
|
||||
<el-form label-width="90px" style="max-width: 360px; padding-top: 20px">
|
||||
<el-form-item label="菜单:">
|
||||
<ele-tree-select
|
||||
clearable
|
||||
v-model="path"
|
||||
:data="treeData"
|
||||
default-expand-all
|
||||
placeholder="请选择菜单"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="徽章值:">
|
||||
<el-input
|
||||
v-model="badge"
|
||||
placeholder="请输入徽章值"
|
||||
clearable
|
||||
:maxlength="20"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="徽章颜色:">
|
||||
<el-select
|
||||
v-model="color"
|
||||
placeholder="请选择徽章颜色"
|
||||
clearable
|
||||
class="ele-fluid"
|
||||
>
|
||||
<el-option label="primary" value="primary" />
|
||||
<el-option label="success" value="success" />
|
||||
<el-option label="warning" value="warning" />
|
||||
<el-option label="danger" value="danger" />
|
||||
<el-option label="info" value="info" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="setBadge">更新</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
<el-card shadow="never" header="分组菜单">
|
||||
<div>
|
||||
<el-button type="primary" @click="toMenuGroup1">
|
||||
一级菜单变为分组形式
|
||||
</el-button>
|
||||
</div>
|
||||
<div style="margin-top: 16px">
|
||||
<el-button type="primary" @click="toMenuGroup2">
|
||||
二级菜单变为分组形式
|
||||
</el-button>
|
||||
</div>
|
||||
<div class="ele-text-secondary" style="margin-top: 6px">
|
||||
二级菜单可查看列表页面/卡片列表的效果
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { formatTreeData } from 'ele-admin';
|
||||
|
||||
export default {
|
||||
name: 'ExampleMenuBadge',
|
||||
data() {
|
||||
return {
|
||||
path: '',
|
||||
badge: '',
|
||||
color: '',
|
||||
orgMenus: JSON.parse(JSON.stringify(this.$store.state.user.menus))
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
treeData() {
|
||||
return formatTreeData(this.$store.state.user.menus, (m) => {
|
||||
return {
|
||||
...m,
|
||||
value: m.path,
|
||||
label: m.meta.title
|
||||
};
|
||||
});
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
setBadge() {
|
||||
if (!this.path) {
|
||||
this.$message.error('请选择菜单');
|
||||
return;
|
||||
}
|
||||
this.$store.dispatch('user/setMenuBadge', {
|
||||
path: this.path,
|
||||
value: this.badge,
|
||||
color: this.color || undefined
|
||||
});
|
||||
},
|
||||
/* 一级菜单变为分组形式 */
|
||||
toMenuGroup1() {
|
||||
this.$store.dispatch(
|
||||
'user/setMenus',
|
||||
this.orgMenus.map((m) => {
|
||||
return {
|
||||
...m,
|
||||
meta: {
|
||||
...m.meta,
|
||||
group: true
|
||||
}
|
||||
};
|
||||
})
|
||||
);
|
||||
},
|
||||
/* 二级菜单变为分组形式 */
|
||||
toMenuGroup2() {
|
||||
this.$store.dispatch(
|
||||
'user/setMenus',
|
||||
this.orgMenus.map((m) => {
|
||||
return {
|
||||
...m,
|
||||
children: m.children
|
||||
? m.children.map((c) => {
|
||||
return {
|
||||
...c,
|
||||
meta: {
|
||||
...c.meta,
|
||||
group: true
|
||||
}
|
||||
};
|
||||
})
|
||||
: void 0
|
||||
};
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@@ -1,93 +0,0 @@
|
||||
<template>
|
||||
<el-card shadow="never">
|
||||
<!-- 数据表格 -->
|
||||
<ele-pro-table
|
||||
ref="table"
|
||||
row-key="userId"
|
||||
title="设置默认排序和筛选"
|
||||
:columns="columns"
|
||||
:datasource="datasource"
|
||||
:default-sort="{ prop: 'username', order: 'ascending' }"
|
||||
size="mini"
|
||||
/>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { pageUsers } from '@/api/system/user';
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
// 表格列配置
|
||||
columns: [
|
||||
{
|
||||
columnKey: 'index',
|
||||
type: 'index',
|
||||
width: 45,
|
||||
align: 'center',
|
||||
showOverflowTooltip: true,
|
||||
fixed: 'left'
|
||||
},
|
||||
{
|
||||
prop: 'username',
|
||||
label: '用户账号',
|
||||
sortable: 'custom',
|
||||
showOverflowTooltip: true,
|
||||
minWidth: 110
|
||||
},
|
||||
{
|
||||
prop: 'nickname',
|
||||
label: '用户名',
|
||||
sortable: 'custom',
|
||||
showOverflowTooltip: true,
|
||||
minWidth: 110
|
||||
},
|
||||
{
|
||||
columnKey: 'sexName',
|
||||
prop: 'sexName',
|
||||
label: '性别',
|
||||
sortable: 'custom',
|
||||
showOverflowTooltip: true,
|
||||
minWidth: 80,
|
||||
filterMultiple: false,
|
||||
filters: [
|
||||
{
|
||||
text: '男',
|
||||
value: '男'
|
||||
},
|
||||
{
|
||||
text: '女',
|
||||
value: '女'
|
||||
}
|
||||
],
|
||||
filteredValue: ['男']
|
||||
},
|
||||
{
|
||||
prop: 'phone',
|
||||
label: '手机号',
|
||||
sortable: 'custom',
|
||||
showOverflowTooltip: true,
|
||||
minWidth: 110
|
||||
},
|
||||
{
|
||||
prop: 'createTime',
|
||||
label: '创建时间',
|
||||
sortable: 'custom',
|
||||
showOverflowTooltip: true,
|
||||
minWidth: 110,
|
||||
formatter: (_row, _column, cellValue) => {
|
||||
return this.$util.toDateString(cellValue);
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
/* 表格数据源 */
|
||||
datasource({ page, limit, order, filterValue }) {
|
||||
return pageUsers({ ...order, ...filterValue, page, limit });
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@@ -1,85 +0,0 @@
|
||||
<template>
|
||||
<el-card shadow="never">
|
||||
<!-- 数据表格 -->
|
||||
<ele-pro-table
|
||||
ref="table"
|
||||
row-key="menuId"
|
||||
title="树形表格懒加载"
|
||||
:columns="columns"
|
||||
:datasource="datasource"
|
||||
:need-page="false"
|
||||
:lazy="true"
|
||||
size="mini"
|
||||
>
|
||||
<!-- 标题列 -->
|
||||
<template v-slot:title="{ row }">
|
||||
<i :class="row.icon"></i> {{ row.title }}
|
||||
</template>
|
||||
</ele-pro-table>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { listMenus } from '@/api/system/menu';
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
// 表格列配置
|
||||
columns: [
|
||||
{
|
||||
columnKey: 'index',
|
||||
type: 'index',
|
||||
width: 45,
|
||||
align: 'center',
|
||||
showOverflowTooltip: true
|
||||
},
|
||||
{
|
||||
prop: 'title',
|
||||
label: '菜单名称',
|
||||
showOverflowTooltip: true,
|
||||
minWidth: 110,
|
||||
slot: 'title'
|
||||
},
|
||||
{
|
||||
prop: 'path',
|
||||
label: '路由地址',
|
||||
showOverflowTooltip: true,
|
||||
minWidth: 110
|
||||
},
|
||||
{
|
||||
prop: 'component',
|
||||
label: '组件路径',
|
||||
showOverflowTooltip: true,
|
||||
minWidth: 110
|
||||
},
|
||||
{
|
||||
prop: 'sortNumber',
|
||||
label: '排序',
|
||||
align: 'center',
|
||||
showOverflowTooltip: true,
|
||||
width: 60
|
||||
},
|
||||
{
|
||||
prop: 'createTime',
|
||||
label: '创建时间',
|
||||
showOverflowTooltip: true,
|
||||
minWidth: 110,
|
||||
formatter: (_row, _column, cellValue) => {
|
||||
return this.$util.toDateString(cellValue);
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
/* 表格数据源 */
|
||||
datasource({ where, parent }) {
|
||||
return listMenus({
|
||||
...where,
|
||||
parentId: parent?.menuId ?? 0
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@@ -1,68 +0,0 @@
|
||||
<template>
|
||||
<el-card shadow="never">
|
||||
<!-- 数据表格 -->
|
||||
<ele-pro-table
|
||||
ref="table"
|
||||
row-key="id"
|
||||
title="合并单元格"
|
||||
:columns="columns"
|
||||
:datasource="datasource"
|
||||
:span-method="spanMethod"
|
||||
size="mini"
|
||||
/>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { pageUserScores } from '@/api/example/table';
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
// 表格列配置
|
||||
columns: [
|
||||
{
|
||||
columnKey: 'index',
|
||||
type: 'index',
|
||||
width: 45,
|
||||
align: 'center',
|
||||
showOverflowTooltip: true,
|
||||
fixed: 'left'
|
||||
},
|
||||
{
|
||||
columnKey: 'userName',
|
||||
prop: 'userName',
|
||||
label: '姓名',
|
||||
showOverflowTooltip: true,
|
||||
minWidth: 110
|
||||
},
|
||||
{
|
||||
prop: 'courseName',
|
||||
label: '课程',
|
||||
showOverflowTooltip: true,
|
||||
minWidth: 110
|
||||
},
|
||||
{
|
||||
prop: 'score',
|
||||
label: '得分',
|
||||
showOverflowTooltip: true,
|
||||
minWidth: 110
|
||||
}
|
||||
]
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
/* 表格数据源 */
|
||||
datasource() {
|
||||
return pageUserScores();
|
||||
},
|
||||
/* 合并表格单元格 */
|
||||
spanMethod({ row, column }) {
|
||||
if (column.columnKey === 'userName') {
|
||||
return [row.userNameRowSpan, 1];
|
||||
}
|
||||
return [1, 1];
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@@ -1,113 +0,0 @@
|
||||
<template>
|
||||
<el-card shadow="never">
|
||||
<!-- 数据表格 -->
|
||||
<ele-pro-table
|
||||
ref="table"
|
||||
row-key="userId"
|
||||
title="可控的排序和筛选"
|
||||
:columns="columns"
|
||||
:datasource="datasource"
|
||||
size="mini"
|
||||
>
|
||||
<template #toolkit>
|
||||
<el-button size="small" type="primary" @click="setSorter">
|
||||
设置用户名排序
|
||||
</el-button>
|
||||
<el-button size="small" type="primary" @click="resetAll">
|
||||
重置排序和筛选
|
||||
</el-button>
|
||||
<div style="padding: 0 10px">
|
||||
<el-divider direction="vertical" />
|
||||
</div>
|
||||
</template>
|
||||
</ele-pro-table>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { pageUsers } from '@/api/system/user';
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
// 表格列配置
|
||||
columns: [
|
||||
{
|
||||
columnKey: 'index',
|
||||
type: 'index',
|
||||
width: 45,
|
||||
align: 'center',
|
||||
showOverflowTooltip: true,
|
||||
fixed: 'left'
|
||||
},
|
||||
{
|
||||
prop: 'username',
|
||||
label: '用户账号',
|
||||
sortable: 'custom',
|
||||
showOverflowTooltip: true,
|
||||
minWidth: 110
|
||||
},
|
||||
{
|
||||
prop: 'nickname',
|
||||
label: '用户名',
|
||||
sortable: 'custom',
|
||||
showOverflowTooltip: true,
|
||||
minWidth: 110
|
||||
},
|
||||
{
|
||||
columnKey: 'sexName',
|
||||
prop: 'sexName',
|
||||
label: '性别',
|
||||
sortable: 'custom',
|
||||
showOverflowTooltip: true,
|
||||
minWidth: 80,
|
||||
filterMultiple: false,
|
||||
filters: [
|
||||
{
|
||||
text: '男',
|
||||
value: '男'
|
||||
},
|
||||
{
|
||||
text: '女',
|
||||
value: '女'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
prop: 'phone',
|
||||
label: '手机号',
|
||||
sortable: 'custom',
|
||||
showOverflowTooltip: true,
|
||||
minWidth: 110
|
||||
},
|
||||
{
|
||||
prop: 'createTime',
|
||||
label: '创建时间',
|
||||
sortable: 'custom',
|
||||
showOverflowTooltip: true,
|
||||
minWidth: 110,
|
||||
formatter: (_row, _column, cellValue) => {
|
||||
return this.$util.toDateString(cellValue);
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
/* 表格数据源 */
|
||||
datasource({ page, limit, order, filterValue }) {
|
||||
return pageUsers({ ...order, ...filterValue, page, limit });
|
||||
},
|
||||
/* 设置排序 */
|
||||
setSorter() {
|
||||
this.$refs.table.sort('nickname', 'descending');
|
||||
},
|
||||
/* 重置排序和筛选 */
|
||||
resetAll() {
|
||||
this.$refs.table.clearSort();
|
||||
this.$refs.table.clearFilter();
|
||||
this.$refs.table.reload({ orders: {}, filters: {} });
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@@ -1,20 +0,0 @@
|
||||
<template>
|
||||
<div class="ele-body">
|
||||
<lazy-tree-table />
|
||||
<default-sorter />
|
||||
<reset-sorter />
|
||||
<merge-cell />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import LazyTreeTable from './components/lazy-tree-table.vue';
|
||||
import DefaultSorter from './components/default-sorter.vue';
|
||||
import ResetSorter from './components/reset-sorter.vue';
|
||||
import MergeCell from './components/merge-cell.vue';
|
||||
|
||||
export default {
|
||||
name: 'ExampleTable',
|
||||
components: { LazyTreeTable, DefaultSorter, ResetSorter, MergeCell }
|
||||
};
|
||||
</script>
|
||||
@@ -1,113 +0,0 @@
|
||||
<template>
|
||||
<div class="ele-body">
|
||||
<el-card shadow="never" header="条形码" style="overflow: visible">
|
||||
<div ref="printRef" class="demo-barcode-images ele-bg-white">
|
||||
<ele-bar-code :value="text" :tag="tag" :options="options" />
|
||||
</div>
|
||||
<el-form label-width="88px" style="max-width: 340px">
|
||||
<el-form-item label="条码类型: ">
|
||||
<el-radio-group :value="options.format" @input="updateFormat">
|
||||
<el-radio label="CODE128">CODE128</el-radio>
|
||||
<el-radio label="EAN13">EAN13</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="渲染方式: ">
|
||||
<el-radio-group v-model="tag">
|
||||
<el-radio label="svg">svg</el-radio>
|
||||
<el-radio label="img">img</el-radio>
|
||||
<el-radio label="canvas">canvas</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="条码文本: ">
|
||||
<el-select
|
||||
v-if="options.format === 'EAN13'"
|
||||
v-model="text"
|
||||
class="ele-fluid"
|
||||
>
|
||||
<el-option value="1234567890128" label="1234567890128" />
|
||||
<el-option value="6971872201359" label="6971872201359" />
|
||||
<el-option value="6954531770199" label="6954531770199" />
|
||||
<el-option value="6923644240318" label="6923644240318" />
|
||||
</el-select>
|
||||
<el-input v-else v-model="text" :maxlength="20" />
|
||||
</el-form-item>
|
||||
<el-form-item label="高度: ">
|
||||
<el-slider v-model="options.height" :min="40" :max="160" :step="10" />
|
||||
</el-form-item>
|
||||
<el-form-item label="宽度: ">
|
||||
<el-slider v-model="options.width" :min="1" :max="6" />
|
||||
</el-form-item>
|
||||
<el-form-item label="间距: ">
|
||||
<el-slider v-model="options.margin" :min="0" :max="40" />
|
||||
</el-form-item>
|
||||
<el-form-item label="显示文本: ">
|
||||
<el-switch v-model="options.displayValue" />
|
||||
</el-form-item>
|
||||
<el-form-item v-if="options.displayValue" label="文本大小: ">
|
||||
<el-slider v-model="options.fontSize" :min="12" :max="36" :step="2" />
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
v-if="options.displayValue && options.format === 'CODE128'"
|
||||
label="文本位置: "
|
||||
>
|
||||
<el-radio-group v-model="options.textPosition">
|
||||
<el-radio label="bottom">bottom</el-radio>
|
||||
<el-radio label="top">top</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<div>
|
||||
<el-button type="primary" @click="print">打印</el-button>
|
||||
</div>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import EleBarCode from 'ele-admin/es/ele-bar-code';
|
||||
import { printElement } from 'ele-admin';
|
||||
|
||||
export default {
|
||||
name: 'ExtensionBarCode',
|
||||
components: { EleBarCode },
|
||||
data() {
|
||||
return {
|
||||
text: '1234567890',
|
||||
tag: 'svg',
|
||||
options: {
|
||||
height: 60,
|
||||
width: 2,
|
||||
margin: 2,
|
||||
displayValue: true,
|
||||
textPosition: 'bottom',
|
||||
fontSize: 14,
|
||||
format: 'CODE128'
|
||||
}
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
updateFormat(value) {
|
||||
if (value === 'EAN13') {
|
||||
this.text = '1234567890128';
|
||||
}
|
||||
this.options.format = value;
|
||||
},
|
||||
print() {
|
||||
printElement(this.$refs.printRef);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.demo-barcode-images {
|
||||
padding-bottom: 16px;
|
||||
margin-bottom: 4px;
|
||||
position: sticky;
|
||||
top: 0;
|
||||
overflow: auto;
|
||||
z-index: 1002;
|
||||
}
|
||||
</style>
|
||||
@@ -1,62 +0,0 @@
|
||||
<template>
|
||||
<div class="ele-body">
|
||||
<el-card shadow="never" header="滚动数字">
|
||||
<h1 style="padding-left: 10px">
|
||||
<vue-count-up
|
||||
:delay="0"
|
||||
:end-val="demoNum"
|
||||
:options="option"
|
||||
@ready="onReady"
|
||||
/>
|
||||
</h1>
|
||||
<div style="margin-top: 15px">
|
||||
<el-button size="mini" @click="restart">重新开始</el-button>
|
||||
<el-button size="mini" @click="update">更新数字</el-button>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import VueCountUp from 'vue-countup-v2';
|
||||
|
||||
export default {
|
||||
name: 'ExtensionCountUp',
|
||||
components: { VueCountUp },
|
||||
data() {
|
||||
return {
|
||||
// 值
|
||||
demoNum: 2345,
|
||||
// 配置
|
||||
option: {
|
||||
useEasing: true,
|
||||
useGrouping: true,
|
||||
separator: ',',
|
||||
decimal: '.',
|
||||
prefix: '',
|
||||
suffix: ''
|
||||
},
|
||||
// 实例
|
||||
instance: null
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
/* 渲染完成 */
|
||||
onReady(ins) {
|
||||
this.instance = ins;
|
||||
},
|
||||
/* 重新开始 */
|
||||
restart() {
|
||||
if (!this.instance) {
|
||||
return;
|
||||
}
|
||||
this.instance.reset();
|
||||
this.instance.start();
|
||||
},
|
||||
/* 更新 */
|
||||
update() {
|
||||
this.demoNum += 100 + Math.round(Math.random() * 300);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@@ -1,41 +0,0 @@
|
||||
<template>
|
||||
<div class="ele-body">
|
||||
<el-card shadow="never" header="基本用法">
|
||||
<ele-dashboard type="success" style="margin-right: 18px">
|
||||
<div style="line-height: 1">
|
||||
<span style="font-size: 48px">100</span>
|
||||
<span style="font-size: 12px; margin-left: 4px">分</span>
|
||||
</div>
|
||||
<div style="margin-top: 4px">安全</div>
|
||||
</ele-dashboard>
|
||||
<ele-dashboard type="warning" style="margin-right: 18px">
|
||||
<div style="line-height: 1">
|
||||
<span style="font-size: 48px">70</span>
|
||||
<span style="font-size: 12px; margin-left: 4px">分</span>
|
||||
</div>
|
||||
<div style="margin-top: 4px">待优化</div>
|
||||
</ele-dashboard>
|
||||
<ele-dashboard type="danger">
|
||||
<div style="line-height: 1">
|
||||
<span style="font-size: 48px">40</span>
|
||||
<span style="font-size: 12px; margin-left: 4px">分</span>
|
||||
</div>
|
||||
<div style="margin-top: 4px">高风险</div>
|
||||
</ele-dashboard>
|
||||
</el-card>
|
||||
<el-card shadow="never" header="自定义颜色和尺寸">
|
||||
<ele-dashboard color="#722ED1" style="margin-right: 18px">
|
||||
<div style="font-size: 48px">100</div>
|
||||
</ele-dashboard>
|
||||
<ele-dashboard size="116px" space="12px">
|
||||
<div style="font-size: 38px">100</div>
|
||||
</ele-dashboard>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'ExtensionDashboard'
|
||||
};
|
||||
</script>
|
||||
@@ -1,14 +0,0 @@
|
||||
<template>
|
||||
<div></div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
created() {
|
||||
console.log('弹窗内组件创建');
|
||||
},
|
||||
destroyed() {
|
||||
console.log('弹窗内组件销毁');
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@@ -1,220 +0,0 @@
|
||||
<template>
|
||||
<el-card shadow="never" header="可拖拽、拉伸、全屏弹窗">
|
||||
<el-form label-width="140px" style="max-width: 360px">
|
||||
<el-form-item label="是否可拖出边界:">
|
||||
<el-select class="ele-block" v-model="moveOut">
|
||||
<el-option label="不可拖出边界" :value="0" />
|
||||
<el-option label="可以拖出边界" :value="1" />
|
||||
<el-option label="只可右下方向拖出边界" :value="2" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="是否可拉伸大小:">
|
||||
<el-select class="ele-block" v-model="resizable">
|
||||
<el-option label="不可拉伸大小" value="false" />
|
||||
<el-option label="可以拉伸大小" value="true" />
|
||||
<el-option label="只可横向拉伸" value="horizontal" />
|
||||
<el-option label="只可纵向拉伸" value="vertical" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="最大化切换按钮:">
|
||||
<el-switch v-model="maxable" />
|
||||
</el-form-item>
|
||||
<!-- <el-form-item label="是否垂直居中:">
|
||||
<el-switch v-model="centered" />
|
||||
</el-form-item> -->
|
||||
<el-form-item label="关闭后重置位置:">
|
||||
<el-switch v-model="resetOnClose" />
|
||||
</el-form-item>
|
||||
<el-form-item label="限制在主体区域:">
|
||||
<el-switch v-model="inner" />
|
||||
</el-form-item>
|
||||
<el-form-item label="默认位置:">
|
||||
<el-select clearable class="ele-block" v-model="position">
|
||||
<el-option label="顶部" value="top" />
|
||||
<el-option label="底部" value="bottom" />
|
||||
<el-option label="左边" value="left" />
|
||||
<el-option label="右边" value="right" />
|
||||
<el-option label="左上角" value="leftTop" />
|
||||
<el-option label="左下角" value="leftBottom" />
|
||||
<el-option label="右上角" value="rightTop" />
|
||||
<el-option label="右下角" value="rightBottom" />
|
||||
<el-option label="正中间" value="center" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="destroy-on-close:">
|
||||
<el-switch v-model="destroyOnClose" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="openDialog">打开可拖拽弹窗</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<ele-modal
|
||||
width="400px"
|
||||
title="拖拽弹窗"
|
||||
:visible.sync="visible"
|
||||
:move-out="moveOut > 0"
|
||||
:move-out-positive="moveOut === 2"
|
||||
:resizable="modalResizable"
|
||||
:maxable="maxable"
|
||||
:inner="inner"
|
||||
:centered="centered"
|
||||
:reset-on-close="resetOnClose"
|
||||
:append-to-body="true"
|
||||
:destroy-on-close="destroyOnClose"
|
||||
:mask-keep-alive="inner || !destroyOnClose"
|
||||
:position="position"
|
||||
@closed="cancel"
|
||||
>
|
||||
<el-form ref="form" :model="form" :rules="rules" label-width="82px">
|
||||
<el-form-item label="用户名:" prop="nickname">
|
||||
<el-input
|
||||
clearable
|
||||
v-model="form.nickname"
|
||||
placeholder="请输入用户名"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="性别:" prop="sex">
|
||||
<el-select
|
||||
clearable
|
||||
class="ele-fluid"
|
||||
v-model="form.sex"
|
||||
placeholder="请选择性别"
|
||||
:popper-append-to-body="false"
|
||||
>
|
||||
<el-option label="男" value="男" />
|
||||
<el-option label="女" value="女" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="手机号:" prop="phone">
|
||||
<el-input clearable v-model="form.phone" placeholder="请输入手机号" />
|
||||
</el-form-item>
|
||||
<el-form-item label="邮箱:" prop="email">
|
||||
<el-input clearable v-model="form.email" placeholder="请输入邮箱" />
|
||||
</el-form-item>
|
||||
<el-form-item label="个人简介:">
|
||||
<el-input
|
||||
:rows="4"
|
||||
clearable
|
||||
type="textarea"
|
||||
v-model="form.introduction"
|
||||
placeholder="请输入个人简介"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<component-test />
|
||||
<template v-slot:footer>
|
||||
<el-button @click="cancel">取消</el-button>
|
||||
<el-button type="primary" @click="save">保存</el-button>
|
||||
</template>
|
||||
</ele-modal>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ComponentTest from './component-test.vue';
|
||||
|
||||
export default {
|
||||
components: { ComponentTest },
|
||||
data() {
|
||||
return {
|
||||
// 弹窗是否打开
|
||||
visible: false,
|
||||
// 是否允许拖出边界
|
||||
moveOut: 0,
|
||||
// 是否可拉伸
|
||||
resizable: 'false',
|
||||
// 是否显示最大化切换按钮
|
||||
maxable: true,
|
||||
// 关闭后重置位置
|
||||
resetOnClose: true,
|
||||
// 限制在主体区域
|
||||
inner: false,
|
||||
// 垂直居中
|
||||
centered: false,
|
||||
// 表单数据
|
||||
form: {
|
||||
nickname: '',
|
||||
sex: undefined,
|
||||
phone: '',
|
||||
email: '',
|
||||
introduction: ''
|
||||
},
|
||||
// 表单验证规则
|
||||
rules: {
|
||||
nickname: [
|
||||
{
|
||||
required: true,
|
||||
message: '请输入用户名',
|
||||
type: 'string'
|
||||
}
|
||||
],
|
||||
sex: [
|
||||
{
|
||||
required: true,
|
||||
message: '请选择性别',
|
||||
type: 'string'
|
||||
}
|
||||
],
|
||||
phone: [
|
||||
{
|
||||
required: true,
|
||||
message: '请输入手机号',
|
||||
type: 'string'
|
||||
}
|
||||
],
|
||||
email: [
|
||||
{
|
||||
required: true,
|
||||
message: '请输入邮箱',
|
||||
type: 'string'
|
||||
}
|
||||
]
|
||||
},
|
||||
// 弹窗关闭后是否销毁
|
||||
destroyOnClose: false,
|
||||
// 默认位置
|
||||
position: undefined
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
modalResizable() {
|
||||
return this.resizable === 'true'
|
||||
? true
|
||||
: this.resizable === 'false'
|
||||
? false
|
||||
: this.resizable;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
/* 打开弹窗 */
|
||||
openDialog() {
|
||||
if (!this.visible) {
|
||||
this.visible = true;
|
||||
}
|
||||
},
|
||||
/* 弹窗关闭回调 */
|
||||
cancel() {
|
||||
this.form = {
|
||||
nickname: '',
|
||||
sex: undefined,
|
||||
phone: '',
|
||||
email: '',
|
||||
introduction: ''
|
||||
};
|
||||
this.$nextTick(() => {
|
||||
this.$refs.form.clearValidate();
|
||||
});
|
||||
this.visible = false;
|
||||
},
|
||||
/* 保存编辑 */
|
||||
save() {
|
||||
this.$refs.form.validate((valid) => {
|
||||
if (!valid) {
|
||||
return false;
|
||||
}
|
||||
this.$message.success('保存成功');
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@@ -1,84 +0,0 @@
|
||||
<template>
|
||||
<el-card shadow="never" header="同时打开多个弹窗">
|
||||
<div>
|
||||
<el-button type="primary" @click="openDialog1">打开弹窗1</el-button>
|
||||
<el-button type="primary" @click="openDialog2">打开弹窗2</el-button>
|
||||
<el-button type="primary" @click="openDialog3">打开弹窗3</el-button>
|
||||
</div>
|
||||
<p style="margin-top: 20px">同时打开多个弹窗时点击会自动置顶</p>
|
||||
<ele-modal
|
||||
width="400px"
|
||||
title="弹窗1"
|
||||
:visible.sync="visible1"
|
||||
:resizable="true"
|
||||
:maxable="true"
|
||||
:multiple="true"
|
||||
:move-out="true"
|
||||
:move-out-positive="true"
|
||||
position="center"
|
||||
>
|
||||
<div style="padding: 20px 0">弹窗1</div>
|
||||
<template v-slot:footer>
|
||||
<el-button @click="visible1 = false">取消</el-button>
|
||||
<el-button type="primary">确定</el-button>
|
||||
</template>
|
||||
</ele-modal>
|
||||
<ele-modal
|
||||
width="400px"
|
||||
title="弹窗2"
|
||||
:visible.sync="visible2"
|
||||
:resizable="true"
|
||||
:maxable="true"
|
||||
:multiple="true"
|
||||
:move-out="true"
|
||||
:move-out-positive="true"
|
||||
position="rightTop"
|
||||
>
|
||||
<div style="padding: 20px 0">弹窗2</div>
|
||||
<template v-slot:footer>
|
||||
<el-button @click="visible2 = false">取消</el-button>
|
||||
<el-button type="primary">确定</el-button>
|
||||
</template>
|
||||
</ele-modal>
|
||||
<ele-modal
|
||||
width="400px"
|
||||
title="弹窗3"
|
||||
:visible.sync="visible3"
|
||||
:resizable="true"
|
||||
:maxable="true"
|
||||
:multiple="true"
|
||||
:move-out="true"
|
||||
:move-out-positive="true"
|
||||
position="rightBottom"
|
||||
>
|
||||
<div style="padding: 20px 0">弹窗3</div>
|
||||
<template v-slot:footer>
|
||||
<el-button @click="visible3 = false">取消</el-button>
|
||||
<el-button type="primary">确定</el-button>
|
||||
</template>
|
||||
</ele-modal>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
visible1: false,
|
||||
visible2: false,
|
||||
visible3: false
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
openDialog1() {
|
||||
this.visible1 = true;
|
||||
},
|
||||
openDialog2() {
|
||||
this.visible2 = true;
|
||||
},
|
||||
openDialog3() {
|
||||
this.visible3 = true;
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@@ -1,19 +0,0 @@
|
||||
<template>
|
||||
<div class="ele-body ele-body-card">
|
||||
<demo-modal />
|
||||
<multiple-modal />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import DemoModal from './components/demo-modal.vue';
|
||||
import MultipleModal from './components/multiple-modal.vue';
|
||||
|
||||
export default {
|
||||
name: 'ExtensionDialog',
|
||||
components: {
|
||||
DemoModal,
|
||||
MultipleModal
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@@ -1,157 +0,0 @@
|
||||
<template>
|
||||
<el-row :gutter="15">
|
||||
<el-col v-bind="styleResponsive ? { md: 8 } : { span: 8 }">
|
||||
<el-card shadow="never" header="宫格拖拽排序">
|
||||
<div class="demo-drag-grid">
|
||||
<vue-draggable
|
||||
v-model="grid"
|
||||
animation="300"
|
||||
:set-data="() => void 0"
|
||||
>
|
||||
<div
|
||||
class="demo-drag-grid-item"
|
||||
v-for="item in grid"
|
||||
:key="item.id"
|
||||
>
|
||||
{{ item.name }}
|
||||
</div>
|
||||
</vue-draggable>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col v-bind="styleResponsive ? { md: 16 } : { span: 16 }">
|
||||
<el-card shadow="never" header="宫格相互拖拽">
|
||||
<el-row :gutter="15">
|
||||
<el-col :span="12">
|
||||
<div class="demo-drag-grid">
|
||||
<vue-draggable
|
||||
v-model="grid1"
|
||||
group="project2"
|
||||
animation="300"
|
||||
:set-data="() => void 0"
|
||||
>
|
||||
<div
|
||||
class="demo-drag-grid-item"
|
||||
v-for="item in grid1"
|
||||
:key="item.id"
|
||||
>
|
||||
{{ item.name }}
|
||||
</div>
|
||||
</vue-draggable>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<div class="demo-drag-grid">
|
||||
<vue-draggable
|
||||
v-model="grid2"
|
||||
group="project2"
|
||||
animation="300"
|
||||
:set-data="() => void 0"
|
||||
>
|
||||
<div
|
||||
class="demo-drag-grid-item"
|
||||
v-for="item in grid2"
|
||||
:key="item.id"
|
||||
>
|
||||
{{ item.name }}
|
||||
</div>
|
||||
</vue-draggable>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import VueDraggable from 'vuedraggable';
|
||||
|
||||
export default {
|
||||
components: { VueDraggable },
|
||||
data() {
|
||||
return {
|
||||
grid: [
|
||||
{ id: 1, name: '项目0000001' },
|
||||
{ id: 2, name: '项目0000002' },
|
||||
{ id: 3, name: '项目0000003' },
|
||||
{ id: 4, name: '项目0000004' },
|
||||
{ id: 5, name: '项目0000005' }
|
||||
],
|
||||
grid1: [
|
||||
{ id: 1, name: '项目0000001' },
|
||||
{ id: 2, name: '项目0000002' },
|
||||
{ id: 3, name: '项目0000003' },
|
||||
{ id: 4, name: '项目0000004' },
|
||||
{ id: 5, name: '项目0000005' }
|
||||
],
|
||||
grid2: [
|
||||
{ id: 6, name: '项目0000006' },
|
||||
{ id: 7, name: '项目0000007' },
|
||||
{ id: 8, name: '项目0000008' },
|
||||
{ id: 9, name: '项目0000009' },
|
||||
{ id: 10, name: '项目0000010' }
|
||||
]
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
// 是否开启响应式布局
|
||||
styleResponsive() {
|
||||
return this.$store.state.theme.styleResponsive;
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
/* 宫格样式 */
|
||||
.demo-drag-grid {
|
||||
position: relative;
|
||||
|
||||
& > div {
|
||||
border: 1px solid hsla(0, 0%, 60%, 0.2);
|
||||
border-right: none;
|
||||
border-bottom: none;
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 33.33%);
|
||||
min-height: 201px;
|
||||
}
|
||||
|
||||
&:before,
|
||||
&:after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
background: hsla(0, 0%, 60%, 0.2);
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
&:before {
|
||||
width: 1px;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
&:after {
|
||||
height: 1px;
|
||||
left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.demo-drag-grid-item {
|
||||
cursor: move;
|
||||
border: 1px solid hsla(0, 0%, 60%, 0.2);
|
||||
border-top: none;
|
||||
border-left: none;
|
||||
height: 100px;
|
||||
line-height: 100px;
|
||||
white-space: nowrap;
|
||||
word-break: break-all;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.demo-drag-grid-item.sortable-chosen {
|
||||
background: hsla(0, 0%, 60%, 0.1);
|
||||
}
|
||||
</style>
|
||||
@@ -1,129 +0,0 @@
|
||||
<template>
|
||||
<el-row :gutter="15">
|
||||
<el-col v-bind="styleResponsive ? { md: 8 } : { span: 8 }">
|
||||
<el-card shadow="never" header="列表拖拽排序">
|
||||
<div class="demo-drag-list">
|
||||
<vue-draggable v-model="list" handle=".sort-handle" animation="300">
|
||||
<div
|
||||
class="demo-drag-list-item ele-cell"
|
||||
v-for="item in list"
|
||||
:key="item.id"
|
||||
>
|
||||
<div class="ele-cell-content">{{ item.name }}</div>
|
||||
<i class="sort-handle el-icon-rank ele-text-secondary"></i>
|
||||
</div>
|
||||
</vue-draggable>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col v-bind="styleResponsive ? { md: 16 } : { span: 16 }">
|
||||
<el-card shadow="never" header="列表相互拖拽">
|
||||
<el-row :gutter="15">
|
||||
<el-col :span="12">
|
||||
<div class="demo-drag-list">
|
||||
<vue-draggable
|
||||
v-model="list1"
|
||||
handle=".sort-handle"
|
||||
group="project1"
|
||||
animation="300"
|
||||
:set-data="() => void 0"
|
||||
>
|
||||
<div
|
||||
class="demo-drag-list-item ele-cell"
|
||||
v-for="item in list1"
|
||||
:key="item.id"
|
||||
>
|
||||
<div class="ele-cell-content">{{ item.name }}</div>
|
||||
<i class="sort-handle el-icon-rank ele-text-secondary"></i>
|
||||
</div>
|
||||
</vue-draggable>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<div class="demo-drag-list">
|
||||
<vue-draggable
|
||||
v-model="list2"
|
||||
handle=".sort-handle"
|
||||
group="project1"
|
||||
animation="300"
|
||||
:set-data="() => void 0"
|
||||
>
|
||||
<div
|
||||
class="demo-drag-list-item ele-cell"
|
||||
v-for="item in list2"
|
||||
:key="item.id"
|
||||
>
|
||||
<div class="ele-cell-content">{{ item.name }}</div>
|
||||
<i class="sort-handle el-icon-rank ele-text-secondary"></i>
|
||||
</div>
|
||||
</vue-draggable>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import VueDraggable from 'vuedraggable';
|
||||
|
||||
export default {
|
||||
components: { VueDraggable },
|
||||
data() {
|
||||
return {
|
||||
list: [
|
||||
{ id: 1, name: '项目0000001' },
|
||||
{ id: 2, name: '项目0000002' },
|
||||
{ id: 3, name: '项目0000003' },
|
||||
{ id: 4, name: '项目0000004' },
|
||||
{ id: 5, name: '项目0000005' }
|
||||
],
|
||||
list1: [
|
||||
{ id: 1, name: '项目0000001' },
|
||||
{ id: 2, name: '项目0000002' },
|
||||
{ id: 3, name: '项目0000003' },
|
||||
{ id: 4, name: '项目0000004' },
|
||||
{ id: 5, name: '项目0000005' }
|
||||
],
|
||||
list2: [
|
||||
{ id: 6, name: '项目0000006' },
|
||||
{ id: 7, name: '项目0000007' },
|
||||
{ id: 8, name: '项目0000008' },
|
||||
{ id: 9, name: '项目0000009' },
|
||||
{ id: 10, name: '项目0000010' }
|
||||
]
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
// 是否开启响应式布局
|
||||
styleResponsive() {
|
||||
return this.$store.state.theme.styleResponsive;
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
/* 列表样式 */
|
||||
.demo-drag-list {
|
||||
border: 1px solid hsla(0, 0%, 60%, 0.2);
|
||||
}
|
||||
|
||||
.demo-drag-list-item {
|
||||
padding: 10px 15px;
|
||||
|
||||
& + .demo-drag-list-item {
|
||||
border-top: 1px solid hsla(0, 0%, 60%, 0.2);
|
||||
}
|
||||
|
||||
&.sortable-chosen {
|
||||
background-color: hsla(0, 0%, 60%, 0.1);
|
||||
}
|
||||
|
||||
.sort-handle {
|
||||
cursor: move;
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,117 +0,0 @@
|
||||
<template>
|
||||
<el-card shadow="never" header="表格拖拽排序">
|
||||
<el-row :gutter="15">
|
||||
<el-col
|
||||
v-for="(item, index) in taskList"
|
||||
:key="index"
|
||||
v-bind="styleResponsive ? { md: 8 } : { span: 8 }"
|
||||
>
|
||||
<table class="ele-table ele-table-border ele-table-medium">
|
||||
<colgroup>
|
||||
<col width="40" />
|
||||
<col />
|
||||
<col width="80" />
|
||||
</colgroup>
|
||||
<thead>
|
||||
<tr>
|
||||
<th></th>
|
||||
<th>任务名称</th>
|
||||
<th style="text-align: center">状态</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<vue-draggable
|
||||
tag="tbody"
|
||||
:value="item"
|
||||
:animation="300"
|
||||
group="demoDragTable"
|
||||
handle=".demo-table-drag-handle"
|
||||
:set-data="() => void 0"
|
||||
@input="(value) => updateModelValue(value, index)"
|
||||
>
|
||||
<tr v-for="d in item" :key="d.id">
|
||||
<td style="text-align: center">
|
||||
<i
|
||||
class="demo-table-drag-handle el-icon-rank ele-text-secondary"
|
||||
style="cursor: move"
|
||||
></i>
|
||||
</td>
|
||||
<td>{{ d.taskName }}</td>
|
||||
<td style="text-align: center">
|
||||
<span
|
||||
:class="
|
||||
['ele-text-warning', 'ele-text-success', 'ele-text-info'][
|
||||
d.status
|
||||
]
|
||||
"
|
||||
>
|
||||
{{ ['未开始', '进行中', '已完成'][d.status] }}
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
<template v-slot:footer>
|
||||
<tr v-if="!item.length" style="background: none">
|
||||
<td colspan="3" style="text-align: center">暂无数据</td>
|
||||
</tr>
|
||||
</template>
|
||||
</vue-draggable>
|
||||
</table>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import VueDraggable from 'vuedraggable';
|
||||
|
||||
export default {
|
||||
components: { VueDraggable },
|
||||
data() {
|
||||
return {
|
||||
taskList: [],
|
||||
result: '',
|
||||
visible: false
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
// 是否开启响应式布局
|
||||
styleResponsive() {
|
||||
return this.$store.state.theme.styleResponsive;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
/* 更新数据 */
|
||||
updateModelValue(value, index) {
|
||||
//this.taskList[index] = value;
|
||||
this.$set(this.taskList, index, value);
|
||||
},
|
||||
/* 查看数据 */
|
||||
viewData() {
|
||||
this.result = JSON.stringify(this.taskList, null, 4);
|
||||
this.visible = true;
|
||||
}
|
||||
},
|
||||
created() {
|
||||
// 处理数据
|
||||
const temp = [];
|
||||
for (let i = 0; i < 18; i++) {
|
||||
const index = parseInt(String(i / 6));
|
||||
if (temp[index] == null) {
|
||||
temp[index] = [];
|
||||
}
|
||||
temp[index].push({
|
||||
id: i,
|
||||
taskName: '测试任务' + (i + 1),
|
||||
status: 0
|
||||
});
|
||||
}
|
||||
this.taskList = temp;
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
/* 表格行拖拽按下去样式 */
|
||||
.ele-table tr.sortable-chosen {
|
||||
background: hsla(0, 0%, 60%, 0.1);
|
||||
}
|
||||
</style>
|
||||
@@ -1,18 +0,0 @@
|
||||
<template>
|
||||
<div class="ele-body ele-body-card">
|
||||
<demo-list />
|
||||
<demo-grid />
|
||||
<demo-table />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import DemoList from './components/demo-list.vue';
|
||||
import DemoGrid from './components/demo-grid.vue';
|
||||
import DemoTable from './components/demo-table.vue';
|
||||
|
||||
export default {
|
||||
name: 'ExtensionDragSort',
|
||||
components: { DemoList, DemoGrid, DemoTable }
|
||||
};
|
||||
</script>
|
||||
@@ -1,109 +0,0 @@
|
||||
<template>
|
||||
<div class="ele-body">
|
||||
<el-card shadow="never">
|
||||
<!-- 操作按钮 -->
|
||||
<div class="ele-table-tool">
|
||||
<el-button size="small" @click="editContent">修改内容</el-button>
|
||||
<el-button size="small" @click="showViewContent = true">
|
||||
获取html
|
||||
</el-button>
|
||||
<el-button
|
||||
size="small"
|
||||
class="hidden-xs-only"
|
||||
@click="showViewText = true"
|
||||
>
|
||||
获取文本
|
||||
</el-button>
|
||||
<el-button size="small" class="hidden-xs-only" @click="toggleDisabled">
|
||||
{{ disabled ? '启用' : '禁用' }}
|
||||
</el-button>
|
||||
</div>
|
||||
<!-- 编辑器 -->
|
||||
<tinymce-editor
|
||||
ref="editor"
|
||||
v-model="value"
|
||||
:init="option"
|
||||
:disabled="disabled"
|
||||
/>
|
||||
</el-card>
|
||||
<!-- 内容弹窗 -->
|
||||
<ele-modal width="400px" title="编辑器内容" :visible.sync="showViewContent">
|
||||
<div>{{ value }}</div>
|
||||
</ele-modal>
|
||||
<!-- 纯文本弹窗 -->
|
||||
<ele-modal width="400px" title="编辑器纯文本" :visible.sync="showViewText">
|
||||
<div>{{ value | htmlToText }}</div>
|
||||
</ele-modal>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import TinymceEditor from '@/components/TinymceEditor/index.vue';
|
||||
|
||||
export default {
|
||||
name: 'ExtensionEditor',
|
||||
components: { TinymceEditor },
|
||||
data() {
|
||||
return {
|
||||
option: {
|
||||
height: 520,
|
||||
// 自定义文件上传(这里使用把选择的文件转成 blob 演示)
|
||||
file_picker_callback: (callback, _value, meta) => {
|
||||
const input = document.createElement('input');
|
||||
input.setAttribute('type', 'file');
|
||||
// 设定文件可选类型
|
||||
if (meta.filetype === 'image') {
|
||||
input.setAttribute('accept', 'image/*');
|
||||
} else if (meta.filetype === 'media') {
|
||||
input.setAttribute('accept', 'video/*');
|
||||
}
|
||||
input.onchange = () => {
|
||||
const file = input.files?.[0];
|
||||
if (!file) {
|
||||
return;
|
||||
}
|
||||
if (meta.filetype === 'media') {
|
||||
if (!file.type.startsWith('video/')) {
|
||||
this.$refs.editor.alert({ content: '只能选择视频文件' });
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (file.size / 1024 / 1024 > 20) {
|
||||
this.$refs.editor.alert({ content: '大小不能超过 20MB' });
|
||||
return;
|
||||
}
|
||||
const reader = new FileReader();
|
||||
reader.onload = (e) => {
|
||||
if (e.target?.result != null) {
|
||||
const blob = new Blob([e.target.result], { type: file.type });
|
||||
callback(URL.createObjectURL(blob));
|
||||
}
|
||||
};
|
||||
reader.readAsArrayBuffer(file);
|
||||
};
|
||||
input.click();
|
||||
}
|
||||
},
|
||||
value: '',
|
||||
showViewContent: false,
|
||||
showViewText: false,
|
||||
disabled: false
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
/* 修改编辑器内容 */
|
||||
editContent() {
|
||||
this.value = [
|
||||
'<div style="text-align: center;color: #fff;background-image: linear-gradient( 135deg, #2AFADF 10%, #4C83FF 100%);padding: 20px;">',
|
||||
' <div style="font-size: 28px;margin-bottom: 10px;">EleAdmin后台管理模板</div>',
|
||||
' <div style="font-size: 18px">通用型后台管理模板,界面美观、开箱即用,拥有丰富的组件和模板</div>',
|
||||
'</div><br/>'
|
||||
].join('');
|
||||
},
|
||||
/* 禁用启用切换 */
|
||||
toggleDisabled() {
|
||||
this.disabled = !this.disabled;
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@@ -1,28 +0,0 @@
|
||||
<template>
|
||||
<div class="ele-body">
|
||||
<el-card shadow="never" header="默认效果">
|
||||
<ele-empty></ele-empty>
|
||||
</el-card>
|
||||
<el-card shadow="never" header="自定义图标">
|
||||
<ele-empty>
|
||||
<template v-slot:icon>
|
||||
<i class="el-icon-_retrieve-solid"></i>
|
||||
</template>
|
||||
</ele-empty>
|
||||
</el-card>
|
||||
<el-card shadow="never" header="自定义操作按钮">
|
||||
<ele-empty text="还没有添加过数据~">
|
||||
<div style="margin-top: 20px">
|
||||
<el-button size="mini">添加数据</el-button>
|
||||
<el-button type="primary" size="mini">重新加载</el-button>
|
||||
</div>
|
||||
</ele-empty>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'ExtensionEmpty'
|
||||
};
|
||||
</script>
|
||||
@@ -1,261 +0,0 @@
|
||||
<template>
|
||||
<el-card shadow="never" header="导出 Excel">
|
||||
<ele-pro-table
|
||||
size="mini"
|
||||
:columns="columns"
|
||||
:datasource="users"
|
||||
:selection.sync="select"
|
||||
:toolkit="['size', 'columns', 'fullscreen']"
|
||||
:need-page="false"
|
||||
>
|
||||
<template v-slot:toolbar>
|
||||
<el-button type="primary" size="small" @click="exportBas">
|
||||
导出
|
||||
</el-button>
|
||||
<el-button type="primary" size="small" @click="exportAdv">
|
||||
导出带表头合并
|
||||
</el-button>
|
||||
<el-button type="primary" size="small" @click="exportSel">
|
||||
导出选中
|
||||
</el-button>
|
||||
</template>
|
||||
</ele-pro-table>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { utils, writeFile } from 'xlsx';
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
// 表格列配置
|
||||
columns: [
|
||||
{
|
||||
columnKey: 'selection',
|
||||
type: 'selection',
|
||||
width: 45,
|
||||
align: 'center'
|
||||
},
|
||||
{
|
||||
columnKey: 'index',
|
||||
type: 'index',
|
||||
width: 45,
|
||||
align: 'center'
|
||||
},
|
||||
{
|
||||
prop: 'username',
|
||||
label: '用户名',
|
||||
align: 'center',
|
||||
showOverflowTooltip: true
|
||||
},
|
||||
{
|
||||
prop: 'addressGroup',
|
||||
label: '地址',
|
||||
align: 'center',
|
||||
showOverflowTooltip: true,
|
||||
children: [
|
||||
{
|
||||
prop: 'province',
|
||||
label: '省',
|
||||
align: 'center',
|
||||
showOverflowTooltip: true
|
||||
},
|
||||
{
|
||||
prop: 'city',
|
||||
label: '市',
|
||||
align: 'center',
|
||||
showOverflowTooltip: true
|
||||
},
|
||||
{
|
||||
prop: 'zone',
|
||||
label: '区',
|
||||
align: 'center',
|
||||
showOverflowTooltip: true
|
||||
},
|
||||
{
|
||||
prop: 'street',
|
||||
label: '街道',
|
||||
align: 'center',
|
||||
showOverflowTooltip: true
|
||||
},
|
||||
{
|
||||
prop: 'address',
|
||||
label: '详细地址',
|
||||
align: 'center',
|
||||
showOverflowTooltip: true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
prop: 'amount',
|
||||
label: '金额',
|
||||
align: 'center',
|
||||
showOverflowTooltip: true
|
||||
}
|
||||
],
|
||||
// 表格数据
|
||||
users: [
|
||||
{
|
||||
key: 1,
|
||||
username: '张小三',
|
||||
amount: 18,
|
||||
province: '浙江',
|
||||
city: '杭州',
|
||||
zone: '西湖区',
|
||||
street: '西溪街道',
|
||||
address: '西溪花园30栋1单元'
|
||||
},
|
||||
{
|
||||
key: 2,
|
||||
username: '李小四',
|
||||
amount: 39,
|
||||
province: '江苏',
|
||||
city: '苏州',
|
||||
zone: '姑苏区',
|
||||
street: '丝绸路',
|
||||
address: '天墅之城9幢2单元'
|
||||
},
|
||||
{
|
||||
key: 3,
|
||||
username: '王小五',
|
||||
amount: 8,
|
||||
province: '江西',
|
||||
city: '南昌',
|
||||
zone: '青山湖区',
|
||||
street: '艾溪湖办事处',
|
||||
address: '中兴和园1幢3单元'
|
||||
},
|
||||
{
|
||||
key: 4,
|
||||
username: '赵小六',
|
||||
amount: 16,
|
||||
province: '福建',
|
||||
city: '泉州',
|
||||
zone: '丰泽区',
|
||||
street: '南洋街道',
|
||||
address: '南洋村6幢1单元'
|
||||
},
|
||||
{
|
||||
key: 5,
|
||||
username: '孙小七',
|
||||
amount: 12,
|
||||
province: '湖北',
|
||||
city: '武汉',
|
||||
zone: '武昌区',
|
||||
street: '武昌大道',
|
||||
address: '两湖花园16幢2单元'
|
||||
},
|
||||
{
|
||||
key: 6,
|
||||
username: '周小八',
|
||||
amount: 11,
|
||||
province: '安徽',
|
||||
city: '黄山',
|
||||
zone: '黄山区',
|
||||
street: '汤口镇',
|
||||
address: '温泉村21号'
|
||||
}
|
||||
],
|
||||
// 选中数据
|
||||
select: []
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
/* 导出 excel */
|
||||
exportBas() {
|
||||
const array = [
|
||||
['用户名', '省', '市', '区', '街道', '详细地址', '金额']
|
||||
];
|
||||
this.users.forEach((d) => {
|
||||
array.push([
|
||||
d.username,
|
||||
d.province,
|
||||
d.city,
|
||||
d.zone,
|
||||
d.street,
|
||||
d.address,
|
||||
d.amount
|
||||
]);
|
||||
});
|
||||
const sheetName = 'Sheet1';
|
||||
const workbook = {
|
||||
SheetNames: [sheetName],
|
||||
Sheets: {}
|
||||
};
|
||||
const sheet = utils.aoa_to_sheet(array);
|
||||
workbook.Sheets[sheetName] = sheet;
|
||||
// 设置列宽
|
||||
sheet['!cols'] = [
|
||||
{ wch: 10 },
|
||||
{ wch: 10 },
|
||||
{ wch: 10 },
|
||||
{ wch: 10 },
|
||||
{ wch: 20 },
|
||||
{ wch: 40 },
|
||||
{ wch: 10 }
|
||||
];
|
||||
writeFile(workbook, '用户数据.xlsx');
|
||||
},
|
||||
/* 导出带单元格合并 */
|
||||
exportAdv() {
|
||||
const array = [
|
||||
['用户名', '地址', null, null, null, null, '金额'],
|
||||
[null, '省', '市', '区', '街道', '详细地址', null]
|
||||
];
|
||||
this.users.forEach((d) => {
|
||||
array.push([
|
||||
d.username,
|
||||
d.province,
|
||||
d.city,
|
||||
d.zone,
|
||||
d.street,
|
||||
d.address,
|
||||
d.amount
|
||||
]);
|
||||
});
|
||||
const sheet = utils.aoa_to_sheet(array);
|
||||
sheet['!merges'] = [
|
||||
{ s: { r: 0, c: 1 }, e: { r: 0, c: 5 } }, // 合并第 0 行第 1 列到第 0 行第 5 列
|
||||
{ s: { r: 0, c: 0 }, e: { r: 1, c: 0 } }, // 合并第 0 行第 0 列到第 1 行第 0 列
|
||||
{ s: { r: 0, c: 6 }, e: { r: 1, c: 6 } } // 合并第 0 行第 6 列到第 1 行第 6 列
|
||||
];
|
||||
const sheetName = 'Sheet1';
|
||||
const workbook = {
|
||||
SheetNames: [sheetName],
|
||||
Sheets: {}
|
||||
};
|
||||
workbook.Sheets[sheetName] = sheet;
|
||||
writeFile(workbook, '用户数据.xlsx');
|
||||
},
|
||||
/* 导出选中数据 */
|
||||
exportSel() {
|
||||
if (this.select.length === 0) {
|
||||
this.$message.error('请至少选择一条数据');
|
||||
return;
|
||||
}
|
||||
const array = [
|
||||
['用户名', '省', '市', '区', '街道', '详细地址', '金额']
|
||||
];
|
||||
this.select.forEach((d) => {
|
||||
array.push([
|
||||
d.username,
|
||||
d.province,
|
||||
d.city,
|
||||
d.zone,
|
||||
d.street,
|
||||
d.address,
|
||||
d.amount
|
||||
]);
|
||||
});
|
||||
const sheetName = 'Sheet1';
|
||||
const workbook = {
|
||||
SheetNames: [sheetName],
|
||||
Sheets: {}
|
||||
};
|
||||
workbook.Sheets[sheetName] = utils.aoa_to_sheet(array);
|
||||
writeFile(workbook, '用户数据.xlsx');
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@@ -1,305 +0,0 @@
|
||||
<template>
|
||||
<el-card shadow="never" header="导入 Excel">
|
||||
<!-- 操作按钮 -->
|
||||
<div style="display: flex; margin-bottom: 12px">
|
||||
<el-upload
|
||||
action=""
|
||||
:show-file-list="false"
|
||||
:before-upload="importFile"
|
||||
accept=".xls,.xlsx"
|
||||
class="ele-action"
|
||||
>
|
||||
<el-button type="primary" size="small" class="hidden-xs-only">
|
||||
导入
|
||||
</el-button>
|
||||
</el-upload>
|
||||
<el-upload
|
||||
action=""
|
||||
:show-file-list="false"
|
||||
:before-upload="importFile2"
|
||||
accept=".xls,.xlsx"
|
||||
class="ele-action"
|
||||
>
|
||||
<el-button type="primary" size="small">导入拆分合并</el-button>
|
||||
</el-upload>
|
||||
<el-upload
|
||||
action=""
|
||||
:show-file-list="false"
|
||||
:before-upload="importFile3"
|
||||
accept=".xls,.xlsx"
|
||||
class="ele-action"
|
||||
>
|
||||
<el-button type="primary" size="small">导入保持合并</el-button>
|
||||
</el-upload>
|
||||
</div>
|
||||
<!-- 数据表格 -->
|
||||
<el-table
|
||||
size="mini"
|
||||
:border="true"
|
||||
:data="importData"
|
||||
style="width: 100%"
|
||||
:span-method="spanMethod"
|
||||
>
|
||||
<el-table-column type="index" width="45" align="center" />
|
||||
<el-table-column
|
||||
v-for="(key, index) in importTitle"
|
||||
:key="index"
|
||||
:prop="key"
|
||||
:label="key"
|
||||
align="center"
|
||||
show-overflow-tooltip
|
||||
/>
|
||||
</el-table>
|
||||
<el-row :gutter="30">
|
||||
<el-col v-bind="styleResponsive ? { md: 12 } : { span: 12 }">
|
||||
<div style="padding: 15px 0">二维数组格式数据:</div>
|
||||
<pre style="max-height: 300px; overflow: auto">{{
|
||||
JSON.stringify(importDataAoa, null, 4)
|
||||
}}</pre>
|
||||
</el-col>
|
||||
<el-col v-bind="styleResponsive ? { md: 12 } : { span: 12 }">
|
||||
<div style="padding: 15px 0">JSON格式数据:</div>
|
||||
<pre style="max-height: 300px; overflow: auto">{{
|
||||
JSON.stringify(importData, null, 4)
|
||||
}}</pre>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { utils, read } from 'xlsx';
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
// 导入数据
|
||||
importData: [],
|
||||
// 导入数据的列
|
||||
importTitle: ['A', 'B', 'C', 'D', 'E', 'F', 'G'],
|
||||
// 导入数据二维数组形式
|
||||
importDataAoa: []
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
// 是否开启响应式布局
|
||||
styleResponsive() {
|
||||
return this.$store.state.theme.styleResponsive;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
/* 导入本地 excel 文件 */
|
||||
importFile(file) {
|
||||
if (
|
||||
![
|
||||
'application/vnd.ms-excel',
|
||||
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
|
||||
].includes(file.type)
|
||||
) {
|
||||
this.$message.error('只能选择 excel 文件');
|
||||
return false;
|
||||
}
|
||||
if (file.size / 1024 / 1024 > 20) {
|
||||
this.$message.error('大小不能超过 20MB');
|
||||
return false;
|
||||
}
|
||||
const reader = new FileReader();
|
||||
reader.onload = (e) => {
|
||||
const data = new Uint8Array(e.target.result);
|
||||
const workbook = read(data, { type: 'array' });
|
||||
const sheetNames = workbook.SheetNames;
|
||||
const worksheet = workbook.Sheets[sheetNames[0]];
|
||||
// 解析成二维数组
|
||||
const aoa = utils.sheet_to_json(worksheet, { header: 1 });
|
||||
// 生成表格需要的数据
|
||||
const list = [];
|
||||
let maxCols = 0;
|
||||
const title = [];
|
||||
aoa.forEach((d) => {
|
||||
if (d.length > maxCols) {
|
||||
maxCols = d.length;
|
||||
}
|
||||
const row = {};
|
||||
for (let i = 0; i < d.length; i++) {
|
||||
row[this.getCharByIndex(i)] = d[i];
|
||||
}
|
||||
list.push(row);
|
||||
});
|
||||
for (let i = 0; i < maxCols; i++) {
|
||||
title.push(this.getCharByIndex(i));
|
||||
}
|
||||
this.importTitle = title;
|
||||
this.importData = list;
|
||||
this.importDataAoa = aoa;
|
||||
};
|
||||
reader.readAsArrayBuffer(file);
|
||||
return false;
|
||||
},
|
||||
/* 导入本地 excel 文件 */
|
||||
importFile2(file) {
|
||||
if (
|
||||
![
|
||||
'application/vnd.ms-excel',
|
||||
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
|
||||
].includes(file.type)
|
||||
) {
|
||||
this.$message.error('只能选择 excel 文件');
|
||||
return false;
|
||||
}
|
||||
if (file.size / 1024 / 1024 > 20) {
|
||||
this.$message.error('大小不能超过 20MB');
|
||||
return false;
|
||||
}
|
||||
const reader = new FileReader();
|
||||
reader.onload = (e) => {
|
||||
const data = new Uint8Array(e.target.result);
|
||||
const workbook = read(data, { type: 'array' });
|
||||
const sheetNames = workbook.SheetNames;
|
||||
const worksheet = workbook.Sheets[sheetNames[0]];
|
||||
// 解析成二维数组
|
||||
const aoa = utils.sheet_to_json(worksheet, { header: 1 });
|
||||
// 拆分合并单元格
|
||||
if (worksheet['!merges']) {
|
||||
worksheet['!merges'].forEach((m) => {
|
||||
for (let r = m.s.r; r <= m.e.r; r++) {
|
||||
for (let c = m.s.c; c <= m.e.c; c++) {
|
||||
aoa[r][c] = aoa[m.s.r][m.s.c];
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
// 生成表格需要的数据
|
||||
const list = [];
|
||||
let maxCols = 0;
|
||||
const title = [];
|
||||
aoa.forEach((d) => {
|
||||
if (d.length > maxCols) {
|
||||
maxCols = d.length;
|
||||
}
|
||||
const row = {};
|
||||
for (let i = 0; i < d.length; i++) {
|
||||
row[this.getCharByIndex(i)] = d[i];
|
||||
}
|
||||
list.push(row);
|
||||
});
|
||||
for (let i = 0; i < maxCols; i++) {
|
||||
title.push(this.getCharByIndex(i));
|
||||
}
|
||||
this.importTitle = title;
|
||||
this.importData = list;
|
||||
this.importDataAoa = aoa;
|
||||
};
|
||||
reader.readAsArrayBuffer(file);
|
||||
return false;
|
||||
},
|
||||
/* 导入本地 excel 文件 */
|
||||
importFile3(file) {
|
||||
if (
|
||||
![
|
||||
'application/vnd.ms-excel',
|
||||
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
|
||||
].includes(file.type)
|
||||
) {
|
||||
this.$message.error('只能选择 excel 文件');
|
||||
return false;
|
||||
}
|
||||
if (file.size / 1024 / 1024 > 20) {
|
||||
this.$message.error('大小不能超过 20MB');
|
||||
return false;
|
||||
}
|
||||
const reader = new FileReader();
|
||||
reader.onload = (e) => {
|
||||
const data = new Uint8Array(e.target.result);
|
||||
const workbook = read(data, { type: 'array' });
|
||||
const sheetNames = workbook.SheetNames;
|
||||
const worksheet = workbook.Sheets[sheetNames[0]];
|
||||
// 解析成二维数组
|
||||
const aoa = utils.sheet_to_json(worksheet, { header: 1 });
|
||||
// 生成表格需要的数据
|
||||
const list = [];
|
||||
let maxCols = 0;
|
||||
const title = [];
|
||||
aoa.forEach((d) => {
|
||||
if (d.length > maxCols) {
|
||||
maxCols = d.length;
|
||||
}
|
||||
const row = {};
|
||||
for (let i = 0; i < d.length; i++) {
|
||||
row[this.getCharByIndex(i)] = d[i];
|
||||
}
|
||||
list.push(row);
|
||||
});
|
||||
for (let i = 0; i < maxCols; i++) {
|
||||
title.push(this.getCharByIndex(i));
|
||||
}
|
||||
// 记录合并单元格
|
||||
if (worksheet['!merges']) {
|
||||
worksheet['!merges'].forEach((m) => {
|
||||
for (let r = m.s.r; r <= m.e.r; r++) {
|
||||
for (let c = m.s.c; c <= m.e.c; c++) {
|
||||
const cc = this.getCharByIndex(c);
|
||||
list[r]['__colspan__' + cc] = 0;
|
||||
list[r]['__rowspan__' + cc] = 0;
|
||||
}
|
||||
}
|
||||
const char = this.getCharByIndex(m.s.c);
|
||||
list[m.s.r]['__colspan__' + char] = m.e.c - m.s.c + 1;
|
||||
list[m.s.r]['__rowspan__' + char] = m.e.r - m.s.r + 1;
|
||||
});
|
||||
}
|
||||
this.importTitle = title;
|
||||
this.importData = list;
|
||||
this.importDataAoa = aoa;
|
||||
};
|
||||
reader.readAsArrayBuffer(file);
|
||||
return false;
|
||||
},
|
||||
/* 生成 Excel 列字母序号 */
|
||||
getCharByIndex(index) {
|
||||
const chars = [
|
||||
'A',
|
||||
'B',
|
||||
'C',
|
||||
'D',
|
||||
'E',
|
||||
'F',
|
||||
'G',
|
||||
'H',
|
||||
'I',
|
||||
'J',
|
||||
'K',
|
||||
'L',
|
||||
'M',
|
||||
'N',
|
||||
'O',
|
||||
'P',
|
||||
'Q',
|
||||
'R',
|
||||
'S',
|
||||
'T',
|
||||
'U',
|
||||
'V',
|
||||
'W',
|
||||
'X',
|
||||
'Y',
|
||||
'Z'
|
||||
];
|
||||
if (index < chars.length) {
|
||||
return chars[index];
|
||||
}
|
||||
const n = parseInt(index / chars.length),
|
||||
m = index % chars.length;
|
||||
return chars[n] + chars[m];
|
||||
},
|
||||
/* 合并表格单元格 */
|
||||
spanMethod({ row, column }) {
|
||||
if (!column.label) {
|
||||
return [1, 1];
|
||||
}
|
||||
const r = row['__rowspan__' + column.label],
|
||||
c = row['__colspan__' + column.label];
|
||||
return [r == null ? 1 : r, c == null ? 1 : c];
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@@ -1,16 +0,0 @@
|
||||
<template>
|
||||
<div class="ele-body">
|
||||
<excel-export />
|
||||
<excel-import />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ExcelExport from './components/excel-export.vue';
|
||||
import ExcelImport from './components/excel-import.vue';
|
||||
|
||||
export default {
|
||||
name: 'ExtensionExcel',
|
||||
components: { ExcelExport, ExcelImport }
|
||||
};
|
||||
</script>
|
||||
@@ -1,103 +0,0 @@
|
||||
<!-- 文件目录面包屑 -->
|
||||
<template>
|
||||
<div class="ele-file-breadcrumb-group ele-cell">
|
||||
<div class="ele-cell-content ele-cell">
|
||||
<div
|
||||
v-if="directorys.length"
|
||||
class="ele-file-breadcrumb-back ele-text-primary"
|
||||
@click="goBack"
|
||||
>
|
||||
返回上一级
|
||||
</div>
|
||||
<div class="ele-file-breadcrumb-list ele-cell-content ele-cell">
|
||||
<div
|
||||
:class="[
|
||||
'ele-file-breadcrumb-item ele-cell',
|
||||
{ 'ele-text-primary': directorys.length }
|
||||
]"
|
||||
@click="goRoot"
|
||||
>
|
||||
<div class="ele-file-breadcrumb-item-title">全部文件</div>
|
||||
<i
|
||||
v-if="directorys.length"
|
||||
class="el-icon-arrow-right ele-text-secondary"
|
||||
></i>
|
||||
</div>
|
||||
<div
|
||||
v-for="(item, i) in directorys"
|
||||
:key="item.id"
|
||||
:class="[
|
||||
'ele-file-breadcrumb-item ele-cell',
|
||||
{ 'ele-text-primary': i !== directorys.length - 1 }
|
||||
]"
|
||||
@click="goDirectory(i)"
|
||||
>
|
||||
<div class="ele-file-breadcrumb-item-title">{{ item.name }}</div>
|
||||
<i
|
||||
v-if="i !== directorys.length - 1"
|
||||
class="el-icon-arrow-right ele-text-secondary"
|
||||
></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="hidden-xs-only">已全部加载, 共{{ total }}个</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
// 文件夹数据
|
||||
directorys: Array,
|
||||
// 总文件数
|
||||
total: Number
|
||||
},
|
||||
methods: {
|
||||
/* 回到上级 */
|
||||
goBack() {
|
||||
this.$emit(
|
||||
'update:directorys',
|
||||
this.directorys.slice(0, this.directorys.length - 1)
|
||||
);
|
||||
},
|
||||
/* 回到根目录 */
|
||||
goRoot() {
|
||||
if (this.directorys.length) {
|
||||
this.$emit('update:directorys', []);
|
||||
}
|
||||
},
|
||||
/* 回到指定目录 */
|
||||
goDirectory(index) {
|
||||
if (index !== this.directorys.length - 1) {
|
||||
this.$emit('update:directorys', this.directorys.slice(0, index + 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
/* 文件目录面包屑 */
|
||||
.ele-file-breadcrumb-group {
|
||||
font-size: 13px;
|
||||
padding: 2px 0 6px 0;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.ele-file-breadcrumb-back {
|
||||
padding-right: 10px;
|
||||
border-right: 2px solid hsla(0, 0%, 60%, 0.2);
|
||||
|
||||
&:hover {
|
||||
text-decoration: underline;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
.ele-file-breadcrumb-item.ele-text-primary:hover {
|
||||
& > .ele-file-breadcrumb-item-title {
|
||||
text-decoration: underline;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,216 +0,0 @@
|
||||
<!-- 文件展示列表 -->
|
||||
<template>
|
||||
<div class="demo-file-list-group">
|
||||
<ele-file-list
|
||||
v-if="data.length"
|
||||
:data="data"
|
||||
:grid="grid"
|
||||
:sort="sort"
|
||||
:order="order"
|
||||
:checked="checked"
|
||||
:style="{ minHeight: '400px', minWidth: grid ? 'auto' : '456px' }"
|
||||
@item-click="onItemClick"
|
||||
@sort-change="onSortChange"
|
||||
@update:checked="updateChecked"
|
||||
@item-context-menu="onCtxMenuClick"
|
||||
:icons="icons"
|
||||
:sm-icons="smIcons"
|
||||
>
|
||||
<template v-slot:context-menu="{ item }">
|
||||
<el-dropdown-item command="open">打开</el-dropdown-item>
|
||||
<el-dropdown-item
|
||||
v-if="!item.isDirectory"
|
||||
command="download"
|
||||
icon="el-icon-download"
|
||||
divided
|
||||
>
|
||||
下载
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item
|
||||
command="edit"
|
||||
icon="el-icon-edit"
|
||||
:divided="item.isDirectory"
|
||||
>
|
||||
重命名
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item command="move" icon="el-icon-rank" divided>
|
||||
移动到
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item command="remove" icon="el-icon-delete">
|
||||
删除
|
||||
</el-dropdown-item>
|
||||
</template>
|
||||
</ele-file-list>
|
||||
<div v-else class="demo-file-list-empty">
|
||||
<ele-empty />
|
||||
</div>
|
||||
<!-- 用于图片预览 -->
|
||||
<div style="display: none">
|
||||
<el-image
|
||||
ref="previewRef"
|
||||
v-if="previewOption.visible"
|
||||
:src="previewOption.current"
|
||||
:preview-src-list="previewImages"
|
||||
/>
|
||||
</div>
|
||||
<!-- 文件重命名弹窗 -->
|
||||
<name-edit
|
||||
:visible.sync="nameEditVisible"
|
||||
:data="nameEditData"
|
||||
@done="onDone"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import EleFileList from 'ele-admin/es/ele-file-list';
|
||||
import NameEdit from './name-edit.vue';
|
||||
import { removeUserFile } from '@/api/system/user-file';
|
||||
import { icons, smIcons } from 'ele-admin/es/ele-file-list/icons';
|
||||
|
||||
export default {
|
||||
components: { EleFileList, NameEdit },
|
||||
props: {
|
||||
// 父级 id
|
||||
parentId: Number,
|
||||
// 文件列表数据
|
||||
data: Array,
|
||||
// 排序字段
|
||||
sort: String,
|
||||
// 排序方式
|
||||
order: String,
|
||||
// 选中数据
|
||||
checked: Array,
|
||||
// 是否网格展示
|
||||
grid: Boolean
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
icons: icons.map((d) => {
|
||||
return {
|
||||
...d,
|
||||
icon: d.icon.replace(
|
||||
'https://cdn.eleadmin.com/20200609/',
|
||||
'/ele-file-list/'
|
||||
)
|
||||
};
|
||||
}),
|
||||
smIcons: smIcons.map((d) => {
|
||||
return {
|
||||
...d,
|
||||
icon: d.icon.replace(
|
||||
'https://cdn.eleadmin.com/20200609/',
|
||||
'/ele-file-list/'
|
||||
)
|
||||
};
|
||||
}),
|
||||
// 图片预览列表
|
||||
previewImages: [],
|
||||
// 图片预览配置
|
||||
previewOption: {
|
||||
visible: false,
|
||||
current: null
|
||||
},
|
||||
// 文件重命名弹窗是否打开
|
||||
nameEditVisible: false,
|
||||
// 文件重命名的数据
|
||||
nameEditData: null
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
/* 文件列表排序方式改变 */
|
||||
onSortChange(option) {
|
||||
this.$emit('sort-change', option);
|
||||
},
|
||||
/* 更新选中数据 */
|
||||
updateChecked(value) {
|
||||
this.$emit('update:checked', value);
|
||||
},
|
||||
/* item 点击事件 */
|
||||
onItemClick(item) {
|
||||
if (item.isDirectory) {
|
||||
// 进入文件夹
|
||||
this.$emit('go-directory', item);
|
||||
} else if (this.isImageFile(item)) {
|
||||
// 预览图片文件
|
||||
this.previewItemImage(item);
|
||||
} else {
|
||||
// 选中或取消选中文件
|
||||
this.updateChecked(
|
||||
this.checked.includes(item)
|
||||
? this.checked.filter((d) => d !== item)
|
||||
: [...this.checked, item]
|
||||
);
|
||||
}
|
||||
},
|
||||
/* 右键菜单点击事件 */
|
||||
onCtxMenuClick({ key, item }) {
|
||||
if (key === 'open') {
|
||||
// 打开文件
|
||||
if (item.isDirectory || this.isImageFile(item)) {
|
||||
this.onItemClick(item);
|
||||
} else {
|
||||
window.open(item.url);
|
||||
}
|
||||
} else if (key === 'download') {
|
||||
// 下载文件
|
||||
if (typeof item.downloadUrl === 'string') {
|
||||
window.open(item.downloadUrl);
|
||||
}
|
||||
} else if (key === 'edit') {
|
||||
// 重命名
|
||||
this.nameEditData = item;
|
||||
this.nameEditVisible = true;
|
||||
} else if (key === 'remove') {
|
||||
// 删除文件
|
||||
this.removeItem(item);
|
||||
}
|
||||
},
|
||||
/* 删除 */
|
||||
removeItem(item) {
|
||||
this.$confirm('确定要删除此文件吗?', '提示', {
|
||||
type: 'warning'
|
||||
})
|
||||
.then(() => {
|
||||
const loading = this.$messageLoading('请求中..');
|
||||
removeUserFile(item.id)
|
||||
.then((msg) => {
|
||||
loading.close();
|
||||
this.$message.success(msg);
|
||||
this.onDone();
|
||||
})
|
||||
.catch((e) => {
|
||||
loading.close();
|
||||
this.$message.error(e.message);
|
||||
});
|
||||
})
|
||||
.catch(() => {});
|
||||
},
|
||||
/* 完成刷新列表数据 */
|
||||
onDone() {
|
||||
this.$emit('done');
|
||||
},
|
||||
/* 判断是否是图片文件 */
|
||||
isImageFile(item) {
|
||||
return (
|
||||
typeof item.contentType === 'string' &&
|
||||
item.contentType.startsWith('image/') &&
|
||||
item.url
|
||||
);
|
||||
},
|
||||
/* 预览图片文件 */
|
||||
previewItemImage(item) {
|
||||
this.previewImages = this.data
|
||||
.filter((d) => this.isImageFile(d))
|
||||
.map((d) => d.url);
|
||||
this.previewOption.current = item.url;
|
||||
this.previewOption.visible = true;
|
||||
this.$nextTick(() => {
|
||||
if (this.$refs.previewRef) {
|
||||
this.$refs.previewRef.showViewer = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@@ -1,211 +0,0 @@
|
||||
<template>
|
||||
<ele-toolbar theme="none">
|
||||
<el-upload
|
||||
action=""
|
||||
:show-file-list="false"
|
||||
:before-upload="onUpload"
|
||||
class="ele-action ele-inline-block"
|
||||
>
|
||||
<el-button
|
||||
size="small"
|
||||
type="primary"
|
||||
class="ele-btn-icon"
|
||||
icon="el-icon-upload2"
|
||||
>
|
||||
上传
|
||||
</el-button>
|
||||
</el-upload>
|
||||
<el-button
|
||||
size="small"
|
||||
class="ele-btn-icon"
|
||||
icon="el-icon-folder-add"
|
||||
@click="openFolderAdd"
|
||||
>
|
||||
新建文件夹
|
||||
</el-button>
|
||||
<el-button
|
||||
size="small"
|
||||
type="danger"
|
||||
icon="el-icon-delete"
|
||||
class="ele-btn-icon hidden-xs-only"
|
||||
:disabled="!checked.length"
|
||||
@click="removeBatch"
|
||||
>
|
||||
删除
|
||||
</el-button>
|
||||
<template v-slot:action>
|
||||
<!-- 搜索框 -->
|
||||
<div
|
||||
:class="['ele-file-tool-search', { 'hidden-xs-only': styleResponsive }]"
|
||||
>
|
||||
<el-input size="small" v-model="search" placeholder="搜索您的文件">
|
||||
<template v-slot:append>
|
||||
<el-button icon="el-icon-search" />
|
||||
</template>
|
||||
</el-input>
|
||||
</div>
|
||||
<!-- 显示方式切换 -->
|
||||
<i
|
||||
v-if="grid"
|
||||
class="ele-file-tool-btn el-icon-_menu"
|
||||
@click="toggleShowType"
|
||||
></i>
|
||||
<i
|
||||
v-else
|
||||
class="ele-file-tool-btn el-icon-_nav"
|
||||
@click="toggleShowType"
|
||||
></i>
|
||||
</template>
|
||||
<!-- 新建文件夹弹窗 -->
|
||||
<folder-add
|
||||
:visible.sync="folderAddVisible"
|
||||
:parent-id="parentId"
|
||||
@done="onDone"
|
||||
/>
|
||||
</ele-toolbar>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { uploadFile } from '@/api/system/file';
|
||||
import { addUserFile, removeUserFiles } from '@/api/system/user-file';
|
||||
import FolderAdd from './folder-add.vue';
|
||||
|
||||
export default {
|
||||
components: { FolderAdd },
|
||||
props: {
|
||||
// 是否网格展示
|
||||
grid: Boolean,
|
||||
// 选中数据
|
||||
checked: Array,
|
||||
// 父级 id
|
||||
parentId: Number
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
// 搜索关键字
|
||||
search: '',
|
||||
// 新建文件夹弹窗是否打开
|
||||
folderAddVisible: false
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
// 是否开启响应式布局
|
||||
styleResponsive() {
|
||||
return this.$store.state.theme.styleResponsive;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
/* 上传 */
|
||||
onUpload(file) {
|
||||
if (file.size / 1024 / 1024 > 100) {
|
||||
this.$message.error('大小不能超过 100MB');
|
||||
return false;
|
||||
}
|
||||
const loading = this.$messageLoading('上传中..');
|
||||
uploadFile(file)
|
||||
.then((data) => {
|
||||
addUserFile({
|
||||
name: data.name,
|
||||
isDirectory: 0,
|
||||
parentId: this.parentId,
|
||||
path: data.path,
|
||||
length: data.length,
|
||||
contentType: data.contentType
|
||||
})
|
||||
.then(() => {
|
||||
loading.close();
|
||||
this.$message.success('上传成功');
|
||||
this.onDone();
|
||||
})
|
||||
.catch((e) => {
|
||||
loading.close();
|
||||
this.$message.error(e.message);
|
||||
});
|
||||
})
|
||||
.catch((e) => {
|
||||
loading.close();
|
||||
this.$message.error(e.message);
|
||||
});
|
||||
return false;
|
||||
},
|
||||
/* 打开新建文件夹弹窗 */
|
||||
openFolderAdd() {
|
||||
this.folderAddVisible = true;
|
||||
},
|
||||
/* 批量删除 */
|
||||
removeBatch() {
|
||||
this.$confirm('确定要删除选中的文件吗?', '提示', {
|
||||
type: 'warning'
|
||||
})
|
||||
.then(() => {
|
||||
const loading = this.$messageLoading('请求中..');
|
||||
removeUserFiles(this.checked.map((d) => d.id))
|
||||
.then((msg) => {
|
||||
loading.close();
|
||||
this.$message.success(msg);
|
||||
this.onDone();
|
||||
})
|
||||
.catch((e) => {
|
||||
loading.close();
|
||||
this.$message.error(e.message);
|
||||
});
|
||||
})
|
||||
.catch(() => {});
|
||||
},
|
||||
/* 完成刷新列表数据 */
|
||||
onDone() {
|
||||
this.$emit('done');
|
||||
},
|
||||
/* 显示方式切换 */
|
||||
toggleShowType() {
|
||||
this.$emit('update:grid', !this.grid);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
/* 图标按钮 */
|
||||
.ele-file-tool-btn {
|
||||
cursor: pointer;
|
||||
font-size: 22px;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
/* 搜索框 */
|
||||
.ele-file-tool-search {
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
background-color: hsla(0, 0%, 60%, 0.15);
|
||||
border-radius: 32px;
|
||||
|
||||
:deep(.el-input-group__append),
|
||||
:deep(.el-input__inner) {
|
||||
background-color: transparent;
|
||||
border: none;
|
||||
}
|
||||
|
||||
:deep(.el-input-group__append) {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
:deep(.el-input-group__append .el-button) {
|
||||
margin: 0;
|
||||
padding: 7px 16px 7px 10px;
|
||||
border: none;
|
||||
}
|
||||
|
||||
:deep(.el-input-group__append .el-button > i) {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
:deep(.el-input__inner) {
|
||||
width: 200px;
|
||||
padding-right: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,99 +0,0 @@
|
||||
<template>
|
||||
<ele-modal
|
||||
width="460px"
|
||||
:visible="visible"
|
||||
:append-to-body="true"
|
||||
:close-on-click-modal="true"
|
||||
custom-class="ele-dialog-form"
|
||||
title="新建文件夹"
|
||||
@update:visible="updateVisible"
|
||||
>
|
||||
<el-form ref="form" :model="form" :rules="rules" label-width="102px">
|
||||
<el-form-item label="文件夹名称:" prop="name">
|
||||
<el-input
|
||||
clearable
|
||||
:maxlength="20"
|
||||
v-model="form.name"
|
||||
placeholder="请输入文件夹名称"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template v-slot:footer>
|
||||
<el-button @click="updateVisible(false)">取消</el-button>
|
||||
<el-button type="primary" :loading="loading" @click="save">
|
||||
保存
|
||||
</el-button>
|
||||
</template>
|
||||
</ele-modal>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { addUserFile } from '@/api/system/user-file';
|
||||
|
||||
export default {
|
||||
props: {
|
||||
// 弹窗是否打开
|
||||
visible: Boolean,
|
||||
// 父级 id
|
||||
parentId: Number
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
// 表单数据
|
||||
form: {
|
||||
name: ''
|
||||
},
|
||||
// 表单验证规则
|
||||
rules: {
|
||||
name: [
|
||||
{
|
||||
required: true,
|
||||
message: '请输入文件夹名称',
|
||||
trigger: 'blur'
|
||||
}
|
||||
]
|
||||
},
|
||||
// 提交状态
|
||||
loading: false
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
/* 保存编辑 */
|
||||
save() {
|
||||
this.$refs.form.validate((valid) => {
|
||||
if (!valid) {
|
||||
return false;
|
||||
}
|
||||
this.loading = true;
|
||||
addUserFile({
|
||||
...this.form,
|
||||
parentId: this.parentId,
|
||||
isDirectory: 1
|
||||
})
|
||||
.then((msg) => {
|
||||
this.loading = false;
|
||||
this.$message.success(msg);
|
||||
this.updateVisible(false);
|
||||
this.$emit('done');
|
||||
})
|
||||
.catch((e) => {
|
||||
this.loading = false;
|
||||
this.$message.error(e.message);
|
||||
});
|
||||
});
|
||||
},
|
||||
/* 更新 visible */
|
||||
updateVisible(value) {
|
||||
this.$emit('update:visible', value);
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
visible(visible) {
|
||||
if (!visible) {
|
||||
this.$refs.form.clearValidate();
|
||||
this.form.name = '';
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@@ -1,97 +0,0 @@
|
||||
<template>
|
||||
<ele-modal
|
||||
width="460px"
|
||||
:visible="visible"
|
||||
:append-to-body="true"
|
||||
:close-on-click-modal="true"
|
||||
custom-class="ele-dialog-form"
|
||||
title="重命名"
|
||||
@update:visible="updateVisible"
|
||||
>
|
||||
<el-form ref="form" :model="form" :rules="rules" label-width="102px">
|
||||
<el-form-item label="文件/夹名称:" prop="name">
|
||||
<el-input
|
||||
clearable
|
||||
:maxlength="20"
|
||||
v-model="form.name"
|
||||
placeholder="请输入文件夹名称"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template v-slot:footer>
|
||||
<el-button @click="updateVisible(false)">取消</el-button>
|
||||
<el-button type="primary" :loading="loading" @click="save">
|
||||
保存
|
||||
</el-button>
|
||||
</template>
|
||||
</ele-modal>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { updateUserFile } from '@/api/system/user-file';
|
||||
|
||||
export default {
|
||||
props: {
|
||||
// 弹窗是否打开
|
||||
visible: Boolean,
|
||||
// 文件数据
|
||||
data: Object
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
// 表单数据
|
||||
form: {
|
||||
name: ''
|
||||
},
|
||||
// 表单验证规则
|
||||
rules: {
|
||||
name: [
|
||||
{
|
||||
required: true,
|
||||
message: '请输入文件/夹名称',
|
||||
trigger: 'blur'
|
||||
}
|
||||
]
|
||||
},
|
||||
// 提交状态
|
||||
loading: false
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
/* 保存编辑 */
|
||||
save() {
|
||||
this.$refs.form.validate((valid) => {
|
||||
if (!valid) {
|
||||
return false;
|
||||
}
|
||||
this.loading = true;
|
||||
updateUserFile({ ...this.form, id: this.data?.id })
|
||||
.then((msg) => {
|
||||
this.loading = false;
|
||||
this.$message.success(msg);
|
||||
this.updateVisible(false);
|
||||
this.$emit('done');
|
||||
})
|
||||
.catch((e) => {
|
||||
this.loading = false;
|
||||
this.$message.error(e.message);
|
||||
});
|
||||
});
|
||||
},
|
||||
/* 更新 visible */
|
||||
updateVisible(value) {
|
||||
this.$emit('update:visible', value);
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
visible(visible) {
|
||||
if (!visible) {
|
||||
this.$refs.form.clearValidate();
|
||||
this.form.name = '';
|
||||
} else if (this.data) {
|
||||
this.form.name = this.data.name;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@@ -1,131 +0,0 @@
|
||||
<template>
|
||||
<div class="ele-body">
|
||||
<el-card shadow="never" body-style="padding: 0;">
|
||||
<div style="padding: 16px 16px 12px 16px">
|
||||
<file-toolbar
|
||||
:grid.sync="grid"
|
||||
:checked="checked"
|
||||
:parentId="parentId"
|
||||
@done="onDone"
|
||||
/>
|
||||
<file-header
|
||||
:total="total"
|
||||
:directorys="directorys"
|
||||
@update:directorys="updateDirectorys"
|
||||
/>
|
||||
</div>
|
||||
<div v-loading="loading">
|
||||
<file-list
|
||||
:grid="grid"
|
||||
:data="data"
|
||||
:sort="sort"
|
||||
:order="order"
|
||||
:parentId="parentId"
|
||||
:checked.sync="checked"
|
||||
@sort-change="onSortChange"
|
||||
@go-directory="onGoDirectory"
|
||||
@done="onDone"
|
||||
/>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import FileToolbar from './components/file-toolbar.vue';
|
||||
import FileHeader from './components/file-header.vue';
|
||||
import FileList from './components/file-list.vue';
|
||||
import { listUserFiles } from '@/api/system/user-file';
|
||||
|
||||
export default {
|
||||
name: 'ExtensionFile',
|
||||
components: { FileToolbar, FileHeader, FileList },
|
||||
data() {
|
||||
return {
|
||||
// 加载状态
|
||||
loading: true,
|
||||
// 文件列表数据
|
||||
data: [],
|
||||
// 排序字段
|
||||
sort: '',
|
||||
// 排序方式
|
||||
order: '',
|
||||
// 选中数据
|
||||
checked: [],
|
||||
// 文件夹数据
|
||||
directorys: [],
|
||||
// 总文件数
|
||||
total: 0,
|
||||
// 是否网格展示
|
||||
grid: true,
|
||||
// 父级 id
|
||||
parentId: 0
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.query();
|
||||
},
|
||||
methods: {
|
||||
/* 查询文件列表 */
|
||||
query() {
|
||||
this.data = [];
|
||||
this.checked = [];
|
||||
this.loading = true;
|
||||
listUserFiles({
|
||||
sort: this.order ? this.sort : '',
|
||||
order: this.order,
|
||||
parentId: this.parentId
|
||||
})
|
||||
.then((list) => {
|
||||
this.loading = false;
|
||||
this.data = list.map((d) => {
|
||||
return Object.assign({ name: d.name }, d, {
|
||||
isDirectory: d.isDirectory === 1 ? true : false,
|
||||
length: this.formatLength(d.length)
|
||||
});
|
||||
});
|
||||
this.total = list.length;
|
||||
})
|
||||
.catch((e) => {
|
||||
this.loading = false;
|
||||
this.$message.error(e.message);
|
||||
});
|
||||
},
|
||||
/* 刷新列表数据 */
|
||||
onDone() {
|
||||
this.query();
|
||||
},
|
||||
/* 文件列表排序方式改变 */
|
||||
onSortChange(option) {
|
||||
this.order = option.order;
|
||||
this.sort = option.sort;
|
||||
this.query();
|
||||
},
|
||||
/* 进入文件夹 */
|
||||
onGoDirectory(item) {
|
||||
this.updateDirectorys([...this.directorys, item]);
|
||||
},
|
||||
/* 更新文件夹数据 */
|
||||
updateDirectorys(values) {
|
||||
this.directorys = values;
|
||||
this.parentId = this.directorys[this.directorys.length - 1]?.id ?? 0;
|
||||
this.query();
|
||||
},
|
||||
/* 格式化文件大小 */
|
||||
formatLength(length) {
|
||||
if (length == null) {
|
||||
return '-';
|
||||
}
|
||||
if (length < 1024) {
|
||||
return length + 'B';
|
||||
} else if (length < 1024 * 1024) {
|
||||
return (length / 1024).toFixed(1) + 'KB';
|
||||
} else if (length < 1024 * 1024 * 1024) {
|
||||
return (length / 1024 / 1024).toFixed(1) + 'M';
|
||||
} else {
|
||||
return (length / 1024 / 1024 / 1024).toFixed(1) + 'G';
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@@ -1,227 +0,0 @@
|
||||
<template>
|
||||
<div :class="['ele-body', { 'demo-icon-responsive': styleResponsive }]">
|
||||
<el-alert
|
||||
show-icon
|
||||
type="info"
|
||||
:title="tips"
|
||||
:closable="true"
|
||||
class="ele-alert-border"
|
||||
style="margin-bottom: 10px"
|
||||
/>
|
||||
<el-card shadow="never" body-style="padding: 0;" style="overflow: visible">
|
||||
<div class="demo-icon-header ele-bg-white">
|
||||
<el-tabs
|
||||
:value="active"
|
||||
class="demo-icon-tabs"
|
||||
@tab-click="onTabChange"
|
||||
>
|
||||
<el-tab-pane
|
||||
v-for="(item, index) in data"
|
||||
:key="index"
|
||||
:label="item.title"
|
||||
:name="String(index)"
|
||||
/>
|
||||
</el-tabs>
|
||||
<div class="demo-icon-search">
|
||||
<el-input
|
||||
clearable
|
||||
size="small"
|
||||
v-model="keywords"
|
||||
suffix-icon="el-icon-search"
|
||||
placeholder="输入关键词搜索"
|
||||
@input="onSearchChange"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div style="padding: 15px">
|
||||
<el-row v-if="result.length" class="demo-icon">
|
||||
<el-col
|
||||
v-for="(d, i) in result"
|
||||
:key="i"
|
||||
v-bind="styleResponsive ? { md: 4, sm: 6, xs: 8 } : { span: 4 }"
|
||||
class="demo-icon-item"
|
||||
v-clipboard:copy="d"
|
||||
v-clipboard:error="onError"
|
||||
v-clipboard:success="onCopy"
|
||||
>
|
||||
<div class="demo-icon-content">
|
||||
<i :class="d"></i>
|
||||
</div>
|
||||
<div class="demo-icon-text ele-text-secondary">{{ d }}</div>
|
||||
<div class="demo-icon-tip ele-bg-primary">点击复制</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<ele-empty v-else />
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import icons from 'ele-admin/es/ele-icon-picker/icons';
|
||||
|
||||
export default {
|
||||
name: 'ExtensionIcon',
|
||||
data() {
|
||||
let elNum = 0;
|
||||
let eleNum = 0;
|
||||
icons.forEach((item) => {
|
||||
item.icons.forEach((d) => {
|
||||
if (d.indexOf('el-icon-_') === 0) {
|
||||
eleNum++;
|
||||
} else {
|
||||
elNum++;
|
||||
}
|
||||
});
|
||||
});
|
||||
const total = elNum + eleNum;
|
||||
return {
|
||||
// 图标数据
|
||||
data: icons,
|
||||
// 搜索关键字
|
||||
keywords: '',
|
||||
// 当前显示的图标
|
||||
result: icons[0]?.icons,
|
||||
// 页签选中
|
||||
active: '0',
|
||||
// 提示文字
|
||||
tips: `新增 ${eleNum} 个图标 + Element UI ${elNum} 个图标, 共计 ${total} 个图标`
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
// 是否开启响应式布局
|
||||
styleResponsive() {
|
||||
return this.$store.state.theme.styleResponsive;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
/* 页签切换事件 */
|
||||
onTabChange(obj) {
|
||||
if (this.active !== obj.name) {
|
||||
this.active = obj.name;
|
||||
const temp = this.data[this.active].icons;
|
||||
if (this.keywords) {
|
||||
this.result = temp.filter((d) => d.includes(this.keywords));
|
||||
} else {
|
||||
this.result = temp;
|
||||
}
|
||||
}
|
||||
},
|
||||
/* 输入框改变事件 */
|
||||
onSearchChange() {
|
||||
for (let i = 0; i < this.data.length; i++) {
|
||||
const temp = this.data[i].icons;
|
||||
const result = temp.filter((d) => d.includes(this.keywords));
|
||||
if (result.length) {
|
||||
this.active = String(i);
|
||||
this.result = result;
|
||||
return;
|
||||
}
|
||||
}
|
||||
this.result = [];
|
||||
},
|
||||
/* 复制成功 */
|
||||
onCopy() {
|
||||
this.$message.success('复制成功');
|
||||
},
|
||||
/* 复制失败 */
|
||||
onError() {
|
||||
this.$message.error('复制失败');
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.demo-icon-header {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
border-radius: 4px;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
/* 选项卡 */
|
||||
.demo-icon-tabs {
|
||||
:deep(.el-tabs__nav-scroll) {
|
||||
padding: 0 0 0 30px;
|
||||
}
|
||||
|
||||
:deep(.el-tabs__item) {
|
||||
height: 48px;
|
||||
line-height: 48px;
|
||||
padding: 0 30px 0 0 !important;
|
||||
}
|
||||
|
||||
:deep(.el-tabs__item:focus.is-active.is-focus:not(:active)) {
|
||||
box-shadow: none;
|
||||
}
|
||||
}
|
||||
|
||||
/* 搜索框 */
|
||||
.demo-icon-search {
|
||||
position: absolute;
|
||||
top: 8px;
|
||||
right: 15px;
|
||||
width: 180px;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 660px) {
|
||||
.demo-icon-responsive .demo-icon-search {
|
||||
width: auto;
|
||||
position: static;
|
||||
margin: 10px 10px 0 10px;
|
||||
}
|
||||
}
|
||||
|
||||
/* 图标 */
|
||||
.demo-icon {
|
||||
border-top: 1px solid hsla(0, 0%, 60%, 0.15);
|
||||
border-left: 1px solid hsla(0, 0%, 60%, 0.15);
|
||||
}
|
||||
|
||||
.demo-icon-item {
|
||||
text-align: center;
|
||||
padding: 24px 0;
|
||||
border-right: 1px solid hsla(0, 0%, 60%, 0.15);
|
||||
border-bottom: 1px solid hsla(0, 0%, 60%, 0.15);
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
cursor: pointer;
|
||||
|
||||
& > .demo-icon-content > i {
|
||||
font-size: 38px;
|
||||
}
|
||||
|
||||
& > .demo-icon-text {
|
||||
padding: 0 5px;
|
||||
font-size: 14px;
|
||||
margin-top: 8px;
|
||||
white-space: nowrap;
|
||||
word-break: break-all;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
& > .demo-icon-tip {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: -30px;
|
||||
color: #fff;
|
||||
padding: 4px 0;
|
||||
font-size: 12px;
|
||||
transition: bottom 0.2s;
|
||||
}
|
||||
|
||||
&:hover > .demo-icon-tip {
|
||||
bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.ele-admin-fixed-header:not(.ele-admin-fixed-body)) {
|
||||
.demo-icon-header {
|
||||
top: 100px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,100 +0,0 @@
|
||||
<template>
|
||||
<el-card shadow="never" header="官网底部地图">
|
||||
<div ref="locationMap" style="max-width: 800px; height: 300px"></div>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import AMapLoader from '@amap/amap-jsapi-loader';
|
||||
import { MAP_KEY } from '@/config/setting';
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
// 官网底部地图的实例
|
||||
mapInsLocation: null
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
// 是否是暗黑模式
|
||||
darkMode() {
|
||||
return this.$store?.state?.theme?.darkMode;
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.renderLocationMap();
|
||||
},
|
||||
methods: {
|
||||
/* 渲染官网底部地图 */
|
||||
renderLocationMap() {
|
||||
AMapLoader.load({
|
||||
key: MAP_KEY,
|
||||
version: '2.0',
|
||||
plugins: ['AMap.InfoWindow', 'AMap.Marker']
|
||||
})
|
||||
.then((AMap) => {
|
||||
// 渲染地图
|
||||
const option = {
|
||||
zoom: 13, // 初缩放级别
|
||||
center: [114.346084, 30.511215 + 0.005] // 初始中心点
|
||||
};
|
||||
if (this.darkMode) {
|
||||
option.mapStyle = 'amap://styles/dark';
|
||||
}
|
||||
this.mapInsLocation = new AMap.Map(this.$refs.locationMap, option);
|
||||
// 创建信息窗体
|
||||
const infoWindow = new AMap.InfoWindow({
|
||||
content: `
|
||||
<div style="color: #333;">
|
||||
<div style="padding: 5px;font-size: 16px;">武汉易云智科技有限公司</div>
|
||||
<div style="padding: 0 5px;">地址: 湖北省武汉市洪山区雄楚大道222号</div>
|
||||
<div style="padding: 0 5px;">电话: 020-123456789</div>
|
||||
</div>
|
||||
<a
|
||||
style="padding: 8px 5px 0;text-decoration: none;display: inline-block;"
|
||||
href="//uri.amap.com/marker?position=114.346084,30.511215&name=武汉易云智科技有限公司"
|
||||
class="ele-text-primary"
|
||||
target="_blank"
|
||||
>到这里去→</a>
|
||||
`
|
||||
});
|
||||
infoWindow.open(this.mapInsLocation, [114.346084, 30.511215]);
|
||||
const icon = new AMap.Icon({
|
||||
size: new AMap.Size(25, 34),
|
||||
image:
|
||||
'//a.amap.com/jsapi_demos/static/demo-center/icons/poi-marker-red.png',
|
||||
imageSize: new AMap.Size(25, 34)
|
||||
});
|
||||
const marker = new AMap.Marker({
|
||||
icon: icon,
|
||||
position: [114.346084, 30.511215],
|
||||
offset: new AMap.Pixel(-12, -28)
|
||||
});
|
||||
marker.setMap(this.mapInsLocation);
|
||||
marker.on('click', () => {
|
||||
infoWindow.open(this.mapInsLocation);
|
||||
});
|
||||
})
|
||||
.catch((e) => {
|
||||
console.error(e);
|
||||
});
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
darkMode(value) {
|
||||
if (this.mapInsLocation) {
|
||||
if (value) {
|
||||
this.mapInsLocation.setMapStyle('amap://styles/dark');
|
||||
} else {
|
||||
this.mapInsLocation.setMapStyle('amap://styles/normal');
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
unmounted() {
|
||||
if (this.mapInsLocation) {
|
||||
this.mapInsLocation.destroy();
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@@ -1,76 +0,0 @@
|
||||
<template>
|
||||
<el-card shadow="never" header="地图位置选择器">
|
||||
<div style="display: flex; align-items: center">
|
||||
<div style="width: 140px; margin-right: 12px">
|
||||
<el-select size="small" class="ele-fluid" v-model="searchType">
|
||||
<el-option label="POI检索模式" :value="0" />
|
||||
<el-option label="关键字检索模式" :value="1" />
|
||||
</el-select>
|
||||
</div>
|
||||
<el-button size="small" class="ele-btn-icon" @click="openMapPicker">
|
||||
打开地图位置选择器
|
||||
</el-button>
|
||||
</div>
|
||||
<div style="margin-top: 12px">选择位置: {{ result.location }}</div>
|
||||
<div style="margin-top: 12px">详细地址: {{ result.address }}</div>
|
||||
<div style="margin-top: 12px"> 经 纬 度 : {{ result.coordinate }}</div>
|
||||
<!-- 地图位置选择弹窗 -->
|
||||
<ele-map-picker
|
||||
:need-city="true"
|
||||
:show.sync="visible"
|
||||
:lock-scroll="false"
|
||||
:close-on-click-modal="false"
|
||||
:search-type="searchType"
|
||||
:dark-mode="darkMode"
|
||||
@done="onChoose"
|
||||
/>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import EleMapPicker from 'ele-admin/es/ele-map-picker';
|
||||
|
||||
export default {
|
||||
components: { EleMapPicker },
|
||||
data() {
|
||||
return {
|
||||
// 是否显示地图选择弹窗
|
||||
visible: false,
|
||||
// 地点检索类型
|
||||
searchType: 0,
|
||||
// 选择结果
|
||||
result: {
|
||||
location: '',
|
||||
address: '',
|
||||
coordinate: ''
|
||||
}
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
// 是否是暗黑模式
|
||||
darkMode() {
|
||||
return this.$store?.state?.theme?.darkMode;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
/* 地图选择后回调 */
|
||||
onChoose(location) {
|
||||
console.log(location);
|
||||
this.result = {
|
||||
location: [
|
||||
location.city.province,
|
||||
location.city.city,
|
||||
location.city.district
|
||||
].join('/'),
|
||||
address: location.name + ' ' + location.address,
|
||||
coordinate: location.lng + ',' + location.lat
|
||||
};
|
||||
this.visible = false;
|
||||
},
|
||||
/* 打开地图选择弹窗 */
|
||||
openMapPicker() {
|
||||
this.visible = true;
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@@ -1,151 +0,0 @@
|
||||
<template>
|
||||
<el-card shadow="never" header="轨迹回放">
|
||||
<div ref="trackMap" style="max-width: 800px; height: 300px"></div>
|
||||
<div style="margin-top: 15px">
|
||||
<el-button size="small" @click="startTrackAnim">开始移动</el-button>
|
||||
<el-button size="small" @click="pauseTrackAnim">暂停移动</el-button>
|
||||
<el-button size="small" @click="resumeTrackAnim">继续移动</el-button>
|
||||
</div>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import AMapLoader from '@amap/amap-jsapi-loader';
|
||||
import { MAP_KEY } from '@/config/setting';
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
// 小车轨迹地图的实例
|
||||
mapInsTrack: null,
|
||||
// 小车的 marker
|
||||
carMarker: null,
|
||||
// 轨迹路线
|
||||
lineData: [
|
||||
[116.478935, 39.997761],
|
||||
[116.478939, 39.997825],
|
||||
[116.478912, 39.998549],
|
||||
[116.478912, 39.998549],
|
||||
[116.478998, 39.998555],
|
||||
[116.478998, 39.998555],
|
||||
[116.479282, 39.99856],
|
||||
[116.479658, 39.998528],
|
||||
[116.480151, 39.998453],
|
||||
[116.480784, 39.998302],
|
||||
[116.480784, 39.998302],
|
||||
[116.481149, 39.998184],
|
||||
[116.481573, 39.997997],
|
||||
[116.481863, 39.997846],
|
||||
[116.482072, 39.997718],
|
||||
[116.482362, 39.997718],
|
||||
[116.483633, 39.998935],
|
||||
[116.48367, 39.998968],
|
||||
[116.484648, 39.999861]
|
||||
]
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
// 是否是暗黑模式
|
||||
darkMode() {
|
||||
return this.$store?.state?.theme?.darkMode;
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.renderTrackMap();
|
||||
},
|
||||
methods: {
|
||||
/* 渲染轨迹回放地图 */
|
||||
renderTrackMap() {
|
||||
AMapLoader.load({
|
||||
key: MAP_KEY,
|
||||
version: '2.0',
|
||||
plugins: ['AMap.MoveAnimation', 'AMap.Marker', 'AMap.Polyline']
|
||||
})
|
||||
.then((AMap) => {
|
||||
// 渲染地图
|
||||
const option = {
|
||||
zoom: 17,
|
||||
center: [116.478935, 39.997761]
|
||||
};
|
||||
if (this.darkMode) {
|
||||
option.mapStyle = 'amap://styles/dark';
|
||||
}
|
||||
this.mapInsTrack = new AMap.Map(this.$refs.trackMap, option);
|
||||
// 创建小车 marker
|
||||
this.carMarker = new AMap.Marker({
|
||||
map: this.mapInsTrack,
|
||||
position: [116.478935, 39.997761],
|
||||
icon: 'https://a.amap.com/jsapi_demos/static/demo-center-v2/car.png',
|
||||
offset: new AMap.Pixel(-13, -26)
|
||||
});
|
||||
// 绘制轨迹
|
||||
new AMap.Polyline({
|
||||
map: this.mapInsTrack,
|
||||
path: this.lineData,
|
||||
showDir: true,
|
||||
strokeColor: '#28F', // 线颜色
|
||||
strokeOpacity: 1, // 线透明度
|
||||
strokeWeight: 6 // 线宽
|
||||
//strokeStyle: 'solid' // 线样式
|
||||
});
|
||||
// 通过的轨迹
|
||||
const passedPolyline = new AMap.Polyline({
|
||||
map: this.mapInsTrack,
|
||||
showDir: true,
|
||||
strokeColor: '#4B5', // 线颜色
|
||||
strokeOpacity: 1, // 线透明度
|
||||
strokeWeight: 6 // 线宽
|
||||
});
|
||||
// 小车移动回调
|
||||
this.carMarker.on('moving', function (e) {
|
||||
passedPolyline.setPath(e.passedPath);
|
||||
});
|
||||
// 地图自适应
|
||||
this.mapInsTrack.setFitView();
|
||||
})
|
||||
.catch((e) => {
|
||||
console.error(e);
|
||||
});
|
||||
},
|
||||
/* 开始轨迹回放动画 */
|
||||
startTrackAnim() {
|
||||
if (this.carMarker) {
|
||||
this.carMarker.stopMove();
|
||||
this.carMarker.moveAlong(this.lineData, {
|
||||
duration: 200,
|
||||
autoRotation: true
|
||||
});
|
||||
}
|
||||
},
|
||||
/* 暂停轨迹回放动画 */
|
||||
pauseTrackAnim() {
|
||||
if (this.carMarker) {
|
||||
this.carMarker.pauseMove();
|
||||
}
|
||||
},
|
||||
/* 继续开始轨迹回放动画 */
|
||||
resumeTrackAnim() {
|
||||
if (this.carMarker) {
|
||||
this.carMarker.resumeMove();
|
||||
}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
darkMode(value) {
|
||||
if (this.mapInsTrack) {
|
||||
if (value) {
|
||||
this.mapInsTrack.setMapStyle('amap://styles/dark');
|
||||
} else {
|
||||
this.mapInsTrack.setMapStyle('amap://styles/normal');
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
unmounted() {
|
||||
if (this.mapInsTrack) {
|
||||
this.mapInsTrack.destroy();
|
||||
}
|
||||
this.carMarker = null;
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@@ -1,18 +0,0 @@
|
||||
<template>
|
||||
<div class="ele-body">
|
||||
<demo-picker />
|
||||
<demo-map />
|
||||
<demo-track />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import DemoPicker from './components/demo-picker.vue';
|
||||
import DemoMap from './components/demo-map.vue';
|
||||
import DemoTrack from './components/demo-track.vue';
|
||||
|
||||
export default {
|
||||
name: 'ExtensionMap',
|
||||
components: { DemoPicker, DemoMap, DemoTrack }
|
||||
};
|
||||
</script>
|
||||
@@ -1,103 +0,0 @@
|
||||
<template>
|
||||
<div class="ele-body">
|
||||
<el-card shadow="never">
|
||||
<!-- 按钮 -->
|
||||
<div style="margin-bottom: 16px">
|
||||
<el-button size="small" @click="setContent">修改内容</el-button>
|
||||
<el-button size="small" @click="showText">获取内容</el-button>
|
||||
</div>
|
||||
<!-- 编辑器 -->
|
||||
<byte-md-editor
|
||||
:value="content"
|
||||
:locale="zh_Hans"
|
||||
:plugins="plugins"
|
||||
:editorConfig="{ lineNumbers: true }"
|
||||
class="ele-bytemd-wrap"
|
||||
@change="handleChange"
|
||||
/>
|
||||
</el-card>
|
||||
<!-- 内容弹窗 -->
|
||||
<ele-modal width="400px" title="编辑器内容" :visible.sync="showViewContent">
|
||||
<div>{{ content }}</div>
|
||||
</ele-modal>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { Editor as ByteMdEditor } from '@bytemd/vue';
|
||||
// 中文语言文件
|
||||
import zh_Hans from 'bytemd/lib/locales/zh_Hans.json';
|
||||
// 链接、删除线、复选框、表格等的插件
|
||||
import gfm from '@bytemd/plugin-gfm';
|
||||
// 插件的中文语言文件
|
||||
import zh_HansGfm from '@bytemd/plugin-gfm/lib/locales/zh_Hans.json';
|
||||
// 编辑器css
|
||||
import 'bytemd/dist/index.min.css';
|
||||
// 预览界面的样式,这里用的github的markdown主题
|
||||
import 'github-markdown-css/github-markdown-light.css';
|
||||
|
||||
export default {
|
||||
name: 'ExtensionMarkdown',
|
||||
components: { ByteMdEditor },
|
||||
data() {
|
||||
return {
|
||||
zh_Hans,
|
||||
// 编辑器内容
|
||||
content: '',
|
||||
// 插件
|
||||
plugins: [
|
||||
gfm({
|
||||
locale: zh_HansGfm
|
||||
})
|
||||
],
|
||||
showViewContent: false
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
/* 更新内容 */
|
||||
handleChange(value) {
|
||||
this.content = value;
|
||||
},
|
||||
/* 修改编辑器内容 */
|
||||
setContent() {
|
||||
this.content = '> **EleAdminPro**后台管理模板';
|
||||
},
|
||||
/* 获取编辑器内容 */
|
||||
showText() {
|
||||
this.showViewContent = true;
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
// 修改编辑器高度
|
||||
.ele-bytemd-wrap :deep(.bytemd) {
|
||||
height: calc(100vh - 290px);
|
||||
|
||||
// 修改全屏的 zIndex
|
||||
&.bytemd-fullscreen {
|
||||
z-index: 999;
|
||||
}
|
||||
|
||||
// 去掉默认的最大宽度限制
|
||||
.CodeMirror .CodeMirror-lines {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
pre.CodeMirror-line,
|
||||
pre.CodeMirror-line-like {
|
||||
padding: 0 24px;
|
||||
}
|
||||
|
||||
.markdown-body {
|
||||
max-width: 100%;
|
||||
padding: 16px 24px;
|
||||
}
|
||||
|
||||
// 去掉 github 图标
|
||||
.bytemd-toolbar-right > .bytemd-toolbar-icon:last-child {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,150 +0,0 @@
|
||||
<template>
|
||||
<div class="ele-body">
|
||||
<el-card shadow="never" header="水平导航">
|
||||
<el-radio-group v-model="dark" size="small">
|
||||
<el-radio-button :label="false">Light</el-radio-button>
|
||||
<el-radio-button :label="true">Dark</el-radio-button>
|
||||
</el-radio-group>
|
||||
<div
|
||||
style="margin: 15px 0 5px 0; overflow: auto"
|
||||
class="ele-scrollbar-hide"
|
||||
>
|
||||
<div style="max-width: 600px" class="demo-menu-wrap">
|
||||
<el-menu mode="horizontal" :class="themeClass" default-active="1-1">
|
||||
<el-submenu index="1">
|
||||
<template v-slot:title>
|
||||
<i class="el-icon-s-tools"></i>
|
||||
<span>系统管理</span>
|
||||
</template>
|
||||
<el-menu-item index="1-1">用户管理</el-menu-item>
|
||||
<el-menu-item index="1-2">角色管理</el-menu-item>
|
||||
<el-menu-item index="1-3">权限管理</el-menu-item>
|
||||
</el-submenu>
|
||||
<el-submenu index="2">
|
||||
<template v-slot:title>
|
||||
<i class="el-icon-s-opportunity"></i>
|
||||
<span>日志管理</span>
|
||||
</template>
|
||||
<el-menu-item index="2-1">登录日志</el-menu-item>
|
||||
<el-menu-item index="2-2">操作日志</el-menu-item>
|
||||
<el-menu-item index="2-3">错误日志</el-menu-item>
|
||||
</el-submenu>
|
||||
<el-submenu index="3">
|
||||
<template v-slot:title>
|
||||
<i class="el-icon-s-order"></i>
|
||||
<span>订单管理</span>
|
||||
</template>
|
||||
<el-menu-item index="3-1">
|
||||
<i class="el-icon-s-opportunity"></i>
|
||||
<span>订单查询</span>
|
||||
</el-menu-item>
|
||||
<el-menu-item index="3-2">
|
||||
<i class="el-icon-s-opportunity"></i>
|
||||
<span>退款记录</span>
|
||||
</el-menu-item>
|
||||
<el-menu-item index="3-3">
|
||||
<i class="el-icon-s-opportunity"></i>
|
||||
<span>订单报表</span>
|
||||
</el-menu-item>
|
||||
</el-submenu>
|
||||
<el-menu-item index="4">
|
||||
<i class="el-icon-s-opportunity"></i>
|
||||
<span>订单报表</span>
|
||||
</el-menu-item>
|
||||
</el-menu>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
<el-card shadow="never" header="垂直导航">
|
||||
<el-radio-group v-model="collapse" size="small">
|
||||
<el-radio-button :label="false">展开</el-radio-button>
|
||||
<el-radio-button :label="true">折叠</el-radio-button>
|
||||
</el-radio-group>
|
||||
<div style="max-width: 200px; margin: 15px 0 5px 0">
|
||||
<el-menu
|
||||
mode="vertical"
|
||||
default-active="4"
|
||||
:class="themeClass"
|
||||
:collapse="collapse"
|
||||
>
|
||||
<el-submenu index="1" :popper-class="themeClass">
|
||||
<template v-slot:title>
|
||||
<i class="el-icon-s-tools"></i>
|
||||
<span>系统管理</span>
|
||||
</template>
|
||||
<el-menu-item index="1-1">用户管理</el-menu-item>
|
||||
<el-menu-item index="1-2">角色管理</el-menu-item>
|
||||
<el-menu-item index="1-3">权限管理</el-menu-item>
|
||||
</el-submenu>
|
||||
<el-submenu index="2" :popper-class="themeClass">
|
||||
<template v-slot:title>
|
||||
<i class="el-icon-s-opportunity"></i>
|
||||
<span>日志管理</span>
|
||||
</template>
|
||||
<el-menu-item index="2-1">登录日志</el-menu-item>
|
||||
<el-menu-item index="2-2">操作日志</el-menu-item>
|
||||
<el-menu-item index="2-3">错误日志</el-menu-item>
|
||||
</el-submenu>
|
||||
<el-submenu index="3" :popper-class="themeClass">
|
||||
<template v-slot:title>
|
||||
<i class="el-icon-s-order"></i>
|
||||
<span>订单管理</span>
|
||||
</template>
|
||||
<el-menu-item index="3-1">
|
||||
<i class="el-icon-s-opportunity"></i>
|
||||
<span>订单查询</span>
|
||||
</el-menu-item>
|
||||
<el-menu-item index="3-2">
|
||||
<i class="el-icon-s-opportunity"></i>
|
||||
<span>退款记录</span>
|
||||
</el-menu-item>
|
||||
<el-menu-item index="3-3">
|
||||
<i class="el-icon-s-opportunity"></i>
|
||||
<span>订单报表</span>
|
||||
</el-menu-item>
|
||||
</el-submenu>
|
||||
<el-menu-item index="4">
|
||||
<i class="el-icon-s-opportunity"></i>
|
||||
<template v-slot:title>
|
||||
<span>订单报表</span>
|
||||
</template>
|
||||
</el-menu-item>
|
||||
</el-menu>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'ExtensionMenu',
|
||||
data() {
|
||||
return {
|
||||
dark: false,
|
||||
collapse: false
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
themeClass() {
|
||||
return this.dark ? 'ele-menu-dark' : '';
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
/* 水平菜单超出不换行显示横向滚动条 */
|
||||
.demo-menu-wrap {
|
||||
overflow-x: auto;
|
||||
overflow-y: hidden;
|
||||
|
||||
:deep(.el-menu) {
|
||||
white-space: nowrap;
|
||||
|
||||
& > li {
|
||||
float: none;
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,201 +0,0 @@
|
||||
<template>
|
||||
<div class="ele-body">
|
||||
<el-card shadow="never" header="消息提示">
|
||||
<div style="margin: 0 0 10px 0">边框风格</div>
|
||||
<div class="ele-action-group">
|
||||
<el-button size="small" @click="showSuccessMessage(true)">
|
||||
成功
|
||||
</el-button>
|
||||
<el-button size="small" @click="showWarningMessage(true)">
|
||||
警告
|
||||
</el-button>
|
||||
<el-button size="small" @click="showErrorMessage(true)">错误</el-button>
|
||||
<el-button size="small" @click="showInfoMessage(true)">消息</el-button>
|
||||
</div>
|
||||
<div style="margin: 20px 0 10px 0">清新风格</div>
|
||||
<div class="ele-action-group">
|
||||
<el-button size="small" @click="showSuccessMessage(false)">
|
||||
成功
|
||||
</el-button>
|
||||
<el-button size="small" @click="showWarningMessage(false)">
|
||||
警告
|
||||
</el-button>
|
||||
<el-button size="small" @click="showErrorMessage(false)">
|
||||
错误
|
||||
</el-button>
|
||||
<el-button size="small" @click="showInfoMessage(false)">消息</el-button>
|
||||
</div>
|
||||
<div>
|
||||
<div style="margin: 20px 0 10px 0">loading</div>
|
||||
<div class="ele-action-group">
|
||||
<el-button size="small" @click="showLoadingMessage1">
|
||||
Loading
|
||||
</el-button>
|
||||
<el-button size="small" @click="showLoadingMessage2">
|
||||
加遮罩层
|
||||
</el-button>
|
||||
<el-button size="small" @click="showLoadingMessage3">
|
||||
居中显示
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
<el-card
|
||||
shadow="never"
|
||||
header="警告组件"
|
||||
body-style="padding: 20px 20px 0 20px;"
|
||||
>
|
||||
<el-row :gutter="20">
|
||||
<el-col
|
||||
v-bind="styleResponsive ? { md: 6, sm: 12, xs: 24 } : { span: 6 }"
|
||||
>
|
||||
<el-alert
|
||||
show-icon
|
||||
type="success"
|
||||
title="Success Tips"
|
||||
class="ele-alert-border"
|
||||
/>
|
||||
<el-alert
|
||||
show-icon
|
||||
type="success"
|
||||
title="Success Tips"
|
||||
class="ele-alert-border"
|
||||
description="Detailed description and advice about successful copywriting."
|
||||
/>
|
||||
</el-col>
|
||||
<el-col
|
||||
v-bind="styleResponsive ? { md: 6, sm: 12, xs: 24 } : { span: 6 }"
|
||||
>
|
||||
<el-alert
|
||||
show-icon
|
||||
type="info"
|
||||
class="ele-alert-border"
|
||||
title="Informational Notes"
|
||||
/>
|
||||
<el-alert
|
||||
show-icon
|
||||
type="info"
|
||||
class="ele-alert-border"
|
||||
title="Informational Notes"
|
||||
description="Additional description and information about copywriting."
|
||||
/>
|
||||
</el-col>
|
||||
<el-col
|
||||
v-bind="styleResponsive ? { md: 6, sm: 12, xs: 24 } : { span: 6 }"
|
||||
>
|
||||
<el-alert
|
||||
show-icon
|
||||
type="warning"
|
||||
title="Warning"
|
||||
class="ele-alert-border"
|
||||
/>
|
||||
<el-alert
|
||||
show-icon
|
||||
type="warning"
|
||||
title="Warning"
|
||||
class="ele-alert-border"
|
||||
description="This is a warning notice about copywriting."
|
||||
/>
|
||||
</el-col>
|
||||
<el-col
|
||||
v-bind="styleResponsive ? { md: 6, sm: 12, xs: 24 } : { span: 6 }"
|
||||
>
|
||||
<el-alert
|
||||
show-icon
|
||||
type="error"
|
||||
title="Error"
|
||||
class="ele-alert-border"
|
||||
/>
|
||||
<el-alert
|
||||
show-icon
|
||||
type="error"
|
||||
title="Error"
|
||||
class="ele-alert-border"
|
||||
description="This is an error message about copywriting."
|
||||
/>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'ExtensionMessage',
|
||||
computed: {
|
||||
// 是否开启响应式布局
|
||||
styleResponsive() {
|
||||
return this.$store.state.theme.styleResponsive;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
showSuccessMessage(border) {
|
||||
this.$message({
|
||||
type: 'success',
|
||||
message: '这是一条成功的提示',
|
||||
customClass: border ? 'ele-message-border' : ''
|
||||
});
|
||||
},
|
||||
showWarningMessage(border) {
|
||||
this.$message({
|
||||
type: 'warning',
|
||||
message: '这是一条警告的提示',
|
||||
customClass: border ? 'ele-message-border' : ''
|
||||
});
|
||||
},
|
||||
showErrorMessage(border) {
|
||||
if (border) {
|
||||
this.$message({
|
||||
type: 'error',
|
||||
message: '这是一条错误的提示',
|
||||
customClass: 'ele-message-border'
|
||||
});
|
||||
} else {
|
||||
this.$message.error('这是一条错误的提示');
|
||||
}
|
||||
},
|
||||
showInfoMessage(border) {
|
||||
if (border) {
|
||||
this.$message({
|
||||
type: 'info',
|
||||
message: '这是一条普通的提示',
|
||||
customClass: 'ele-message-border'
|
||||
});
|
||||
} else {
|
||||
this.$message.info('这是一条普通的提示');
|
||||
}
|
||||
},
|
||||
showLoadingMessage1() {
|
||||
const loading = this.$messageLoading('正在加载中..');
|
||||
setTimeout(() => {
|
||||
loading.close();
|
||||
}, 3000);
|
||||
},
|
||||
showLoadingMessage2() {
|
||||
const loading = this.$messageLoading({
|
||||
message: '正在加载中..',
|
||||
background: true
|
||||
});
|
||||
setTimeout(() => {
|
||||
loading.close();
|
||||
}, 3000);
|
||||
},
|
||||
showLoadingMessage3() {
|
||||
const loading = this.$messageLoading({
|
||||
message: '正在加载中..',
|
||||
background: true,
|
||||
center: true
|
||||
});
|
||||
setTimeout(() => {
|
||||
loading.close();
|
||||
}, 3000);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.ele-alert-border {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
</style>
|
||||
@@ -1,82 +0,0 @@
|
||||
<template>
|
||||
<el-card shadow="never" header="基础演示">
|
||||
<!-- 操作按钮 -->
|
||||
<div style="margin-bottom: 10px" class="ele-action-group">
|
||||
<el-button size="mini" :disabled="!ready" @click="play">播放</el-button>
|
||||
<el-button size="mini" :disabled="!ready" @click="pause">暂停</el-button>
|
||||
<el-button size="mini" :disabled="!ready" @click="replay">
|
||||
重新播放
|
||||
</el-button>
|
||||
<el-button size="mini" :disabled="!ready" @click="changeSrc">
|
||||
切换视频源
|
||||
</el-button>
|
||||
</div>
|
||||
<!-- 播放器 -->
|
||||
<xgplayer :config="config" @player="onPlayer" />
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Xgplayer from 'xgplayer-vue';
|
||||
|
||||
export default {
|
||||
components: { Xgplayer },
|
||||
data() {
|
||||
return {
|
||||
// 视频播放器配置
|
||||
config: {
|
||||
id: 'demoPlayer1',
|
||||
lang: 'zh-cn',
|
||||
// 宽度 100%
|
||||
fluid: true,
|
||||
// 视频地址
|
||||
url: 'https://s1.pstatp.com/cdn/expire-1-M/byted-player-videos/1.0.0/xgplayer-demo.mp4',
|
||||
// 封面
|
||||
poster:
|
||||
'https://imgcache.qq.com/open_proj/proj_qcloud_v2/gateway/solution/general-video/css/img/scene/1.png',
|
||||
// 开启倍速播放
|
||||
playbackRate: [0.5, 1, 1.5, 2],
|
||||
// 开启画中画
|
||||
pip: true
|
||||
},
|
||||
// 视频播放器实例
|
||||
player: null,
|
||||
// 视频播放器是否实例化完成
|
||||
ready: false
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
/* 播放器渲染完成 */
|
||||
onPlayer(e) {
|
||||
this.player = e;
|
||||
this.player.on('play', () => {
|
||||
this.ready = true;
|
||||
});
|
||||
},
|
||||
/* 播放 */
|
||||
play() {
|
||||
if (this.player.paused) {
|
||||
this.player.play();
|
||||
}
|
||||
},
|
||||
/* 暂停 */
|
||||
pause() {
|
||||
if (!this.player.paused) {
|
||||
this.player.pause();
|
||||
}
|
||||
},
|
||||
/* 重新播放 */
|
||||
replay() {
|
||||
this.player.replay();
|
||||
},
|
||||
/* 切换视频源 */
|
||||
changeSrc() {
|
||||
this.player.src =
|
||||
'https://blz-videos.nosdn.127.net/1/OverWatch/AnimatedShots/Overwatch_TheatricalTeaser_WeAreOverwatch_zhCN.mp4';
|
||||
if (this.player.paused) {
|
||||
this.player.play();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@@ -1,243 +0,0 @@
|
||||
<template>
|
||||
<el-card shadow="never" header="弹幕功能">
|
||||
<!-- 操作按钮 -->
|
||||
<div style="margin-bottom: 10px" class="ele-action-group">
|
||||
<div style="display: inline-block; width: 160px" class="ele-action">
|
||||
<el-input
|
||||
v-model="text"
|
||||
placeholder="请输入弹幕内容"
|
||||
size="mini"
|
||||
:disabled="!ready"
|
||||
/>
|
||||
</div>
|
||||
<el-button size="mini" :disabled="!ready" @click="shoot">发射</el-button>
|
||||
</div>
|
||||
<!-- 播放器 -->
|
||||
<xgplayer :config="config" @player="onPlayer" />
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Xgplayer from 'xgplayer-vue';
|
||||
|
||||
export default {
|
||||
components: { Xgplayer },
|
||||
data() {
|
||||
return {
|
||||
// 视频播放器配置
|
||||
config: {
|
||||
id: 'demoPlayer2',
|
||||
lang: 'zh-cn',
|
||||
fluid: true,
|
||||
url: 'https://blz-videos.nosdn.127.net/1/OverWatch/AnimatedShots/Overwatch_TheatricalTeaser_WeAreOverwatch_zhCN.mp4',
|
||||
poster:
|
||||
'https://imgcache.qq.com/open_proj/proj_qcloud_v2/gateway/solution/general-video/css/img/scene/1.png',
|
||||
danmu: {
|
||||
comments: [
|
||||
{
|
||||
id: '1',
|
||||
start: 0,
|
||||
txt: '空降',
|
||||
duration: 15000,
|
||||
color: true,
|
||||
style: {
|
||||
color: '#ffcd08',
|
||||
fontSize: '20px'
|
||||
}
|
||||
},
|
||||
{
|
||||
id: '2',
|
||||
start: 1500,
|
||||
txt: '前方高能',
|
||||
duration: 15000,
|
||||
color: true,
|
||||
style: {
|
||||
color: '#ffcd08',
|
||||
fontSize: '20px'
|
||||
}
|
||||
},
|
||||
{
|
||||
id: '3',
|
||||
start: 3500,
|
||||
txt: '弹幕护体',
|
||||
duration: 15000,
|
||||
color: true,
|
||||
style: {
|
||||
color: '#ffcd08',
|
||||
fontSize: '20px'
|
||||
}
|
||||
},
|
||||
{
|
||||
id: '4',
|
||||
start: 4500,
|
||||
txt: '弹幕护体',
|
||||
duration: 15000,
|
||||
color: true,
|
||||
style: {
|
||||
color: '#ffcd08',
|
||||
fontSize: '20px'
|
||||
}
|
||||
},
|
||||
{
|
||||
id: '5',
|
||||
start: 6000,
|
||||
txt: '前方高能',
|
||||
duration: 15000,
|
||||
color: true,
|
||||
style: {
|
||||
color: '#ffcd08',
|
||||
fontSize: '20px'
|
||||
}
|
||||
},
|
||||
{
|
||||
id: '6',
|
||||
start: 8500,
|
||||
txt: '弹幕护体',
|
||||
duration: 15000,
|
||||
color: true,
|
||||
style: {
|
||||
color: '#ffcd08',
|
||||
fontSize: '20px'
|
||||
}
|
||||
},
|
||||
{
|
||||
id: '7',
|
||||
start: 10000,
|
||||
txt: '666666666',
|
||||
duration: 15000,
|
||||
color: true,
|
||||
style: {
|
||||
color: '#ffcd08',
|
||||
fontSize: '20px'
|
||||
}
|
||||
},
|
||||
{
|
||||
id: '8',
|
||||
start: 12500,
|
||||
txt: '前方高能',
|
||||
duration: 15000,
|
||||
color: true,
|
||||
style: {
|
||||
color: '#ffcd08',
|
||||
fontSize: '20px'
|
||||
}
|
||||
},
|
||||
{
|
||||
id: '9',
|
||||
start: 15500,
|
||||
txt: '666666666',
|
||||
duration: 15000,
|
||||
color: true,
|
||||
style: {
|
||||
color: '#ffcd08',
|
||||
fontSize: '20px'
|
||||
}
|
||||
},
|
||||
{
|
||||
id: '10',
|
||||
start: 16500,
|
||||
txt: '666666666',
|
||||
duration: 15000,
|
||||
color: true,
|
||||
style: {
|
||||
color: '#ffcd08',
|
||||
fontSize: '20px'
|
||||
}
|
||||
},
|
||||
{
|
||||
id: '11',
|
||||
start: 18000,
|
||||
txt: '关弹幕, 保智商',
|
||||
duration: 15000,
|
||||
color: true,
|
||||
style: {
|
||||
color: '#ffcd08',
|
||||
fontSize: '20px'
|
||||
}
|
||||
},
|
||||
{
|
||||
id: '12',
|
||||
start: 20500,
|
||||
txt: '关弹幕, 保智商',
|
||||
duration: 15000,
|
||||
color: true,
|
||||
style: {
|
||||
color: '#ffcd08',
|
||||
fontSize: '20px'
|
||||
}
|
||||
},
|
||||
{
|
||||
id: '13',
|
||||
start: 22000,
|
||||
txt: '666666666',
|
||||
duration: 15000,
|
||||
color: true,
|
||||
style: {
|
||||
color: '#ffcd08',
|
||||
fontSize: '20px'
|
||||
}
|
||||
},
|
||||
{
|
||||
id: '14',
|
||||
start: 25500,
|
||||
txt: '666666666',
|
||||
duration: 15000,
|
||||
color: true,
|
||||
style: {
|
||||
color: '#ffcd08',
|
||||
fontSize: '20px'
|
||||
}
|
||||
},
|
||||
{
|
||||
id: '15',
|
||||
start: 26000,
|
||||
txt: '前方高能',
|
||||
duration: 15000,
|
||||
color: true,
|
||||
style: {
|
||||
color: '#ffcd08',
|
||||
fontSize: '20px'
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
// 视频播放器实例
|
||||
player: null,
|
||||
// 视频播放器是否实例化完成
|
||||
ready: false,
|
||||
// 弹幕输入内容
|
||||
text: ''
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
/* 播放器渲染完成 */
|
||||
onPlayer(e) {
|
||||
this.player = e;
|
||||
this.player.on('play', () => {
|
||||
this.ready = true;
|
||||
});
|
||||
},
|
||||
/* 发射弹幕 */
|
||||
shoot() {
|
||||
if (!this.text) {
|
||||
this.$message.error('请输入弹幕内容');
|
||||
return;
|
||||
}
|
||||
this.player.danmu.sendComment({
|
||||
id: new Date().getTime(),
|
||||
duration: 15000,
|
||||
color: true,
|
||||
start: this.player.currentTime * 1000,
|
||||
txt: this.text,
|
||||
style: {
|
||||
color: '#fa1f41',
|
||||
fontSize: '20px',
|
||||
border: 'solid 1px #fa1f41'
|
||||
}
|
||||
});
|
||||
this.text = '';
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@@ -1,34 +0,0 @@
|
||||
<template>
|
||||
<div class="ele-body ele-body-card">
|
||||
<el-row :gutter="15">
|
||||
<el-col v-bind="styleResponsive ? { md: 12 } : { span: 12 }">
|
||||
<demo-basic />
|
||||
</el-col>
|
||||
<el-col v-bind="styleResponsive ? { md: 12 } : { span: 12 }">
|
||||
<demo-danmu />
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import DemoBasic from './components/demo-basic.vue';
|
||||
import DemoDanmu from './components/demo-danmu.vue';
|
||||
|
||||
export default {
|
||||
name: 'ExtensionPlayer',
|
||||
components: { DemoBasic, DemoDanmu },
|
||||
computed: {
|
||||
// 是否开启响应式布局
|
||||
styleResponsive() {
|
||||
return this.$store.state.theme.styleResponsive;
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.xgplayer-skin-default .xgplayer-pip {
|
||||
margin: -1px 0 0 10px;
|
||||
}
|
||||
</style>
|
||||
@@ -1,211 +0,0 @@
|
||||
<template>
|
||||
<el-card shadow="never" header="进阶示例">
|
||||
<el-button size="small" @click="printDataTable">打印数据表格</el-button>
|
||||
<el-button size="small" @click="printAnyTable">打印复杂表格</el-button>
|
||||
<el-button size="small" @click="printPdfUrl">打印 pdf</el-button>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { printHtml, printPdf, makeTable } from 'ele-admin';
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
users: [
|
||||
{
|
||||
key: 1,
|
||||
username: '张小三',
|
||||
amount: 18,
|
||||
province: '浙江',
|
||||
city: '杭州',
|
||||
zone: '西湖区',
|
||||
street: '西溪街道',
|
||||
address: '西溪花园30栋1单元'
|
||||
},
|
||||
{
|
||||
key: 2,
|
||||
username: '李小四',
|
||||
amount: 39,
|
||||
province: '江苏',
|
||||
city: '苏州',
|
||||
zone: '姑苏区',
|
||||
street: '丝绸路',
|
||||
address: '天墅之城9幢2单元'
|
||||
},
|
||||
{
|
||||
key: 3,
|
||||
username: '王小五',
|
||||
amount: 8,
|
||||
province: '江西',
|
||||
city: '南昌',
|
||||
zone: '青山湖区',
|
||||
street: '艾溪湖办事处',
|
||||
address: '中兴和园1幢3单元'
|
||||
},
|
||||
{
|
||||
key: 4,
|
||||
username: '赵小六',
|
||||
amount: 16,
|
||||
province: '福建',
|
||||
city: '泉州',
|
||||
zone: '丰泽区',
|
||||
street: '南洋街道',
|
||||
address: '南洋村6幢1单元'
|
||||
},
|
||||
{
|
||||
key: 5,
|
||||
username: '孙小七',
|
||||
amount: 12,
|
||||
province: '湖北',
|
||||
city: '武汉',
|
||||
zone: '武昌区',
|
||||
street: '武昌大道',
|
||||
address: '两湖花园16幢2单元'
|
||||
},
|
||||
{
|
||||
key: 6,
|
||||
username: '周小八',
|
||||
amount: 11,
|
||||
province: '安徽',
|
||||
city: '黄山',
|
||||
zone: '黄山区',
|
||||
street: '汤口镇',
|
||||
address: '温泉村21号'
|
||||
}
|
||||
]
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
/* 打印数据表格 */
|
||||
printDataTable() {
|
||||
const html = makeTable(this.users, [
|
||||
[
|
||||
{
|
||||
field: 'username',
|
||||
width: 150,
|
||||
rowspan: 2,
|
||||
title: '联系人'
|
||||
},
|
||||
{
|
||||
align: 'center',
|
||||
colspan: 3,
|
||||
title: '地址'
|
||||
},
|
||||
{
|
||||
field: 'amount',
|
||||
width: 120,
|
||||
rowspan: 2,
|
||||
title: '金额',
|
||||
align: 'center'
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
field: 'province',
|
||||
width: 120,
|
||||
title: '省'
|
||||
},
|
||||
{
|
||||
field: 'city',
|
||||
width: 120,
|
||||
title: '市'
|
||||
},
|
||||
{
|
||||
width: 200,
|
||||
title: '区',
|
||||
templet: (d) => {
|
||||
return `<span style="color: red;">${d.zone}</span>`;
|
||||
}
|
||||
}
|
||||
]
|
||||
]);
|
||||
printHtml({
|
||||
html: '<p>提供数据和cols配置自动生成复杂表格, 非常的方便</p>' + html,
|
||||
loading: false
|
||||
});
|
||||
},
|
||||
/* 打印自定义表格 */
|
||||
printAnyTable() {
|
||||
const html = `
|
||||
<h2 style="text-align: center;color: #333;">XXXXX班级课程表</h2>
|
||||
<table class="ele-printer-table">
|
||||
<colgroup>
|
||||
<col width="130px"/>
|
||||
</colgroup>
|
||||
<tr>
|
||||
<th style="position: relative;">
|
||||
<div style="position: absolute;right: 20px;top: 10px;line-height: normal;">星期</div>
|
||||
<div style="position: absolute;left: 20px;bottom: 10px;line-height: normal;">时间</div>
|
||||
<div
|
||||
style="border-top: 1px solid #000; width:141px;height: 0;position: absolute;left: 0;top: 0;transform: rotate(22deg);transform-origin: 0 0;">
|
||||
</div>
|
||||
</th>
|
||||
<th>周一</th>
|
||||
<th>周二</th>
|
||||
<th>周三</th>
|
||||
<th>周四</th>
|
||||
<th>周五</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>8:00-10:00</td>
|
||||
<td>HTML5网页设计<br/>曲丽丽 - 441教室</td>
|
||||
<td>数据库原理及应用<br/>严良 - 716机房</td>
|
||||
<td>JavaSE初级程序设计<br/>肖萧 - 715机房</td>
|
||||
<td></td>
|
||||
<td>JavaScript程序设计<br/>董娜 - 733机房</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>10:30-12:30</td>
|
||||
<td></td>
|
||||
<td>JavaScript程序设计<br/>董娜 - 733机房</td>
|
||||
<td></td>
|
||||
<td>锋利的jQuery<br/>程咏 - 303教室</td>
|
||||
<td>JavaEE应用开发<br/>周星 - 303教室</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="6" style="height: auto;">午休</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>13:30-15:30</td>
|
||||
<td>JavaSE初级程序设计<br/>肖萧 - 715机房</td>
|
||||
<td></td>
|
||||
<td>HTML5网页设计<br/>曲丽丽 - 441教室</td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>16:00-18:00</td>
|
||||
<td></td>
|
||||
<td>JavaEE应用开发<br/>周星 - 303教室</td>
|
||||
<td></td>
|
||||
<td>数据库原理及应用<br/>严良 - 716机房</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
</table>
|
||||
<style>
|
||||
th, td {
|
||||
text-align: center;
|
||||
line-height: 35px;
|
||||
}
|
||||
td {
|
||||
height: 100px;
|
||||
}
|
||||
</style>
|
||||
`;
|
||||
printHtml({
|
||||
html: html,
|
||||
horizontal: true,
|
||||
title: '.',
|
||||
loading: false
|
||||
});
|
||||
},
|
||||
/* 打印pdf */
|
||||
printPdfUrl() {
|
||||
printPdf({
|
||||
url: 'https://cdn.eleadmin.com/20200610/20200708224450.pdf'
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@@ -1,73 +0,0 @@
|
||||
<template>
|
||||
<el-card shadow="never" header="打印指定区域">
|
||||
<div ref="printRef" class="demo-print-group">
|
||||
<div class="demo-print-div">
|
||||
<div>示例示例示例示例示例</div>
|
||||
<div class="demo-hide-2" style="font-size: 12px; margin-top: 8px">
|
||||
此段内容不打印
|
||||
</div>
|
||||
</div>
|
||||
<div class="demo-print-right ele-bg-white">
|
||||
<div>
|
||||
<el-tag size="mini">示例</el-tag>
|
||||
<el-tag size="mini" type="success">示例</el-tag>
|
||||
<el-tag size="mini" type="warning">示例</el-tag>
|
||||
</div>
|
||||
<div style="margin-top: 12px">
|
||||
<el-input v-model="value" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div style="margin-top: 20px">
|
||||
<el-button size="small" @click="print">打印</el-button>
|
||||
</div>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { printElement } from 'ele-admin';
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
value: '示例示例示例'
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
print() {
|
||||
printElement(this.$refs.printRef, { hide: ['.demo-hide-2'] });
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.demo-print-group {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.demo-print-div {
|
||||
background: #096dd9;
|
||||
color: #fff;
|
||||
font-size: 18px;
|
||||
text-align: center;
|
||||
padding: 40px 0;
|
||||
flex: 1;
|
||||
border: 2px solid #096dd9;
|
||||
height: 120px;
|
||||
box-sizing: border-box;
|
||||
border-top-left-radius: 8px;
|
||||
border-bottom-left-radius: 8px;
|
||||
}
|
||||
|
||||
.demo-print-right {
|
||||
flex: 1;
|
||||
padding: 20px;
|
||||
border: 2px solid #096dd9;
|
||||
height: 120px;
|
||||
box-sizing: border-box;
|
||||
border-top-right-radius: 8px;
|
||||
border-bottom-right-radius: 8px;
|
||||
}
|
||||
</style>
|
||||
@@ -1,75 +0,0 @@
|
||||
<template>
|
||||
<el-card shadow="never" header="打印任意内容">
|
||||
<el-form label-width="64px">
|
||||
<el-form-item label="loading">
|
||||
<el-radio-group v-model="option.loading">
|
||||
<el-radio :label="false">不显示</el-radio>
|
||||
<el-radio :label="true">显示</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<el-button size="small" @click="printAnyHtml">打印任意内容</el-button>
|
||||
<el-button size="small" @click="printAddHeader">设置页眉页脚</el-button>
|
||||
<el-button size="small" @click="printImage">打印图片</el-button>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { printHtml } from 'ele-admin';
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
// 打印任意内容参数
|
||||
option: {
|
||||
loading: false
|
||||
}
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
/* 打印任意内容 */
|
||||
printAnyHtml() {
|
||||
printHtml({
|
||||
...this.option,
|
||||
html: [
|
||||
'<h1 style="color: #1890ff;">EleAdmin 后台管理模板</h1>',
|
||||
'<div style="color: #F51D2C;">通用型后台管理模板, 界面美观、开箱即用</div>'
|
||||
].join('')
|
||||
});
|
||||
},
|
||||
/* 打印设置页眉页脚 */
|
||||
printAddHeader() {
|
||||
printHtml({
|
||||
...this.option,
|
||||
margin: 0,
|
||||
html: [
|
||||
'<div style="padding: 0 60px;">',
|
||||
Array(38).join('<h3>EleAdmin 后台管理模板</h3>'),
|
||||
'</div>'
|
||||
].join(''),
|
||||
header: `
|
||||
<div style="display: flex;font-size: 12px;padding: 15px 30px 25px;">
|
||||
<div>我是页眉左侧</div>
|
||||
<div style="flex: 1;text-align: center;">我是页眉</div>
|
||||
<div>我是页眉右侧</div>
|
||||
</div>`,
|
||||
footer: `
|
||||
<div style="display: flex;font-size: 12px;padding: 15px 30px 25px;">
|
||||
<div>我是页脚左侧</div>
|
||||
<div style="flex: 1;text-align: center;">我是页脚</div>
|
||||
<div>我是页脚右侧</div>
|
||||
</div>`,
|
||||
style: '<style> h3 {color: red;} </style>'
|
||||
});
|
||||
},
|
||||
/* 打印图片 */
|
||||
printImage() {
|
||||
printHtml({
|
||||
...this.option,
|
||||
margin: 0,
|
||||
html: '<img src="https://cdn.eleadmin.com/20200610/LrCTN2j94lo9N7wEql7cBr1Ux4rHMvmZ.jpg" style="width: 100%;"/>'
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@@ -1,57 +0,0 @@
|
||||
<template>
|
||||
<el-card shadow="never" header="分页打印">
|
||||
<el-button size="small" @click="printAnyPage">分页打印</el-button>
|
||||
<el-button size="small" @click="printPageAddHeader">设置页眉页脚</el-button>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { printPage } from 'ele-admin';
|
||||
|
||||
export default {
|
||||
methods: {
|
||||
/* 分页打印 */
|
||||
printAnyPage() {
|
||||
printPage({
|
||||
pages: [
|
||||
'<h3>我是第一页</h3>',
|
||||
'<h3>我是第二页</h3>',
|
||||
'<h3>我是第三页</h3>',
|
||||
'<h3>我是第四页</h3>',
|
||||
'<h3>我是第五页</h3>'
|
||||
],
|
||||
style: '<style> h3 { color: red; } </style>',
|
||||
loading: false
|
||||
});
|
||||
},
|
||||
/* 分页打印设置页眉页脚 */
|
||||
printPageAddHeader() {
|
||||
printPage({
|
||||
pages: [
|
||||
'<h3>我是第一页</h3>',
|
||||
'<h3>我是第二页</h3>',
|
||||
'<h3>我是第三页</h3>',
|
||||
'<h3>我是第四页</h3>',
|
||||
'<h3>我是第五页</h3>'
|
||||
],
|
||||
margin: 0,
|
||||
padding: '20px 60px',
|
||||
header: `
|
||||
<div style="display: flex;font-size: 12px;padding: 15px 30px;">
|
||||
<div>我是页眉左侧</div>
|
||||
<div style="flex: 1;text-align: center;">我是页眉</div>
|
||||
<div>我是页眉右侧</div>
|
||||
</div>`,
|
||||
footer: `
|
||||
<div style="display: flex;font-size: 12px;padding: 15px 30px;">
|
||||
<div>我是页脚左侧</div>
|
||||
<div style="flex: 1;text-align: center;">我是页脚</div>
|
||||
<div>我是页脚右侧</div>
|
||||
</div>`,
|
||||
style: '<style> h3 { color: red; } </style>',
|
||||
loading: false
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@@ -1,72 +0,0 @@
|
||||
<template>
|
||||
<el-card shadow="never" header="打印当前页面">
|
||||
<el-form label-width="80px" size="small" style="max-width: 320px">
|
||||
<el-form-item label="纸张方向">
|
||||
<el-select
|
||||
clearable
|
||||
class="ele-block"
|
||||
v-model="option.horizontal"
|
||||
placeholder="不设置"
|
||||
>
|
||||
<el-option label="横向" :value="true" />
|
||||
<el-option label="纵向" :value="false" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="页面间距">
|
||||
<el-select
|
||||
clearable
|
||||
class="ele-block"
|
||||
v-model="option.margin"
|
||||
placeholder="不设置"
|
||||
>
|
||||
<el-option label="0px" value="0px" />
|
||||
<el-option label="50px" value="50px" />
|
||||
<el-option label="100px" value="100px" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="页面标题">
|
||||
<el-input clearable v-model="option.title" placeholder="不设置" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<el-button size="small" @click="print">打印</el-button>
|
||||
<el-button size="small" @click="printHide">打印隐藏指定内容</el-button>
|
||||
<div style="margin-top: 15px">
|
||||
<span class="ele-text-primary ele-printer-hide">
|
||||
此段内容在所有打印时隐藏, 打印完复原。
|
||||
</span>
|
||||
<span class="ele-text-danger demo-hide-1">
|
||||
此段内容在指定打印时才隐藏。
|
||||
</span>
|
||||
</div>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { printThis } from 'ele-admin';
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
// 打印当前页面参数
|
||||
option: {
|
||||
horizontal: null,
|
||||
margin: null,
|
||||
title: ''
|
||||
}
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
/* 打印当前页面 */
|
||||
print() {
|
||||
printThis(this.option1);
|
||||
},
|
||||
/* 打印隐藏指定内容 */
|
||||
printHide() {
|
||||
printThis({
|
||||
...this.option1,
|
||||
hide: ['.demo-hide-1']
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@@ -1,28 +0,0 @@
|
||||
<template>
|
||||
<div class="ele-body">
|
||||
<print-this />
|
||||
<print-div />
|
||||
<print-html />
|
||||
<print-page />
|
||||
<print-advanced />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import PrintThis from './components/print-this.vue';
|
||||
import PrintDiv from './components/print-div.vue';
|
||||
import PrintHtml from './components/print-html.vue';
|
||||
import PrintPage from './components/print-page.vue';
|
||||
import PrintAdvanced from './components/print-advanced.vue';
|
||||
|
||||
export default {
|
||||
name: 'ExtensionPrinter',
|
||||
components: {
|
||||
PrintThis,
|
||||
PrintDiv,
|
||||
PrintHtml,
|
||||
PrintPage,
|
||||
PrintAdvanced
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@@ -1,193 +0,0 @@
|
||||
<template>
|
||||
<div class="ele-body">
|
||||
<el-card shadow="never" header="二维码" style="overflow: visible">
|
||||
<div ref="printRef" class="demo-qrcode-images ele-bg-white">
|
||||
<div class="demo-qrcode-image-item">
|
||||
<div class="demo-qr-code-title">canvas 渲染</div>
|
||||
<ele-qr-code
|
||||
:value="text"
|
||||
:size="size"
|
||||
:level="level"
|
||||
:margin="margin"
|
||||
:image-settings="image"
|
||||
/>
|
||||
</div>
|
||||
<div class="demo-qrcode-image-item">
|
||||
<div class="demo-qr-code-title">svg 渲染</div>
|
||||
<ele-qr-code-svg
|
||||
:value="text"
|
||||
:size="size"
|
||||
:level="level"
|
||||
:margin="margin"
|
||||
:image-settings="image"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<el-form label-width="88px" style="max-width: 340px">
|
||||
<el-form-item label="二维码内容">
|
||||
<el-input v-model="text" :maxlength="150" />
|
||||
</el-form-item>
|
||||
<el-form-item label="容错等级">
|
||||
<el-select v-model="level" class="ele-fluid">
|
||||
<el-option value="L" label="L" />
|
||||
<el-option value="M" label="M" />
|
||||
<el-option value="Q" label="Q" />
|
||||
<el-option value="H" label="H" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="尺寸">
|
||||
<el-slider v-model="size" :min="80" :max="280" :step="40" />
|
||||
</el-form-item>
|
||||
<el-form-item label="间距">
|
||||
<el-slider v-model="margin" :min="0" :max="20" />
|
||||
</el-form-item>
|
||||
<el-form-item label="自定义图片">
|
||||
<el-switch v-model="showImage" @change="onShowImageChange" />
|
||||
</el-form-item>
|
||||
<template v-if="showImage">
|
||||
<el-form-item label="图片地址">
|
||||
<el-input v-model="image.src" :maxlength="400" />
|
||||
</el-form-item>
|
||||
<el-form-item label="图片宽高">
|
||||
<div class="ele-cell">
|
||||
<div style="width: 80px; margin-right: 20px">
|
||||
<el-input-number
|
||||
v-model="image.width"
|
||||
size="mini"
|
||||
:min="0"
|
||||
:max="size"
|
||||
controls-position="right"
|
||||
class="ele-fluid"
|
||||
/>
|
||||
</div>
|
||||
<div style="width: 80px">
|
||||
<el-input-number
|
||||
v-model="image.height"
|
||||
size="mini"
|
||||
:min="0"
|
||||
:max="size"
|
||||
controls-position="right"
|
||||
class="ele-fluid"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="位置居中">
|
||||
<div class="ele-cell" style="min-height: 36px">
|
||||
<el-switch v-model="center" @change="onCenterChange" />
|
||||
<template v-if="!center">
|
||||
<div style="padding: 0 10px">x</div>
|
||||
<div style="width: 80px">
|
||||
<el-input-number
|
||||
v-model="image.x"
|
||||
size="mini"
|
||||
:min="0"
|
||||
:max="size"
|
||||
controls-position="right"
|
||||
class="ele-fluid"
|
||||
/>
|
||||
</div>
|
||||
<div style="padding: 0 10px">y</div>
|
||||
<div style="width: 80px">
|
||||
<el-input-number
|
||||
v-model="image.y"
|
||||
size="mini"
|
||||
:min="0"
|
||||
:max="size"
|
||||
controls-position="right"
|
||||
class="ele-fluid"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="背景擦除">
|
||||
<el-switch v-model="image.excavate" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<div>
|
||||
<el-button type="primary" @click="print">打印</el-button>
|
||||
</div>
|
||||
</el-form-item>
|
||||
</template>
|
||||
</el-form>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import EleQrCode from 'ele-admin/es/ele-qr-code';
|
||||
import EleQrCodeSvg from 'ele-admin/es/ele-qr-code-svg';
|
||||
import { printElement } from 'ele-admin';
|
||||
const IMAGE_SRC = 'https://cdn.eleadmin.com/20200610/logo-radius.png';
|
||||
|
||||
export default {
|
||||
name: 'ExtensionQrCode',
|
||||
components: { EleQrCode, EleQrCodeSvg },
|
||||
data() {
|
||||
return {
|
||||
text: 'https://eleadmin.com',
|
||||
level: 'L',
|
||||
size: 120,
|
||||
margin: 0,
|
||||
showImage: true,
|
||||
image: {
|
||||
src: IMAGE_SRC,
|
||||
width: 28,
|
||||
height: 28,
|
||||
x: undefined,
|
||||
y: undefined,
|
||||
excavate: false
|
||||
},
|
||||
center: true
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
onShowImageChange(checked) {
|
||||
if (checked) {
|
||||
this.image.src = IMAGE_SRC;
|
||||
} else {
|
||||
this.image.src = undefined;
|
||||
}
|
||||
},
|
||||
onCenterChange(checked) {
|
||||
if (checked) {
|
||||
this.image.x = undefined;
|
||||
this.image.y = undefined;
|
||||
} else {
|
||||
this.image.x = 0;
|
||||
this.image.y = 0;
|
||||
}
|
||||
},
|
||||
print() {
|
||||
printElement(this.$refs.printRef);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.demo-qrcode-images {
|
||||
display: flex;
|
||||
padding-bottom: 16px;
|
||||
margin-bottom: 4px;
|
||||
position: sticky;
|
||||
top: 0;
|
||||
overflow: auto;
|
||||
z-index: 1002;
|
||||
|
||||
.demo-qrcode-image-item {
|
||||
padding: 0 20px;
|
||||
|
||||
.demo-qr-code-title {
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 768px) {
|
||||
.demo-qrcode-images .demo-qrcode-image-item {
|
||||
padding: 0 10px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,60 +0,0 @@
|
||||
<template>
|
||||
<div class="ele-body">
|
||||
<el-card shadow="never" header="省市区级联选择">
|
||||
<div style="max-width: 280px">
|
||||
<regions-select
|
||||
v-model="city"
|
||||
placeholder="请选择省市区"
|
||||
class="ele-fluid"
|
||||
/>
|
||||
</div>
|
||||
</el-card>
|
||||
<el-card shadow="never" header="省市级联选择">
|
||||
<div style="max-width: 280px">
|
||||
<regions-select
|
||||
v-model="provinceCity"
|
||||
placeholder="请选择省市"
|
||||
type="provinceCity"
|
||||
class="ele-fluid"
|
||||
/>
|
||||
</div>
|
||||
</el-card>
|
||||
<el-card shadow="never" header="省选择">
|
||||
<div style="max-width: 280px">
|
||||
<regions-select
|
||||
v-model="province"
|
||||
placeholder="请选择省"
|
||||
type="province"
|
||||
class="ele-fluid"
|
||||
/>
|
||||
</div>
|
||||
</el-card>
|
||||
<el-card shadow="never" header="可多选">
|
||||
<div style="max-width: 280px">
|
||||
<regions-select
|
||||
v-model="citys"
|
||||
placeholder="请选择省市区"
|
||||
:props="{ multiple: true }"
|
||||
class="ele-fluid"
|
||||
/>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import RegionsSelect from '@/components/RegionsSelect/index.vue';
|
||||
|
||||
export default {
|
||||
name: 'ExtensionRegions',
|
||||
components: { RegionsSelect },
|
||||
data() {
|
||||
return {
|
||||
city: [],
|
||||
provinceCity: [],
|
||||
province: [],
|
||||
citys: []
|
||||
};
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@@ -1,179 +0,0 @@
|
||||
<template>
|
||||
<div class="ele-body">
|
||||
<el-card shadow="never" header="基本用法">
|
||||
<div class="option-item">
|
||||
<div>显示折叠按钮:</div>
|
||||
<div class="option-item-body">
|
||||
<el-radio-group v-model="allowCollapse">
|
||||
<el-radio :label="true">是</el-radio>
|
||||
<el-radio :label="false">否</el-radio>
|
||||
</el-radio-group>
|
||||
</div>
|
||||
</div>
|
||||
<div class="option-item">
|
||||
<div>支持自由拉伸:</div>
|
||||
<div class="option-item-body">
|
||||
<el-radio-group v-model="resizable">
|
||||
<el-radio :label="true">是</el-radio>
|
||||
<el-radio :label="false">否</el-radio>
|
||||
</el-radio-group>
|
||||
</div>
|
||||
</div>
|
||||
<div class="option-item">
|
||||
<div>上下布局模式:</div>
|
||||
<div class="option-item-body">
|
||||
<el-radio-group v-model="vertical">
|
||||
<el-radio :label="true">是</el-radio>
|
||||
<el-radio :label="false">否</el-radio>
|
||||
</el-radio-group>
|
||||
</div>
|
||||
</div>
|
||||
<div class="option-item">
|
||||
<div>反转布局方向:</div>
|
||||
<div class="option-item-body">
|
||||
<el-radio-group v-model="reverse">
|
||||
<el-radio :label="true">是</el-radio>
|
||||
<el-radio :label="false">否</el-radio>
|
||||
</el-radio-group>
|
||||
</div>
|
||||
</div>
|
||||
<ele-split-layout
|
||||
space="0px"
|
||||
:allow-collapse="allowCollapse"
|
||||
:resizable="resizable"
|
||||
:vertical="vertical"
|
||||
:reverse="reverse"
|
||||
:min-size="40"
|
||||
:left-style="{
|
||||
background: 'rgba(185, 182, 229, .4)',
|
||||
overflow: 'hidden'
|
||||
}"
|
||||
:right-style="{
|
||||
background: 'rgba(125, 226, 252, .4)',
|
||||
overflow: 'hidden'
|
||||
}"
|
||||
style="height: 480px; margin-top: 12px"
|
||||
>
|
||||
<div>边栏</div>
|
||||
<template #content>
|
||||
<div>内容</div>
|
||||
</template>
|
||||
</ele-split-layout>
|
||||
</el-card>
|
||||
<el-card shadow="never" header="组合使用">
|
||||
<div style="margin: 0 0 8px 0">先左右再上下</div>
|
||||
<ele-split-layout
|
||||
space="0px"
|
||||
:resizable="true"
|
||||
:min-size="40"
|
||||
:max-size="-40"
|
||||
:left-style="{
|
||||
background: 'rgba(185, 182, 229, .4)',
|
||||
overflow: 'hidden'
|
||||
}"
|
||||
:right-style="{ overflow: 'hidden' }"
|
||||
:responsive="false"
|
||||
style="height: 400px"
|
||||
>
|
||||
<div>边栏</div>
|
||||
<template #content>
|
||||
<ele-split-layout
|
||||
space="0px"
|
||||
width="240px"
|
||||
:min-size="40"
|
||||
:max-size="-40"
|
||||
:resizable="true"
|
||||
:vertical="true"
|
||||
:left-style="{
|
||||
background: 'rgba(171, 199, 255, .5)',
|
||||
overflow: 'hidden'
|
||||
}"
|
||||
:right-style="{
|
||||
background: 'rgba(125, 226, 252, .4)',
|
||||
overflow: 'hidden'
|
||||
}"
|
||||
:responsive="false"
|
||||
style="height: 400px"
|
||||
>
|
||||
<div>内容一</div>
|
||||
<template #content>
|
||||
<div>内容二</div>
|
||||
</template>
|
||||
</ele-split-layout>
|
||||
</template>
|
||||
</ele-split-layout>
|
||||
<div style="margin: 16px 0 8px 0">先上下再左右</div>
|
||||
<ele-split-layout
|
||||
space="0px"
|
||||
width="120px"
|
||||
:min-size="40"
|
||||
:max-size="-40"
|
||||
:vertical="true"
|
||||
:resizable="true"
|
||||
:left-style="{
|
||||
background: 'rgba(185, 182, 229, .4)',
|
||||
overflow: 'hidden'
|
||||
}"
|
||||
:right-style="{ overflow: 'hidden' }"
|
||||
:responsive="false"
|
||||
style="height: 400px"
|
||||
>
|
||||
<div>顶栏</div>
|
||||
<template #content>
|
||||
<ele-split-layout
|
||||
space="0px"
|
||||
:min-size="40"
|
||||
:max-size="-40"
|
||||
:resizable="true"
|
||||
:left-style="{
|
||||
background: 'rgba(171, 199, 255, .5)',
|
||||
overflow: 'hidden'
|
||||
}"
|
||||
:right-style="{
|
||||
background: 'rgba(125, 226, 252, .4)',
|
||||
overflow: 'hidden'
|
||||
}"
|
||||
:responsive="false"
|
||||
style="height: 100%"
|
||||
>
|
||||
<div>边栏</div>
|
||||
<template #content>
|
||||
<div>内容</div>
|
||||
</template>
|
||||
</ele-split-layout>
|
||||
</template>
|
||||
</ele-split-layout>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'ExtensionSplit',
|
||||
data() {
|
||||
return {
|
||||
allowCollapse: true,
|
||||
resizable: false,
|
||||
vertical: false,
|
||||
reverse: false
|
||||
};
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.option-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.option-item-body {
|
||||
flex: 1;
|
||||
padding-left: 12px;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
& + .option-item {
|
||||
margin-top: 6px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,112 +0,0 @@
|
||||
<template>
|
||||
<div class="ele-body">
|
||||
<el-card shadow="never" header="水平步骤条" body-style="overflow: auto;">
|
||||
<div style="min-width: 520px">
|
||||
<div class="demo-steps-item">
|
||||
<el-steps :active="stepsActive" class="ele-steps-horizontal">
|
||||
<el-step title="第一步" />
|
||||
<el-step title="第二步" />
|
||||
<el-step title="第三步" />
|
||||
<el-step title="第四步" />
|
||||
</el-steps>
|
||||
</div>
|
||||
<div class="demo-steps-item">
|
||||
<el-steps :active="stepsActive" class="ele-steps-horizontal">
|
||||
<el-step title="第一步" description="这里是该步骤的描述信息" />
|
||||
<el-step title="第二步" description="这里是该步骤的描述信息" />
|
||||
<el-step title="第三步" description="这里是该步骤的描述信息" />
|
||||
<el-step title="第四步" description="这里是该步骤的描述信息" />
|
||||
</el-steps>
|
||||
</div>
|
||||
<div class="demo-steps-item">
|
||||
<el-button @click="stepsPrev" size="small">上一步</el-button>
|
||||
<el-button type="primary" @click="stepsNext" size="small">
|
||||
下一步
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
<el-card shadow="never" header="垂直步骤条">
|
||||
<div style="white-space: nowrap">
|
||||
<div class="demo-steps-item-vertical">
|
||||
<el-steps
|
||||
direction="vertical"
|
||||
:active="stepsActive"
|
||||
style="height: 360px"
|
||||
>
|
||||
<el-step title="第一步" />
|
||||
<el-step title="第二步" />
|
||||
<el-step title="第三步" />
|
||||
<el-step title="第四步" />
|
||||
</el-steps>
|
||||
</div>
|
||||
<div class="demo-steps-item-vertical">
|
||||
<el-steps
|
||||
direction="vertical"
|
||||
:active="stepsActive"
|
||||
style="height: 360px"
|
||||
>
|
||||
<el-step title="第一步" description="这里是该步骤的描述信息" />
|
||||
<el-step title="第二步" description="这里是该步骤的描述信息" />
|
||||
<el-step title="第三步" description="这里是该步骤的描述信息" />
|
||||
<el-step title="第四步" description="这里是该步骤的描述信息" />
|
||||
</el-steps>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'ExtensionSteps',
|
||||
data() {
|
||||
return {
|
||||
stepsActive: 0
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
/* 下一步 */
|
||||
stepsNext() {
|
||||
this.stepsActive++;
|
||||
if (this.stepsActive > 4) {
|
||||
this.stepsActive = 0;
|
||||
}
|
||||
},
|
||||
/* 上一步 */
|
||||
stepsPrev() {
|
||||
this.stepsActive--;
|
||||
if (this.stepsActive < 0) {
|
||||
this.stepsActive = 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.demo-steps-item {
|
||||
max-width: 900px;
|
||||
padding: 10px 10px 0 10px;
|
||||
|
||||
& + .demo-steps-item {
|
||||
margin-top: 15px;
|
||||
}
|
||||
}
|
||||
|
||||
.el-button + .el-button {
|
||||
margin-left: 20px;
|
||||
}
|
||||
|
||||
.demo-steps-item-vertical {
|
||||
width: 250px;
|
||||
display: inline-block;
|
||||
padding: 10px 0 10px 10px;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 768px) {
|
||||
.demo-steps-item-vertical {
|
||||
width: calc(50% - 15px);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,31 +0,0 @@
|
||||
<template>
|
||||
<div style="max-width: 200px">
|
||||
<el-input
|
||||
clearable
|
||||
size="small"
|
||||
v-model="where.keywords"
|
||||
placeholder="输入关键字搜索"
|
||||
prefix-icon="el-icon-search"
|
||||
@change="search"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
// 搜索表单
|
||||
where: {
|
||||
keywords: ''
|
||||
}
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
// 搜索
|
||||
search() {
|
||||
this.$emit('search', this.where);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@@ -1,140 +0,0 @@
|
||||
<template>
|
||||
<el-card shadow="never" header="可搜索">
|
||||
<div style="max-width: 260px">
|
||||
<ele-table-select
|
||||
ref="select"
|
||||
v-model="value"
|
||||
:multiple="true"
|
||||
:clearable="true"
|
||||
placeholder="请选择"
|
||||
value-key="userId"
|
||||
label-key="nickname"
|
||||
:table-config="tableConfig"
|
||||
:popper-width="580"
|
||||
:init-value="initValue"
|
||||
>
|
||||
<!-- 角色列 -->
|
||||
<template v-slot:roles="{ row }">
|
||||
<el-tag
|
||||
v-for="item in row.roles"
|
||||
:key="item.roleId"
|
||||
size="mini"
|
||||
type="primary"
|
||||
:disable-transitions="true"
|
||||
>
|
||||
{{ item.roleName }}
|
||||
</el-tag>
|
||||
</template>
|
||||
<!-- 表头工具栏 -->
|
||||
<template v-slot:toolbar>
|
||||
<demo-advanced-search @search="search" />
|
||||
</template>
|
||||
</ele-table-select>
|
||||
</div>
|
||||
<div style="margin-top: 12px">
|
||||
<el-button size="small" type="primary" @click="setInitValue">
|
||||
回显数据
|
||||
</el-button>
|
||||
</div>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { pageUsers } from '@/api/system/user';
|
||||
import DemoAdvancedSearch from './demo-advanced-search.vue';
|
||||
|
||||
export default {
|
||||
components: { DemoAdvancedSearch },
|
||||
data() {
|
||||
return {
|
||||
value: [],
|
||||
// 可搜索表格配置
|
||||
tableConfig: {
|
||||
datasource({ page, limit, where, order }) {
|
||||
return pageUsers({ ...where, ...order, page, limit });
|
||||
},
|
||||
columns: [
|
||||
{
|
||||
columnKey: 'selection',
|
||||
type: 'selection',
|
||||
width: 45,
|
||||
align: 'center',
|
||||
reserveSelection: true
|
||||
},
|
||||
{
|
||||
columnKey: 'index',
|
||||
type: 'index',
|
||||
width: 45,
|
||||
align: 'center',
|
||||
showOverflowTooltip: true
|
||||
},
|
||||
{
|
||||
prop: 'username',
|
||||
label: '用户账号',
|
||||
sortable: 'custom',
|
||||
showOverflowTooltip: true,
|
||||
minWidth: 110
|
||||
},
|
||||
{
|
||||
prop: 'nickname',
|
||||
label: '用户名',
|
||||
sortable: 'custom',
|
||||
showOverflowTooltip: true,
|
||||
minWidth: 110
|
||||
},
|
||||
{
|
||||
prop: 'sexName',
|
||||
label: '性别',
|
||||
sortable: 'custom',
|
||||
showOverflowTooltip: true,
|
||||
minWidth: 80
|
||||
},
|
||||
{
|
||||
columnKey: 'roles',
|
||||
label: '角色',
|
||||
showOverflowTooltip: true,
|
||||
minWidth: 110,
|
||||
slot: 'roles'
|
||||
}
|
||||
],
|
||||
pageSize: 5,
|
||||
pageSizes: [5, 10, 15, 20],
|
||||
rowClickChecked: true,
|
||||
rowClickCheckedIntelligent: false,
|
||||
toolkit: ['reload', 'columns'],
|
||||
size: 'small',
|
||||
toolStyle: { padding: '0 10px' }
|
||||
},
|
||||
// 回显值
|
||||
initValue: undefined
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
/* 回显数据 */
|
||||
setInitValue() {
|
||||
//this.value = [3, 5, 6];
|
||||
this.initValue = [
|
||||
{
|
||||
userId: 3,
|
||||
nickname: '管理员'
|
||||
},
|
||||
{
|
||||
userId: 5,
|
||||
nickname: '用户四'
|
||||
},
|
||||
{
|
||||
userId: 6,
|
||||
nickname: '用户五'
|
||||
}
|
||||
];
|
||||
},
|
||||
// 搜索
|
||||
search(where) {
|
||||
this.$refs.select.reload({
|
||||
where: where,
|
||||
page: 1
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@@ -1,123 +0,0 @@
|
||||
<template>
|
||||
<el-card shadow="never" header="表格后端分页">
|
||||
<div style="max-width: 260px">
|
||||
<ele-table-select
|
||||
v-model="value"
|
||||
:clearable="true"
|
||||
placeholder="请选择"
|
||||
:disabled="disabled"
|
||||
value-key="userId"
|
||||
label-key="nickname"
|
||||
:table-config="tableConfig"
|
||||
:popper-width="580"
|
||||
:init-value="initValue"
|
||||
@select="onSelect"
|
||||
>
|
||||
<!-- 角色列 -->
|
||||
<template v-slot:roles="{ row }">
|
||||
<el-tag
|
||||
v-for="item in row.roles"
|
||||
:key="item.roleId"
|
||||
size="mini"
|
||||
type="primary"
|
||||
:disable-transitions="true"
|
||||
>
|
||||
{{ item.roleName }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</ele-table-select>
|
||||
</div>
|
||||
<div class="ele-cell" style="margin-top: 15px">
|
||||
<div style="line-height: 22px"> 禁用:</div>
|
||||
<div class="ele-cell-content">
|
||||
<el-radio-group v-model="disabled">
|
||||
<el-radio :label="false">否</el-radio>
|
||||
<el-radio :label="true">是</el-radio>
|
||||
</el-radio-group>
|
||||
</div>
|
||||
</div>
|
||||
<div style="margin-top: 12px">
|
||||
<el-button size="small" type="primary" @click="setInitValue">
|
||||
回显数据
|
||||
</el-button>
|
||||
</div>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { pageUsers } from '@/api/system/user';
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
value: undefined,
|
||||
// 表格配置
|
||||
tableConfig: {
|
||||
datasource({ page, limit, where, order }) {
|
||||
return pageUsers({ ...where, ...order, page, limit });
|
||||
},
|
||||
columns: [
|
||||
{
|
||||
columnKey: 'index',
|
||||
type: 'index',
|
||||
width: 45,
|
||||
align: 'center',
|
||||
showOverflowTooltip: true,
|
||||
fixed: 'left'
|
||||
},
|
||||
{
|
||||
prop: 'username',
|
||||
label: '用户账号',
|
||||
sortable: 'custom',
|
||||
showOverflowTooltip: true,
|
||||
minWidth: 110
|
||||
},
|
||||
{
|
||||
prop: 'nickname',
|
||||
label: '用户名',
|
||||
sortable: 'custom',
|
||||
showOverflowTooltip: true,
|
||||
minWidth: 110
|
||||
},
|
||||
{
|
||||
prop: 'sexName',
|
||||
label: '性别',
|
||||
sortable: 'custom',
|
||||
showOverflowTooltip: true,
|
||||
minWidth: 80
|
||||
},
|
||||
{
|
||||
columnKey: 'roles',
|
||||
label: '角色',
|
||||
showOverflowTooltip: true,
|
||||
minWidth: 110,
|
||||
slot: 'roles'
|
||||
}
|
||||
],
|
||||
toolbar: false,
|
||||
pageSize: 5,
|
||||
pageSizes: [5, 10, 15, 20],
|
||||
size: 'small'
|
||||
},
|
||||
// 禁用
|
||||
disabled: false,
|
||||
// 回显值
|
||||
initValue: undefined
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
/* 回显数据 */
|
||||
setInitValue() {
|
||||
//this.value = 1;
|
||||
this.initValue = {
|
||||
userId: 1,
|
||||
nickname: '管理员'
|
||||
};
|
||||
},
|
||||
/* 选中事件 */
|
||||
onSelect(item) {
|
||||
console.log('item:', item);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@@ -1,102 +0,0 @@
|
||||
<template>
|
||||
<el-card shadow="never" header="基础用法">
|
||||
<div style="max-width: 260px">
|
||||
<ele-table-select
|
||||
v-model="value"
|
||||
:clearable="true"
|
||||
placeholder="请选择"
|
||||
value-key="userId"
|
||||
label-key="nickname"
|
||||
:table-config="tableConfig"
|
||||
:popper-width="580"
|
||||
>
|
||||
<!-- 角色列 -->
|
||||
<template v-slot:roles="{ row }">
|
||||
<el-tag
|
||||
v-for="item in row.roles"
|
||||
:key="item.roleId"
|
||||
size="mini"
|
||||
type="primary"
|
||||
:disable-transitions="true"
|
||||
>
|
||||
{{ item.roleName }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</ele-table-select>
|
||||
</div>
|
||||
<div style="margin-top: 12px">
|
||||
<el-button size="small" type="primary" @click="setInitValue">
|
||||
回显数据
|
||||
</el-button>
|
||||
</div>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { listUsers } from '@/api/system/user';
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
value: undefined,
|
||||
// 表格配置
|
||||
tableConfig: {
|
||||
datasource: [],
|
||||
columns: [
|
||||
{
|
||||
columnKey: 'index',
|
||||
type: 'index',
|
||||
width: 45,
|
||||
align: 'center',
|
||||
showOverflowTooltip: true,
|
||||
fixed: 'left'
|
||||
},
|
||||
{
|
||||
prop: 'username',
|
||||
label: '用户账号',
|
||||
sortable: 'custom',
|
||||
showOverflowTooltip: true,
|
||||
minWidth: 110
|
||||
},
|
||||
{
|
||||
prop: 'nickname',
|
||||
label: '用户名',
|
||||
sortable: 'custom',
|
||||
showOverflowTooltip: true,
|
||||
minWidth: 110
|
||||
},
|
||||
{
|
||||
prop: 'sexName',
|
||||
label: '性别',
|
||||
sortable: 'custom',
|
||||
showOverflowTooltip: true,
|
||||
minWidth: 80
|
||||
},
|
||||
{
|
||||
columnKey: 'roles',
|
||||
label: '角色',
|
||||
showOverflowTooltip: true,
|
||||
minWidth: 110,
|
||||
slot: 'roles'
|
||||
}
|
||||
],
|
||||
toolbar: false,
|
||||
pageSize: 5,
|
||||
pageSizes: [5, 10, 15, 20],
|
||||
size: 'small'
|
||||
}
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
/* 回显数据 */
|
||||
setInitValue() {
|
||||
this.value = 1;
|
||||
}
|
||||
},
|
||||
created() {
|
||||
listUsers().then((data) => {
|
||||
this.tableConfig.datasource = data;
|
||||
});
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@@ -1,123 +0,0 @@
|
||||
<template>
|
||||
<el-card shadow="never" header="多选">
|
||||
<div style="max-width: 260px">
|
||||
<ele-table-select
|
||||
v-model="value"
|
||||
:multiple="true"
|
||||
:clearable="true"
|
||||
placeholder="请选择"
|
||||
:disabled="disabled"
|
||||
value-key="userId"
|
||||
label-key="nickname"
|
||||
:table-config="tableConfig"
|
||||
:popper-width="580"
|
||||
>
|
||||
<!-- 角色列 -->
|
||||
<template v-slot:roles="{ row }">
|
||||
<el-tag
|
||||
v-for="item in row.roles"
|
||||
:key="item.roleId"
|
||||
size="mini"
|
||||
type="primary"
|
||||
:disable-transitions="true"
|
||||
>
|
||||
{{ item.roleName }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</ele-table-select>
|
||||
</div>
|
||||
<div class="ele-cell" style="margin-top: 15px">
|
||||
<div style="line-height: 22px"> 禁用:</div>
|
||||
<div class="ele-cell-content">
|
||||
<el-radio-group v-model="disabled">
|
||||
<el-radio :label="false">否</el-radio>
|
||||
<el-radio :label="true">是</el-radio>
|
||||
</el-radio-group>
|
||||
</div>
|
||||
</div>
|
||||
<div style="margin-top: 12px">
|
||||
<el-button size="small" type="primary" @click="setInitValue">
|
||||
回显数据
|
||||
</el-button>
|
||||
</div>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { listUsers } from '@/api/system/user';
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
value: undefined,
|
||||
// 表格配置
|
||||
tableConfig: {
|
||||
datasource: [],
|
||||
columns: [
|
||||
{
|
||||
columnKey: 'selection',
|
||||
type: 'selection',
|
||||
width: 45,
|
||||
align: 'center',
|
||||
reserveSelection: true
|
||||
},
|
||||
{
|
||||
columnKey: 'index',
|
||||
type: 'index',
|
||||
width: 45,
|
||||
align: 'center',
|
||||
showOverflowTooltip: true
|
||||
},
|
||||
{
|
||||
prop: 'username',
|
||||
label: '用户账号',
|
||||
sortable: 'custom',
|
||||
showOverflowTooltip: true,
|
||||
minWidth: 110
|
||||
},
|
||||
{
|
||||
prop: 'nickname',
|
||||
label: '用户名',
|
||||
sortable: 'custom',
|
||||
showOverflowTooltip: true,
|
||||
minWidth: 110
|
||||
},
|
||||
{
|
||||
prop: 'sexName',
|
||||
label: '性别',
|
||||
sortable: 'custom',
|
||||
showOverflowTooltip: true,
|
||||
minWidth: 80
|
||||
},
|
||||
{
|
||||
columnKey: 'roles',
|
||||
label: '角色',
|
||||
showOverflowTooltip: true,
|
||||
minWidth: 110,
|
||||
slot: 'roles'
|
||||
}
|
||||
],
|
||||
toolbar: false,
|
||||
pageSize: 5,
|
||||
pageSizes: [5, 10, 15, 20],
|
||||
rowClickChecked: true,
|
||||
rowClickCheckedIntelligent: false,
|
||||
size: 'small'
|
||||
},
|
||||
// 禁用
|
||||
disabled: false
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
/* 回显数据 */
|
||||
setInitValue() {
|
||||
this.value = [3, 5, 6];
|
||||
}
|
||||
},
|
||||
created() {
|
||||
listUsers().then((data) => {
|
||||
this.tableConfig.datasource = data;
|
||||
});
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@@ -1,20 +0,0 @@
|
||||
<template>
|
||||
<div class="ele-body">
|
||||
<demo-basic />
|
||||
<demo-basic-page />
|
||||
<demo-multiple />
|
||||
<demo-advanced />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import DemoBasic from './components/demo-basic.vue';
|
||||
import DemoBasicPage from './components/demo-basic-page.vue';
|
||||
import DemoMultiple from './components/demo-multiple.vue';
|
||||
import DemoAdvanced from './components/demo-advanced.vue';
|
||||
|
||||
export default {
|
||||
name: 'ExtensionTableSelect',
|
||||
components: { DemoBasic, DemoBasicPage, DemoMultiple, DemoAdvanced }
|
||||
};
|
||||
</script>
|
||||
@@ -1,203 +0,0 @@
|
||||
<template>
|
||||
<div class="ele-body">
|
||||
<el-card shadow="never" header="标签组件" body-style="overflow: auto;">
|
||||
<div style="min-width: 460px">
|
||||
<div class="ele-cell">
|
||||
<div>默认样式:</div>
|
||||
<div class="ele-cell-content">
|
||||
<el-tag :size="tagSize" :effect="tagTheme">标签一</el-tag>
|
||||
<el-tag :size="tagSize" :effect="tagTheme" type="success">
|
||||
标签二
|
||||
</el-tag>
|
||||
<el-tag :size="tagSize" :effect="tagTheme" type="info">
|
||||
标签三
|
||||
</el-tag>
|
||||
<el-tag :size="tagSize" :effect="tagTheme" type="warning">
|
||||
标签四
|
||||
</el-tag>
|
||||
<el-tag :size="tagSize" :effect="tagTheme" type="danger">
|
||||
标签五
|
||||
</el-tag>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ele-cell">
|
||||
<div>圆角样式:</div>
|
||||
<div class="ele-cell-content">
|
||||
<el-tag :size="tagSize" :effect="tagTheme" class="ele-tag-radius">
|
||||
标签一
|
||||
</el-tag>
|
||||
<el-tag
|
||||
:size="tagSize"
|
||||
:effect="tagTheme"
|
||||
type="success"
|
||||
class="ele-tag-radius"
|
||||
>
|
||||
标签二
|
||||
</el-tag>
|
||||
<el-tag
|
||||
:size="tagSize"
|
||||
:effect="tagTheme"
|
||||
type="info"
|
||||
class="ele-tag-radius"
|
||||
>
|
||||
标签三
|
||||
</el-tag>
|
||||
<el-tag
|
||||
:size="tagSize"
|
||||
:effect="tagTheme"
|
||||
type="warning"
|
||||
class="ele-tag-radius"
|
||||
>
|
||||
标签四
|
||||
</el-tag>
|
||||
<el-tag
|
||||
:size="tagSize"
|
||||
:effect="tagTheme"
|
||||
type="danger"
|
||||
class="ele-tag-radius"
|
||||
>
|
||||
标签五
|
||||
</el-tag>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ele-cell">
|
||||
<div>圆形样式:</div>
|
||||
<div class="ele-cell-content">
|
||||
<el-tag :size="tagSize" :effect="tagTheme" class="ele-tag-round">
|
||||
1
|
||||
</el-tag>
|
||||
<el-tag
|
||||
:size="tagSize"
|
||||
:effect="tagTheme"
|
||||
type="success"
|
||||
class="ele-tag-round"
|
||||
>
|
||||
2
|
||||
</el-tag>
|
||||
<el-tag
|
||||
:size="tagSize"
|
||||
:effect="tagTheme"
|
||||
type="info"
|
||||
class="ele-tag-round"
|
||||
>
|
||||
3
|
||||
</el-tag>
|
||||
<el-tag
|
||||
:size="tagSize"
|
||||
:effect="tagTheme"
|
||||
type="warning"
|
||||
class="ele-tag-round"
|
||||
>
|
||||
4
|
||||
</el-tag>
|
||||
<el-tag
|
||||
:size="tagSize"
|
||||
:effect="tagTheme"
|
||||
type="danger"
|
||||
class="ele-tag-round"
|
||||
>
|
||||
5
|
||||
</el-tag>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ele-cell">
|
||||
<div>尺寸设置:</div>
|
||||
<div class="ele-cell-content">
|
||||
<el-radio-group v-model="tagSize">
|
||||
<el-radio label="large">默认</el-radio>
|
||||
<el-radio label="medium">中等</el-radio>
|
||||
<el-radio label="small">小型</el-radio>
|
||||
<el-radio label="mini">超小</el-radio>
|
||||
</el-radio-group>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ele-cell">
|
||||
<div>主题设置:</div>
|
||||
<div class="ele-cell-content">
|
||||
<el-radio-group v-model="tagTheme">
|
||||
<el-radio label="light">light</el-radio>
|
||||
<el-radio label="dark">dark</el-radio>
|
||||
<el-radio label="plain">plain</el-radio>
|
||||
</el-radio-group>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
<el-card shadow="never" header="标签输入">
|
||||
<ele-tags-input v-model="tags" :size="tagSize" :effect="tagTheme" />
|
||||
<div style="margin: 8px 0">{{ JSON.stringify(tags) }}</div>
|
||||
<div style="margin: 8px 0">自定义异步验证:</div>
|
||||
<ele-tags-input
|
||||
:validator="validator"
|
||||
v-model="tags2"
|
||||
:size="tagSize"
|
||||
:effect="tagTheme"
|
||||
/>
|
||||
</el-card>
|
||||
<el-card shadow="never" header="状态文字" body-style="overflow: auto;">
|
||||
<div style="min-width: 360px">
|
||||
<div class="ele-cell">
|
||||
<div>默认效果:</div>
|
||||
<div class="ele-cell-content">
|
||||
<ele-dot :ripple="ripple" text="运行中" />
|
||||
<ele-dot type="success" :ripple="ripple" text="已上线" />
|
||||
<ele-dot type="danger" :ripple="ripple" text="异常" />
|
||||
<ele-dot type="info" :ripple="ripple" text="关闭" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="ele-cell">
|
||||
<div>大小设置:</div>
|
||||
<div class="ele-cell-content">
|
||||
<ele-dot :ripple="ripple" text="运行中" size="8px" />
|
||||
<ele-dot type="success" :ripple="ripple" text="已上线" size="8px" />
|
||||
<ele-dot type="danger" :ripple="ripple" text="异常" size="8px" />
|
||||
<ele-dot type="info" :ripple="ripple" text="关闭" size="8px" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="ele-cell">
|
||||
<div>显示动画:</div>
|
||||
<div class="ele-cell-content">
|
||||
<el-radio-group v-model="ripple">
|
||||
<el-radio :label="true">是</el-radio>
|
||||
<el-radio :label="false">否</el-radio>
|
||||
</el-radio-group>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'ExtensionTag',
|
||||
data() {
|
||||
return {
|
||||
tagSize: 'small',
|
||||
tagTheme: 'light',
|
||||
tags: ['标签一', '标签二', '标签三'],
|
||||
tags2: ['标签一', '标签二', '标签三'],
|
||||
ripple: true
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
validator(value) {
|
||||
return new Promise((resolve, reject) => {
|
||||
setTimeout(() => {
|
||||
reject(new Error(value + '不合法, 请重新输入'));
|
||||
}, 1000);
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.ele-cell + .ele-cell {
|
||||
margin-top: 16px;
|
||||
}
|
||||
|
||||
.ele-dot + .ele-dot {
|
||||
margin-left: 16px;
|
||||
}
|
||||
</style>
|
||||
@@ -1,150 +0,0 @@
|
||||
<template>
|
||||
<div class="ele-body">
|
||||
<el-card shadow="never" header="基本用法">
|
||||
<div>
|
||||
<el-button type="primary" @click="onStart1">开始引导</el-button>
|
||||
</div>
|
||||
<div style="margin-top: 20px">
|
||||
<el-button ref="uploadRef1">Upload</el-button>
|
||||
<el-button ref="saveRef1" type="primary">Save</el-button>
|
||||
<el-button ref="moreRef1">More</el-button>
|
||||
</div>
|
||||
</el-card>
|
||||
<el-card shadow="never" header="不带遮罩层">
|
||||
<div>
|
||||
<el-button type="primary" @click="onStart2">开始引导</el-button>
|
||||
</div>
|
||||
<div style="margin-top: 20px">
|
||||
<el-button ref="uploadRef2">Upload</el-button>
|
||||
<el-button ref="saveRef2" type="primary">Save</el-button>
|
||||
<el-button ref="moreRef2">More</el-button>
|
||||
</div>
|
||||
</el-card>
|
||||
<el-card shadow="never" header="混合弹窗等多种形式">
|
||||
<div>
|
||||
<el-button type="primary" @click="onStart3">开始引导</el-button>
|
||||
</div>
|
||||
<div style="margin-top: 20px">
|
||||
<el-button ref="uploadRef3">Upload</el-button>
|
||||
<el-button ref="saveRef3" type="primary">Save</el-button>
|
||||
<el-button ref="moreRef3">More</el-button>
|
||||
</div>
|
||||
</el-card>
|
||||
<ele-tour v-model="current1" :steps="steps1" />
|
||||
<ele-tour v-model="current2" :steps="steps2" :mask="false" />
|
||||
<ele-tour v-model="current3" :steps="steps3">
|
||||
<template #text="{ step, current }">
|
||||
<template v-if="current === 0">
|
||||
<div style="margin-bottom: 10px">
|
||||
<img
|
||||
src="https://gw.alipayobjects.com/mdn/rms_08e378/afts/img/A*P0S-QIRUbsUAAAAAAAAAAABkARQnAQ"
|
||||
style="height: 184px; width: 100%; object-fit: cover"
|
||||
/>
|
||||
</div>
|
||||
<div>{{ step.description }}</div>
|
||||
</template>
|
||||
</template>
|
||||
</ele-tour>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'ExtensionTour',
|
||||
data() {
|
||||
return {
|
||||
// 当前步骤
|
||||
current1: null,
|
||||
// 步骤
|
||||
steps1: [
|
||||
{
|
||||
target: () => this.$refs.uploadRef1?.$el,
|
||||
title: '如何进行文件上传',
|
||||
description: '点击这个按钮在弹出框中选择想要上传的文件即可.'
|
||||
},
|
||||
{
|
||||
target: () => this.$refs.saveRef1?.$el,
|
||||
title: '如何提交数据',
|
||||
description: '数据录入完成后点击这个按钮即可提交数据到后台.'
|
||||
},
|
||||
{
|
||||
target: () => this.$refs.moreRef1?.$el,
|
||||
title: '如何进行更多的操作',
|
||||
description: '鼠标移入到此按钮上即可展示出更多的操作功能.'
|
||||
}
|
||||
],
|
||||
// 当前步骤
|
||||
current2: null,
|
||||
// 按钮
|
||||
uploadRef2: null,
|
||||
saveRef2: null,
|
||||
moreRef2: null,
|
||||
// 步骤
|
||||
steps2: [
|
||||
{
|
||||
target: () => this.$refs.uploadRef2?.$el,
|
||||
title: '如何进行文件上传',
|
||||
description: '点击这个按钮在弹出框中选择想要上传的文件即可.',
|
||||
popoverProps: { placement: 'top-start' }
|
||||
},
|
||||
{
|
||||
target: () => this.$refs.saveRef2?.$el,
|
||||
title: '如何提交数据',
|
||||
description: '数据录入完成后点击这个按钮即可提交数据到后台.',
|
||||
popoverProps: { placement: 'bottom' }
|
||||
},
|
||||
{
|
||||
target: () => this.$refs.moreRef2?.$el,
|
||||
title: '如何进行更多的操作',
|
||||
description: '鼠标移入到此按钮上即可展示出更多的操作功能.',
|
||||
popoverProps: { placement: 'top-end' }
|
||||
}
|
||||
],
|
||||
// 当前步骤
|
||||
current3: null,
|
||||
// 按钮
|
||||
uploadRef3: null,
|
||||
saveRef3: null,
|
||||
moreRef3: null,
|
||||
// 步骤
|
||||
steps3: [
|
||||
{
|
||||
title: '欢迎使用 EleAdmin 系统',
|
||||
description:
|
||||
'下面将为您介绍一些常用功能的操作说明, 如果之前已经为您介绍过, 您可以直接点击跳过结束指引.'
|
||||
},
|
||||
{
|
||||
target: () => this.$refs.uploadRef3?.$el,
|
||||
title: '如何进行文件上传',
|
||||
description: '点击这个按钮在弹出框中选择想要上传的文件即可.'
|
||||
},
|
||||
{
|
||||
target: () => this.$refs.saveRef3?.$el,
|
||||
title: '如何提交数据',
|
||||
description: '数据录入完成后点击这个按钮即可提交数据到后台.',
|
||||
mask: false
|
||||
},
|
||||
{
|
||||
target: () => this.$refs.moreRef3?.$el,
|
||||
title: '如何进行更多的操作',
|
||||
description: '鼠标移入到此按钮上即可展示出更多的操作功能.'
|
||||
}
|
||||
]
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
/* 开始引导 */
|
||||
onStart1() {
|
||||
this.current1 = 0;
|
||||
},
|
||||
/* 开始引导 */
|
||||
onStart2() {
|
||||
this.current2 = 0;
|
||||
},
|
||||
/* 开始引导 */
|
||||
onStart3() {
|
||||
this.current3 = 0;
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@@ -1,30 +0,0 @@
|
||||
<template>
|
||||
<el-card shadow="never" header="可搜索">
|
||||
<div style="max-width: 260px">
|
||||
<ele-tree-select
|
||||
:data="data"
|
||||
v-model="value"
|
||||
:multiple="true"
|
||||
:clearable="true"
|
||||
:filterable="true"
|
||||
placeholder="请选择"
|
||||
:default-expand-all="true"
|
||||
/>
|
||||
</div>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import treeData from './tree-data';
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
// 可搜索
|
||||
value: [],
|
||||
// 数据
|
||||
data: treeData
|
||||
};
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@@ -1,59 +0,0 @@
|
||||
<template>
|
||||
<el-card shadow="never" header="基础用法">
|
||||
<div style="max-width: 260px">
|
||||
<ele-tree-select
|
||||
:data="data"
|
||||
v-model="value"
|
||||
:clearable="true"
|
||||
placeholder="请选择"
|
||||
:disabled="disabled"
|
||||
:default-expand-all="true"
|
||||
:expand-on-click-node="expandOnClickNode"
|
||||
/>
|
||||
</div>
|
||||
<div class="ele-cell" style="margin-top: 15px">
|
||||
<div style="line-height: 22px">
|
||||
<em></em><em></em><em></em>禁用:
|
||||
</div>
|
||||
<div class="ele-cell-content">
|
||||
<el-radio-group v-model="disabled">
|
||||
<el-radio :label="false">否</el-radio>
|
||||
<el-radio :label="true">是</el-radio>
|
||||
</el-radio-group>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ele-cell" style="margin-top: 15px">
|
||||
<div style="line-height: 22px"> 只能选子级:</div>
|
||||
<div class="ele-cell-content">
|
||||
<el-radio-group v-model="expandOnClickNode">
|
||||
<el-radio :label="false">否</el-radio>
|
||||
<el-radio :label="true">是</el-radio>
|
||||
</el-radio-group>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import treeData from './tree-data';
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
// 单选
|
||||
value: undefined,
|
||||
// 数据
|
||||
data: treeData,
|
||||
// 禁用
|
||||
disabled: false,
|
||||
// 只能选子级
|
||||
expandOnClickNode: false
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
expandOnClickNode() {
|
||||
this.value = '';
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@@ -1,136 +0,0 @@
|
||||
<template>
|
||||
<el-card shadow="never" header="懒加载">
|
||||
<div style="margin-bottom: 12px">单选:</div>
|
||||
<div style="max-width: 260px">
|
||||
<ele-tree-select
|
||||
v-model="value"
|
||||
:clearable="true"
|
||||
:lazy="true"
|
||||
placeholder="请选择"
|
||||
:load="loadNode"
|
||||
:init-value="initValue"
|
||||
/>
|
||||
</div>
|
||||
<div style="margin: 12px 0">多选:</div>
|
||||
<div style="max-width: 260px">
|
||||
<ele-tree-select
|
||||
v-model="value2"
|
||||
:multiple="true"
|
||||
:clearable="true"
|
||||
:lazy="true"
|
||||
placeholder="请选择"
|
||||
:load="loadNode"
|
||||
:init-value="initValue2"
|
||||
/>
|
||||
</div>
|
||||
<div style="margin-top: 12px">
|
||||
<el-button size="small" type="primary" @click="setInitValue">
|
||||
回显数据
|
||||
</el-button>
|
||||
</div>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
// 懒加载
|
||||
value: undefined,
|
||||
// 回显数据
|
||||
initValue: undefined,
|
||||
// 懒加载
|
||||
value2: [],
|
||||
// 回显数据
|
||||
initValue2: undefined
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
// 懒加载
|
||||
loadNode(node, resolve) {
|
||||
setTimeout(() => {
|
||||
if (!node.data) {
|
||||
resolve([
|
||||
{
|
||||
label: '系统管理',
|
||||
value: '1'
|
||||
},
|
||||
{
|
||||
label: '日志管理',
|
||||
value: '8'
|
||||
}
|
||||
]);
|
||||
} else if (node.data.value === '1') {
|
||||
resolve([
|
||||
{
|
||||
label: '用户管理',
|
||||
value: '2'
|
||||
},
|
||||
{
|
||||
label: '角色管理',
|
||||
value: '5'
|
||||
}
|
||||
]);
|
||||
} else if (node.data.value === '2') {
|
||||
resolve([
|
||||
{
|
||||
label: '添加用户',
|
||||
value: '3'
|
||||
},
|
||||
{
|
||||
label: '修改用户',
|
||||
value: '4'
|
||||
}
|
||||
]);
|
||||
} else if (node.data.value === '5') {
|
||||
resolve([
|
||||
{
|
||||
label: '添加角色',
|
||||
value: '6'
|
||||
},
|
||||
{
|
||||
label: '修改角色',
|
||||
value: '7'
|
||||
}
|
||||
]);
|
||||
} else if (node.data.value === '8') {
|
||||
resolve([
|
||||
{
|
||||
label: '登录日志',
|
||||
value: '9'
|
||||
},
|
||||
{
|
||||
label: '操作日志',
|
||||
value: '10'
|
||||
}
|
||||
]);
|
||||
return;
|
||||
} else {
|
||||
resolve([]);
|
||||
}
|
||||
}, 500);
|
||||
},
|
||||
// 回显数据
|
||||
setInitValue() {
|
||||
this.initValue = {
|
||||
value: '3',
|
||||
label: '添加用户'
|
||||
};
|
||||
this.initValue2 = [
|
||||
{
|
||||
value: '3',
|
||||
label: '添加用户'
|
||||
},
|
||||
{
|
||||
label: '修改角色',
|
||||
value: '7'
|
||||
},
|
||||
{
|
||||
label: '登录日志',
|
||||
value: '9'
|
||||
}
|
||||
];
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@@ -1,54 +0,0 @@
|
||||
<template>
|
||||
<el-card shadow="never" header="多选">
|
||||
<div style="max-width: 260px">
|
||||
<ele-tree-select
|
||||
:data="data"
|
||||
v-model="value"
|
||||
:multiple="true"
|
||||
:clearable="true"
|
||||
placeholder="请选择"
|
||||
:disabled="disabled"
|
||||
:default-expand-all="true"
|
||||
:check-strictly="checkStrictly"
|
||||
expandOnClickNode
|
||||
/>
|
||||
</div>
|
||||
<div class="ele-cell" style="margin-top: 15px">
|
||||
<div style="line-height: 22px"> <em></em><em></em>禁用:</div>
|
||||
<div class="ele-cell-content">
|
||||
<el-radio-group v-model="disabled">
|
||||
<el-radio :label="false">否</el-radio>
|
||||
<el-radio :label="true">是</el-radio>
|
||||
</el-radio-group>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ele-cell" style="margin-top: 15px">
|
||||
<div style="line-height: 22px"> 父子联动:</div>
|
||||
<div class="ele-cell-content">
|
||||
<el-radio-group v-model="checkStrictly">
|
||||
<el-radio :label="false">是</el-radio>
|
||||
<el-radio :label="true">否</el-radio>
|
||||
</el-radio-group>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import treeData from './tree-data';
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
// 多选
|
||||
value: [],
|
||||
// 数据
|
||||
data: treeData,
|
||||
// 禁用
|
||||
disabled: false,
|
||||
// 关闭父子联动
|
||||
checkStrictly: false
|
||||
};
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@@ -1,80 +0,0 @@
|
||||
export default [
|
||||
{
|
||||
label: '系统管理',
|
||||
value: '1',
|
||||
children: [
|
||||
{
|
||||
label: '用户管理',
|
||||
value: '2',
|
||||
children: [
|
||||
{
|
||||
label: '添加用户',
|
||||
value: '3'
|
||||
},
|
||||
{
|
||||
label: '修改用户',
|
||||
value: '4'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
label: '角色管理',
|
||||
value: '5',
|
||||
children: [
|
||||
{
|
||||
label: '添加角色',
|
||||
value: '6',
|
||||
disabled: false
|
||||
},
|
||||
{
|
||||
label: '修改角色',
|
||||
value: '7'
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
label: '日志管理',
|
||||
value: '8',
|
||||
children: [
|
||||
{
|
||||
label: '登录日志',
|
||||
value: '9'
|
||||
},
|
||||
{
|
||||
label: '操作日志',
|
||||
value: '10',
|
||||
disabled: false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
label: '列表页面',
|
||||
value: '11',
|
||||
children: [
|
||||
{
|
||||
label: '基础列表',
|
||||
value: '12'
|
||||
},
|
||||
{
|
||||
label: '卡片列表',
|
||||
value: '13',
|
||||
children: [
|
||||
{
|
||||
label: '项目',
|
||||
value: '14'
|
||||
},
|
||||
{
|
||||
label: '应用',
|
||||
value: '15'
|
||||
},
|
||||
{
|
||||
label: '文章',
|
||||
value: '16'
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
];
|
||||
@@ -1,20 +0,0 @@
|
||||
<template>
|
||||
<div class="ele-body">
|
||||
<demo-basic />
|
||||
<demo-multiple />
|
||||
<demo-lazy />
|
||||
<demo-advanced />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import DemoBasic from './components/demo-basic.vue';
|
||||
import DemoMultiple from './components/demo-multiple.vue';
|
||||
import DemoLazy from './components/demo-lazy.vue';
|
||||
import DemoAdvanced from './components/demo-advanced.vue';
|
||||
|
||||
export default {
|
||||
name: 'ExtensionTreeSelect',
|
||||
components: { DemoBasic, DemoMultiple, DemoLazy, DemoAdvanced }
|
||||
};
|
||||
</script>
|
||||
@@ -1,100 +0,0 @@
|
||||
<template>
|
||||
<el-card shadow="never" header="手动上传">
|
||||
<ele-image-upload
|
||||
v-model="images"
|
||||
:auto-upload="false"
|
||||
:before-remove="onBeforeRemove"
|
||||
/>
|
||||
<div>
|
||||
<el-button
|
||||
type="primary"
|
||||
size="small"
|
||||
:loading="loading"
|
||||
@click="onSubmit"
|
||||
>
|
||||
提交
|
||||
</el-button>
|
||||
</div>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import EleImageUpload from 'ele-admin/es/ele-image-upload';
|
||||
|
||||
export default {
|
||||
components: { EleImageUpload },
|
||||
data() {
|
||||
return {
|
||||
images: [
|
||||
{
|
||||
uid: 1,
|
||||
url: 'https://cdn.eleadmin.com/20200609/c184eef391ae48dba87e3057e70238fb.jpg',
|
||||
status: 'done'
|
||||
},
|
||||
{
|
||||
uid: 2,
|
||||
url: 'https://cdn.eleadmin.com/20200610/WLXm7gp1EbLDtvVQgkeQeyq5OtDm00Jd.jpg',
|
||||
status: 'done'
|
||||
}
|
||||
],
|
||||
loading: false
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
/* 手动上传 */
|
||||
onSubmit() {
|
||||
if (this.checkDone()) {
|
||||
this.submitForm();
|
||||
return;
|
||||
}
|
||||
this.loading = true;
|
||||
this.images.forEach((item) => {
|
||||
if (!item.status) {
|
||||
this.uploadItem(item);
|
||||
}
|
||||
});
|
||||
},
|
||||
/* 上传图片 */
|
||||
uploadItem(item) {
|
||||
// 模拟上传
|
||||
item.progress += 20;
|
||||
item.status = 'uploading';
|
||||
const timer = setInterval(() => {
|
||||
item.progress += 20;
|
||||
if (item.progress === 100) {
|
||||
item.status = 'done';
|
||||
clearInterval(timer);
|
||||
// 每个图片上传完成后都检查是否全部上传完成
|
||||
if (this.checkDone()) {
|
||||
this.submitForm();
|
||||
}
|
||||
}
|
||||
}, Math.round(Math.random() * 2500) + 500);
|
||||
},
|
||||
/* 检查是否全部上传完毕 */
|
||||
checkDone() {
|
||||
return !this.images.some((d) => d.status !== 'done');
|
||||
},
|
||||
/* 全部上传完毕后与其它表单数据一起提交 */
|
||||
submitForm() {
|
||||
this.$message.success('已全部上传完毕');
|
||||
console.log('data:', this.images);
|
||||
this.loading = false;
|
||||
},
|
||||
/* 删除增加确认弹窗 */
|
||||
onBeforeRemove() {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.$confirm('确定要删除吗?', '提示', {
|
||||
type: 'warning'
|
||||
})
|
||||
.then(() => {
|
||||
resolve();
|
||||
})
|
||||
.catch(() => {
|
||||
reject();
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user