Browse Source

Merge branch 'Luckysheet-mk' into luckysheet

luckysheet-xiaowang-Intelligen
mk 9 months ago
parent
commit
619dac5c69
  1. 40
      src/utils/luckysheetConfig.js
  2. 9
      src/views/components/resiSearch.vue
  3. 290
      src/views/modules/base/smartExcel/cpts/excel-upload-data.vue
  4. 146
      src/views/modules/base/smartExcel/cpts/excel-view.vue
  5. 130
      src/views/modules/base/smartExcel/cpts/hose-search.vue

40
src/utils/luckysheetConfig.js

@ -3,46 +3,6 @@ const options = {
container: 'luckysheet', // 设定DOM容器的id
lang: 'zh', // 设定表格语言
showtoolbar: true, //是否显示工具栏
showtoolbarConfig: {
//自定义配置工具栏
undoRedo: true, // 撤销重做,注意撤销重做是两个按钮,由这一个配置决定显示还是隐藏
paintFormat: true, //格式刷
currencyFormat: false, //货币格式
percentageFormat: false, //百分比格式
numberDecrease: false, // '减少小数位数'
numberIncrease: false, // '增加小数位数'
moreFormats: false, // '更多格式'
font: true, // '字体'
fontSize: true, // '字号大小'
bold: true, // '粗体(Ctrl + B)'
italic: true, // '斜体(Ctrl + I)'
strikethrough: true, //删除线(Alt + Shift + 5)
underline: true, // 下划线(Alt + Shift + 6)
textColor: true, //文本颜色
fillColor: true, // 单元格颜色
border: true, // 边框
mergeCell: true, //合并单元格
horizontalAlignMode: true, //水平对齐方式
verticalAlignMode: true, //垂直对齐方式
textWrapMode: false, //换行方式
textRotateMode: false, //文本旋转方式
image: false, //插入图片
link: false, //插入链接
chart: false, //图表(图标隐藏,但是如果配置了chart插件,右击仍然可以新建图表)
postil: false, //批注
pivotTable: true, //数据透视表
function: true, //公式
frozenMode: true, //冻结方式
sortAndFilter: true, //排序和筛选
conditionalFormat: true, //条件格式
dataVerification: true, //数据验证
splitColumn: false, //分列
screenshot: false, //截图
findAndReplace: true, //查找替换
protection: true, // 工作表保护
print: true, //打印
},
showinfobar: true, //是否显示顶部信息栏
showsheetbar: true, //是否显示底部sheet页按钮
cellRightClickConfig:{

9
src/views/components/resiSearch.vue

@ -34,7 +34,7 @@
<el-cascader
size="small"
class="u-item-width-normal"
v-model.trim="form.attentionCrowds" @change="handleChange"
v-model.trim="form.attentionCrowds"
:options="resiClass"
:props="{ multiple: true,checkStrictly: true,emitPath:false}"
collapse-tags
@ -1005,13 +1005,6 @@ export default {
}, 300)); // 300ms
},
methods: {
handleChange(val){
console.log(this.form.attentionCrowds,"dskljldsks");
console.log(val,"dslkjflkdsklfjdskl");
},
handleCategoryChange(newVal, oldVal) {
console.log(newVal, oldVal,"slkdfjlfj");

290
src/views/modules/base/smartExcel/cpts/excel-upload-data.vue

@ -1,64 +1,145 @@
<template>
<div class="m-detail-main">
<div class="steps1">
<el-steps :active="progress">
<el-step
:class="[this.operatorName == null ? 'showNum' : '']"
title="填写基本信息"
:description="`${this.operatorName}(${this.createdTime})`"
></el-step>
<el-step
title="上传表格文件"
:class="[this.progress == 2 || this.progress == 3 ? '' : 'showNum']"
></el-step>
<el-step title="配置表格文字"></el-step>
</el-steps>
<div class="steps1">
<el-steps :active="progress">
<el-step :class="[this.operatorName == null ? 'showNum' : '']" title="填写基本信息"
:description="`${this.operatorName}(${this.createdTime})`"></el-step>
<el-step title="上传表格文件" :class="[this.progress == 2 || this.progress == 3 ? '' : 'showNum']"></el-step>
<el-step title="配置表格文字"></el-step>
</el-steps>
</div>
<div v-show="progress == 1">
<el-form :model="formData" ref="ref_searchform" :label-width="'120px'">
<el-form-item label="标题名称" prop="taskTitle">
<el-input v-model.trim="formData.taskTitle" type="textarea" size="small" clearable style=" height: 40px;"
placeholder="请输入">
</el-input>
<div style="margin-top: 10px;">5-30个字符</div>
</el-form-item>
<el-form-item label="请选择数据源" prop="taskTitle">
</el-form-item>
</el-form>
<div class="flex">
<div @click="onClickTab(item)" class="flex"
style=" cursor: pointer; position: relative;display: flex; flex-direction: column; align-items: center; justify-content: center; width: 155px;height: 90px;background: #F1F4FA;border-radius: 4px; margin-left: 20px;"
v-for="(item, index) in dataSourceList">
<img style="width: 30px; height: 30px;" :src="item.image" alt="">
<span style="margin-top: 10px;">{{ item.name }}</span>
<img v-if="item.status" style="width: 30px; height: 30px;position: absolute; top: 0;right: 0;"
src="@/assets/images/index/select.png" alt="">
<img v-if="!item.status" style="width: 30px; height: 30px;position: absolute; top: 0;right: 0;"
src="@/assets/images/index/notselect.png" alt="">
</div>
</div>
<div style="margin-top: 37px;margin-bottom: 37px">
<excelCeatedTask ref="excelCeatedTask"
v-if="progress == 1"
:progress="progress"
@handelClickUpload="handelClickUpload"
@handelClickBack="handelClickBack"
></excelCeatedTask>
<excelCeatedTask
v-if="progress == 2"
:key="progress"
:fileCode="fileCode"
:tableData="dataList"
:progress="progress"
></excelCeatedTask>
<div v-if="progress == 2">111</div>
<excelCeatedTask
v-if="progress == 3"
@handelClickBack="handelClickBack"
:fileCodeRow="fileCodeRow"
@updateoperatorName="updateoperatorName"
:fileCode="fileCode"
></excelCeatedTask>
</div>
<div v-show="dataList.length > 0 && progress == 2" style="height: 600px; overflow-y: scroll">
<el-table ref="ref_table" :data="dataList" border class="m-table-item" style="width: 100%">
<el-table-column label="序号" header-align="center" align="center" type="index" width="100"></el-table-column>
<el-table-column prop="userTableHeader" header-align="center" align="center" label="上传表格列" min-width="60">
<template slot-scope="scope">
<span :class="[
scope.row.itemId && scope.row.itemId != ''
? ''
: 'font_color_red',
]">{{ scope.row.userTableHeader || "--" }}</span>
</template>
</el-table-column>
<el-table-column header-align="center" align="center" label="对应到" min-width="30">
<template slot-scope="scope"><span v-if="scope.row.itemId"> =></span> </template>
</el-table-column>
<el-table-column prop="itemGroupId" header-align="center" align="center" label="系统字段" min-width="110">
<template slot-scope="scope">
<div>
<el-select class="item_width_sel" v-model.trim="scope.row.itemGroupId" size="small" placeholder="请选择">
<el-option v-for="item in groupList" @click.native="handleSelGroup(scope.$index, item, 'change')"
:key="item.fileModeCode" :label="item.fileModeName" :value="item.fileModeName">
</el-option>
</el-select>
<el-select class="item_width_sel" v-model.trim="scope.row.itemId" size="small" style="margin-left: 10px"
placeholder="请选择">
<el-option v-for="item in scope.row.itemList" :key="item.itemId" :label="item.columnName"
:value="item.columnName">
</el-option>
</el-select>
</div>
</template>
</el-table-column>
</el-table>
</div>
<div v-show="progress == 3">
<div v-if="formData1.importCategory === 'resident_base_info'">
<resi-search ref="resi_form"></resi-search>
</div>
<span slot="footer" style="margin-top: 100px;">
<el-button v-if="progress!=1" @click="progress=progress-1"
>上一步</el-button
>
<el-button type="primary" @click="onClickNext()"
>下一步</el-button
>
</span>
<div v-else>
<HoseSearch ref="house_form"/>
</div>
</div>
<span slot="footer" style="margin-top: 100px;">
<el-button v-if="progress != 1" @click="progress = progress - 1">上一步</el-button>
<el-button type="primary" @click="onClickNext()">下一步</el-button>
</span>
</div>
</template>
<script>
import { requestPost } from "@/js/dai/request";
import excelCeatedTask from './excel-created-task.vue';
<script>
import { requestPost } from "@/js/dai/request";
import resiSearch from "../../../../components/resiSearch.vue";
import HoseSearch from "./hose-search.vue";
export default {
data() {
return {
dataList:[],
dataList: [],
progress: 1,
fileCode: null,
progressNum: null,
createdTime: null,
operatorName: null,
formData1: {
id: 0,
name: "楼栋房屋信息一张表",
image: "https://elink-esua-epdc.oss-cn-qingdao.aliyuncs.com/epmet-saas/dev/internal/20250114/003b8782213a487b8ce7d4267262d0ec.png",
status: 1,
importCategory: "resident_base_info",
originalFilePath: "https://elink-esua-epdc.oss-cn-qingdao.aliyuncs.com/epmet-saas/dev/20250115/c4102136584140aeaf323767361a1e92.xls"
},
dataSourceList: [
{
id: 1,
name: "居民信息一张表",
image: "https://elink-esua-epdc.oss-cn-qingdao.aliyuncs.com/epmet-saas/dev/internal/20250114/0c1e1ea17f8842e49bf5f1afeac72e42.png",
status: 1,
importCategory: "community_info",
originalFilePath: "https://elink-esua-epdc.oss-cn-qingdao.aliyuncs.com/epmet-saas/dev/20250115/1acd160dd0fe41409cddd461b4eb0328.xls"
},
{
id: 0,
name: "楼栋房屋信息一张表",
image: "https://elink-esua-epdc.oss-cn-qingdao.aliyuncs.com/epmet-saas/dev/internal/20250114/003b8782213a487b8ce7d4267262d0ec.png",
status: 0,
importCategory: "resident_base_info",
originalFilePath: "https://elink-esua-epdc.oss-cn-qingdao.aliyuncs.com/epmet-saas/dev/20250115/c4102136584140aeaf323767361a1e92.xls"
},
// {
// id:2,
// name:"",
// image:"https://elink-esua-epdc.oss-cn-qingdao.aliyuncs.com/epmet-saas/dev/internal/20250114/211af7c657c9409fbccd11185edf0474.png",
// status:0
// },
// {
// id:3,
// name:"",
// image:"https://elink-esua-epdc.oss-cn-qingdao.aliyuncs.com/epmet-saas/dev/internal/20250114/bc3e4b1e89e84ed7bc31eb90bba6cbd6.png",
// status:0
// },
],
formData: {
columnMateJson: '',
searchForm: {},
formCode:''
},
resident_category_import_list: [],
groupList: [],
fileCode: null,
dataList: [],
};
},
props: {
@ -74,33 +155,104 @@ export default {
type: String,
default: null,
},
currentTable: {
type: Array,
default: () => []
}
},
created() {
this.loadPersonGroup();
},
methods: {
async onClickNext(){
console.log(this.$refs.excelCeatedTask.formData1,"sdfkljjslkdf");
await this.checkExtractExcelHead()
if (this.progress == 1) {
console.log("2");
this.progress=2
onClickTab(value) {
this.formData1 = {}
this.dataSourceList.filter(item => item.status === 1).forEach(item => {
item.status = 0;
});
this.dataSourceList.filter(item1 => item1.id === value.id).forEach(item2 => {
item2.status = 1;
},
this.formData1 = this.dataSourceList[value.id],
this.formData.formCode = this.dataSourceList[value.id].importCategory
);
},
onClickNext() {
if (this.progress === 1) {
this.progress = 2;
this.checkExtractExcelHead()
} else if (this.progress === 2) {
let obj = this.dataList.reduce((acc, item) => {
if (item.userTableHeader) {
acc[item.userTableHeader] = item.itemId;
}
return acc;
}, {});
this.formData.columnMateJson = JSON.stringify(obj)
this.progress = 3;
} else {
if(this.formData1.importCategory === 'resident_base_info'){
this.formData.searchForm= this.$refs['resi_form'].form;
}else{
this.formData.searchForm= this.$refs['house_form'].form;
}
this.$emit('saveUploadForm',this.formData)
}
},
async loadPersonGroup() {
const url = "/oper/customize/fileModeColumns/listModule";
// const url = 'http://yapi.elinkservice.cn/mock/245/gov/org/isServiceProject/service/serviceScopeTree'
const { data, code, msg } = await requestPost(url);
if (code === 0) {
this.groupList = data;
} else {
this.$message.error(msg);
}
},
async handleSelGroup(index, item, change) {
const url = "/oper/customize/fileModeColumns/listField";
// const url = 'http://yapi.elinkservice.cn/mock/245/gov/org/isServiceProject/service/serviceScopeTree'
let params = {
REVISION: 1010,
fileModeCode: this.formData1.importCategory,
};
const { data, code, msg } = await requestPost(url, params);
if (code === 0) {
let oneData = this.dataList[index];
if (change == "change") {
this.dataList[index].itemId = "";
}
oneData.itemList = data;
this.$set(this.dataList, index, oneData);
} else {
this.$message.error(msg);
}
},
async checkExtractExcelHead() {
const columnMateStr = this.currentTable[0].data[0]
.filter(item => item && item.v != null)
.map(item => item.v)
.join(';');
const url = "/actual/base/intelligentImportData/extractImportHead";
let params = {
importCategory: "BASEINFO",
columnMateStr:"网格名称;小区名称;楼栋名称;单元名称;门牌号;姓名;手机号;证件号;"
importCategory: this.formData1.importCategory,
columnMateStr
};
const { data, code, msg } = await requestPost(url, params);
if (code === 0) {
this.dataList = data.metaListData;
console.log( this.dataList,"sdfkljsdklf");
const { metaListData, fileCode, msg } = data;
this.dataList = metaListData;
let groupMap = new Map(
this.groupList.map((item) => [item.label, item])
);
for (let i in this.dataList) {
this.handleSelGroup(i, groupMap.get(this.dataList[i].fileModeCode));
}
this.dataListLoading = false;
} else if (code >= 8000) {
this.$message.err(msg);
this.dataListLoading = false;
}
},
handelClickUpload(fileCode) {
@ -115,10 +267,10 @@ export default {
this.progressNum = 100;
},
updateProgress(num) {
if(num > 100){
if (num > 100) {
this.progress = 3;
this.progressNum = 100;
}else{
} else {
this.progressNum = num;
}
},
@ -127,19 +279,23 @@ export default {
this.createdTime = createdTime;
},
},
components: {excelCeatedTask },
components: {resiSearch,HoseSearch},
computed: {},
watch: {},
};
</script>
<style lang="scss" scoped>
<style lang="scss" scoped>
@import "@/assets/scss/buttonstyle.scss";
@import "@/assets/scss/modules/management/detail-main.scss";
@import "@/assets/scss/pages/smartImport.scss";
.showUploadData {
width: 110px;
}
.showNum {
/deep/.el-step__description {
display: none;
}
}
</style>
</style>

146
src/views/modules/base/smartExcel/cpts/excel-view.vue

@ -6,7 +6,7 @@
<section v-if="!sheetTotal">
<div :class="{ 'menu_item': true, 'active': menuActive === index }" v-for="(item, index) in menuList" :key="index"
@click="handleClickMenu(index,item)">
<span>{{ item.name }}{{pageType}}</span>
<span>{{ item.name }}</span>
<i class="el-icon-arrow-right"></i>
</div>
</section>
@ -14,19 +14,19 @@
<div class="flex flex-y flex1 luckysheet-wrap">
<div class="top_btn flex flex-end">
<div>
<el-button type="warning" @click="getAllTables" v-if="pageType === 'add'"> 自动检测</el-button>
<el-button type="warning" v-if="pageType === 'add'"> 自动检测</el-button>
<el-button type="success" @click="onClickUplond()" v-else> 智能填表</el-button>
</div>
<div>
<el-button type="danger" v-if="pageType === 'add'"> 驳回重提</el-button>
<el-button type="primary" v-if="pageType === 'add'"> 审核存档</el-button>
<el-button type="success" v-if="pageType === 'filling'"> 保存</el-button>
<el-button type="primary" v-if="pageType === 'filling'"> 保存</el-button>
</div>
</div>
<div id="luckysheet"></div>
</div>
<el-dialog title="上传共享数据" :visible.sync="showUploadData" width="50%" :close-on-click-modal="false">
<excelUploadData @handelUploadData="handelUploadData">
<el-dialog title="上传共享数据" v-if="showUploadData" :visible.sync="showUploadData" width="60%" :close-on-click-modal="false">
<excelUploadData @handelUploadData="handelUploadData" :currentTable="currentTable" @saveUploadForm="saveUploadForm">
</excelUploadData>
</el-dialog>
</div>
@ -86,7 +86,6 @@ export default {
computed: {
tableHeight() {
return (this.clientHeight - 140) + 'px'
},
...mapGetters(['clientHeight', 'resolution']),
},
@ -105,8 +104,37 @@ export default {
})
},
methods: {
async saveUploadForm(val){
const url = '/actual/base/residentBaseInfo/exportOneSheet'
const {data,code,msg} = await requestPost(url,val)
if(code === 0){
this.showUploadData = false
this.updataSheet(data)
}else{
console.log(msg);
}
},
onClickUplond(){
this.showUploadData=true
this.showUploadData=true;
let list = luckysheet.getAllSheets()
this.currentTable = list.filter(item => item.status == '1')
const findLastNonNullIndex = (arr) => {
for (let i = arr.length - 1; i >= 0; i--) {
const subArray = arr[i];
// null
if (Array.isArray(subArray) && subArray.some(item => item !== null && item.v && item.v !== null&& item.v !== '')) {
return i; //
}
}
return -1; // -1
};
this.sheetR = findLastNonNullIndex(this.currentTable[0].data)
if(this.sheetR != -1){
luckysheet.insertRow(this.currentTable[0].data.length,5)
// this.updataSheet()
}
},
handelUploadData(){
this.showUploadData=false
@ -153,7 +181,7 @@ export default {
uploadExcel(files) {
if (files == null || files.length == 0) return alert('没有文件等待导入');
let name = files[0].name;//
let name = files[0].name;
let suffixArr = name.split('.'),
suffix = suffixArr[suffixArr.length - 1];
debugger
@ -177,69 +205,49 @@ export default {
handelClickBack() {
this.$emit('close')
},
getAllTables() {
let list = luckysheet.getAllSheets()
this.currentTable = list.filter(item => item.status == '1')
const findLastNonNullIndex = (arr) => {
for (let i = arr.length - 1; i >= 0; i--) {
const subArray = arr[i];
// null
if (Array.isArray(subArray) && subArray.some(item => item !== null && item.v && item.v !== null&& item.v !== '')) {
return i; //
}
}
return -1; // -1
};
this.sheetR = findLastNonNullIndex(this.currentTable[0].data)
console.log(this.sheetR);
if(this.sheetR != -1){
luckysheet.insertRow(this.currentTable[0].data.length,5)
this.updataSheet()
}
},
updataSheet() {
updataSheet(list) {
let arr = [
{
1: '张三1',
2: '证件类型1',
3: '1234',
4: '456',
5: '国籍',
6: '性别',
7: '出生日期',
8: '所属社区',
9: '所属网格',
10: '所属小区',
11: '楼栋名称',
12: '单元号',
13: '门牌号',
14: '人房关系',
15: '人户状况',
16: '与户主关系',
17: '民族'
},
{
1: '张三12',
2: '证件类型12',
3: '12342',
4: '4562',
5: '国籍2',
6: '性别2',
7: '出生日期2',
8: '所属社区2',
9: '所属网格2',
10: '所属小区2',
11: '楼栋名称2',
12: '单元号2',
13: '门牌号2',
14: '人房关系2',
15: '人户状况2',
16: '与户主关系2',
17: '民族'
}
// {
// 1: '1',
// 2: '1',
// 3: '1234',
// 4: '456',
// 5: '',
// 6: '',
// 7: '',
// 8: '',
// 9: '',
// 10: '',
// 11: '',
// 12: '',
// 13: '',
// 14: '',
// 15: '',
// 16: '',
// 17: ''
// },
// {
// 1: '12',
// 2: '12',
// 3: '12342',
// 4: '4562',
// 5: '2',
// 6: '2',
// 7: '2',
// 8: '2',
// 9: '2',
// 10: '2',
// 11: '2',
// 12: '2',
// 13: '2',
// 14: '2',
// 15: '2',
// 16: '2',
// 17: ''
// }
]
arr.forEach((item, index) => {
list.forEach((item, index) => {
luckysheet.insertRow(this.currentTable[0].data.length,1)
for (let k in item) {
luckysheet.setCellValue(index+this.sheetR + 1, k - 1, item[k])

130
src/views/modules/base/smartExcel/cpts/hose-search.vue

@ -0,0 +1,130 @@
<template>
<div class=''>
<el-form :inline="true" class="communityHeight" ref="ref_searchform" :label-width="'100px'">
<el-form-item label="房主姓名" prop="ownerName">
<el-input v-model.trim="form.ownerName" class="u-item-width-normal" size="small" clearable
placeholder="请输入内容">
</el-input>
</el-form-item>
<el-form-item label="联系电话" prop="ownerPhone">
<el-input v-model.trim="form.ownerPhone" class="u-item-width-normal" size="small" clearable
placeholder="请输入联系电话">
</el-input>
</el-form-item>
<el-form-item label="房屋状态" prop="rentFlag">
<el-select class="u-item-width-normal" v-model.trim="form.rentFlag" placeholder="请选择" size="small" clearable>
<el-option v-for="item in rentList" :key="item.value" :label="item.label" :value="item.value">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="房屋用途" prop="purpose">
<el-select v-model.trim="form.purpose" class="u-item-width-normal" placeholder="请选择" size="small" clearable>
<el-option v-for="item in purposeArr" :key="item.dictValue" :label="item.dictName"
:value="item.dictValue">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="更新时间" prop="updateStartDate">
<el-date-picker v-model.trim="form.updateStartDate" :picker-options="startPickerOptions"
class="u-item-width-daterange" size="small" type="datetime" value-format="yyyy-MM-dd HH:mm:ss"
value="yyyy-MM-dd" placeholder="开始时间">
</el-date-picker>
<span class="u-data-tag"></span>
<el-date-picker v-model.trim="form.updateEndDate" :picker-options="endPickerOptions"
class="u-item-width-daterange u-data-tag" size="small" type="datetime"
value-format="yyyy-MM-dd HH:mm:ss" value="yyyy-MM-dd" placeholder="结束时间">
</el-date-picker>
</el-form-item>
<el-form-item label="居住人数" prop="resiNumber">
<el-select v-model.trim="form.resiNumber" class="u-item-width-normal" placeholder="请选择" size="small"
clearable>
<el-option v-for="(item, index) in 7" :key="index" :label="index" :value="index">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input v-model.trim="form.remark" class="u-item-width-normal" size="small" clearable placeholder="请输入备注">
</el-input>
</el-form-item>
</el-form>
</div>
</template>
<script>
export default {
data() {
let endDisabledDate = (time) => {
//datareturn
let nowData = Date.now();
if (this.updateStartDate) {
let startTime = new Date(this.updateStartDate);
return (
time.getTime() > nowData ||
time.getTime() < startTime ||
time.getTime() === startTime
);
} else {
return time.getTime() > nowData;
}
};
let startDisabledDate = (time) => {
//datareturn
let nowData = Date.now();
return time.getTime() > nowData;
};
return {
endPickerOptions: {
disabledDate: endDisabledDate,
},
startPickerOptions: {
disabledDate: startDisabledDate,
},
form: {
ownerName: "",
ownerPhone: "",
rentFlag: "",
purpose: "",
remark: "",
updateStartDate: "",
updateEndDate: "",
resiNumber: "",
},
rentList: [
{
value: "1",
label: "出租",
},
{
value: "2",
label: "闲置",
},
{
value: "0",
label: "自住",
},
{
value: "3",
label: "未出售",
},
],
purposeArr: [
{ dictValue: "1", dictName: "住宅" },
{ dictValue: "2", dictName: "商业" },
{ dictValue: "3", dictName: "办公" },
{ dictValue: "4", dictName: "工业" },
{ dictValue: "5", dictName: "仓储" },
{ dictValue: "6", dictName: "商住混用" },
{ dictValue: "7", dictName: "其他" },
],
};
},
created() { },
methods: {},
components: {},
computed: {},
watch: {},
}
</script>
<style lang='scss' scoped></style>
Loading…
Cancel
Save