信息模块完成,审批假界面

This commit is contained in:
妖姐 2024-04-18 16:05:01 +08:00
parent 0f8c188be6
commit 4a785953a5
14 changed files with 1067 additions and 552 deletions

2
auto-imports.d.ts vendored
View File

@ -2,6 +2,4 @@
export {} export {}
declare global { declare global {
const ElMessage: typeof import('element-plus/es')['ElMessage'] const ElMessage: typeof import('element-plus/es')['ElMessage']
const ElMessageBox: typeof import('element-plus/es')['ElMessageBox']
const ElNotification: typeof import('element-plus/es')['ElNotification']
} }

4
components.d.ts vendored
View File

@ -36,6 +36,7 @@ declare module '@vue/runtime-core' {
ElMenuItem: typeof import('element-plus/es')['ElMenuItem'] ElMenuItem: typeof import('element-plus/es')['ElMenuItem']
ElOption: typeof import('element-plus/es')['ElOption'] ElOption: typeof import('element-plus/es')['ElOption']
ElPagination: typeof import('element-plus/es')['ElPagination'] ElPagination: typeof import('element-plus/es')['ElPagination']
ElPopconfirm: typeof import('element-plus/es')['ElPopconfirm']
ElProgress: typeof import('element-plus/es')['ElProgress'] ElProgress: typeof import('element-plus/es')['ElProgress']
ElRadio: typeof import('element-plus/es')['ElRadio'] ElRadio: typeof import('element-plus/es')['ElRadio']
ElRadioGroup: typeof import('element-plus/es')['ElRadioGroup'] ElRadioGroup: typeof import('element-plus/es')['ElRadioGroup']
@ -75,4 +76,7 @@ declare module '@vue/runtime-core' {
UploadExcel: typeof import('./src/components/UploadExcel/index.vue')['default'] UploadExcel: typeof import('./src/components/UploadExcel/index.vue')['default']
VueCountTo: typeof import('./src/components/vue-count-to/vue-countTo.vue')['default'] VueCountTo: typeof import('./src/components/vue-count-to/vue-countTo.vue')['default']
} }
export interface ComponentCustomProperties {
vLoading: typeof import('element-plus/es')['ElLoadingDirective']
}
} }

57
src/api/examine.js Normal file
View File

@ -0,0 +1,57 @@
import request from '../utils/request';
function getCurrentTimestamp() {
return new Date().getTime();
}
// 提交申请
export function ReviewAdd(data, token) {
return request({
url: '/review/add',
method: 'post',
params: data,
headers: {
'Authorization':'Bearer '+token,
'Timestamp':getCurrentTimestamp()
}
});
}
// 获取我的审核列表
export function GetMyReview(data, token) {
return request({
url: '/review/getMyReview',
method: 'get',
params: data,
headers: {
'Authorization':'Bearer '+token,
'Timestamp':getCurrentTimestamp()
}
});
}
//修改审核状态
// id result
export function UpdateReviewResult(data, token) {
return request({
url: '/review/updateReviewResult',
method: 'get',
params: data,
headers: {
'Authorization':'Bearer '+token,
'Timestamp':getCurrentTimestamp()
}
});
}
//获取审核记录
export function ReviewRecords(data, token) {
return request({
url: '/review/getReviewRecords',
method: 'get',
params: data,
headers: {
'Authorization':'Bearer '+token,
'Timestamp':getCurrentTimestamp()
}
});
}

View File

@ -1,15 +1,29 @@
import request from '../utils/request';
function getCurrentTimestamp() { function getCurrentTimestamp() {
return new Date().getTime(); return new Date().getTime();
} }
export function login(data) { export function messageGet(data, token) {
return request({ return request({
url: '/message/get', url: '/message/get',
method: 'post', method: 'get',
data, params: data,
headers: { headers: {
'Authorization':'Bearer '+token,
'Timestamp':getCurrentTimestamp() 'Timestamp':getCurrentTimestamp()
} }
}); });
} }
export function messageDelete(data, token) {
return request({
url: '/message/delete',
method: 'delete',
params: data,
headers: {
'Authorization':'Bearer '+token,
'Timestamp':getCurrentTimestamp()
}
})
}

View File

@ -89,8 +89,9 @@ export default defineComponent({
async logout() { async logout() {
console.log('5989569898') console.log('5989569898')
// store.user().login() // store.user().login()
// await store.user().logout(); // await store.user().logoutBug();
await store.user().logout(); await store.user().logout();
// await store.user().logoutTest();
this.$router.push(`/login?redirect=${this.$route.fullPath}`); this.$router.push(`/login?redirect=${this.$route.fullPath}`);
} }
} }

View File

@ -163,7 +163,7 @@ export const asyncRoutes:RouteRecordRaw[] = [
alwaysShow: true, // will always show the root menu alwaysShow: true, // will always show the root menu
title: '个人项目', title: '个人项目',
icon: 'nested', icon: 'nested',
roles: ['admin', 'teacher_user'] roles: ['admin', 'teacher_user', 'principle', 'developer', 'console']
}, },
children: [ children: [
{ {
@ -171,21 +171,21 @@ export const asyncRoutes:RouteRecordRaw[] = [
path: 'charge', path: 'charge',
component: () => import('@/views/personal/project/charge.vue'), component: () => import('@/views/personal/project/charge.vue'),
name: 'Charge', name: 'Charge',
meta: { title: '我负责的', icon: 'user', affix: true } meta: { title: '我负责的', icon: 'user', affix: true, role: ['console'] }
}, },
{ {
// 我管理的 // 我管理的
path: 'manage', path: 'manage',
component: () => import('@/views/personal/project/manage.vue'), component: () => import('@/views/personal/project/manage.vue'),
name: 'Manage', name: 'Manage',
meta: { title: '我管理的', icon: 'user', affix: true } meta: { title: '我管理的', icon: 'user', affix: true, role: ['principle', 'developer', 'console'] }
}, },
{ {
// 我参与的 // 我参与的
path: 'participate', path: 'participate',
component: () => import('@/views/personal/project/participate.vue'), component: () => import('@/views/personal/project/participate.vue'),
name: 'Participate', name: 'Participate',
meta: { title: '我参与的', icon: 'user', affix: true } meta: { title: '我参与的', icon: 'user', affix: true, role: ['principle', 'developer', 'console'] }
}, },
@ -253,7 +253,7 @@ export const asyncRoutes:RouteRecordRaw[] = [
path: 'd', path: 'd',
component: () => import('@/views/tab/index.vue'), component: () => import('@/views/tab/index.vue'),
name: 'Tab', name: 'Tab',
meta: { title: '日报', icon: 'tab' } meta: { title: '日报', icon: 'tab', role: ['principle', 'developer', 'console'] }
} }
] ]
}, },
@ -291,47 +291,41 @@ export const asyncRoutes:RouteRecordRaw[] = [
path: 'ms', path: 'ms',
component: () => import('@/views/error-log/index.vue'), component: () => import('@/views/error-log/index.vue'),
name: 'ErrorLog', name: 'ErrorLog',
meta: { title: '信息', icon: 'bug' } meta: { title: '信息', icon: 'bug', role: ['principle', 'developer', 'console'] }
} }
] ]
}, },
// { {
// path: '/excel', path: '/excel',
// component: Layout, component: Layout,
// redirect: '/excel/export-excel', redirect: '/excel/export-excel',
// name: 'Excel', name: 'Excel',
// meta: { meta: {
// title: 'Excel', title: '申请和审批',
// icon: 'excel' icon: 'excel'
// }, },
// children: [ children: [
// { {
// path: 'export-excel', path: 'export-excel',
// component: () => import('@/views/excel/export-excel.vue'), component: () => import('@/views/excel/export-excel.vue'),
// name: 'ExportExcel', name: 'ExportExcel',
// meta: { title: 'Export Excel' } meta: { title: '提交申请' }
// }, },
// { {
// path: 'export-selected-excel', path: 'export-selected-excel',
// component: () => import('@/views/excel/select-excel.vue'), component: () => import('@/views/excel/select-excel.vue'),
// name: 'SelectExcel', name: 'SelectExcel',
// meta: { title: 'Export Selected' } meta: { title: '我的审批' }
// }, },
// { {
// path: 'export-merge-header', path: 'export-update-excel',
// component: () => import('@/views/excel/merge-header.vue'), component: () => import('@/views/excel/upload-excel.vue'),
// name: 'MergeHeader', name: 'MergeHeader',
// meta: { title: 'Merge Header' } meta: { title: '记录查询' }
// }, }
// { ]
// path: 'upload-excel', },
// component: () => import('@/views/excel/upload-excel.vue'),
// name: 'UploadExcel',
// meta: { title: 'Upload Excel' }
// }
// ]
// },
// { // {
// path: '/zip', // path: '/zip',

View File

@ -131,6 +131,7 @@ export default defineStore({
}); });
}, },
//logoutBug: 只删除后端的token不删除浏览器的token
logoutBug():Promise<void> { logoutBug():Promise<void> {
console.log("token",this.token) console.log("token",this.token)
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
@ -148,6 +149,7 @@ export default defineStore({
}); });
}, },
//logoutTest: 只删除浏览器的token后端不删除
logoutTest(): void { logoutTest(): void {
removeToken(); removeToken();
console.log("removeTokenTestSuccess"); console.log("removeTokenTestSuccess");

View File

@ -15,9 +15,9 @@ const service = axios.create({
// request interceptor // request interceptor
service.interceptors.request.use( service.interceptors.request.use(
config => { config => {
// do something before request is sent // do something before request is sent
if (store.user().token) { if (store.user().token) {
// let each request carry token // let each request carry token
// ['X-Token'] is a custom headers key // ['X-Token'] is a custom headers key
@ -48,7 +48,7 @@ service.interceptors.response.use(
response => { response => {
const res = response.data; const res = response.data;
// console.log("removeToken:",removeToken()) // console.log("removeToken:",removeToken())
console.log('999999',res) console.log('999999',response)
if (res.code === 40103) { if (res.code === 40103) {
store.user().logoutTest(); store.user().logoutTest();
console.log("返回登录成功") console.log("返回登录成功")

View File

@ -6,41 +6,21 @@
<span>消息</span> <span>消息</span>
</template> </template>
<div style="display:flex;flex-direction:row;justify-content: space-between "> <div style="display:flex;flex-direction:row;justify-content: space-between ">
<div> <div class="block">
时间 <span class="demonstration" style="margin-right: 8px">时间</span>
<el-date-picker <el-date-picker
v-model="value2" v-model="value2"
type="daterange" type="datetimerange"
unlink-panels
range-separator="——"
start-placeholder="开始时间"
end-placeholder="结束时间"
:shortcuts="shortcuts" :shortcuts="shortcuts"
:size="large" range-separator="To"
style="margin-left:0.5vw" start-placeholder="Start date"
end-placeholder="End date"
/> />
</div> </div>
<!-- <div>-->
<!-- 状态-->
<!-- <el-select-->
<!-- v-model="value"-->
<!-- clearable-->
<!-- placeholder="Status"-->
<!-- style="width: 240px;margin-left:0.5vw"-->
<!-- >-->
<!-- <el-option-->
<!-- v-for="item in options"-->
<!-- :key="item.value"-->
<!-- :label="item.label"-->
<!-- :value="item.value"-->
<!-- />-->
<!-- </el-select>-->
<!-- </div>-->
<div> <div>
<el-button type="primary" style="width:80px">查询</el-button> <el-button type="primary" style="width:80px" @click="selectMessage">查询</el-button>
<el-button style="width:80px">重置</el-button> <el-button style="width:80px" @click="resetting">重置</el-button>
</div> </div>
</div> </div>
@ -49,22 +29,23 @@
<div style="display:flex;flex-direction: row;justify-content: space-between"> <div style="display:flex;flex-direction: row;justify-content: space-between">
<el-button <el-button
text text
type=''
>历史记录</el-button >历史记录</el-button
> >
<el-tag type="primary" style="margin-right: 1.7vw">总数{{messageData.total}}</el-tag>
</div> </div>
<div v-for="(row, index) in tableData" :key="index" class="table-row"> <div style="height: 43vh">
<div class="table-cell"> <div v-for="(row, index) in messageData.data" :key="index" class="table-row">
<div class="date" style="display:flex;flex-direction: column"> <div class="table-author" style="text-align: left">
<span style="color:skyblue">{{row.name}}</span> <span class="date" style="display:flex;flex-direction: column">
<span style="color:skyblue">{{row.senderName}}</span>
<span>{{ row.text }}</span> <span>{{ row.text }}</span>
</span>
</div> </div>
<div class="table-time createdTime">
<span>{{ formatDateTime(row.createdAt) }}</span>
</div> </div>
<div class="table-cell createdTime"> <div class="table-btn table-cell-right">
<div>{{ row.createdAt }}</div>
</div>
<div class="table-cell table-cell-right">
<el-button size="small" type="danger" @click="handleDelete(index, row);centerDialogVisible = true">Delete</el-button> <el-button size="small" type="danger" @click="handleDelete(index, row);centerDialogVisible = true">Delete</el-button>
<el-dialog v-model="centerDialogVisible" title="删除" width="500" :modal="false"> <el-dialog v-model="centerDialogVisible" title="删除" width="500" :modal="false">
<span> <span>
@ -73,7 +54,7 @@
<template #footer> <template #footer>
<div class="dialog-footer"> <div class="dialog-footer">
<el-button @click="centerDialogVisible = false">取消</el-button> <el-button @click="centerDialogVisible = false">取消</el-button>
<el-button type="primary" @click="centerDialogVisible = false"> <el-button type="primary" @click="deleteItem">
确认 确认
</el-button> </el-button>
</div> </div>
@ -81,12 +62,20 @@
</el-dialog> </el-dialog>
</div> </div>
</div> </div>
</div>
<!-- <el-pagination page-size="5" v-model:current-page="currentPage"-->
<!-- background-->
<!-- layout="prev, pager, next"-->
<!-- :total="messageData.total"-->
<!-- style="display: flex;flex-direction: row;justify-content: center;margin-top: 0.5vh"-->
<!-- />-->
<el-pagination <el-pagination
size="large" @current-change="pagination"
background background layout="prev, pager, next"
layout="prev, pager, next" :total="messageData.total"
:total="50" v-model:page-size="requestData.pageSize"
style="display: flex;flex-direction: row;justify-content: center;margin-top:5vh" style="display: flex;flex-direction: row;justify-content: center;margin-top: 0.5vh"
/> />
</el-card> </el-card>
@ -95,66 +84,86 @@
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { ref } from 'vue'; import {onMounted, reactive, ref, watch} from 'vue';
import {messageGet, messageDelete} from '@/api/message'
import {getToken} from "@/utils/auth";
// //
const centerDialogVisible = ref(false); const centerDialogVisible = ref(false);
// //
const value2 = ref(''); const value2 = ref('')
let currentPage = ref(1);
function flushData() {
messageGet(requestData, getToken()).then((res)=>{
console.log("getMessageResult:",res.data);
messageData.data = res.data.list
messageData.total = res.data.total
currentPage = res.data.currentPage
})
}
function pagination(currentPage: number) {
requestData.page = currentPage
flushData()
}
const shortcuts = [ const shortcuts = [
{ {
text: 'Last week', text: 'Last week',
value: () => { value: () => {
const end = new Date(); const end = new Date()
const start = new Date(); const start = new Date()
start.setTime(start.getTime() - 3600 * 1000 * 24 * 7); start.setDate(start.getDate() - 7)
return [start, end]; return [start, end]
} },
}, },
{ {
text: 'Last month', text: 'Last month',
value: () => { value: () => {
const end = new Date(); const end = new Date()
const start = new Date(); const start = new Date()
start.setTime(start.getTime() - 3600 * 1000 * 24 * 30); start.setMonth(start.getMonth() - 1)
return [start, end]; return [start, end]
} },
}, },
{ {
text: 'Last 3 months', text: 'Last 3 months',
value: () => { value: () => {
const end = new Date(); const end = new Date()
const start = new Date(); const start = new Date()
start.setTime(start.getTime() - 3600 * 1000 * 24 * 90); start.setMonth(start.getMonth() - 3)
return [start, end]; return [start, end]
},
},
]
let requestData = reactive({
page:1,
pageSize: 5,
begin: '',
end: ''
})
//
watch(value2, (newValue) => {
if (newValue !== '') {
requestData.begin = formatDateTime(newValue[0])
requestData.end = formatDateTime(newValue[1])
} }
} })
]; // watch(currentPage, async (newPage, oldPage) => {
// requestData.page = newPage
// flushData()
// })
const messageData = reactive({
data:[],
total: 0
})
onMounted(() => {
flushData()
})
// //
const value = ref('');
const options = [
{
value: 'Option1',
label: '未开始'
},
{
value: 'Option2',
label: '进行中'
},
{
value: 'Option3',
label: '暂停'
},
{
value: 'Option4',
label: 'Option4'
},
{
value: 'Option5',
label: '已完成'
}
];
// //
interface Message { interface Message {
@ -163,38 +172,55 @@ interface Message {
name: string name: string
text: string text: string
} }
const deleteData = reactive({
id: -1
})
const handleDelete = (index: number, row: Message) => { const handleDelete = (index: number, row: Message) => {
deleteData.id = row.id
console.log(index, row); console.log(index, row);
console.log("time:select", value2.value[1])
}; };
function deleteItem(){
if (deleteData.id === -1) {
ElMessage.error("删除异常,请重试!")
} else {
messageDelete(deleteData, getToken()).then((res) => {
console.log(res,'删除')
if (res.code === 200) {
flushData()
ElMessage.success("删除成功")
}
})
}
centerDialogVisible.value = false
}
const tableData: Message[] = [ function selectMessage (){
{ try {
id:1 , flushData()
createdAt: '2016-05-03', console.log(requestData)
name: 'Tom', ElMessage.success('查询成功')
text: 'No. 189, Grove St, Los Angeles' }catch (e) {
}, ElMessage.success('查询失败')
{ }
id:1 , }
createdAt: '2016-05-03', function resetting(){
name: 'Tom', requestData.begin = ''
text: 'No. 189, Grove St, Los Angeles' requestData.end = ''
}, value2.value = ''
{ }
id:1 , //
createdAt: '2016-05-03', function formatDateTime(dateTimeString: string): string {
name: 'Tom', const dateTime = new Date(dateTimeString);
text: 'No. 189, Grove St, Los Angeles' const year = dateTime.getFullYear();
}, const month = String(dateTime.getMonth() + 1).padStart(2, '0');
{ const date = String(dateTime.getDate()).padStart(2, '0');
id:1 , const hours = String(dateTime.getHours()).padStart(2, '0');
createdAt: '2016-05-03', const minutes = String(dateTime.getMinutes()).padStart(2, '0');
name: 'Tom', const seconds = String(dateTime.getSeconds()).padStart(2, '0');
text: 'No. 189, Grove St, Los Angeles'
},
]; return `${year}-${month}-${date} ${hours}:${minutes}:${seconds}`;
}
</script> </script>
<style> <style>
.my-autocomplete li { .my-autocomplete li {
@ -219,19 +245,38 @@ const tableData: Message[] = [
/*margin-bottom: 10px;*/ /*margin-bottom: 10px;*/
} }
.table-cell { .table-author {
flex: 1; flex: 1;
padding: 10px; padding: 10px;
display: flex; display: flex;
justify-content: center; justify-content: left;
align-items: center; align-items: center;
/*background-color: #04befe;*/
}
.table-time {
flex: 0.3;
padding: 10px;
display: flex;
justify-content: right;
align-items: center;
/*background-color: #ff1439;*/
}
.table-btn {
flex: 0.3;
padding: 0px;
display: flex;
justify-content: right;
align-items: center;
/*background-color: #32fe04;*/
} }
.createdTime{ .createdTime{
margin-left: 50px; margin-left: 50px;
margin-top: 10px;
} }
.table-cell-right { .table-cell-right {
justify-content: flex-end; justify-content: flex-end;
margin-right:5vw; margin-right:2vw;
} }
.date { .date {
display: flex; display: flex;

View File

@ -1,120 +1,119 @@
<template> <template>
<div class="app-container"> <el-card style="max-width: 100vw; margin: 1.5vw;height: 81vh">
<template #header>
<div style="margin: 0 0 20px 0;"> <strong >提交申请</strong>
<FilenameOption v-model="filename" /> </template>
<AutoWidthOption v-model="autoWidth" /> <div>
<BookTypeOption v-model="bookType" /> <div class="selectedContent">
<el-button :loading="downloadLoading" style="margin:0 0 0 20px;" type="primary" :icon="IconDocument" @click="handleDownload"> <span class="selectedHeader">01.申请类别</span>
Export Excel <el-select v-model="form.region" placeholder="请选择申请类别" style="width: 15vw">
</el-button> <el-option label="子系统" value="system" />
<a href="https://vue3-element-admin-site.midfar.com/feature/component/excel.html" target="_blank" style="margin-left:15px;"> <el-option label="模块" value="module" />
<el-tag type="info" size="large">Documentation</el-tag> </el-select>
</a> </div>
<div class="selectedContent">
<span class="selectedHeader">02.申请所属</span>
<el-autocomplete
v-model="state2"
:fetch-suggestions="querySearch"
:trigger-on-focus="false"
clearable
class="inline-input w-50"
placeholder="所属项目"
@select="handleSelect"
style="width: 15vw"
/>
</div>
<div class="selectedContent">
<!-- <span>02.申请所属</span>-->
<el-select v-model="form.childSystem" class="selectedChild" v-show="form.region === 'module'" placeholder="所属子系统" style="width: 15vw">
<el-option label="子系统" value="system" />
<el-option label="模块" value="module" />
</el-select>
</div>
<div class="selectedContent">
<span class="selectedHeader">03.申请名称</span>
<el-select style="width: 15vw">
<el-option></el-option>
</el-select>
</div>
<div class="selectedContent" style="display: flex;flex-direction: row">
<span class="selectedHeader">04.申请理由</span>
<el-input
v-model="textarea"
:rows="4"
type="textarea"
placeholder="Please input"
style="width: 20vw"
/>
</div>
<el-button type="primary" style="margin: 7vh 45vw ">提交申请</el-button>
</div> </div>
<el-table v-loading="listLoading" :data="list" element-loading-text="Loading..." border fit highlight-current-row> </el-card>
<el-table-column align="center" label="Id" width="95">
<template v-slot="scope">
{{ scope.$index }}
</template>
</el-table-column>
<el-table-column label="Title">
<template v-slot="scope">
{{ scope.row.title }}
</template>
</el-table-column>
<el-table-column label="Author" width="110" align="center">
<template v-slot="scope">
<el-tag>{{ scope.row.author }}</el-tag>
</template>
</el-table-column>
<el-table-column label="Readings" width="115" align="center">
<template v-slot="scope">
{{ scope.row.pageviews }}
</template>
</el-table-column>
<el-table-column align="center" label="Date" width="220">
<template v-slot="scope">
<el-icon><IconTimer /></el-icon>
<span>{{ parseTime(scope.row.timestamp, '{y}-{m}-{d} {h}:{i}') }}</span>
</template>
</el-table-column>
</el-table>
</div>
</template> </template>
<script setup lang="ts">
import {onMounted, reactive, ref} from "vue";
<script> const textarea = ref('')
import { defineComponent, markRaw } from 'vue'; const form = reactive({
import { fetchList } from '@/api/article'; region:'',
import { parseTime } from '@/utils'; childSystem:''
// options components })
import FilenameOption from './components/FilenameOption'; interface RestaurantItem {
import AutoWidthOption from './components/AutoWidthOption'; value: string
import BookTypeOption from './components/BookTypeOption'; link: string
import { Document as IconDocument, Timer as IconTimer } from '@element-plus/icons-vue'; }
export default defineComponent({
name: 'ExportExcel', const state2 = ref('')
components: { FilenameOption, AutoWidthOption, BookTypeOption, IconTimer },
data() { const restaurants = ref<RestaurantItem[]>([])
return { const querySearch = (queryString: string, cb: any) => {
IconDocument: markRaw(IconDocument), const results = queryString
list: null, ? restaurants.value.filter(createFilter(queryString))
listLoading: true, : restaurants.value
downloadLoading: false, // call callback function to return suggestions
filename: '', cb(results)
autoWidth: true,
bookType: 'xlsx'
};
},
created() {
this.fetchData();
},
methods: {
parseTime,
fetchData() {
this.listLoading = true;
fetchList().then(response => {
this.list = response.data.items;
this.listLoading = false;
});
},
handleDownload() {
this.downloadLoading = true;
import('@/vendor/Export2Excel').then(excel => {
const tHeader = ['Id', 'Title', 'Author', 'Readings', 'Date'];
const filterVal = ['id', 'title', 'author', 'pageviews', 'display_time'];
const list = this.list;
const data = this.formatJson(filterVal, list);
excel.export_json_to_excel({
header: tHeader,
data,
filename: this.filename,
autoWidth: this.autoWidth,
bookType: this.bookType
});
this.downloadLoading = false;
});
},
formatJson(filterVal, jsonData) {
return jsonData.map(v => filterVal.map(j => {
if (j === 'timestamp') {
return parseTime(v[j]);
} else {
return v[j];
} }
})); const createFilter = (queryString: string) => {
return (restaurant: RestaurantItem) => {
return (
restaurant.value.toLowerCase().indexOf(queryString.toLowerCase()) === 0
)
} }
} }
}); const loadAll = () => {
return [
{ value: 'vue', link: 'https://github.com/vuejs/vue' },
{ value: 'element', link: 'https://github.com/ElemeFE/element' },
{ value: 'cooking', link: 'https://github.com/ElemeFE/cooking' },
{ value: 'mint-ui', link: 'https://github.com/ElemeFE/mint-ui' },
{ value: 'vuex', link: 'https://github.com/vuejs/vuex' },
{ value: 'vue-router', link: 'https://github.com/vuejs/vue-router' },
{ value: 'babel', link: 'https://github.com/babel/babel' },
]
}
const handleSelect = (item: RestaurantItem) => {
console.log(item)
}
onMounted(() => {
restaurants.value = loadAll()
})
</script> </script>
<style> <style scoped>
.radio-label { .selectedHeader{
font-size: 14px; font-weight: bold;
color: #606266; margin-right: 2vw;
line-height: 40px; }
padding: 0 12px 0 30px; .selectedContent{
margin-left: 35vw;
margin-top:5vh
}
.selectedChild{
margin-left: 7.7vw;
} }
</style> </style>

View File

@ -1,106 +0,0 @@
<template>
<div class="app-container">
<el-button :loading="downloadLoading" style="margin-bottom:20px" type="primary" :icon="IconDocument" @click="handleDownload">Export</el-button>
<el-table
ref="multipleTable"
v-loading="listLoading"
:data="list"
element-loading-text="Loading"
border
fit
highlight-current-row
>
<el-table-column align="center" label="Id" width="95">
<template v-slot="scope">
{{ scope.$index }}
</template>
</el-table-column>
<el-table-column label="Main Information" align="center">
<el-table-column label="Title">
<template v-slot="scope">
{{ scope.row.title }}
</template>
</el-table-column>
<el-table-column label="Author" width="110" align="center">
<template v-slot="scope">
<el-tag>{{ scope.row.author }}</el-tag>
</template>
</el-table-column>
<el-table-column label="Readings" width="115" align="center">
<template v-slot="scope">
{{ scope.row.pageviews }}
</template>
</el-table-column>
</el-table-column>
<el-table-column align="center" label="Date" width="220">
<template v-slot="scope">
<el-icon><IconTimer /></el-icon>
<span>{{ parseTime(scope.row.timestamp, '{y}-{m}-{d} {h}:{i}') }}</span>
</template>
</el-table-column>
</el-table>
</div>
</template>
<script>
import { defineComponent, markRaw } from 'vue';
import { fetchList } from '@/api/article';
import { parseTime } from '@/utils';
import { Document as IconDocument, Timer as IconTimer } from '@element-plus/icons-vue';
export default defineComponent({
name: 'MergeHeader',
components: { IconTimer },
data() {
return {
IconDocument: markRaw(IconDocument),
list: null,
listLoading: true,
downloadLoading: false
};
},
created() {
this.fetchData();
},
methods: {
parseTime,
fetchData() {
this.listLoading = true;
fetchList(this.listQuery).then(response => {
this.list = response.data.items;
this.listLoading = false;
});
},
handleDownload() {
this.downloadLoading = true;
import('@/vendor/Export2Excel').then(excel => {
const multiHeader = [['Id', 'Main Information', '', '', 'Date']];
const header = ['', 'Title', 'Author', 'Readings', ''];
const filterVal = ['id', 'title', 'author', 'pageviews', 'display_time'];
const list = this.list;
const data = this.formatJson(filterVal, list);
const merges = ['A1:A2', 'B1:D1', 'E1:E2'];
excel.export_json_to_excel({
multiHeader,
header,
merges,
data
});
this.downloadLoading = false;
});
},
formatJson(filterVal, jsonData) {
return jsonData.map(v => filterVal.map(j => {
if (j === 'timestamp') {
return parseTime(v[j]);
} else {
return v[j];
}
}));
}
}
});
</script>

View File

@ -1,113 +1,396 @@
<template> <template>
<div class="app-container"> <div style=" width:100%">
<div style="margin-bottom:20px"> <el-card style="max-width: 100vw;margin: 1.5vw;">
<el-input v-model="filename" placeholder="Please enter the file name (default excel-list)" style="width:350px;" :prefix-icon="IconDocument" /> <!-- <template #header><span>我的审批</span></template>-->
<el-button :loading="downloadLoading" type="primary" :icon="IconDocument" @click="handleDownload"> <template #header><strong >我的审批</strong></template>
Export Selected Items <div style="display:flex;flex-direction:row;justify-content: space-around ">
</el-button> <div>
<a href="https://panjiachen.github.io/vue-element-admin-site/feature/component/excel.html" target="_blank" style="margin-left:15px;"> 名称
<el-tag type="info" size="large">Documentation</el-tag> <el-input v-model="input" style="width: 240px;margin-left:0.5vw" placeholder="请输入" />
</a>
</div> </div>
<el-table <div>
ref="multipleTable" 状态
v-loading="listLoading" <el-autocomplete
:data="list" v-model="state"
element-loading-text="拼命加载中" :fetch-suggestions="querySearch"
border popper-class="my-autocomplete"
fit placeholder="Please input"
highlight-current-row @select="handleSelect"
@selection-change="handleSelectionChange" style="margin-left:0.5vw"
> >
<el-table-column type="selection" align="center" /> <template #suffix>
<el-table-column align="center" label="Id" width="95"> <el-icon class="el-input__icon" @click="handleIconClick">
<template v-slot="scope"> <ArrowDownBold />
{{ scope.$index }} </el-icon>
</template> </template>
<template #default="{ item }">
<div class="value">{{ item.value }}</div>
<span class="link">{{ item.link }}</span>
</template>
</el-autocomplete>
</div>
<div>
<el-button type="primary" style="width:80px">查询</el-button>
<el-button style="width:80px">重置</el-button>
</div>
</div>
</el-card>
<el-card style="max-width: 100vw;height:60vh;margin:1.3vw">
<div style="display:flex;flex-direction: row;justify-content: space-between">
<el-button text >历史记录</el-button>
</div>
<!-- <el-table ref="multipleTableRef" :data="tableData" style="max-width: 100vw;"-->
<!-- @selection-change="handleSelectionChange">-->
<!-- <el-table-column fixed type="selection" width="55" />-->
<!-- <el-table-column fixed label="序号" width="120">-->
<!-- <template #default="scope">{{ scope.row.date }}</template>-->
<!-- </el-table-column>-->
<!-- <el-table-column property="name" label="申请名称" width="120" />-->
<!-- <el-table-column property="address" label="所属项目" show-overflow-tooltip />-->
<!-- <el-table-column property="address" label="所属子系统" />-->
<!-- <el-table-column property="address" label="申请者" >-->
<!-- <el-tag type="primary" property="address">Tag 1</el-tag>-->
<!-- </el-table-column>-->
<!-- <el-table-column property="address" label="类型" />-->
<!-- <el-table-column property="address" label="状态" >-->
<!-- <el-tag type="success" property="address">已通过</el-tag>-->
<!-- <el-tag type="warning" property="address">待审核</el-tag>-->
<!-- <el-tag type="danger" property="address">已拒绝</el-tag>-->
<!-- </el-table-column>-->
<!-- <el-table-column property="address" label="申请理由" />-->
<!-- <el-table-column property="address" label="申请时间" />-->
<!-- <el-table-column fixed="right" property="address" label="操作" >-->
<!-- <el-button size="small" text style="color:deepskyblue" @click="EditDialogVisible = true">审核通过</el-button>-->
<!-- <el-divider direction="vertical" />-->
<!-- <el-button size="small" text style="color:red" @click="EditDialogVisible = true">拒绝申请</el-button>-->
<!-- <el-dialog v-model="EditDialogVisible" width="500" center :modal="false" :show-close="false">-->
<!-- <template #header>-->
<!-- <div style="display:flex;flex-direction: row;justify-content: flex-start;color:#409eff;font-size:large" >编辑日报</div>-->
<!-- <el-divider content-position="left" style="background:red"><el-icon><CaretTop /></el-icon></el-divider>-->
<!-- </template>-->
<!-- <div>-->
<!-- &lt;!&ndash; <div style="margin-top:-4vh ">&ndash;&gt;-->
<!-- &lt;!&ndash; <span style="color:red">项目名称</span>&ndash;&gt;-->
<!-- &lt;!&ndash; <el-input&ndash;&gt;-->
<!-- &lt;!&ndash; v-model="input"&ndash;&gt;-->
<!-- &lt;!&ndash; style="width: 200px"&ndash;&gt;-->
<!-- &lt;!&ndash; placeholder="请输入"&ndash;&gt;-->
<!-- &lt;!&ndash; />&ndash;&gt;-->
<!-- &lt;!&ndash; </div>&ndash;&gt;-->
<!-- <div style="margin-top:-4vh ">-->
<!-- <span style="color:red"> 工作时间</span>-->
<!-- <el-date-picker-->
<!-- v-model="value1"-->
<!-- type="date"-->
<!-- placeholder="请选择日期"-->
<!-- style="width: 200px"-->
<!-- :default-value="new Date(2010, 9, 1)"-->
<!-- />-->
<!-- </div>-->
<!-- <div style="margin-top:2vh ;display:flex;flex-direction:row;">-->
<!-- <span style="color: red">日报内容</span>-->
<!-- <el-input-->
<!-- v-model="textarea"-->
<!-- style="width: 300px;"-->
<!-- :rows="4"-->
<!-- type="textarea"-->
<!-- placeholder="请输入"-->
<!-- />-->
<!-- </div>-->
<!-- </div>-->
<!-- <template #footer>-->
<!-- <div class="dialog-footer">-->
<!-- <el-button @click="EditDialogVisible = false">取消</el-button>-->
<!-- <el-button type="primary" @click="EditDialogVisible = false">-->
<!-- 确认-->
<!-- </el-button>-->
<!-- </div>-->
<!-- </template>-->
<!-- </el-dialog>-->
<!-- </el-table-column>-->
<!-- </el-table>-->
<el-table :data="tableData" style="width: 100%">
<el-table-column fixed prop="date" label="序号" width="150" />
<el-table-column prop="name" label="申请名称" width="120" />
<el-table-column prop="state" label="所属项目" width="120" />
<el-table-column prop="city" label="所属子系统" width="120" />
<el-table-column prop="address" label="申请者" width="180" >
<el-tag type="primary" property="address">Tag 1</el-tag>
</el-table-column> </el-table-column>
<el-table-column label="Title"> <el-table-column prop="zip" label="类型" width="120" />
<template v-slot="scope"> <el-table-column prop="zip" label="状态" width="120" >
{{ scope.row.title }} <!-- <el-tag type="success" property="address">已通过</el-tag>&ndash;&gt;-->
</template> <el-tag type="warning" property="address">待审核</el-tag>
<!-- <el-tag type="danger" property="address">已拒绝</el-tag>-->
</el-table-column> </el-table-column>
<el-table-column label="Author" width="110" align="center"> <el-table-column prop="zip" label="申请理由" width="400" />
<template v-slot="scope"> <el-table-column prop="zip" label="申请时间" width="120" />
<el-tag>{{ scope.row.author }}</el-tag> <el-table-column fixed="right" property="address" label="操作" width="200">
<!-- <el-button size="small" text style="color:deepskyblue" @click="EditDialogVisible = true">审核通过</el-button>-->
<el-popconfirm
confirm-button-text="通过"
cancel-button-text="关闭"
:icon="InfoFilled"
icon-color="#626AEF"
title="确定要通过审核吗?"
@confirm="confirmEvent"
@cancel="cancelEvent"
>
<template #reference>
<el-button size="small" text style="color:deepskyblue">审核通过</el-button>
</template> </template>
</el-table-column> </el-popconfirm>
<el-table-column label="Readings" width="115" align="center"> <el-divider direction="vertical" />
<template v-slot="scope"> <!-- <el-button size="small" text style="color:red" @click="EditDialogVisible = true">拒绝申请</el-button>-->
{{ scope.row.pageviews }} <el-popconfirm
</template> confirm-button-text="拒绝"
</el-table-column> cancel-button-text="关闭"
<el-table-column align="center" label="PDate" width="220"> :icon="InfoFilled"
<template v-slot="scope"> icon-color="red"
<el-icon><IconTimer /></el-icon> title="确认要拒绝通过吗?确定后不能改变"
<span>{{ scope.row.display_time }}</span> @confirm="confirmEvent"
@cancel="cancelEvent"
>
<template #reference>
<el-button size="small" text style="color:red">拒绝申请</el-button>
</template> </template>
</el-popconfirm>
</el-table-column> </el-table-column>
</el-table> </el-table>
<el-pagination
larger
background
layout="prev, pager, next"
:total="50" class="mt-4"
style="display: flex;flex-direction: row;justify-content: center;margin-top:5vh"
/>
</el-card>
</div> </div>
</template> </template>
<script> <script lang="ts" setup>
import { defineComponent, markRaw } from 'vue'; import { ref } from 'vue';
import { fetchList } from '@/api/article'; import { ElTable } from 'element-plus';
import { Document as IconDocument, Timer as IconTimer } from '@element-plus/icons-vue'; import { ArrowDownBold, InfoFilled } from '@element-plus/icons-vue';
export default defineComponent({ const confirmEvent = () => {
name: 'SelectExcel', console.log('confirm!')
components: { IconTimer }, }
data() { const cancelEvent = () => {
return { console.log('cancel!')
IconDocument: markRaw(IconDocument), }
list: null, const value1 = ref('');
listLoading: true, //
multipleSelection: [], const EditDialogVisible = ref(false);
downloadLoading: false, //
filename: '' const AddDialogVisible = ref(false);
interface User {
date: string
name: string
address: string
}
const multipleTableRef = ref<InstanceType<typeof ElTable>>();
const multipleSelection = ref<User[]>([]);
const handleSelectionChange = (val: User[]) => {
multipleSelection.value = val;
}; };
},
created() { // const tableData: User[] = [
this.fetchData(); // {
}, // date: '2016-05-03',
methods: { // name: 'Tom',
fetchData() { // address: 'No. 189, Grove St, Los Angeles'
this.listLoading = true; // },
fetchList(this.listQuery).then(response => { // {
this.list = response.data.items; // date: '2016-05-02',
this.listLoading = false; // name: 'Tom',
}); // address: 'No. 189, Grove St, Los Angeles'
}, // },
handleSelectionChange(val) { // {
this.multipleSelection = val; // date: '2016-05-04',
}, // name: 'Tom',
handleDownload() { // address: 'No. 189, Grove St, Los Angeles'
if (this.multipleSelection.length) { // },
this.downloadLoading = true; // {
import('@/vendor/Export2Excel').then(excel => { // date: '2016-05-01',
const tHeader = ['Id', 'Title', 'Author', 'Readings', 'Date']; // name: 'Tom',
const filterVal = ['id', 'title', 'author', 'pageviews', 'display_time']; // address: 'No. 189, Grove St, Los Angeles'
const list = this.multipleSelection; // }
const data = this.formatJson(filterVal, list); //
excel.export_json_to_excel({ // ];
header: tHeader,
data, // 1
filename: this.filename import { onMounted } from 'vue';
});
this.$refs.multipleTable.clearSelection();
this.downloadLoading = false; interface LinkItem {
}); value: string
} else { link: string
ElMessage({ }
message: 'Please select at least one item',
type: 'warning' const state = ref('');
const links = ref<LinkItem[]>([]);
const querySearch = (queryString: string, cb) => {
const results = queryString
? links.value.filter(createFilter(queryString))
: links.value;
// call callback function to return suggestion objects
cb(results);
};
const createFilter = (queryString) => {
return (restaurant) => {
return (
restaurant.value.toLowerCase().indexOf(queryString.toLowerCase()) === 0
);
};
};
const loadAll = () => {
return [
{ value: '1' },
{ value: '2' },
{ value: '3' },
{ value: '4' },
{ value: '5' }
];
};
const handleSelect = (item: LinkItem) => {
console.log(item);
};
const handleIconClick = (ev: Event) => {
console.log(ev);
};
onMounted(() => {
links.value = loadAll();
}); });
//
const value2 = ref('');
const shortcuts = [
{
text: 'Last week',
value: () => {
const end = new Date();
const start = new Date();
start.setTime(start.getTime() - 3600 * 1000 * 24 * 7);
return [start, end];
} }
}, },
formatJson(filterVal, jsonData) { {
return jsonData.map(v => filterVal.map(j => v[j])); text: 'Last month',
value: () => {
const end = new Date();
const start = new Date();
start.setTime(start.getTime() - 3600 * 1000 * 24 * 30);
return [start, end];
}
},
{
text: 'Last 3 months',
value: () => {
const end = new Date();
const start = new Date();
start.setTime(start.getTime() - 3600 * 1000 * 24 * 90);
return [start, end];
} }
} }
}); ];
const handleClick = () => {
console.log('click')
}
const tableData = [
{
date: '2016-05-03',
name: 'Tom',
state: 'California',
city: 'Los Angeles',
address: 'No. 189, Grove St',
zip: 'CA 90036',
tag: 'Home',
},
{
date: '2016-05-02',
name: 'Tom',
state: 'California',
city: 'Los Angeles',
address: 'No. 189, Grove St',
zip: 'CA 90036',
tag: 'Office',
},
{
date: '2016-05-04',
name: 'Tom',
state: 'California',
city: 'Los Angeles',
address: 'No. 189, Grove St',
zip: 'CA 90036',
tag: 'Home',
},
{
date: '2016-05-01',
name: 'Tom',
state: 'California',
city: 'Los Angeles',
address: 'No. 189, Grove St',
zip: 'CA 90036',
tag: 'Office',
},
,
{
date: '2016-05-01',
name: 'Tom',
state: 'California',
city: 'Los Angeles',
address: 'No. 189, Grove St',
zip: 'CA 90036',
tag: 'Office',
},
{
date: '2016-05-01',
name: 'Tom',
state: 'California',
city: 'Los Angeles',
address: 'No. 189, Grove St',
zip: 'CA 90036',
tag: 'Office',
},
]
</script> </script>
<style>
.my-autocomplete li {
line-height: normal;
padding: 7px;
}
.my-autocomplete li .name {
text-overflow: ellipsis;
overflow: hidden;
}
.my-autocomplete li .addr {
font-size: 12px;
color: #b4b4b4;
}
.my-autocomplete li .highlighted .addr {
color: #ddd;
}
</style>

View File

@ -1,43 +1,267 @@
<template> <template>
<div class="app-container"> <div style=" width:100%">
<upload-excel-component :on-success="handleSuccess" :before-upload="beforeUpload" /> <el-card style="max-width: 100vw;margin: 1.5vw;">
<el-table :data="tableData" border highlight-current-row style="width: 100%;margin-top:20px;"> <!-- <template #header><span>我的审批</span></template>-->
<el-table-column v-for="item of tableHeader" :key="item" :prop="item" :label="item" /> <template #header><strong >记录查询</strong></template>
<div style="display:flex;flex-direction:row;justify-content: space-around ">
<div>
名称
<el-input v-model="input" style="width: 240px;margin-left:0.5vw" placeholder="请输入" />
</div>
<div>
状态
<el-autocomplete
v-model="state"
:fetch-suggestions="querySearch"
popper-class="my-autocomplete"
placeholder="Please input"
@select="handleSelect"
style="margin-left:0.5vw"
>
<template #suffix>
<el-icon class="el-input__icon" @click="handleIconClick">
<ArrowDownBold />
</el-icon>
</template>
<template #default="{ item }">
<div class="value">{{ item.value }}</div>
<span class="link">{{ item.link }}</span>
</template>
</el-autocomplete>
</div>
<div>
<el-button type="primary" style="width:80px">查询</el-button>
<el-button style="width:80px">重置</el-button>
</div>
</div>
</el-card>
<el-card style="max-width: 100vw;height:60vh;margin:1.3vw">
<div style="display:flex;flex-direction: row;justify-content: space-between">
<el-button text >历史记录</el-button>
</div>
<el-table :data="tableData" style="width: 100%">
<el-table-column fixed prop="date" label="序号" width="150" />
<el-table-column prop="name" label="申请名称" width="120" />
<el-table-column prop="state" label="所属项目" width="120" />
<el-table-column prop="city" label="所属子系统" width="120" />
<el-table-column prop="zip" label="类型" width="120" />
<el-table-column prop="zip" label="状态" width="120" >
<!-- <el-tag type="success" property="address">已通过</el-tag>&ndash;&gt;-->
<el-tag type="warning" property="address">待审核</el-tag>
<!-- <el-tag type="danger" property="address">已拒绝</el-tag>-->
</el-table-column>
<el-table-column prop="address" label="申请者" width="180" >
<el-tag type="primary" property="address">Tag 1</el-tag>
</el-table-column>
<el-table-column prop="zip" label="申请时间" width="120" />
<el-table-column prop="zip" label="申请理由" width="400" />
</el-table> </el-table>
<el-pagination
larger
background
layout="prev, pager, next"
:total="50" class="mt-4"
style="display: flex;flex-direction: row;justify-content: center;margin-top:5vh"
/>
</el-card>
</div> </div>
</template> </template>
<script> <script lang="ts" setup>
import { defineComponent } from 'vue'; import { ref } from 'vue';
import UploadExcelComponent from '@/components/UploadExcel/index.vue'; import { ElTable } from 'element-plus';
import { ArrowDownBold, InfoFilled } from '@element-plus/icons-vue';
export default defineComponent({ const confirmEvent = () => {
name: 'UploadExcel', console.log('confirm!')
components: { UploadExcelComponent }, }
data() { const cancelEvent = () => {
return { console.log('cancel!')
tableData: [], }
tableHeader: [] const value1 = ref('');
//
const EditDialogVisible = ref(false);
//
const AddDialogVisible = ref(false);
interface User {
date: string
name: string
address: string
}
const multipleTableRef = ref<InstanceType<typeof ElTable>>();
const multipleSelection = ref<User[]>([]);
const handleSelectionChange = (val: User[]) => {
multipleSelection.value = val;
}; };
},
methods: {
beforeUpload(file) {
const isLt1M = file.size / 1024 / 1024 < 1;
if (isLt1M) {
return true; // 1
import { onMounted } from 'vue';
interface LinkItem {
value: string
link: string
} }
ElMessage({ const state = ref('');
message: 'Please do not upload files larger than 1m in size.', const links = ref<LinkItem[]>([]);
type: 'warning'
const querySearch = (queryString: string, cb) => {
const results = queryString
? links.value.filter(createFilter(queryString))
: links.value;
// call callback function to return suggestion objects
cb(results);
};
const createFilter = (queryString) => {
return (restaurant) => {
return (
restaurant.value.toLowerCase().indexOf(queryString.toLowerCase()) === 0
);
};
};
const loadAll = () => {
return [
{ value: '1' },
{ value: '2' },
{ value: '3' },
{ value: '4' },
{ value: '5' }
];
};
const handleSelect = (item: LinkItem) => {
console.log(item);
};
const handleIconClick = (ev: Event) => {
console.log(ev);
};
onMounted(() => {
links.value = loadAll();
}); });
return false;
//
const value2 = ref('');
const shortcuts = [
{
text: 'Last week',
value: () => {
const end = new Date();
const start = new Date();
start.setTime(start.getTime() - 3600 * 1000 * 24 * 7);
return [start, end];
}
}, },
handleSuccess({ results, header }) { {
this.tableData = results; text: 'Last month',
this.tableHeader = header; value: () => {
const end = new Date();
const start = new Date();
start.setTime(start.getTime() - 3600 * 1000 * 24 * 30);
return [start, end];
}
},
{
text: 'Last 3 months',
value: () => {
const end = new Date();
const start = new Date();
start.setTime(start.getTime() - 3600 * 1000 * 24 * 90);
return [start, end];
} }
} }
}); ];
const handleClick = () => {
console.log('click')
}
const tableData = [
{
date: '2016-05-03',
name: 'Tom',
state: 'California',
city: 'Los Angeles',
address: 'No. 189, Grove St',
zip: 'CA 90036',
tag: 'Home',
},
{
date: '2016-05-02',
name: 'Tom',
state: 'California',
city: 'Los Angeles',
address: 'No. 189, Grove St',
zip: 'CA 90036',
tag: 'Office',
},
{
date: '2016-05-04',
name: 'Tom',
state: 'California',
city: 'Los Angeles',
address: 'No. 189, Grove St',
zip: 'CA 90036',
tag: 'Home',
},
{
date: '2016-05-01',
name: 'Tom',
state: 'California',
city: 'Los Angeles',
address: 'No. 189, Grove St',
zip: 'CA 90036',
tag: 'Office',
},
,
{
date: '2016-05-01',
name: 'Tom',
state: 'California',
city: 'Los Angeles',
address: 'No. 189, Grove St',
zip: 'CA 90036',
tag: 'Office',
},
{
date: '2016-05-01',
name: 'Tom',
state: 'California',
city: 'Los Angeles',
address: 'No. 189, Grove St',
zip: 'CA 90036',
tag: 'Office',
},
]
</script> </script>
<style>
.my-autocomplete li {
line-height: normal;
padding: 7px;
}
.my-autocomplete li .name {
text-overflow: ellipsis;
overflow: hidden;
}
.my-autocomplete li .addr {
font-size: 12px;
color: #b4b4b4;
}
.my-autocomplete li .highlighted .addr {
color: #ddd;
}
</style>

View File

@ -113,8 +113,8 @@ export default defineComponent({
}; };
return { return {
loginForm: { loginForm: {
username: 'teacher_user', username: 'principal_user',
password: '123456' password: 'jsl_nbxt'
}, },
loginRules: { loginRules: {
username: [{ required: true, trigger: 'blur', validator: validateUsername }], username: [{ required: true, trigger: 'blur', validator: validateUsername }],