修改
This commit is contained in:
parent
0c9cb50548
commit
bfa6f73975
@ -62,7 +62,18 @@ export function changePassword(data) {
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: 获取短信验证码
|
||||
*/
|
||||
export function sendSms(data) {
|
||||
return http.request(
|
||||
{
|
||||
url: `/sms/sendSms`,
|
||||
method: 'POST',
|
||||
data
|
||||
}
|
||||
);
|
||||
}
|
||||
/**
|
||||
* @description: 用户登出
|
||||
*/
|
||||
@ -142,6 +153,16 @@ export function userBatchDelete(data:any) {
|
||||
data
|
||||
});
|
||||
}
|
||||
/**
|
||||
* @description: 导入用户
|
||||
*/
|
||||
export function userImport(data) {
|
||||
return http.request({
|
||||
url: '/user/import',
|
||||
method: 'POST',
|
||||
data
|
||||
});
|
||||
}
|
||||
/**
|
||||
* @description: 导出用户
|
||||
*/
|
||||
@ -153,6 +174,16 @@ export function userExport() {
|
||||
isTransformResponse: false,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: 下载模板
|
||||
*/
|
||||
export function getTemplateByCode(code:any) {
|
||||
return http.request({
|
||||
url: '/file/template/getTemplateByCode/'+code,
|
||||
method: 'GET'
|
||||
});
|
||||
}
|
||||
/**
|
||||
* @description: 城市列表
|
||||
*/
|
||||
|
@ -8,6 +8,7 @@
|
||||
:layout="layout"
|
||||
:total="pager.count"
|
||||
:hide-on-single-page="false"
|
||||
background
|
||||
@size-change="sizeChange"
|
||||
@current-change="pageChange"
|
||||
></el-pagination>
|
||||
|
@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<PageWrapper>
|
||||
<el-row :gutter="10" class="mt-3">
|
||||
<el-col :xs="24" :sm="24" :md="8" :lg="8" :xl="8" class="mb-4">
|
||||
<el-col :xs="24" :sm="24" :md="7" :lg="7" :xl="7" class="mb-4">
|
||||
<el-card shadow="hover" class="border-0">
|
||||
<template #header>
|
||||
<el-row>
|
||||
@ -15,36 +15,40 @@
|
||||
</el-input>
|
||||
</el-col>
|
||||
<el-col :span="4" style="text-align: right;">
|
||||
<el-button type="primary" @click="reloadTable"> 查询 </el-button>
|
||||
<el-button type="primary" @click="pager.page=1;loadDataTable()"> 查询 </el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<div style="margin-top:15px;">
|
||||
<el-button type="primary" @click="addConfig">新建</el-button>
|
||||
<el-button type="danger" :disabled="!selectionData.length" @click="handleDelete()">删除</el-button>
|
||||
<el-button type="primary" icon="Plus" @click="addConfig" v-perm="['sys:config:add']">新建</el-button>
|
||||
<el-button type="warning" icon="Edit" @click="handleEdit" v-perm="['sys:config:edit']">编辑</el-button>
|
||||
<el-button type="danger" icon="Delete" @click="handleDelete()" v-perm="['sys:config:delete']">删除</el-button>
|
||||
</div>
|
||||
</template>
|
||||
<BasicTable :columns="columns" :showTableSetting="false" :request="loadDataTable" :row-key="(row) => row.id"
|
||||
ref="tableRef" :actionColumn="actionColumn" @selection-change="onSelectionChange" highlight-current-row
|
||||
@row-click="onCheckedRow" />
|
||||
<div :style="{ height: fwbHeight + 'px' }" class="dict-list-box">
|
||||
<div v-for="(item, index) in configDataList" :key="index" @click="onCheckedRow(item)" class="dict-item"
|
||||
:class="item.id == configId ? 'active' : ''">
|
||||
<span class="t1">{{ item.name }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<pagination style="justify-content: flex-end" class="mt-10 flex" @change="loadDataTable" v-model="pager" layout="total, jumper">
|
||||
</pagination>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="24" :md="16" :lg="16" :xl="16" class="mb-4">
|
||||
<el-col :xs="24" :sm="24" :md="17" :lg="17" :xl="17" class="mb-4">
|
||||
<el-card shadow="hover" class="mb-4 border-0 proCard">
|
||||
<configItem :configId="configId" v-if="configItemShow"></configItem>
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<editDialog v-if="editVisible" :configId="configId" v-model:visible="editVisible" @success="reloadTable">
|
||||
<editDialog v-if="editVisible" :configId="configId" v-model:visible="editVisible" @success="loadDataTable()">
|
||||
</editDialog>
|
||||
</PageWrapper>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, reactive, h, nextTick, defineAsyncComponent } from 'vue';
|
||||
import { ref,nextTick, defineAsyncComponent,onMounted } from 'vue';
|
||||
import { SearchOutlined } from '@vicons/antd';
|
||||
import { TableAction } from '@/components/Table';
|
||||
import { getConfigList, configDelete, configBatchDelete } from '@/api/data/config';
|
||||
import { columns } from './columns';
|
||||
import { getConfigList, configDelete } from '@/api/data/config';
|
||||
import configItem from './configItem.vue';
|
||||
import { message, confirm } from "@/utils/auth";
|
||||
const editDialog = defineAsyncComponent(() =>
|
||||
@ -54,86 +58,52 @@ const configId = ref(0)
|
||||
const configItemShow = ref(false)
|
||||
const tableRef = ref();
|
||||
const editVisible = ref(false)
|
||||
const selectionData = ref([])
|
||||
const params = ref({
|
||||
name: '',
|
||||
});
|
||||
|
||||
const actionColumn = reactive({
|
||||
lable: 150,
|
||||
title: '操作',
|
||||
prop: 'action',
|
||||
fixed: 'right',
|
||||
render(record) {
|
||||
return h(TableAction as any, {
|
||||
style: 'text',
|
||||
actions: [
|
||||
{
|
||||
label: '编辑',
|
||||
icon:'Edit',
|
||||
type: 'warning',
|
||||
onClick: handleEdit.bind(null, record),
|
||||
},
|
||||
{
|
||||
label: '删除',
|
||||
icon:'Delete',
|
||||
type: 'danger',
|
||||
onClick: handleDelete.bind(null, record),
|
||||
}
|
||||
],
|
||||
});
|
||||
},
|
||||
const configDataList = ref([])
|
||||
const pager = ref({
|
||||
page: 1,
|
||||
size: 10,
|
||||
count: configDataList.value.length
|
||||
});
|
||||
const fwbHeight = document.body.clientHeight - 390
|
||||
|
||||
|
||||
//新建字典
|
||||
const addConfig = async () => {
|
||||
configId.value=0
|
||||
await nextTick();
|
||||
editVisible.value=true
|
||||
};
|
||||
//编辑字典
|
||||
const handleEdit = async (record: Recordable) => {
|
||||
configId.value=record.row.id
|
||||
await nextTick();
|
||||
|
||||
const handleEdit = () => {
|
||||
editVisible.value=true
|
||||
};
|
||||
//选择字典项
|
||||
|
||||
function onCheckedRow(row) {
|
||||
configId.value = row.id
|
||||
}
|
||||
|
||||
//刷新字典项值列表
|
||||
function reloadTable() {
|
||||
tableRef.value.reload({ pageNo: 1 });
|
||||
}
|
||||
|
||||
//加载字典项值列表;
|
||||
const loadDataTable = async (res) => {
|
||||
const result = await getConfigList({ ...params.value, ...res });
|
||||
const loadDataTable = async () => {
|
||||
const result = await getConfigList({ ...params.value, pageNo:pager.value.page,pageSize:pager.value.size });
|
||||
configId.value = result?.records[0]?.id
|
||||
configItemShow.value = true
|
||||
nextTick(() => {
|
||||
const tables = tableRef.value.getTableRef();
|
||||
tables.setCurrentRow(result?.records[0])
|
||||
})
|
||||
return result;
|
||||
configDataList.value = result.records
|
||||
pager.value.count = result.total
|
||||
};
|
||||
|
||||
//删除字典项
|
||||
async function handleDelete(record: Recordable) {
|
||||
let ids = []
|
||||
if (!record) {
|
||||
ids = selectionData.value.map(({ id }) => id);
|
||||
}
|
||||
async function handleDelete() {
|
||||
|
||||
await confirm('确定要删除?');
|
||||
record ? await configDelete(record.row.id) : await configBatchDelete(ids);
|
||||
await configDelete(configId.value);
|
||||
message("删除成功");
|
||||
reloadTable()
|
||||
}
|
||||
function onSelectionChange(value) {
|
||||
selectionData.value = value
|
||||
pager.value.page = 1
|
||||
loadDataTable()
|
||||
}
|
||||
onMounted(() => {
|
||||
loadDataTable()
|
||||
})
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.card-header {
|
||||
@ -141,4 +111,42 @@ function onSelectionChange(value) {
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.dict-list-box {
|
||||
.dict-item {
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
padding: 0 6px;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
.t1 {
|
||||
font-size: 14px;
|
||||
display: block;
|
||||
font-weight: 700;
|
||||
.t2 {
|
||||
font-size: 12px;
|
||||
font-weight: normal;
|
||||
}
|
||||
}
|
||||
|
||||
&.active {
|
||||
background-color: #e8f1ff;
|
||||
border-radius: 3px;
|
||||
|
||||
.t1 {
|
||||
color: #1677ff;
|
||||
}
|
||||
.t2 {
|
||||
color:rgb(22, 119, 255,.8)
|
||||
}
|
||||
}
|
||||
|
||||
.el-badge__content.is-fixed {
|
||||
top: 20px;
|
||||
right: calc(-10px + var(--el-badge-size)/ 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<PageWrapper>
|
||||
<el-row :gutter="10" class="mt-3">
|
||||
<el-col :xs="24" :sm="24" :md="8" :lg="8" :xl="8" class="mb-4">
|
||||
<el-col :xs="24" :sm="24" :md="7" :lg="7" :xl="7" class="mb-4">
|
||||
<el-card shadow="hover" class="border-0">
|
||||
<template #header>
|
||||
<el-row>
|
||||
@ -15,37 +15,43 @@
|
||||
</el-input>
|
||||
</el-col>
|
||||
<el-col :span="4" style="text-align: right;">
|
||||
<el-button type="primary" @click="reloadTable"> 查询 </el-button>
|
||||
<el-button type="primary" @click="pager.page=1;loadDataTable()"> 查询 </el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-button type="primary" icon="RefreshRight" @click="dictRefresh" style="margin-top:15px;"
|
||||
v-perm="['sys:dict:cache']">刷新缓存</el-button>
|
||||
<div style="margin-top:15px;">
|
||||
<el-button type="primary" @click="dictRefresh" v-perm="['sys:dict:cache']">刷新缓存</el-button>
|
||||
<el-button type="primary" @click="addDict" v-perm="['sys:dict:add']">新建</el-button>
|
||||
<el-button type="danger" v-perm="['sys:dict:delete']" :disabled="!selectionData.length" @click="handleDelete()">删除</el-button>
|
||||
<el-button type="primary" icon="Plus" @click="addDict" v-perm="['sys:dict:add']">新建</el-button>
|
||||
<el-button type="warning" icon="Edit" @click="handleEdit" v-perm="['sys:dict:edit']">编辑</el-button>
|
||||
<el-button type="danger" icon="Delete" v-perm="['sys:dict:delete']"
|
||||
@click="handleDelete()">删除</el-button>
|
||||
</div>
|
||||
</template>
|
||||
<BasicTable :columns="columns" :showTableSetting="false" :request="loadDataTable" :row-key="(row) => row.id"
|
||||
ref="tableRef" :actionColumn="actionColumn" @selection-change="onSelectionChange" highlight-current-row
|
||||
@row-click="onCheckedRow" />
|
||||
<div :style="{ height: fwbHeight + 'px' }" class="dict-list-box">
|
||||
<div v-for="(item, index) in dictDataList" :key="index" @click="onCheckedRow(item)" class="dict-item"
|
||||
:class="item.id == dictId ? 'active' : ''">
|
||||
<span class="t1">{{ item.name }}<span class="t2">({{ item.code }})</span></span>
|
||||
</div>
|
||||
</div>
|
||||
<pagination style="justify-content: flex-end" class="mt-10 flex" @change="loadDataTable" v-model="pager" layout="total, jumper">
|
||||
</pagination>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="24" :md="16" :lg="16" :xl="16" class="mb-4">
|
||||
<el-col :xs="24" :sm="24" :md="17" :lg="17" :xl="17" class="mb-4">
|
||||
<el-card shadow="hover" class="mb-4 border-0 proCard">
|
||||
<dictItem :dictId="dictId" v-if="dictItemShow"></dictItem>
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<editDialog v-if="editVisible" :dictId="dictId" v-model:visible="editVisible" @success="reloadTable">
|
||||
<editDialog v-if="editVisible" :dictId="dictId" v-model:visible="editVisible" @success="loadDataTable()">
|
||||
</editDialog>
|
||||
</PageWrapper>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, reactive, h, nextTick, defineAsyncComponent } from 'vue';
|
||||
import { onMounted, ref, nextTick, defineAsyncComponent } from 'vue';
|
||||
import { SearchOutlined } from '@vicons/antd';
|
||||
import { TableAction } from '@/components/Table';
|
||||
import { getDictList, refreshCache, dictDelete, dictBatchDelete } from '@/api/data/dictionary';
|
||||
import { columns } from './columns';
|
||||
import { getDictList, refreshCache, dictDelete } from '@/api/data/dictionary';
|
||||
import dictItem from './dictItem.vue';
|
||||
import { message, confirm } from "@/utils/auth";
|
||||
const editDialog = defineAsyncComponent(() =>
|
||||
@ -53,42 +59,17 @@ const editDialog = defineAsyncComponent(() =>
|
||||
)
|
||||
const dictId = ref(0)
|
||||
const dictItemShow = ref(false)
|
||||
const tableRef = ref();
|
||||
const selectedKey = ref('');
|
||||
const rowKeysName = ref('');
|
||||
const currentRow = ref();
|
||||
const dictDataList = ref([])
|
||||
const editVisible = ref(false)
|
||||
const selectionData = ref([])
|
||||
const params = ref({
|
||||
name: '',
|
||||
});
|
||||
|
||||
const actionColumn = reactive({
|
||||
lable: 150,
|
||||
title: '操作',
|
||||
prop: 'action',
|
||||
fixed: 'right',
|
||||
render(record) {
|
||||
return h(TableAction as any, {
|
||||
style: 'text',
|
||||
actions: [
|
||||
{
|
||||
label: '编辑',
|
||||
icon:'Edit',
|
||||
type: 'warning',
|
||||
onClick: handleEdit.bind(null, record),
|
||||
},
|
||||
{
|
||||
label: '删除',
|
||||
icon:'Delete',
|
||||
type: 'danger',
|
||||
onClick: handleDelete.bind(null, record),
|
||||
}
|
||||
],
|
||||
const pager = ref({
|
||||
page: 1,
|
||||
size: 10,
|
||||
count: dictDataList.value.length
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
const fwbHeight = document.body.clientHeight - 440
|
||||
|
||||
//新建字典
|
||||
const addDict = async () => {
|
||||
@ -97,9 +78,7 @@ const addDict = async () => {
|
||||
editVisible.value = true
|
||||
};
|
||||
//编辑字典
|
||||
const handleEdit = async (record: Recordable) => {
|
||||
dictId.value=record.row.id
|
||||
await nextTick();
|
||||
const handleEdit = () => {
|
||||
editVisible.value = true
|
||||
};
|
||||
//选择字典项
|
||||
@ -107,21 +86,13 @@ function onCheckedRow(row) {
|
||||
dictId.value = row.id
|
||||
}
|
||||
|
||||
//刷新字典项值列表
|
||||
function reloadTable() {
|
||||
tableRef.value.reload({ pageNo: 1 });
|
||||
}
|
||||
|
||||
//加载字典项值列表;
|
||||
const loadDataTable = async (res) => {
|
||||
const result = await getDictList({ ...params.value, ...res });
|
||||
const loadDataTable = async () => {
|
||||
const result = await getDictList({ ...params.value, pageNo:pager.value.page,pageSize:pager.value.size });
|
||||
dictId.value = result?.records[0]?.id
|
||||
dictItemShow.value = true
|
||||
nextTick(() => {
|
||||
const tables = tableRef.value.getTableRef();
|
||||
tables.setCurrentRow(result?.records[0])
|
||||
})
|
||||
return result;
|
||||
dictDataList.value = result.records
|
||||
pager.value.count = result.total
|
||||
};
|
||||
|
||||
//刷新缓存
|
||||
@ -130,19 +101,17 @@ async function dictRefresh() {
|
||||
message("刷新成功");
|
||||
}
|
||||
//删除字典项
|
||||
async function handleDelete(record: Recordable) {
|
||||
let ids = []
|
||||
if (!record) {
|
||||
ids = selectionData.value.map(({ id }) => id);
|
||||
}
|
||||
async function handleDelete() {
|
||||
|
||||
await confirm('确定要删除?');
|
||||
record ? await dictDelete(record.row.id) : await dictBatchDelete(ids);
|
||||
await dictDelete(dictId.value);
|
||||
message("删除成功");
|
||||
reloadTable()
|
||||
}
|
||||
function onSelectionChange(value) {
|
||||
selectionData.value = value
|
||||
pager.value.page = 1
|
||||
loadDataTable()
|
||||
}
|
||||
onMounted(() => {
|
||||
loadDataTable()
|
||||
})
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.card-header {
|
||||
@ -150,4 +119,42 @@ function onSelectionChange(value) {
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.dict-list-box {
|
||||
.dict-item {
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
padding: 0 6px;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
.t1 {
|
||||
font-size: 14px;
|
||||
display: block;
|
||||
font-weight: 700;
|
||||
.t2 {
|
||||
font-size: 12px;
|
||||
font-weight: normal;
|
||||
}
|
||||
}
|
||||
|
||||
&.active {
|
||||
background-color: #e8f1ff;
|
||||
border-radius: 3px;
|
||||
|
||||
.t1 {
|
||||
color: #1677ff;
|
||||
}
|
||||
.t2 {
|
||||
color:rgb(22, 119, 255,.8)
|
||||
}
|
||||
}
|
||||
|
||||
.el-badge__content.is-fixed {
|
||||
top: 20px;
|
||||
right: calc(-10px + var(--el-badge-size)/ 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<el-dialog v-model="props.visible" :title="dialogTitle" :append-to-body="true" width="600" :close-on-click-modal="false"
|
||||
<el-dialog v-model="props.visible" :title="dialogTitle" width="600" :close-on-click-modal="false"
|
||||
:before-close="dialogClose">
|
||||
<el-form ref="formRef" :model="formData" label-width="90px">
|
||||
<el-form-item
|
||||
|
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<el-dialog v-model="props.visible" :title="dialogTitle" :append-to-body="true" width="600" :close-on-click-modal="false"
|
||||
<el-dialog v-model="props.visible" :title="dialogTitle" width="600" :close-on-click-modal="false"
|
||||
:before-close="dialogClose">
|
||||
<el-form ref="formRef" :model="formData" label-width="90px">
|
||||
<el-form-item
|
||||
|
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<el-dialog v-model="props.visible" :title="dialogTitle" :append-to-body="true" width="600" :close-on-click-modal="false"
|
||||
<el-dialog v-model="props.visible" :title="dialogTitle" width="600" :close-on-click-modal="false"
|
||||
:before-close="dialogClose">
|
||||
<el-form ref="formRef" :model="formData" label-width="90px">
|
||||
<el-form-item
|
||||
|
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<el-dialog v-model="props.visible" :title="dialogTitle" :append-to-body="true" width="600" :close-on-click-modal="false"
|
||||
<el-dialog v-model="props.visible" :title="dialogTitle" width="600" :close-on-click-modal="false"
|
||||
:before-close="dialogClose">
|
||||
<el-form ref="formRef" :model="formData" label-width="90px">
|
||||
<el-form-item
|
||||
|
@ -42,11 +42,11 @@ export const columns = [
|
||||
},
|
||||
{
|
||||
label: '模板编号',
|
||||
prop: 'number',
|
||||
prop: 'code',
|
||||
},
|
||||
{
|
||||
label: '接收人手机',
|
||||
prop: 'receiveMobile',
|
||||
label: '接收人邮箱',
|
||||
prop: 'receiveEmail',
|
||||
},
|
||||
{
|
||||
label: '接收人类型',
|
||||
|
@ -10,12 +10,22 @@
|
||||
<el-descriptions column="2" border>
|
||||
<el-descriptions-item label="日志标题:" label-class-name="des-width">{{formData.title}}</el-descriptions-item>
|
||||
<el-descriptions-item label="日志类型:" label-class-name="des-width">{{getTyepText(formData.type)}}</el-descriptions-item>
|
||||
<el-descriptions-item label="模板编号:">{{formData.number}}</el-descriptions-item>
|
||||
<el-descriptions-item label="接收人手机:">{{formData.receiveMobile}}</el-descriptions-item>
|
||||
<el-descriptions-item label="模板编号:">{{formData.code}}</el-descriptions-item>
|
||||
<el-descriptions-item label="接收人邮箱:">{{formData.receiveEmail}}</el-descriptions-item>
|
||||
<el-descriptions-item label="接收人类型:">{{getReviceType(formData.receiveType)}}</el-descriptions-item>
|
||||
<el-descriptions-item label="请求耗时:">{{formData.consumeTime}}s</el-descriptions-item>
|
||||
<el-descriptions-item label="日志状态:">{{formData.status==1?'已读':'未读'}}</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
<el-descriptions class="margin-top" :column="1" border>
|
||||
<el-descriptions-item label="请求参数" label-class-name="des-width">
|
||||
{{formData.param}}
|
||||
</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
<el-descriptions class="margin-top" :column="1" border>
|
||||
<el-descriptions-item label="返回结果" label-class-name="des-width">
|
||||
{{formData.result}}
|
||||
</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="dialogClose">关闭</el-button>
|
||||
|
@ -37,7 +37,7 @@ import { useRoute, useRouter } from 'vue-router';
|
||||
import { useUserStore } from '@/store/modules/user';
|
||||
import { ElMessage } from 'element-plus';
|
||||
import { ResultEnum } from '@/enums/httpEnum';
|
||||
import { getInfoCaptcha } from '@/api/system/user';
|
||||
import { getInfoCaptcha,sendSms } from '@/api/system/user';
|
||||
import { PageEnum } from '@/enums/pageEnum';
|
||||
import { SafetyCertificateOutlined } from '@vicons/antd';
|
||||
const captchaImg = ref('')
|
||||
@ -56,7 +56,6 @@ const loading = ref(false);
|
||||
|
||||
const codeMsg: any = ref('获取验证码');
|
||||
const isGetCode = ref(false);
|
||||
const autoLogin = ref(true);
|
||||
const LOGIN_NAME = PageEnum.BASE_LOGIN_NAME;
|
||||
|
||||
const formInline = reactive({
|
||||
@ -73,11 +72,12 @@ const userStore = useUserStore();
|
||||
|
||||
const router = useRouter();
|
||||
const route = useRoute();
|
||||
function getCode() {
|
||||
async function getCode() {
|
||||
if (!formInline.mobile) {
|
||||
formRef.value.validateField('mobile')
|
||||
return
|
||||
}
|
||||
await sendSms({mobile:formInline.mobile})
|
||||
codeMsg.value = 60;
|
||||
isGetCode.value = true;
|
||||
let time = setInterval(() => {
|
||||
|
@ -37,7 +37,15 @@
|
||||
</template>
|
||||
删除
|
||||
</el-button>
|
||||
<el-upload
|
||||
<el-button type="primary" @click="importVisible=true" v-perm="['sys:user:import']">
|
||||
<template #icon>
|
||||
<el-icon class="el-input__icon">
|
||||
<Upload />
|
||||
</el-icon>
|
||||
</template>
|
||||
导入
|
||||
</el-button>
|
||||
<!-- <el-upload
|
||||
ref="upload"
|
||||
action="/api/user/import"
|
||||
:headers="uploadHeaders"
|
||||
@ -56,7 +64,7 @@
|
||||
</template>
|
||||
导入
|
||||
</el-button>
|
||||
</el-upload>
|
||||
</el-upload> -->
|
||||
<el-button type="primary" @click="handleExport" :loading="exportLoading" :disabled="exportLoading" v-perm="['sys:user:export']">
|
||||
<template #icon>
|
||||
<el-icon class="el-input__icon">
|
||||
@ -76,31 +84,30 @@
|
||||
@success="reloadTable('noRefresh')"
|
||||
>
|
||||
</editDialog>
|
||||
<userUpload v-if="importVisible" v-model:visible="importVisible" @success="reloadTable()"/>
|
||||
</PageWrapper>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { h, nextTick, reactive, ref ,defineAsyncComponent} from 'vue';
|
||||
import { ColProps, UploadInstance } from 'element-plus';
|
||||
import { ColProps } from 'element-plus';
|
||||
import { TableAction } from '@/components/Table';
|
||||
import { useForm } from '@/components/Form/index';
|
||||
import { getUserList,userDelete,userBatchDelete,userExport,resetPwd } from '@/api/system/user';
|
||||
import {message,confirm,loading, closeLoading} from "@/utils/auth";
|
||||
import {message,confirm} from "@/utils/auth";
|
||||
import { columns } from './columns';
|
||||
import { schemas } from './querySchemas';
|
||||
import { useUserStore } from '@/store/modules/user';
|
||||
import {downloadByData} from '@/utils/file/download';
|
||||
const userId = ref(0);
|
||||
const tableRef = ref();
|
||||
const editVisible = ref(false)
|
||||
const importVisible = ref(false)
|
||||
const selectionData = ref([])
|
||||
const upload = ref<UploadInstance>();
|
||||
const exportLoading=ref(false)
|
||||
const editDialog = defineAsyncComponent(() =>
|
||||
import('./edit.vue'))
|
||||
const uploadHeaders = reactive({
|
||||
authorization:useUserStore().getToken
|
||||
});
|
||||
const userUpload = defineAsyncComponent(() =>
|
||||
import('./userUpload.vue'))
|
||||
const formParams = reactive({
|
||||
realname: '',
|
||||
role:'',
|
||||
@ -216,34 +223,7 @@
|
||||
userId.value =0
|
||||
editVisible.value = true
|
||||
}
|
||||
const beforeUpload = (file: UploadFile) => {
|
||||
const isLt2M = file.size / 1024 / 1024 < 200;
|
||||
if (!isLt2M) {
|
||||
message("大小不能超过200MB!", "error");
|
||||
return false;
|
||||
}
|
||||
if (!/\.(xlsx|xls|XLSX|XLS)$/.test(file.name)) {
|
||||
message("请上传.xlsx .xls", "error");
|
||||
return false;
|
||||
}
|
||||
loading("上传中");
|
||||
return true;
|
||||
};
|
||||
const onSuccess = (file: UploadFile) => {
|
||||
upload.value!.clearFiles();
|
||||
closeLoading();
|
||||
if (file.code == 0) {
|
||||
message("导入成功");
|
||||
reloadTable()
|
||||
} else {
|
||||
message(file.msg ? file.msg : "导入失败", "error");
|
||||
}
|
||||
};
|
||||
const onError = () => {
|
||||
upload.value!.clearFiles();
|
||||
closeLoading();
|
||||
message("导入失败", "error");
|
||||
};
|
||||
|
||||
//导出
|
||||
const handleExport = async()=>{
|
||||
exportLoading.value=true
|
||||
|
103
src/views/system/user/userUpload.vue
Normal file
103
src/views/system/user/userUpload.vue
Normal file
@ -0,0 +1,103 @@
|
||||
<template>
|
||||
<el-dialog v-model="props.visible" :title="dialogTitle" width="450" :close-on-click-modal="false"
|
||||
:before-close="dialogClose">
|
||||
<el-upload
|
||||
style="width:400px"
|
||||
drag
|
||||
ref="upload"
|
||||
action="/api/user/import"
|
||||
:headers="uploadHeaders"
|
||||
:on-error="onError"
|
||||
:on-success="onSuccess"
|
||||
:before-upload="beforeUpload"
|
||||
:show-file-list="false"
|
||||
:limit="1"
|
||||
v-perm="['sys:user:import']"
|
||||
>
|
||||
<el-icon class="el-icon--upload" style="color:#165DFF;"><upload-filled /></el-icon>
|
||||
<div class="el-upload__text">
|
||||
点击或将文件拖拽到这里上传
|
||||
</div>
|
||||
</el-upload>
|
||||
<div style="margin-top:20px;">
|
||||
<span>只能上传 xls、xlsx 文件,</span>
|
||||
<el-button type="primary" link @click="handleDownload">下载模板
|
||||
</el-button>
|
||||
</div>
|
||||
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { getTemplateByCode } from '@/api/system/user';
|
||||
import { computed,shallowRef,ref,reactive } from "vue";
|
||||
import { UploadInstance } from 'element-plus';
|
||||
import { FormInstance } from "element-plus";
|
||||
import { message,loading,closeLoading } from "@/utils/auth";
|
||||
const formRef = shallowRef<FormInstance>();
|
||||
|
||||
import { useUserStore } from '@/store/modules/user';
|
||||
|
||||
const props = defineProps({
|
||||
visible: {
|
||||
type: Boolean,
|
||||
required: true,
|
||||
default: false
|
||||
},
|
||||
id: {
|
||||
type: Number,
|
||||
required: true,
|
||||
default: 0
|
||||
}
|
||||
});
|
||||
const upload = ref<UploadInstance>();
|
||||
const uploadHeaders = reactive({
|
||||
authorization:useUserStore().getToken
|
||||
});
|
||||
const emit = defineEmits(["success", "update:visible"]);
|
||||
|
||||
const dialogTitle = computed(() => {
|
||||
return '导入用户';
|
||||
});
|
||||
|
||||
|
||||
const dialogClose = () => {
|
||||
emit("update:visible", false);
|
||||
};
|
||||
|
||||
const beforeUpload = (file: UploadFile) => {
|
||||
const isLt2M = file.size / 1024 / 1024 < 200;
|
||||
if (!isLt2M) {
|
||||
message("大小不能超过200MB!", "error");
|
||||
return false;
|
||||
}
|
||||
if (!/\.(xlsx|xls|XLSX|XLS)$/.test(file.name)) {
|
||||
message("请上传.xlsx .xls", "error");
|
||||
return false;
|
||||
}
|
||||
loading("上传中");
|
||||
return true;
|
||||
};
|
||||
const onSuccess = (file: UploadFile) => {
|
||||
upload.value!.clearFiles();
|
||||
closeLoading();
|
||||
if (file.code == 0) {
|
||||
message("导入成功");
|
||||
emit("update:visible", false);
|
||||
emit("success");
|
||||
} else {
|
||||
message(file.msg ? file.msg : "导入失败", "error");
|
||||
}
|
||||
};
|
||||
const onError = () => {
|
||||
upload.value!.clearFiles();
|
||||
closeLoading();
|
||||
message("导入失败", "error");
|
||||
};
|
||||
const handleDownload = async()=>{
|
||||
const res =await getTemplateByCode('user_import')
|
||||
window.open(res.filePath)
|
||||
}
|
||||
|
||||
|
||||
</script>
|
Loading…
Reference in New Issue
Block a user