This commit is contained in:
“XCYH” 2024-04-25 16:15:40 +08:00
commit e90f354b9d
36 changed files with 2090 additions and 1041 deletions

3
components.d.ts vendored
View File

@ -14,7 +14,6 @@ declare module '@vue/runtime-core' {
Dropzone: typeof import('./src/components/Dropzone/index.vue')['default']
EditorImage: typeof import('./src/components/Tinymce/components/EditorImage.vue')['default']
ElAlert: typeof import('element-plus/es')['ElAlert']
ElAutocomplete: typeof import('element-plus/es')['ElAutocomplete']
ElBadge: typeof import('element-plus/es')['ElBadge']
ElBreadcrumb: typeof import('element-plus/es')['ElBreadcrumb']
ElBreadcrumbItem: typeof import('element-plus/es')['ElBreadcrumbItem']
@ -38,10 +37,12 @@ declare module '@vue/runtime-core' {
ElMenuItem: typeof import('element-plus/es')['ElMenuItem']
ElOption: typeof import('element-plus/es')['ElOption']
ElPagination: typeof import('element-plus/es')['ElPagination']
ElPopconfirm: typeof import('element-plus/es')['ElPopconfirm']
ElProgress: typeof import('element-plus/es')['ElProgress']
ElRow: typeof import('element-plus/es')['ElRow']
ElScrollbar: typeof import('element-plus/es')['ElScrollbar']
ElSelect: typeof import('element-plus/es')['ElSelect']
ElSelectV2: typeof import('element-plus/es')['ElSelectV2']
ElSubMenu: typeof import('element-plus/es')['ElSubMenu']
ElSwitch: typeof import('element-plus/es')['ElSwitch']
ElTable: typeof import('element-plus/es')['ElTable']

View File

@ -355,12 +355,12 @@ export const asyncRoutes = [
},
{
path: '/tab',
path: '/daily',
component: 'layout/Layout',
children: [
{
path: 'index',
component: 'views/tab/index',
component: 'views/daily/index',
name: 'Tab',
meta: { title: 'Tab', icon: 'tab' }
}
@ -393,13 +393,13 @@ export const asyncRoutes = [
},
{
path: '/error-log',
path: '/Message',
component: 'layout/Layout',
redirect: 'noRedirect',
children: [
{
path: 'log',
component: 'views/error-log/index',
component: 'views/Message/index',
name: 'ErrorLog',
meta: { title: 'Error Log', icon: 'bug' }
}
@ -407,36 +407,36 @@ export const asyncRoutes = [
},
{
path: '/excel',
path: '/examine',
component: 'layout/Layout',
redirect: '/excel/export-excel',
redirect: '/examine/export-examine',
name: 'Excel',
meta: {
title: 'Excel',
icon: 'excel'
icon: 'examine'
},
children: [
{
path: 'export-excel',
component: 'views/excel/export-excel',
path: 'export-examine',
component: 'views/examine/export-examine',
name: 'ExportExcel',
meta: { title: 'Export Excel' }
},
{
path: 'export-selected-excel',
component: 'views/excel/select-excel',
path: 'export-selected-examine',
component: 'views/examine/select-examine',
name: 'SelectExcel',
meta: { title: 'Select Excel' }
},
{
path: 'export-merge-header',
component: 'views/excel/merge-header',
component: 'views/examine/merge-header',
name: 'MergeHeader',
meta: { title: 'Merge Header' }
},
{
path: 'upload-excel',
component: 'views/excel/upload-excel',
path: 'upload-examine',
component: 'views/examine/upload-examine',
name: 'UploadExcel',
meta: { title: 'Upload Excel' }
}

View File

@ -1,5 +1,5 @@
import request from '@/utils/request';
const a = process.env.VUE_APP_APIII;
export function fetchList(query) {
return request({
url: '/vue-element-admin/article/list',

58
src/api/daily.js Normal file
View File

@ -0,0 +1,58 @@
import request from '../utils/request';
function getCurrentTimestamp() {
return new Date().getTime();
}
// 获取日报
export function GetMyDaily(data, token) {
return request({
url: '/daily/getMyDaily',
method: 'get',
params: data,
headers: {
'Authorization':'Bearer '+token,
'Timestamp':getCurrentTimestamp()
}
});
}
//提交日报
export function DailyAdd(data, token) {
return request({
url: '/daily/add',
method: 'post',
data: data,
headers: {
'content-type':'application/json;charset=utf-8',
'Authorization':'Bearer '+token,
'Timestamp':getCurrentTimestamp()
}
});
}
//编辑日报
export function DailyUpdate(data, token) {
return request({
url: '/daily/update',
method: 'put',
data: data,
headers: {
'content-type':'application/json;charset=utf-8',
'Authorization':'Bearer '+token,
'Timestamp':getCurrentTimestamp()
}
});
}
//查询日报
export function SearchDaily(data, token) {
return request({
url: '/daily/search',
method: 'get',
params: data,
headers: {
'Authorization':'Bearer '+token,
'Timestamp':getCurrentTimestamp()
}
});
}

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

@ -0,0 +1,123 @@
import request from '../utils/request';
function getCurrentTimestamp() {
return new Date().getTime();
}
// 根据名称获取项目列表
export function ProjectGetByName(data, token) {
return request({
url: '/project/get/name',
method: 'get',
params: data,
headers: {
'Authorization':'Bearer '+token,
'Timestamp':getCurrentTimestamp()
}
});
}
// 项目名查询所有子系统
export function ProjectChildGetName(data, token) {
return request({
url: '/project/child/get/id',
method: 'get',
params: data,
headers: {
'Authorization':'Bearer '+token,
'Timestamp':getCurrentTimestamp()
}
});
}
//根据项目和系统名查询系统所属子模块
export function ProjectModuleGetName(data, token) {
return request({
url: '/project/module/get/id',
method: 'get',
params: data,
headers: {
'Authorization':'Bearer '+token,
'Timestamp':getCurrentTimestamp()
}
});
}
// 提交申请
export function ReviewAdd(data, token) {
return request({
url: '/review/add',
method: 'post',
data: data,
headers: {
'content-type':'application/json;charset=utf-8',
'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/updateReview',
method: 'put',
data: data,
headers: {
'Authorization':'Bearer '+token,
'content-type':'application/json;charset=utf-8',
'Timestamp':getCurrentTimestamp()
}
});
}
//获取审核记录
export function ReviewRecords(data, token) {
return request({
url: '/review/getReviewRecords',
method: 'get',
params: data,
headers: {
'Authorization':'Bearer '+token,
'Timestamp':getCurrentTimestamp()
}
});
}
//查询我的审核
export function ReviewSearchMyReview(data, token) {
return request({
url: '/review/searchMyReview',
method: 'get',
params: data,
headers: {
'Authorization':'Bearer '+token,
'Timestamp':getCurrentTimestamp()
}
});
}
//查询我的记录
export function ReviewRecordsSearch(data, token) {
return request({
url: '/review/searchReviewRecords',
method: 'get',
params: data,
headers: {
'Authorization':'Bearer '+token,
'Timestamp':getCurrentTimestamp()
}
});
}

View File

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

View File

@ -1,12 +1,13 @@
import request from '@/utils/request';
const api = 'http://nbxt.oa.x-lf.cn'
function getCurrentTimestamp() {
return new Date().getTime();
}
export function login(data) {
return request({
url: '/auth/login',
url: api+ '/auth/login',
method: 'post',
data,
headers: {
@ -17,7 +18,7 @@ export function login(data) {
export function getInfo(token) {
return request({
url: '/user/profile/get',
url: api +'/user/profile/get',
method: 'get',
// params: {token},
headers: {
@ -30,7 +31,7 @@ export function getInfo(token) {
export function logout(token) {
return request({
url: '/auth/logout',
url: api +'/auth/logout',
method: 'get',
headers: {
'Authorization':'Bearer '+token,

View File

@ -76,7 +76,7 @@ export default defineComponent({
this.upload(rawFile);
},
upload(rawFile) {
this.$refs['excel-upload-input'].value = null; // fix can't select the same excel
this.$refs['excel-upload-input'].value = null; // fix can't select the same examine
if (!this.beforeUpload) {
this.readerData(rawFile);

View File

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

View File

@ -1,9 +1,9 @@
<template>
<div v-if="!isItemHidden" class="root-sidebar-item">
<div v-if="!isItemHidden" class="root-sidebar-item" >
<template
v-if="hasOneShowingChild(item.children, item) && (!onlyOneChild.children || onlyOneChild.noShowingChildren) && !(item.meta && item.meta.alwaysShow)">
<app-link class="link" :to="resolvePath(onlyOneChild.path)">
<el-menu-item class="left-menu-item" v-if="onlyOneChild.meta" :index="resolvePath(onlyOneChild.path)"
<el-menu-item class="left-menu-item" v-if="onlyOneChild.meta" :index="resolvePath(onlyOneChild.path)"
:class="{ 'submenu-title-noDropdown': !isNest }">
<!-- <item :icon="onlyOneChild.meta.icon || (item.meta && item.meta.icon)" :title="onlyOneChild.meta.title" /> -->

View File

@ -72,7 +72,7 @@ export const constantRoutes:RouteRecordRaw[] = [
// children: [
// {
// path: 'index',
// component: () => import('@/views/documentation/index.vue'),
// component: () => import('@/views/documentation/Message.vue'),
// name: 'Documentation',
// meta: { title: 'Documentation', icon: 'documentation', affix: true }
// }
@ -85,7 +85,7 @@ export const constantRoutes:RouteRecordRaw[] = [
// children: [
// {
// path: 'index',
// component: () => import('@/views/guide/index.vue'),
// component: () => import('@/views/guide/Message.vue'),
// name: 'Guide',
// meta: { title: 'Guide', icon: 'guide', noCache: true }
// }
@ -126,7 +126,7 @@ export const asyncRoutes:RouteRecordRaw[] = [
// children: [
// {
// path: 'index',
// component: () => import('@/views/icons/index.vue'),
// component: () => import('@/views/icons/Message.vue'),
// name: 'Icons',
// meta: { title: 'Icons', icon: 'icon', noCache: true }
// }
@ -176,9 +176,9 @@ export const asyncRoutes:RouteRecordRaw[] = [
children: [
{
path: 'd',
component: () => import('@/views/tab/index.vue'),
component: () => import('@/views/daily/index.vue'),
name: 'Tab',
meta: { title: '日报', icon: 'tab' }
meta: { title: '日报', icon: 'tab', role: ['principle', 'developer', 'console'] }
}
]
},
@ -214,49 +214,43 @@ export const asyncRoutes:RouteRecordRaw[] = [
children: [
{
path: 'ms',
component: () => import('@/views/error-log/index.vue'),
name: 'ErrorLog',
meta: { title: '信息', icon: 'bug' }
component: () => import('@/views/Message/Message.vue'),
name: 'email',
meta: { title: '信息', icon: 'email', role: ['principle', 'developer', 'console'] }
}
]
},
// {
// path: '/excel',
// component: Layout,
// redirect: '/excel/export-excel',
// name: 'Excel',
// meta: {
// title: 'Excel',
// icon: 'excel'
// },
// children: [
// {
// path: 'export-excel',
// component: () => import('@/views/excel/export-excel.vue'),
// name: 'ExportExcel',
// meta: { title: 'Export Excel' }
// },
// {
// path: 'export-selected-excel',
// component: () => import('@/views/excel/select-excel.vue'),
// name: 'SelectExcel',
// meta: { title: 'Export Selected' }
// },
// {
// path: 'export-merge-header',
// component: () => import('@/views/excel/merge-header.vue'),
// name: 'MergeHeader',
// meta: { title: 'Merge Header' }
// },
// {
// path: 'upload-excel',
// component: () => import('@/views/excel/upload-excel.vue'),
// name: 'UploadExcel',
// meta: { title: 'Upload Excel' }
// }
// ]
// },
{
path: '/examine',
component: Layout,
redirect: '/examine/export-examine',
name: 'examine',
meta: {
title: '申请和审批',
icon: 'excel'
},
children: [
{
path: 'submit-application',
component: () => import('@/views/examine/submit-application.vue'),
name: 'ExportExcel',
meta: { title: '提交申请' }
},
{
path: 'export-selected-examine',
component: () => import('@/views/examine/My-review.vue'),
name: 'MyReview',
meta: { title: '我的审批' }
},
{
path: 'search-record',
component: () => import('@/views/examine/search-records.vue'),
name: 'searchRecord',
meta: { title: '记录查询' }
}
]
},
// {
// path: '/zip',
@ -267,7 +261,7 @@ export const asyncRoutes:RouteRecordRaw[] = [
// children: [
// {
// path: 'download',
// component: () => import('@/views/zip/index.vue'),
// component: () => import('@/views/zip/Message.vue'),
// name: 'ExportZip',
// meta: { title: 'Export Zip' }
// }
@ -281,7 +275,7 @@ export const asyncRoutes:RouteRecordRaw[] = [
// children: [
// {
// path: 'index',
// component: () => import('@/views/pdf/index.vue'),
// component: () => import('@/views/pdf/Message.vue'),
// name: 'PDF',
// meta: { title: 'PDF', icon: 'pdf' }
// }
@ -299,7 +293,7 @@ export const asyncRoutes:RouteRecordRaw[] = [
// children: [
// {
// path: 'index',
// component: () => import('@/views/theme/index.vue'),
// component: () => import('@/views/theme/Message.vue'),
// name: 'Theme',
// meta: { title: 'Theme', icon: 'theme' }
// }
@ -312,7 +306,7 @@ export const asyncRoutes:RouteRecordRaw[] = [
// children: [
// {
// path: 'index',
// component: () => import('@/views/clipboard/index.vue'),
// component: () => import('@/views/clipboard/Message.vue'),
// name: 'ClipboardDemo',
// meta: { title: 'Clipboard', icon: 'clipboard' }
// }

View File

@ -9,7 +9,7 @@ const tableRouter = {
redirect: '/table/complex-table',
name: 'Table',
meta: {
title: 'Table',
title: '个人项目',
icon: 'table'
},
children: [
@ -17,25 +17,25 @@ const tableRouter = {
path: 'dynamic-table',
component: () => import('@/views/table/dynamic-table/index.vue'),
name: 'DynamicTable',
meta: { title: 'Dynamic Table' }
meta: { title: '我参与的' }
},
{
path: 'drag-table',
component: () => import('@/views/table/drag-table.vue'),
name: 'DragTable',
meta: { title: 'Drag Table' }
},
{
path: 'inline-edit-table',
component: () => import('@/views/table/inline-edit-table.vue'),
name: 'InlineEditTable',
meta: { title: 'Inline Edit' }
meta: { title: '我管理的' }
},
// {
// path: 'inline-edit-table',
// component: () => import('@/views/table/inline-edit-table.vue'),
// name: 'InlineEditTable',
// meta: { title: 'Inline Edit' }
// },
{
path: 'complex-table',
component: () => import('@/views/table/complex-table.vue'),
name: 'ComplexTable',
meta: { title: 'Complex Table' }
meta: { title: '我负责的' }
}
]
};

View File

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

View File

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

View File

@ -154,7 +154,7 @@ export function export_json_to_excel({
bookType = 'xlsx'
} = {}) {
/* original data */
filename = filename || 'excel-list'
filename = filename || 'examine-list'
data = [...data]
data.unshift(header);

View File

@ -0,0 +1,263 @@
<template>
<div style=" width:100%">
<el-card style="max-width: 100vw;margin: 1.5vw;">
<template #header>
<span>消息</span>
</template>
<div style="display:flex;flex-direction:row;justify-content: space-between ">
<div class="block">
<span class="demonstration" style="margin-right: 8px">时间</span>
<el-date-picker
v-model="value2"
type="datetimerange"
:shortcuts="shortcuts"
range-separator="To"
start-placeholder="Start date"
end-placeholder="End date"
/>
</div>
<div>
<el-button type="primary" style="width:80px" @click="selectMessage">查询</el-button>
<el-button style="width:80px" @click="resetting">重置</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
>
<el-tag style="margin-right: 1.7vw">总数{{messageData.total}}</el-tag>
</div>
<div style="height: 43vh">
<div v-for="(row) in messageData.data" :key="Message" class="table-row">
<div class="table-author" style="text-align: left">
<span class="date" style="display:flex;flex-direction: column">
<span style="color:skyblue">{{row.senderName}}</span>
<span>{{ row.text }}</span>
</span>
</div>
<div class="table-time createdTime">
<span>{{ formatDateTime(row.createdAt) }}</span>
</div>
<div class="table-btn table-cell-right">
<el-button size="small" type="danger" @click="handleDelete(row);centerDialogVisible = true">Delete</el-button>
<el-dialog v-model="centerDialogVisible" title="删除" width="500" :modal="false">
<span>
是否确认删除此条信息
</span>
<template #footer>
<div class="dialog-footer">
<el-button @click="centerDialogVisible = false">取消</el-button>
<el-button type="primary" @click="deleteItem">
确认
</el-button>
</div>
</template>
</el-dialog>
</div>
</div>
</div>
<el-pagination
@current-change="pagination"
background layout="prev, pager, next"
:total="messageData.total"
v-model:page-size="requestData.pageSize"
style="display: flex;flex-direction: row;justify-content: center;margin-top: 0.5vh"
/>
</el-card>
</div>
</template>
<script lang="ts" setup>
import {onMounted, reactive, ref, watch} from 'vue';
import {messageGet, messageDelete} from '@/api/message'
import {getToken} from "@/utils/auth";
//
const centerDialogVisible = ref(false);
//
const value2 = ref('')
const shortcuts = [
{
text: 'Last week',
value: () => {
const end = new Date()
const start = new Date()
start.setDate(start.getDate() - 7)
return [start, end]
},
},
{
text: 'Last month',
value: () => {
const end = new Date()
const start = new Date()
start.setMonth(start.getMonth() - 1)
return [start, end]
},
},
{
text: 'Last 3 months',
value: () => {
const end = new Date()
const start = new Date()
start.setMonth(start.getMonth() - 3)
return [start, end]
},
},
]
//
interface Message {
id: number
createdAt: string
name: string
text: string
}
const deleteData = reactive({
id: -1
})
const handleDelete = ( row: Message) => {
deleteData.id = row.id
console.log("time:select", value2.value[1])
};
const messageData = reactive({
data:[],
total: 0
})
let requestData = reactive({
page:1,
pageSize: 5,
begin: '',
end: ''
})
//
watch(value2, (newValue) => {
if (newValue !== '') {
requestData.begin = formatDateTime(newValue[0])
requestData.end = formatDateTime(newValue[1])
}
})
onMounted(() => {
flushData()
})
function flushData() {
messageGet(requestData, getToken()).then((res)=>{
console.log("getMessageResult:",res.data.list);
messageData.data = res.data.list
messageData.total = res.data.total
})
}
function pagination(currentPage: number) {
requestData.page = currentPage
flushData()
}
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
}
function selectMessage (){
try {
flushData()
console.log(requestData)
ElMessage.success('查询成功')
}catch (e) {
ElMessage.success('查询失败')
}
}
function resetting(){
requestData.begin = ''
requestData.end = ''
value2.value = ''
}
//
function formatDateTime(dateTimeString: string): string {
const dateTime = new Date(dateTimeString);
const year = dateTime.getFullYear();
const month = String(dateTime.getMonth() + 1).padStart(2, '0');
const date = String(dateTime.getDate()).padStart(2, '0');
const hours = String(dateTime.getHours()).padStart(2, '0');
const minutes = String(dateTime.getMinutes()).padStart(2, '0');
const seconds = String(dateTime.getSeconds()).padStart(2, '0');
return `${year}-${month}-${date} ${hours}:${minutes}:${seconds}`;
}
</script>
<style>
.my-autocomplete li {
line-height: normal;
padding: 7px;
}
.table-row {
display: flex;
align-items: center;
}
.table-author {
flex: 1;
padding: 10px;
display: flex;
justify-content: left;
align-items: center;
}
.table-time {
flex: 0.3;
padding: 10px;
display: flex;
justify-content: right;
align-items: center;
}
.table-btn {
flex: 0.3;
padding: 0;
display: flex;
justify-content: right;
align-items: center;
/*background-color: #32fe04;*/
}
.createdTime{
margin-left: 50px;
margin-top: 10px;
}
.table-cell-right {
justify-content: flex-end;
margin-right:2vw;
}
.date {
display: flex;
}
.date el-icon {
margin-right: 10px;
}
</style>

380
src/views/daily/index.vue Normal file
View File

@ -0,0 +1,380 @@
<template>
<div style=" width:100%">
<el-card style="max-width: 100vw;margin: 1.5vw;">
<template #header><span>日报</span></template>
<div style="display:flex;flex-direction:row;justify-content: space-around ">
<div>
项目
<el-select-v2
v-model="requestData.projectId"
style="width: 240px;"
filterable
remote
:remote-method="remoteMethod"
clearable
:options="options"
:loading="loading"
placeholder="请输入所属项目"
/>
</div>
<div>
时间
<el-date-picker
v-model="value2"
type="datetimerange"
:shortcuts="shortcuts"
range-separator="To"
start-placeholder="Start date"
end-placeholder="End date"
/>
</div>
<div>
<el-button type="primary" style="width:80px" @click="selectMessage">查询</el-button>
<el-button style="width:80px" @click="resetting">重置</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">
<div>
<el-button text >历史记录</el-button>
<el-tag>总条数{{ messageData.total }}</el-tag>
</div>
<el-button type="primary" @click="AddDialogVisible=true">新建</el-button>
<el-dialog v-model="AddDialogVisible" width="500" center :modal="false" :show-close="false">
<template #header>
<div style="display:flex;flex-direction: row;justify-content: flex-start;color:red;font-size:large" >新增日报</div>
<el-divider content-position="left" style="background:red"><el-icon><CaretTop /></el-icon></el-divider>
</template>
<div>
<div style="margin-top:-4vh ">
<span style="color:red">项目名称</span>
<el-select-v2
v-model="AddContent.projectId"
style="width: 240px;"
filterable
remote
:remote-method="remoteMethod"
clearable
:options="options"
:loading="loading"
placeholder="请输入所属项目"
/>
</div>
<div style="margin-top:2vh ">
<span style="color:red"> 工作时间</span>
<el-date-picker
v-model="AddContent.dailyTime"
type="datetime"
placeholder="Pick a Date"
/>
</div>
<div style="margin-top:2vh ;display:flex;flex-direction:row;">
<span style="color: red">日报内容</span>
<el-input
v-model="AddContent.content"
style="width: 360px;"
:rows="4"
type="textarea"
placeholder="请输入"
/>
</div>
</div>
<template #footer>
<div class="dialog-footer">
<el-button @click="AddDialogVisible = false" type="info" style="width: 80px">取消 </el-button>
<el-button type="danger" style="width:80px" @click="AddDailyMs">
新增
</el-button>
</div>
</template>
</el-dialog>
</div>
<div style="height: 45vh;">
<el-table :data="messageData.data" style="max-width: 100vw;">
<el-table-column property="projectName" label="项目名称" width="120" />
<el-table-column property="userName" label="项目负责人" />
<el-table-column property="content" label="日报" />
<el-table-column property="userName" label="日报填写者" />
<el-table-column property="createdAt" label="填写时间" />
<el-table-column property="dailyTime" label="工作时间" />
<el-table-column property="id" label="操作" >
<template #default="scope">
<el-button size="small" text style="color:deepskyblue" @click="EditDailyMs(scope.row)">修改</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>
<div style="margin-top:-4vh ">
<span style="color:#409eff"> 工作时间</span>
<el-date-picker
v-model="updateContent.dailyTime"
type="datetime"
placeholder="输入工作时间"
/>
</div>
<div style="margin-top:2vh ;display:flex;flex-direction:row;">
<span style="color:#409eff">日报内容</span>
<el-input
v-model="updateContent.content"
style="width: 360px;"
: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="EditDailyContent">
确认
</el-button>
</div>
</template>
</el-dialog>
</template>
</el-table-column>
</el-table>
</div>
<el-pagination
@current-change="pagination"
background layout="prev, pager, next"
:total="messageData.total"
v-model:page-size="requestData.pageSize"
style="display: flex;flex-direction: row;justify-content: center;margin-top: 0.5vh"
/>
</el-card>
</div>
</template>
<script lang="ts" setup>
import {onMounted, reactive, ref, watch} from 'vue';
import { ElTable } from 'element-plus';
import {getToken} from "@/utils/auth";
import { CaretTop } from '@element-plus/icons-vue';
import {GetMyDaily,DailyUpdate,DailyAdd,SearchDaily} from '@/api/daily'
import {ProjectGetByName} from "@/api/examine";
//
let EditDialogVisible = ref(false);
const updateContent = reactive({
dailyTime:'',
content:'',
id:null,
projectId: null,
})
function EditDailyMs(row){
updateContent.content = row.content
updateContent.dailyTime = row.dailyTime
updateContent.id = row.id
updateContent.projectId = row.projectId
EditDialogVisible.value = true
}
//
const AddDialogVisible = ref(false);
const AddContent = reactive({
projectId:<unknown>null,
content:'',
dailyTime:''
})
function AddDailyMs(){
AddContent.dailyTime = formatDateTime(AddContent.dailyTime)
// console.log("requestAddData:", AddContent)
DailyAdd(AddContent,getToken()).then((res)=>{
console.log("新增日报Result",res)
if (res.code === 200) {
ElMessage.success("新增成功")
}
flushData()
AddContent.dailyTime = ''
AddContent.content = ''
AddContent.projectId = null
})
AddDialogVisible.value = false
}
//
let list: ProjectAll[] = []
interface ProjectAll {
value: string
label: string
}
const value = ref()
const options = ref<ProjectAll[]>([])
const loading = ref(false)
const qwe = reactive({
data: <ProjectAll[]>[]
})
const remoteMethod = (query: string) => {
if (query !== '') {
loading.value = true
setTimeout(() => {
loading.value = false
options.value = list.filter((item) => {
// return item.name.toLowerCase().includes(query.toLowerCase())
const lowerCaseName = item.label.toLowerCase();
const lowerCaseQuery = query.toLowerCase();
return lowerCaseName.includes(lowerCaseQuery);
})
// console.log("",options.value)
}, 200)
} else {
// console.log("")
options.value = []
}
}
//
let requestData = reactive({
page:1,
pageSize: 6,
beginTime: '',
endTime: '',
projectId:<unknown>null,
})
const messageData = reactive({
data:[],
total: 0
})
onMounted(() => {
flushData()
});
//
//
const value2 = ref('')
watch(value2, (newValue) => {
if (newValue !== '') {
requestData.beginTime = formatDateTime(newValue[0])
requestData.endTime = formatDateTime(newValue[1])
}
})
function pagination(currentPage: number) {
requestData.page = currentPage
flushData()
}
function flushData() {
GetMyDaily(requestData, getToken()).then((res)=>{
console.log('requestData',requestData)
console.log("getMessageResult999:",res.data);
messageData.data = res.data.list
messageData.total = res.data.totalCount
})
ProjectGetByName(projectByName, getToken()).then((res) => {
qwe.data = res.data
list = qwe.data.map((item): ProjectAll => {
return { value: item.id, label: item.name }
})
})
}
const projectByName = reactive({
name:''
})
const state = 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];
}
},
{
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];
}
}
];
function resetting(){
requestData.beginTime = ''
requestData.endTime = ''
value2.value = ''
requestData.projectId = ''
}
//
function selectMessage (){
if(requestData.projectId !==null ){
SearchDaily(requestData,getToken()).then((res)=>{
if (res.code === 200){
messageData.data = res.data.list
messageData.total = res.data.totalCount
ElMessage.success("查询成功!")
}else {
ElMessage.error("查询失败!请重试!")
}
console.log('查询成功?',res)
})
}else {
flushData()
}
}
//
function formatDateTime(dateTimeString: string): string {
const dateTime = new Date(dateTimeString);
const year = dateTime.getFullYear();
const month = String(dateTime.getMonth() + 1).padStart(2, '0');
const date = String(dateTime.getDate()).padStart(2, '0');
const hours = String(dateTime.getHours()).padStart(2, '0');
const minutes = String(dateTime.getMinutes()).padStart(2, '0');
const seconds = String(dateTime.getSeconds()).padStart(2, '0');
return `${year}-${month}-${date} ${hours}:${minutes}:${seconds}`;
}
//
function EditDailyContent(){
EditDialogVisible.value = false
DailyUpdate(updateContent,getToken()).then((res)=>{
if(res.code === 200){
ElMessage.success('修改成功!')
flushData()
}
})
}
</script>
<style>
.my-autocomplete li {
line-height: normal;
padding: 7px;
}
</style>

View File

@ -1,15 +0,0 @@
<template>
<div>
<!--error code-->
{{ a.a }}
<!--error code-->
</div>
</template>
<script>
import { defineComponent } from 'vue';
export default defineComponent({
name: 'ErrorTestA'
});
</script>

View File

@ -1,13 +0,0 @@
<template>
<div />
</template>
<script>
import { defineComponent } from 'vue';
export default defineComponent({
created() {
this.b = b // eslint-disable-line
}
});
</script>

View File

@ -1,11 +1,12 @@
<template>
<div style=" width:100%">
<div style=" width:100%">
<el-card style="max-width: 100vw;margin: 1.5vw;">
<template #header>
<template #header>
<span>消息</span>
</template>
<div style="display:flex;flex-direction:row;justify-content: space-between ">
<div style="display:flex;flex-direction:row;justify-content: space-around ">
<div>
时间
<el-date-picker
@ -18,28 +19,29 @@
:shortcuts="shortcuts"
:size="large"
style="margin-left:0.5vw"
/>
</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>
状态
<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">查询</el-button>
<el-button style="width:80px">重置</el-button>
</div>
@ -58,11 +60,11 @@
<div class="table-cell">
<div class="date" style="display:flex;flex-direction: column">
<span style="color:skyblue">{{row.name}}</span>
<span>{{ row.text }}</span>
<span>{{ row.date }}</span>
</div>
</div>
<div class="table-cell createdTime">
<div>{{ row.createdAt }}</div>
<div class="table-cell">
<div>address: {{ row.address }}</div>
</div>
<div class="table-cell table-cell-right">
<el-button size="small" type="danger" @click="handleDelete(index, row);centerDialogVisible = true">Delete</el-button>
@ -82,7 +84,7 @@
</div>
</div>
<el-pagination
size="large"
size="large"
background
layout="prev, pager, next"
:total="50"
@ -91,7 +93,6 @@
</el-card>
</div>
</template>
<script lang="ts" setup>
@ -99,7 +100,9 @@ import { ref } from 'vue';
//
const centerDialogVisible = ref(false);
//
const value2 = ref('');
const shortcuts = [
{
text: 'Last week',
@ -148,52 +151,47 @@ const options = [
},
{
value: 'Option4',
label: 'Option4'
},
{
value: 'Option5',
label: '已完成'
}
];
//
interface Message {
id: number
createdAt: string
interface User {
date: string
name: string
text: string
address: string
}
const handleDelete = (index: number, row: Message) => {
const handleDelete = (index: number, row: User) => {
console.log(index, row);
};
const tableData: Message[] = [
const tableData: User[] = [
{
id:1 ,
createdAt: '2016-05-03',
date: '2016-05-03',
name: 'Tom',
text: 'No. 189, Grove St, Los Angeles'
address: 'No. 189, Grove St, Los Angeles'
},
{
id:1 ,
createdAt: '2016-05-03',
name: 'Tom',
text: 'No. 189, Grove St, Los Angeles'
},
{
id:1 ,
createdAt: '2016-05-03',
name: 'Tom',
text: 'No. 189, Grove St, Los Angeles'
},
{
id:1 ,
createdAt: '2016-05-03',
name: 'Tom',
text: 'No. 189, Grove St, Los Angeles'
},
{
date: '2016-05-02',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles'
},
{
date: '2016-05-04',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles'
},
{
date: '2016-05-01',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles'
},
{
date: '2016-05-01',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles'
}
];
</script>
<style>
@ -216,19 +214,16 @@ const tableData: Message[] = [
.table-row {
display: flex;
align-items: center;
/*margin-bottom: 10px;*/
margin-bottom: 10px;
}
.table-cell {
flex: 1;
padding: 10px;
padding: 5px;
display: flex;
justify-content: center;
justify-content: space-between;
align-items: center;
}
.createdTime{
margin-left: 50px;
}
.table-cell-right {
justify-content: flex-end;
margin-right:5vw;
@ -241,4 +236,4 @@ const tableData: Message[] = [
.date el-icon {
margin-right: 10px;
}
</style>
</style>

View File

@ -0,0 +1,184 @@
<template>
<div style=" width:100%">
<el-card style="max-width: 100vw;margin: 1.5vw;">
<template #header><strong >我的审批</strong></template>
<div style="display:flex;flex-direction:row;justify-content: space-between ">
<div>
名称
<el-input v-model="requestData.content" style="width: 240px;margin-left:0.5vw" placeholder="请输入" />
</div>
<div>
<el-button type="primary" style="width:80px" @click="SelectMyms">查询</el-button>
<el-button style="width:80px" @click="resetting">重置</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>
<el-tag style="margin-right: 6vw">总数{{ examineData.total }}</el-tag>
</div>
<div style="height: 40vh">
<el-table type="index" :data="examineData.data" empty-text="无数据" style="width: 100%">
<el-table-column fixed prop="name" label="申请名称" width="120" />
<el-table-column prop="projectChildName" label="所属项目" width="120" />
<el-table-column prop="projectModuleName" label="所属子系统" width="120" />
<el-table-column prop="senderName" label="申请者" width="180" >
</el-table-column>
<el-table-column prop="category" label="类型" width="120" />
<el-table-column prop="result" label="状态" width="120" >
<el-tag type="warning" property="result">待审核</el-tag>
</el-table-column>
<el-table-column prop="applicationTime" label="申请时间" width="200" />
<el-table-column prop="content" label="申请理由" width="400" />
<el-table-column fixed="right" property="id" label="操作" width="200">
<template #default="scope">
<el-popconfirm
confirm-button-text="通过"
cancel-button-text="关闭"
:icon="InfoFilled"
icon-color="#626AEF"
title="确定要通过审核吗?"
@confirm="okExamine(scope.row.id)"
@cancel="cancelEvent"
>
<template #reference>
<el-button size="small" text style="color:deepskyblue">审核通过</el-button>
</template>
</el-popconfirm>
<el-divider direction="vertical" />
<el-popconfirm
confirm-button-text="拒绝"
cancel-button-text="关闭"
:icon="InfoFilled"
icon-color="red"
title="确认要拒绝通过吗?确定后不能改变"
@confirm="offExamine(scope.row.id)"
@cancel="cancelEvent"
>
<template #reference>
<el-button size="small" text style="color:red">拒绝申请</el-button>
</template>
</el-popconfirm>
</template>
</el-table-column>
</el-table>
</div>
<el-pagination
larger
@current-change="pagination"
background
layout="prev, pager, next"
v-model:page-size="requestData.pageSize"
:total="examineData.total" class="mt-4"
style="display: flex;flex-direction: row;justify-content: center;margin-top:5vh"
/>
</el-card>
</div>
</template>
<script lang="ts" setup>
import {reactive, ref} from 'vue';
import { ElTable } from 'element-plus';
import { InfoFilled } from '@element-plus/icons-vue';
import {GetMyReview, UpdateReviewResult,ReviewSearchMyReview} from '@/api/examine'
import { onMounted } from 'vue';
import {getToken} from "@/utils/auth";
const cancelEvent = () => {
console.log('cancel!')
}
const state = ref('');
const okExamineRequestData = reactive({
id: -1,
result: -1
})
const requestData = reactive({
page: 1,
pageSize: 6,
content:''
})
const examineData = reactive({
data:[],
total:0,
})
const content = ref()
function okExamine(id: number){
okExamineRequestData.result = 1
okExamineRequestData.id = id
UpdateReviewResult(okExamineRequestData, getToken()).then((res) => {
if (res.code === 200) {
ElMessage.success("已通过此审批")
flushData()
} else {
ElMessage.error("通过审批失败,请重试")
flushData()
}
// console.log("", res)
})
}
function offExamine(id: number) {
okExamineRequestData.result = 0
okExamineRequestData.id = id
UpdateReviewResult(okExamineRequestData, getToken()).then((res) => {
// console.log("", res)
if (res.code === 200) {
ElMessage.success("拒绝审核成功!")
flushData()
}else {
ElMessage.error("拒绝审核失败,请重试")
flushData()
}
})
}
function flushData(){
GetMyReview(requestData, getToken()).then((res) => {
console.log('获取审批',res)
examineData.data = res.data.reviews
examineData.total = res.data.totalCount
// ElMessage.success("")
})
}
function pagination(currentPage: number) {
requestData.page = currentPage
flushData()
}
onMounted(() => {
flushData()
});
//
function SelectMyms(){
ReviewSearchMyReview(requestData,getToken()).then((res) => {
console.log('输出查询',res)
if (res.code === 200){
examineData.data = res.data.reviews
examineData.total = res.data.totalCount
ElMessage.success('查询成功!')
}else {
ElMessage.error('查询失败!请重试!')
}
})
}
//
function resetting(){
requestData.content = ''
}
</script>
<style>
.my-autocomplete li {
line-height: normal;
padding: 7px;
}
</style>

View File

@ -0,0 +1,144 @@
<template>
<div style=" width:100%">
<el-card style="max-width: 100vw;margin: 1.5vw;">
<template #header><strong >记录查询</strong></template>
<div style="display:flex;flex-direction:row;justify-content: space-around ">
<div>
名称
<el-input v-model="requestData.content" style="width: 240px;margin-left:0.5vw" placeholder="请输入" />
</div>
<div>
状态
<el-select
v-model="requestData.statue"
placeholder="请选择"
style="width: 240px"
>
<el-option
label="已审核"
value=1
/>
<el-option
label="已拒绝"
value=0
/>
<el-option
label="待审核"
value=2
/>
</el-select>
</div>
<div>
<el-button type="primary" style="width:80px" @click="selectMessage">查询</el-button>
<el-button style="width:80px" @click="resetting">重置</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>
<el-tag style="margin-right: 6vw">总条数{{historyData.total}}</el-tag>
</div>
<div style="height: 45vh">
<el-table :data="historyData.data" style="width: 100%">
<!-- <el-table-column prop="date" label="序号" width="150" />-->
<el-table-column prop="name" label="申请名称" width="120" />
<el-table-column prop="projectChildName" label="所属项目" width="120" />
<el-table-column prop="projectChildId" label="所属子系统" width="120" />
<el-table-column prop="category" label="类型" width="120" />
<el-table-column label="状态" width="120" >
<template #default="scope">
<el-tag type="success" v-show="scope.row.result === '已通过'" >已通过</el-tag>
<el-tag type="warning" v-show="scope.row.result === '待审核'">待审核</el-tag>
<el-tag type="danger" v-show="scope.row.result === '已拒绝'">已拒绝</el-tag>
</template>
</el-table-column>
<el-table-column prop="senderName" label="申请者" width="180" >
</el-table-column>
<el-table-column prop="applicationTime" label="申请时间" width="200" />
<el-table-column prop="content" label="申请理由" width="400" />
</el-table>
</div>
<el-pagination
larger
background
@current-change="pagination"
v-model:page-size="requestData.pageSize"
layout="prev, pager, next"
:total="historyData.total" class="mt-4"
style="display: flex;flex-direction: row;justify-content: center;margin-top: 0.5vh"
/>
</el-card>
</div>
</template>
<script lang="ts" setup>
import {reactive} from 'vue';
import { ElTable } from 'element-plus';
import {ReviewRecords, ReviewRecordsSearch} from '@/api/examine';
import { onMounted } from 'vue';
import {getToken} from "@/utils/auth";
import pagination from "@/components/Pagination/index.vue";
const historyData = reactive({
data:[],
total:0,
})
const requestData = reactive({
page: 1,
pageSize: 6,
content:'',
statue: <unknown>null,
})
onMounted(() => {
flushData();
});
//
function resetting(){
requestData.statue = null
requestData.content = ''
}
function selectMessage(){
console.log("requestData:", requestData)
ReviewRecordsSearch(requestData,getToken()).then((res) => {
console.log('查询我的记录',res)
historyData.total = res.data.totalCount
historyData.data = res.data.reviews
})
}
function flushData(){
ReviewRecords(requestData,getToken()).then((res) => {
console.log("记录查询",res)
historyData.total = res.data.totalCount
historyData.data = res.data.reviews
})
}
</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

@ -0,0 +1,207 @@
<template>
<el-card style="max-width: 100vw; margin: 1.5vw;height: 81vh">
<template #header>
<strong >提交申请</strong>
</template>
<div>
<div class="selectedContent">
<span class="selectedHeader">01.申请类别</span>
<el-select v-model="form.region" placeholder="请选择申请类别" style="width: 15vw">
<el-option label="子系统" value="system" />
<el-option label="模块" value="module" />
</el-select>
</div>
<div class="selectedContent">
<span class="selectedHeader">02.申请所属</span>
<el-select-v2
v-model="value"
style="width: 240px;"
filterable
remote
:remote-method="remoteMethod"
clearable
:options="options"
:loading="loading"
placeholder="请输入所属项目"
/>
</div>
<div class="selectedContent">
<el-select v-model="selectedSystem" class="selectedChild" v-show="form.region === 'module'" placeholder="所属子系统" style="width: 15vw">
<el-option v-for="(row, index) in systemData" :value="row.id" :label="row.name"/>
</el-select>
</div>
<div class="selectedContent" v-if="form.region === 'module'">
<span class="selectedHeader">03.申请名称</span>
<el-select style="width: 15vw" v-model="selectedModule">
<el-option v-for="(row) in moduleData" :value="row.id" :label="row.name"/>
</el-select>
</div>
<div class="selectedContent" v-else>
<span class="selectedHeader">03.申请名称</span>
<el-select style="width: 15vw" v-model="selectedSystem">
<el-option v-for="(row) in systemData" :value="row.id" :label="row.name"/>
</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 " @click="submitCommit">提交申请</el-button>
</div>
</el-card>
</template>
<script setup lang="ts">
import {onMounted, reactive, ref, watch} from "vue";
import {ProjectGetByName, ProjectChildGetName, ReviewAdd, ProjectModuleGetName} from '@/api/examine';
import {getToken} from "@/utils/auth";
const qwe = reactive({
data: <ProjectAll[]>[]
})
let list: ProjectAll[] = []
//id
const value = ref()
const options = ref<ProjectAll[]>([])
const loading = ref(false)
const getSystemByProjectName = reactive({
id: null
})
const systemData = ref([])
//id
const selectedSystem = ref()
//id
const selectedModule = ref()
const moduleRequestData = reactive({
childId:null
})
const moduleData = ref([])
const textarea = ref('')
const form = reactive({
region:'',
})
const projectByName = reactive({
name:''
})
const submitRequestData = reactive({
name: '无',
content: '',
projectId: null,
projectChildId: null,
projectModuleId: null
})
interface ProjectAll {
value: string
label: string
}
onMounted(() => {
flushData()
})
watch(value, async (newValue, oldValue) => {
console.log("new:", newValue)
console.log("old:", oldValue)
getSystemByProjectName.id = newValue
if (newValue !== null) {
await ProjectChildGetName(getSystemByProjectName, getToken()).then((res) => {
console.log("system",res)
systemData.value = res.data
})
}
})
watch(selectedSystem, async (newValue, oldValue) => {
console.log("new:", newValue)
console.log("old:", oldValue)
moduleRequestData.childId = newValue
if (newValue !== null) {
await ProjectModuleGetName(moduleRequestData, getToken()).then((res) => {
console.log("modules",res)
moduleData.value = res.data
})
}
})
const remoteMethod = (query: string) => {
if (query !== '') {
loading.value = true
setTimeout(() => {
loading.value = false
options.value = list.filter((item) => {
// return item.name.toLowerCase().includes(query.toLowerCase())
const lowerCaseName = item.label.toLowerCase();
const lowerCaseQuery = query.toLowerCase();
return lowerCaseName.includes(lowerCaseQuery);
})
// console.log("",options.value)
}, 200)
} else {
// console.log("")
options.value = []
}
}
watch(form, () => {
clearData()
})
function flushData() {
//
ProjectGetByName(projectByName, getToken()).then((res) => {
qwe.data = res.data
list = qwe.data.map((item): ProjectAll => {
return { value: item.id, label: item.name }
})
})
}
function clearData() {
value.value = null
selectedSystem.value = null
selectedModule.value = null
textarea.value = ''
}
function submitCommit(){
submitRequestData.content = textarea.value
submitRequestData.projectId = value.value
submitRequestData.projectChildId = selectedSystem.value
if (form.region === 'module') {
submitRequestData.projectModuleId = selectedModule.value
}
console.log("submitRequestData",submitRequestData)
ReviewAdd(submitRequestData, getToken()).then((res) => {
console.log("submitResult:", res)
if (res.code === 200) {
ElMessage.success("提交申请成功!")
form.region = ''
clearData()
}else {
ElMessage.error("提交失败,请重试!")
}
})
}
</script>
<style scoped>
.selectedHeader{
font-weight: bold;
margin-right: 2vw;
}
.selectedContent{
margin-left: 35vw;
margin-top:5vh
}
.selectedChild{
margin-left: 7.7vw;
}
</style>

View File

@ -1,36 +0,0 @@
<template>
<div style="display:inline-block;">
<label class="radio-label">Cell Auto-Width: </label>
<el-radio-group v-model="autoWidth">
<el-radio :label="true" border>
True
</el-radio>
<el-radio :label="false" border>
False
</el-radio>
</el-radio-group>
</div>
</template>
<script>
import { defineComponent } from 'vue';
export default defineComponent({
props: {
modelValue: {
type: Boolean,
default: true
}
},
computed: {
autoWidth: {
get() {
return this.modelValue;
},
set(val) {
this.$emit('update:modelValue', val);
}
}
}
});
</script>

View File

@ -1,41 +0,0 @@
<template>
<div style="display:inline-block;">
<label class="radio-label">Book Type: </label>
<el-select v-model="bookType" style="width:120px;">
<el-option
v-for="item in options"
:key="item"
:label="item"
:value="item"
/>
</el-select>
</div>
</template>
<script>
import { defineComponent } from 'vue';
export default defineComponent({
props: {
modelValue: {
type: String,
default: 'xlsx'
}
},
data() {
return {
options: ['xlsx', 'csv', 'txt']
};
},
computed: {
bookType: {
get() {
return this.modelValue;
},
set(val) {
this.$emit('update:modelValue', val);
}
}
}
});
</script>

View File

@ -1,35 +0,0 @@
<template>
<div style="display:inline-block;">
<label class="radio-label" style="padding-left:0;">Filename: </label>
<el-input v-model="filename" placeholder="Please enter the file name (default excel-list)" style="width:345px;" :prefix-icon="IconDocument" />
</div>
</template>
<script>
import { defineComponent, markRaw } from 'vue';
import { Document as IconDocument } from '@element-plus/icons-vue';
export default defineComponent({
props: {
modelValue: {
type: String,
default: ''
}
},
data() {
return {
IconDocument: markRaw(IconDocument)
};
},
computed: {
filename: {
get() {
return this.modelValue;
},
set(val) {
this.$emit('update:modelValue', val);
}
}
}
});
</script>

View File

@ -1,120 +0,0 @@
<template>
<div class="app-container">
<div style="margin: 0 0 20px 0;">
<FilenameOption v-model="filename" />
<AutoWidthOption v-model="autoWidth" />
<BookTypeOption v-model="bookType" />
<el-button :loading="downloadLoading" style="margin:0 0 0 20px;" type="primary" :icon="IconDocument" @click="handleDownload">
Export Excel
</el-button>
<a href="https://vue3-element-admin-site.midfar.com/feature/component/excel.html" target="_blank" style="margin-left:15px;">
<el-tag type="info" size="large">Documentation</el-tag>
</a>
</div>
<el-table 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="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>
<script>
import { defineComponent, markRaw } from 'vue';
import { fetchList } from '@/api/article';
import { parseTime } from '@/utils';
// options components
import FilenameOption from './components/FilenameOption';
import AutoWidthOption from './components/AutoWidthOption';
import BookTypeOption from './components/BookTypeOption';
import { Document as IconDocument, Timer as IconTimer } from '@element-plus/icons-vue';
export default defineComponent({
name: 'ExportExcel',
components: { FilenameOption, AutoWidthOption, BookTypeOption, IconTimer },
data() {
return {
IconDocument: markRaw(IconDocument),
list: null,
listLoading: true,
downloadLoading: false,
filename: '',
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];
}
}));
}
}
});
</script>
<style>
.radio-label {
font-size: 14px;
color: #606266;
line-height: 40px;
padding: 0 12px 0 30px;
}
</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 +0,0 @@
<template>
<div class="app-container">
<div style="margin-bottom:20px">
<el-input v-model="filename" placeholder="Please enter the file name (default excel-list)" style="width:350px;" :prefix-icon="IconDocument" />
<el-button :loading="downloadLoading" type="primary" :icon="IconDocument" @click="handleDownload">
Export Selected Items
</el-button>
<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>
</a>
</div>
<el-table
ref="multipleTable"
v-loading="listLoading"
:data="list"
element-loading-text="拼命加载中"
border
fit
highlight-current-row
@selection-change="handleSelectionChange"
>
<el-table-column type="selection" align="center" />
<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="PDate" width="220">
<template v-slot="scope">
<el-icon><IconTimer /></el-icon>
<span>{{ scope.row.display_time }}</span>
</template>
</el-table-column>
</el-table>
</div>
</template>
<script>
import { defineComponent, markRaw } from 'vue';
import { fetchList } from '@/api/article';
import { Document as IconDocument, Timer as IconTimer } from '@element-plus/icons-vue';
export default defineComponent({
name: 'SelectExcel',
components: { IconTimer },
data() {
return {
IconDocument: markRaw(IconDocument),
list: null,
listLoading: true,
multipleSelection: [],
downloadLoading: false,
filename: ''
};
},
created() {
this.fetchData();
},
methods: {
fetchData() {
this.listLoading = true;
fetchList(this.listQuery).then(response => {
this.list = response.data.items;
this.listLoading = false;
});
},
handleSelectionChange(val) {
this.multipleSelection = val;
},
handleDownload() {
if (this.multipleSelection.length) {
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.multipleSelection;
const data = this.formatJson(filterVal, list);
excel.export_json_to_excel({
header: tHeader,
data,
filename: this.filename
});
this.$refs.multipleTable.clearSelection();
this.downloadLoading = false;
});
} else {
ElMessage({
message: 'Please select at least one item',
type: 'warning'
});
}
},
formatJson(filterVal, jsonData) {
return jsonData.map(v => filterVal.map(j => v[j]));
}
}
});
</script>

View File

@ -1,43 +0,0 @@
<template>
<div class="app-container">
<upload-excel-component :on-success="handleSuccess" :before-upload="beforeUpload" />
<el-table :data="tableData" border highlight-current-row style="width: 100%;margin-top:20px;">
<el-table-column v-for="item of tableHeader" :key="item" :prop="item" :label="item" />
</el-table>
</div>
</template>
<script>
import { defineComponent } from 'vue';
import UploadExcelComponent from '@/components/UploadExcel/index.vue';
export default defineComponent({
name: 'UploadExcel',
components: { UploadExcelComponent },
data() {
return {
tableData: [],
tableHeader: []
};
},
methods: {
beforeUpload(file) {
const isLt1M = file.size / 1024 / 1024 < 1;
if (isLt1M) {
return true;
}
ElMessage({
message: 'Please do not upload files larger than 1m in size.',
type: 'warning'
});
return false;
},
handleSuccess({ results, header }) {
this.tableData = results;
this.tableHeader = header;
}
}
});
</script>

View File

@ -25,32 +25,35 @@
@selection-change="handleSelectionChange">
<!-- <el-table-column type="selection" width="55" />-->
<el-table-column label="序号" width="120">
<template #default="{row}">{{ row.id }}</template>
<template #default="{ row }">{{ row.id }}</template>
</el-table-column>
<el-table-column property="name" label="子系统名称" width="120" />
<el-table-column property="workLoad" label="工作量" show-overflow-tooltip />
<el-table-column property="cycle" label="周期" />
<el-table-column property="principalName" label="负责人" />
<el-table-column property="status" label="状态" />
<el-table-column property="description" label="子系统简介" >
<template #default="{row}">
<span >{{ row.description }}</span>
<el-table-column property="description" label="子系统简介">
<template #default="{ row }">
<!-- 在模板中直接处理超长文本的显示 -->
<span>
{{ row.description.length > 20 ? row.description.substring(0, 20) + '...' : row.description }}
</span>
</template>
</el-table-column>
<el-table-column property="deadLine" label="截止时间" #default="{row}">
<span>{{ new Date(row.deadLine).toLocaleDateString() }}</span>
<el-table-column property="deadLine" label="截止时间" #default="{ row }">
<span>{{ new Date(row.deadLine).toLocaleDateString() }}</span>
</el-table-column>
<el-table-column property="address" label="操作" #default="{row}">
<el-table-column property="address" label="操作" #default="{ row }">
<el-button link style="color:deepskyblue" @click="toChildModel(row.id)">查看详情</el-button>
</el-table-column>
</el-table>
<el-pagination larger background layout="prev, pager, next" :total="5" class="mt-4"
style="display: flex;flex-direction: row;justify-content: center;margin-top:5vh" />
</el-card>
<el-alert >
<router-view />
</el-alert>
<el-alert>
<router-view />
</el-alert>
</div>
</template>
@ -66,22 +69,22 @@ import { getProjectSysList } from '@/api/manage';
const router = useRouter();
const toChildModel = (id) => {
router.push({ name: 'ChildModManage' , query: { id: id } })
router.push({ name: 'ChildModManage', query: { id: id } })
};
interface User {
cycle:number
deadLine:string
description: {description :string}
id:number
isDelete:number
name:string
principalName:string
projectId:number
status:string
workLoad:number
cycle: number
deadLine: string
description: { description: string }
id: number
isDelete: number
name: string
principalName: string
projectId: number
status: string
workLoad: number
}
const multipleTableRef = ref<InstanceType<typeof ElTable>>();
@ -106,55 +109,55 @@ const tableData = ref<User[]>([
const initialTableData = ref<User[]>([]);
// projectid
const route = useRoute();
const projectId = route.query.id;
const route = useRoute();
const projectId = route.query.id;
console.log(projectId);
//
const parseData = (data)=>{
//
const parseData = (data) => {
return {
cycle: data.cycle,
deadLine: data.deadLine,
description: data.description,
id: data.id,
isDelete: data.isDelete,
name: data.name,
principalName: data.principalName,
projectId: data.projectId,
status: data.status,
workLoad: data.workLoad,
}
}
const fetchData = () => {
const project = getProjectSysList(projectId, getToken());
//
project.then(res => {
console.log(res);
const data = res.data.data
if (data) {
const newData = data.map(item => parseData(item))
console.log(newData);
tableData.value = [...newData, ...tableData.value];
initialTableData.value = tableData.value.slice(); // tableDatainitialTableData
return{
cycle:data.cycle,
deadLine:data.deadLine,
description: data.description,
id:data.id,
isDelete:data.isDelete,
name:data.name,
principalName:data.principalName,
projectId:data.projectId,
status:data.status,
workLoad:data.workLoad,
}
}
const fetchData = () => {
const project = getProjectSysList( projectId ,getToken());
//
project.then(res=>{
console.log(res);
const data = res.data.data
if(data){
const newData = data.map(item=>parseData(item))
console.log(newData);
tableData.value = [...newData,...tableData.value];
initialTableData.value = tableData.value.slice(); // tableDatainitialTableData
}
})
}
})
}
fetchData();
fetchData();
//
const search = () => {
const keyword = input1.value.trim().toLowerCase();
@ -179,9 +182,9 @@ const reset = () => {
input2.value = '';
tableData.value = initialTableData.value.slice();
};

View File

@ -1,104 +0,0 @@
<template>
<el-table :data="list" border fit highlight-current-row style="width: 100%">
<el-table-column
v-loading="loading"
align="center"
label="ID"
width="65"
element-loading-text="请给我点时间!"
>
<template v-slot="scope">
<span>{{ scope.row.id }}</span>
</template>
</el-table-column>
<el-table-column width="180px" align="center" label="Date">
<template v-slot="scope">
<span>{{ parseTime(scope.row.timestamp,'{y}-{m}-{d} {h}:{i}') }}</span>
</template>
</el-table-column>
<el-table-column min-width="300px" label="Title">
<template v-slot="{row}">
<span>{{ row.title }}</span>
<el-tag>{{ row.type }}</el-tag>
</template>
</el-table-column>
<el-table-column width="110px" align="center" label="Author">
<template v-slot="scope">
<span>{{ scope.row.author }}</span>
</template>
</el-table-column>
<el-table-column width="120px" label="Importance">
<template v-slot="scope">
<svg-icon v-for="n in +scope.row.importance" :key="n" icon-class="star" />
</template>
</el-table-column>
<el-table-column align="center" label="Readings" width="95">
<template v-slot="scope">
<span>{{ scope.row.pageviews }}</span>
</template>
</el-table-column>
<el-table-column class-name="status-col" label="Status" width="110">
<template v-slot="{row}">
<el-tag :type="statusFilter(row.status)">
{{ row.status }}
</el-tag>
</template>
</el-table-column>
</el-table>
</template>
<script>
import { defineComponent } from 'vue';
import { parseTime } from '@/utils';
import { fetchList } from '@/api/article';
export default defineComponent({
props: {
type: {
type: String,
default: 'CN'
}
},
data() {
return {
list: null,
listQuery: {
page: 1,
limit: 5,
type: this.type,
sort: '+id'
},
loading: false
};
},
created() {
this.getList();
},
methods: {
parseTime,
statusFilter(status) {
const statusMap = {
published: 'success',
draft: 'info',
deleted: 'danger'
};
return statusMap[status];
},
getList() {
this.loading = true;
this.$emit('create'); // for test
fetchList(this.listQuery).then(response => {
this.list = response.data.items;
this.loading = false;
});
}
}
});
</script>

View File

@ -1,51 +1,57 @@
<template>
<div style=" width:100%">
<el-card style="max-width: 100vw;margin: 1.5vw;">
<template #header><span>日报</span></template>
<div style="display:flex;flex-direction:row;justify-content: space-around ">
<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-date-picker
v-model="value2" type="daterange"
unlink-panels
range-separator="——"
start-placeholder="开始时间"
end-placeholder="结束时间"
:shortcuts="shortcuts"
style="margin-left:0.5vw"
/>
</div>
<div>
<el-button type="primary" style="width: 80px">查询</el-button>
<div style=" width:100%">
<el-card style="max-width: 100vw;margin: 1.5vw;">
<template #header><span>日报</span></template>
<div style="display:flex;flex-direction:row;justify-content: space-around ">
<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-date-picker
v-model="value2"
type="daterange"
unlink-panels
range-separator="——"
start-placeholder="开始时间"
end-placeholder="结束时间"
:shortcuts="shortcuts"
style="margin-left:0.5vw"
/>
</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>
<el-button type="primary" @click="AddDialogVisible=true">新建</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
>
<el-button type="primary" @click="AddDialogVisible=true">新建</el-button>
<el-dialog v-model="AddDialogVisible" width="500" center :modal="false" :show-close="false">
<template #header>
<div style="display:flex;flex-direction: row;justify-content: flex-start;color:red;font-size:large" >新增日报</div>
@ -54,7 +60,7 @@
<div>
<div style="margin-top:-4vh ">
<span style="color:red">项目名称</span>
<span style="color:red">项目名称</span>
<el-input
v-model="input"
style="width: 200px"
@ -62,7 +68,7 @@
/>
</div>
<div style="margin-top:2vh ">
<span style="color:red"> 工作时间</span>
<span style="color:red"> 工作时间</span>
<el-date-picker
v-model="value1"
type="date"
@ -72,7 +78,7 @@
/>
</div>
<div style="margin-top:2vh ;display:flex;flex-direction:row;">
<span style="color: red">日报内容</span>
<span style="color: red">日报内容</span>
<el-input
v-model="textarea"
style="width: 300px;"
@ -91,82 +97,46 @@
</div>
</template>
</el-dialog>
</div>
<el-table ref="multipleTableRef" :data="tableData" style="max-width: 100vw;"
@selection-change="handleSelectionChange">
</div>
<el-table
ref="multipleTableRef"
:data="tableData"
style="max-width: 100vw;"
@selection-change="handleSelectionChange"
>
<el-table-column type="selection" width="55" />
<el-table-column label="序号" width="120">
<template #default="scope">{{ scope.row.date }}</template>
<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-table-column property="address" label="填写时间" />
<el-table-column property="address" label="工作时间" />
<el-table-column property="address" label="日报" />
<el-table-column property="address" label="日报填写者" />
<el-table-column property="address" label="填写时间" />
<el-table-column property="address" label="工作时间" />
<el-table-column property="address" label="操作" >
<el-button size="small" text style="color:deepskyblue" @click="EditDialogVisible = true">修改</el-button>
<!-- <el-dialog v-model="EditDialogVisible" title="删除" width="500" :modal="false">-->
<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>
<!-- <div style="margin-top:-4vh ">-->
<!-- <span style="color:red">项目名称</span>-->
<!-- <el-input-->
<!-- v-model="input"-->
<!-- style="width: 200px"-->
<!-- placeholder="请输入"-->
<!-- />-->
<!-- </div>-->
<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>
<el-dialog v-model="EditDialogVisible" title="删除" width="500" :modal="false">
<template #footer>
<div class="dialog-footer">
<el-button @click="EditDialogVisible = false">取消</el-button>
<el-button type="primary" @click="EditDialogVisible = false">
确认
</el-button>
</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>
</template>
</el-dialog>
</el-table-column>
</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>
</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>
</template>
@ -180,9 +150,9 @@ const EditDialogVisible = ref(false);
//
const AddDialogVisible = ref(false);
interface User {
date: string
name: string
address: string
date: string
name: string
address: string
}
const multipleTableRef = ref<InstanceType<typeof ElTable>>();
@ -218,11 +188,9 @@ const tableData: User[] = [
// 1
import { onMounted } from 'vue';
interface LinkItem {
value: string
link: string
value: string
link: string
}
const state = ref('');
@ -232,7 +200,7 @@ const querySearch = (queryString: string, cb) => {
const results = queryString
? links.value.filter(createFilter(queryString))
: links.value;
// call callback function to return suggestion objects
// call callback function to return suggestion objects
cb(results);
};
const createFilter = (queryString) => {
@ -265,7 +233,6 @@ onMounted(() => {
});
//
const value2 = ref('');
const shortcuts = [
@ -298,24 +265,20 @@ const shortcuts = [
}
];
</script>
<style>
.my-autocomplete li {
line-height: normal;
padding: 7px;
line-height: normal;
padding: 7px;
}
.my-autocomplete li .name {
text-overflow: ellipsis;
overflow: hidden;
text-overflow: ellipsis;
overflow: hidden;
}
.my-autocomplete li .addr {
font-size: 12px;
color: #b4b4b4;
font-size: 12px;
color: #b4b4b4;
}
.my-autocomplete li .highlighted .addr {
color: #ddd;
color: #ddd;
}
</style>
</style>

View File

@ -0,0 +1,137 @@
<template>
<div style=" width:100%">
<el-card style="max-width: 100vw;margin: 1.5vw;max-height:100vh;height:80vh ">
<template #header>
<strong>子模块1</strong>
</template>
<!-- <div style=" display: flex;flex-direction: column;justify-content: center">-->
<div class="ModuleData" style="margin-left: 30vw;width: 24vw;height: 55vh;display: flex;flex-direction: column;justify-content: space-around;
">
<div style="display: flex;flex-direction: row;justify-content: space-between">
<strong>01.模块名称 </strong>
<span style="width: 250px">子模块1</span>
</div>
<div style="display: flex;flex-direction: row;justify-content: space-between">
<strong>02.模块周期</strong>
<span style="width: 250px">13</span>
</div>
<div style="display: flex;flex-direction: row;justify-content: space-between">
<strong>03.工作量 </strong>
<span style="width: 250px">子模块1</span>
</div>
<div style="display: flex;flex-direction: row;justify-content: space-between">
<strong>04.负责人 </strong>
<span style="width: 250px">子模块1</span>
</div>
<div style="display: flex;flex-direction: row;justify-content: space-between">
<strong>05.状态 </strong>
<el-autocomplete
v-model="state"
:fetch-suggestions="querySearch"
popper-class="my-autocomplete"
placeholder="Please input"
@select="handleSelect"
style="width: 250px"
>
<template #suffix>
<el-icon class="el-input__icon" @click="handleIconClick">
<edit />
</el-icon>
</template>
<template #default="{ item }">
<div class="value">{{ item.value }}</div>
<span class="link">{{ item.link }}</span>
</template>
</el-autocomplete>
</div>
<div style="display: flex;flex-direction: row;justify-content: space-between">
<strong>06.截止时间 </strong>
<span style="width: 250px">子模块1</span>
</div>
<div style="display: flex;flex-direction: row;justify-content: space-between">
<strong>07.简介 </strong>
<el-input
v-model="textarea2"
style="width: 250px"
:autosize="{ minRows: 4, maxRows: 6 }"
type="textarea"
placeholder="Please input"
:row="4"
/>
</div>
</div>
<!-- </div>-->
</el-card>
</div>
</template>
<script lang="ts" setup>
import { onMounted, ref } from 'vue';
import { Edit } from '@element-plus/icons-vue';
interface LinkItem {
value: string
link: string
}
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: '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: LinkItem) => {
console.log(item);
};
const handleIconClick = (ev: Event) => {
console.log(ev);
};
onMounted(() => {
links.value = loadAll();
});
</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

@ -0,0 +1,203 @@
<template>
<div style=" width:100%">
<el-card style="max-width: 100vw;margin: 1.5vw;">
<template #header><strong >子系统1</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-input v-model="input" style="width: 240px;margin-left:0.5vw" placeholder="请输入" />
</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
type=''
>子模块列表</el-button
>
</div>
<el-table
ref="multipleTableRef"
:data="tableData"
style="max-width: 100vw;"
@selection-change="handleSelectionChange"
>
<!-- <el-table-column type="selection" width="55" />-->
<el-table-column 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-table-column property="address" label="状态" />
<el-table-column property="address" label="子模块简介" />
<el-table-column property="address" label="截止时间" />
<el-table-column property="address" label="操作" >
<el-button
link
style="color:deepskyblue"
>查看详情</el-button
>
</el-table-column>
</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>
</template>
<script lang="ts" setup>
import { ref } from 'vue';
import { ElTable } from 'element-plus';
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;
};
const tableData: User[] = [
{
date: '2016-05-03',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles'
},
{
date: '2016-05-02',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles'
},
{
date: '2016-05-04',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles'
},
{
date: '2016-05-01',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles'
}
];
// 1
import { onMounted } from 'vue';
import { Edit } from '@element-plus/icons-vue';
interface LinkItem {
value: string
link: string
}
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);
};
//
const value1 = ref('');
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];
}
},
{
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];
}
}
];
</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,71 +1,73 @@
<template>
<div style=" width:100%">
<el-card style="max-width: 100vw;margin: 1.5vw;">
<template #header><strong >项目1</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-input v-model="input" style="width: 240px;margin-left:0.5vw" placeholder="请输入" />
</div>
<div>
<el-button type="primary" style="width:80px">查询</el-button>
<div style=" width:100%">
<el-card style="max-width: 100vw;margin: 1.5vw;">
<template #header><strong >项目1</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-input v-model="input" style="width: 240px;margin-left:0.5vw" placeholder="请输入" />
</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
type=''
>子系统列表</el-button
>
</div>
<el-table
ref="multipleTableRef"
:data="tableData"
style="max-width: 100vw;"
@selection-change="handleSelectionChange"
>
</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
type=''
>子系统列表</el-button
>
</div>
<el-table
ref="multipleTableRef"
:data="tableData"
style="max-width: 100vw;"
@selection-change="handleSelectionChange"
>
<!-- <el-table-column type="selection" width="55" />-->
<el-table-column 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-table-column property="address" label="状态" />
<el-table-column property="address" label="子系统简介" />
<el-table-column property="address" label="截止时间" />
<el-table-column property="address" label="操作" >
<el-button
link
style="color:deepskyblue"
>查看详情</el-button
>
</el-table-column>
</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>
<el-table-column 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-table-column property="address" label="状态" />
<el-table-column property="address" label="子系统简介" />
<el-table-column property="address" label="截止时间" />
<el-table-column property="address" label="操作" >
<el-button
link
style="color:deepskyblue"
>查看详情</el-button
>
</el-table-column>
</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>
</template>
<script lang="ts" setup>
import { ref } from 'vue';
import { ElTable } from 'element-plus';
interface User {
date: string
name: string
@ -121,4 +123,4 @@ const tableData: User[] = [
.my-autocomplete li .highlighted .addr {
color: #ddd;
}
</style>
</style>