From b5f23e89d8536a4af882789010b76459c0283433 Mon Sep 17 00:00:00 2001
From: wangjy <1595161655@qq.com>
Date: Thu, 10 Oct 2024 17:57:26 +0800
Subject: [PATCH] =?UTF-8?q?=E9=A1=B9=E7=9B=AE=E6=8E=A5=E5=8F=A3=E8=B0=83?=
=?UTF-8?q?=E8=AF=95=E5=AE=8C=E6=88=90?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.env.development | 8 +-
.env.test | 2 +-
src/components/table.vue | 33 +++
src/router/routes.js | 2 +-
src/stores/user.js | 26 +-
src/utils/api.js | 28 ++-
src/utils/request.js | 8 +-
src/views/Login/Login.vue | 26 +-
src/views/project/detail.vue | 474 ++++++++++++++++++++++++++---------
src/views/project/list.vue | 156 +++++++++---
vite.config.js | 11 -
11 files changed, 553 insertions(+), 221 deletions(-)
diff --git a/.env.development b/.env.development
index a4cb9d2..710fb84 100644
--- a/.env.development
+++ b/.env.development
@@ -1,6 +1,6 @@
VITE_BASE_URL = "./"
-VITE_BASE_NAME = "external"
-VITE_APP_PROXYURL = 'http://183.230.174.15:8088/external'
-VITE_APP_REQUESTURL = '/external'
-VITE_APP_ROUTERURL = '/external/'
+VITE_BASE_NAME = "pms-front-test"
+VITE_APP_PROXYURL = 'http://192.168.124.202:8080'
+VITE_APP_REQUESTURL = '/pms-front-test'
+VITE_APP_ROUTERURL = '/pms-front-test/'
diff --git a/.env.test b/.env.test
index 9013e48..707e773 100644
--- a/.env.test
+++ b/.env.test
@@ -1,5 +1,5 @@
VITE_BASE_URL = '/pms-front-test'
VITE_BASE_NAME = "pms-front-test"
-VITE_APP_PROXYURL = 'http://183.230.174.15:8093/aiops-external'
+VITE_APP_PROXYURL = 'http://192.168.124.202:8080'
VITE_APP_REQUESTURL = '/pms-front-test'
VITE_APP_ROUTERURL = '/pms-front-test/'
\ No newline at end of file
diff --git a/src/components/table.vue b/src/components/table.vue
index cf38883..32f8316 100644
--- a/src/components/table.vue
+++ b/src/components/table.vue
@@ -27,6 +27,13 @@
+
+
+
+
+ {{ scope.row[column.prop] }}
+
+
{{ scope.row[column.prop] }}
@@ -160,4 +167,30 @@ onUnmounted(() => {
display: flex;
justify-content: flex-end;
}
+:deep(.el-scrollbar__wrap--hidden-default){
+ min-height: 100px;
+}
+ :deep(.el-table) {
+ --el-table-text-align: center;
+}
+
+ :deep(.el-table th) {
+ text-align: center;
+}
+
+ :deep(.el-table .cell) {
+ text-align: center;
+}
+
+/* 如果操作列需要特殊处理,可以添加以下样式 */
+ :deep(.operation-column .cell) {
+ text-align: center;
+ display: flex;
+ justify-content: center;
+}
+:deep(.el-table__inner-wrapper::before){
+
+ display: none;
+
+}
diff --git a/src/router/routes.js b/src/router/routes.js
index 6eaf732..27cc19a 100644
--- a/src/router/routes.js
+++ b/src/router/routes.js
@@ -108,7 +108,7 @@ export const asyncRoutes = [
name: 'worklogList',
authKey: 'Workorder',
meta: {
- title: '日志列表',
+ title: '工作日志',
},
component: () => import('@/views/workLog/list.vue'),
},
diff --git a/src/stores/user.js b/src/stores/user.js
index e466a69..6002ddb 100644
--- a/src/stores/user.js
+++ b/src/stores/user.js
@@ -25,22 +25,10 @@ export const useUserStore = defineStore('user', {
async login(params) {
try {
const res = await loginApi.login(params)
- const roleType = res.data.user.roles
- .filter(item => item.roleType)
- .map(per => per.roleType)
- .join(',')
- // setPerssionsTabbar(roleType)
- const roleKey = res.data.user.roles
- .filter(item => item.roleKey)
- .map(per => per.roleKey)
- .join(',')
- sessionStorage.setItem('roleType', $utils.encryptByDES.CBC(roleType))
- sessionStorage.setItem('roleKey', $utils.encryptByDES.CBC(roleKey))
- const token = $utils.encryptByMD5(`123456`)
- setToken(token)
- await this.updateUserInfo(res.data)
+ setToken(res.token)
+ await this.updateUserInfo()
ElMessage.success({ message: '登录成功' })
- const permissions = [...res.data.resourceKeys]
+ const permissions = [...this.userInfo.permissions]
// , 'WorkOrderError', 'workOrderDestroy', 'workOrderReserver'
sessionStorage.setItem('permissions', $utils.encryptByDES.CBC(JSON.stringify(permissions)))
this.updateAsyncRoutes()
@@ -56,8 +44,8 @@ export const useUserStore = defineStore('user', {
removeToken()
router.push('/')
},
- async updateUserInfo(data) {
- const userInfo = data.user
+ async updateUserInfo() {
+ const userInfo = await loginApi.getUserInfo()
sessionStorage.setItem('userInfo', $utils.encryptByDES.CBC(JSON.stringify(userInfo)))
this.userInfo = userInfo
},
@@ -67,8 +55,8 @@ export const useUserStore = defineStore('user', {
updateAsyncRoutes() {
// 权限时处理异步路由
let sessionPermissions = JSON.parse($utils.decryptByDES.CBC(sessionStorage.getItem('permissions')))
- // console.log(asyncRoutes, sessionPermissions, 'asyncRoutes, sessionPermissions')
- let result = filterAsyncRoutes(asyncRoutes, sessionPermissions)
+ // let result = filterAsyncRoutes(asyncRoutes, sessionPermissions)
+ let result = asyncRoutes
result = editRedirect(result)
// console.log(result, 'result')
diff --git a/src/utils/api.js b/src/utils/api.js
index 7e431b9..791e77e 100644
--- a/src/utils/api.js
+++ b/src/utils/api.js
@@ -1,14 +1,37 @@
import request from '@/utils/request'
-
//登录板块api
export const loginApi = {
// 登录
- login: data => request('/login', 'post', data),
+ login: data => request('/login', 'json', data),
// 退出登录
loginOut: () => request('/aiops-api/logout', 'get'),
//修改密码
editPassword: data => request('/aiops-api/auth/user/updatePwd', 'post', data),
+ // 获取验证码
+ getCode: () => request('/captchaImage', 'captchaImage', {}, {
+ SHOW_LOADING: false, headers: {
+ 'Content-Type': 'application/json'
+ }
+ }),
+ getUserInfo: () => request('/getInfo', 'get'),
}
+
+// 项目板块
+export const projectApi = {
+ // 查询项目列表
+ listProject: query => request('/business/project/list', 'get', query),
+ deleteProject: id => request(`/business/project/${id}`, 'delete'),
+ addProject: data => request('/business/project/add', 'json', data),
+ updateProject: data => request('/business/project/update', 'json', data),
+ getProjectCode: () => request('/business/project/getCode', 'get'),
+ getProjectDetail: id => request(`/business/project/info/${id}`, 'get'),
+ // 项目成员
+ getProjectUser: id => request(`/business/project/${id}`, 'get'),
+ updateProjectUser: data => request('/business/project/team', 'json', data),
+ deleteProjectUser: id => request(`/business/project/team/${id}`, 'delete'),
+}
+
+// 用户板块
export const useUserApi = () => {
@@ -16,6 +39,7 @@ export const useUserApi = () => {
// 系统板块
export const systemApi = {
getUserList: data => request('/aiops-api/auth/user/list', 'post', data),
+ getDictData: dictCode => request('/system/dict/data/type/' + dictCode, 'get'),
}
// 系统定时任务
export const systemJobApi = {
diff --git a/src/utils/request.js b/src/utils/request.js
index e11bf35..bee06db 100644
--- a/src/utils/request.js
+++ b/src/utils/request.js
@@ -17,7 +17,7 @@ const service = axios.create({
service.interceptors.request.use(
config => {
if (getToken()) {
- config.headers['token'] = getToken()
+ config.headers['Authorization'] = 'Bearer ' + getToken()
}
return config
},
@@ -105,6 +105,9 @@ const doRequest = (url, method = 'GET', params, opts, callback) => {
method = 'POST'
opts.headers['Content-Type'] = 'application/json'
opts.responseType = 'blob'
+ }else if (/captchaImage/i.test(method)) {
+ method = 'get'
+ opts.headers['Content-Type'] = 'application/json'
}
service({
url: url,
@@ -156,7 +159,7 @@ const doRequest = (url, method = 'GET', params, opts, callback) => {
opts.SHOW_LOADING && loadingInstance && loadingInstance.close()
return
}
- if (res.code === 0) {
+ if (res.code === 200) {
resolve(res) //
// resolve(res.data)
} else if (res.code === 401) {
@@ -175,7 +178,6 @@ const doRequest = (url, method = 'GET', params, opts, callback) => {
opts.SHOW_LOADING && loadingInstance && loadingInstance.close()
})
.catch(err => {
- console.log('ssss')
opts.SHOW_LOADING && loadingInstance && loadingInstance.close()
if (err.code === 'ERR_CANCELED') return
ElMessage.error({
diff --git a/src/views/Login/Login.vue b/src/views/Login/Login.vue
index 44f16d2..56df71d 100644
--- a/src/views/Login/Login.vue
+++ b/src/views/Login/Login.vue
@@ -73,6 +73,7 @@
import { ElMessage } from 'element-plus'
import { reactive, ref } from 'vue'
import { useRouter } from 'vue-router'
+import { loginApi } from '@/utils/api'
import { useUserStore } from '@/stores/user'
import { storeToRefs } from 'pinia'
const userStore = useUserStore()
@@ -82,23 +83,14 @@ const login = reactive({
pwd: '',
validateCode: '',
})
-const codeSrc = ref(
- process.env.NODE_ENV === 'production'
- ? `${window.location.origin}${
- import.meta.env.VITE_APP_REQUESTURL
- }/captcha/captchaImage?type=math&&t=${Math.random()}`
- : `${import.meta.env.VITE_APP_REQUESTURL}/captcha/captchaImage?type=math`,
-) //${window.location.origin}
+const codeSrc = ref()
+const uuid = ref()
const updateCode = async () => {
- codeSrc.value =
- process.env.NODE_ENV === 'production'
- ? `${window.location.origin}${
- import.meta.env.VITE_APP_REQUESTURL
- }/captcha/captchaImage?type=math&&t=${Math.random()}`
- : `${import.meta.env.VITE_APP_REQUESTURL}/captcha/captchaImage?type=math&&t=${Math.random()}` //char math
+ const res = await loginApi.getCode()
+ codeSrc.value = 'data:image/png;base64,' + res.img
+ uuid.value = res.uuid
}
-// getCode()
const confirmLogin = async () => {
if (!login.account) {
ElMessage.error({ message: `用户名不能为空!` })
@@ -113,9 +105,10 @@ const confirmLogin = async () => {
return
}
const params = {
- password: $utils.encryptByMD5(`${login.account}${login.pwd}`),
+ password: login.pwd,
username: login.account,
- validateCode: login.validateCode,
+ code: login.validateCode,
+ uuid: uuid.value,
}
try {
await userStore.login(params)
@@ -127,6 +120,7 @@ const confirmLogin = async () => {
const usershadow = ref(false)
const shadow = ref(false)
const codeShadow = ref(false)
+updateCode()
\ No newline at end of file
+
diff --git a/src/views/project/list.vue b/src/views/project/list.vue
index daa1547..e34e0c5 100644
--- a/src/views/project/list.vue
+++ b/src/views/project/list.vue
@@ -6,16 +6,19 @@
-
-
-
-
+
+
-
-
-
-
+
+
+
+
@@ -64,6 +67,15 @@
+
+
+
@@ -71,26 +83,68 @@
import { ref, reactive, onMounted } from 'vue'
import { useRouter } from 'vue-router'
import CustomTable from '@/components/table.vue'
+import SelectUser from '@/components/selectUser.vue'
import { WarningFilled } from '@element-plus/icons-vue'
+import { projectApi } from '@/utils/api'
const router = useRouter()
const searchForm = reactive({
projectName: '',
- manager: '',
- status: '',
+ projectLeaderName: '',
+ projectLeader: '',
+ projectState: '',
})
const columns = [
{ prop: 'projectName', label: '项目名称' },
{ prop: 'projectCode', label: '项目编号' },
- { prop: 'manager', label: '负责人' },
- { prop: 'budgetDays', label: '预计工时(天)' },
- { prop: 'startDate', label: '开始时间' },
- { prop: 'endDate', label: '结束时间' },
- { prop: 'status', label: '项目状态' },
- { prop: 'memberCount', label: '参与项目人数' },
- { prop: 'createdBy', label: '项目创建人' },
+ { prop: 'projectLeaderName', label: '负责人' },
+ { prop: 'budgetDate', label: '预计工时(天)' },
+ {
+ prop: 'startDate',
+ label: '开始时间',
+ type: 'status',
+ callback: (data, row) => {
+ return data.split(' ')[0]
+ },
+ },
+ {
+ prop: 'endDate',
+ label: '结束时间',
+ type: 'status',
+ callback: (data, row) => {
+ return data.split(' ')[0]
+ },
+ },
+ {
+ prop: 'projectState',
+ label: '项目状态',
+ type: 'status',
+ callback: (value, row) => {
+ let status = '未知'
+ let color = ''
+
+ switch (value) {
+ case '0':
+ status = '未启动'
+ color = '#909399' // 灰色
+ break
+ case '1':
+ status = '进行中'
+ color = '#409EFF' // 蓝色
+ break
+ case '2':
+ status = '已完成'
+ color = '#67C23A' // 绿色
+ break
+ }
+
+ return `${status}`
+ },
+ },
+ { prop: 'teamNum', label: '参与项目人数' },
+ { prop: 'createByName', label: '项目创建人' },
{
prop: 'operation',
label: '操作',
@@ -105,6 +159,35 @@ const total = ref(0)
const deleteDialogVisible = ref(false)
const currentDeleteItem = ref(null)
+const pageNum = ref(1)
+const pageSize = ref(10)
+
+// 用户选择相关
+const userSelectDialogVisible = ref(false)
+const currentSelectedUser = ref([])
+
+const openUserSelectDialog = () => {
+ userSelectDialogVisible.value = true
+}
+
+const handleUserSelectClose = () => {
+ userSelectDialogVisible.value = false
+}
+
+const handleUserConfirm = (selectedUsers) => {
+ if (selectedUsers.length > 0) {
+ const selectedUser = selectedUsers[0]
+ searchForm.projectLeaderName = selectedUser.name
+ searchForm.projectLeader = selectedUser.id
+ currentSelectedUser.value = [selectedUser]
+ } else {
+ searchForm.projectLeaderName = ''
+ searchForm.projectLeader = ''
+ currentSelectedUser.value = []
+ }
+ userSelectDialogVisible.value = false
+}
+
const onSearch = () => {
// 实现搜索逻辑
console.log('Search with:', searchForm)
@@ -125,7 +208,7 @@ const addProject = () => {
const handleEdit = row => {
router.push({
path: '/project/detail',
- query: { id: row.id },
+ query: { id: row.projectId },
state: { projectData: row },
})
}
@@ -140,42 +223,35 @@ const handleCloseDeleteDialog = () => {
currentDeleteItem.value = null
}
-const confirmDelete = () => {
+const confirmDelete = async () => {
// 实现删除逻辑
- console.log('Delete project:', currentDeleteItem.value)
+ await projectApi.deleteProject(currentDeleteItem.value.projectId)
deleteDialogVisible.value = false
currentDeleteItem.value = null
+ ElMessage.success('删除成功')
fetchProjectList()
}
const handleSizeChange = val => {
- console.log(`每页 ${val} 条`)
+ pageSize.value = val
+ pageNum.value = 1 // 重置为第一页
fetchProjectList()
}
const handleCurrentChange = val => {
- console.log(`当前页: ${val}`)
+ pageNum.value = val
fetchProjectList()
}
-const fetchProjectList = () => {
+const fetchProjectList = async () => {
// 这里使用假数据,实际应该调用API
- const fakeData = Array(20)
- .fill(null)
- .map((_, index) => ({
- id: index + 1,
- projectName: `项目${index + 1}`,
- projectCode: `XM00${index + 1}`,
- manager: ['张三', '李四', '王五'][index % 3],
- budgetDays: Math.floor(Math.random() * 100) + 10,
- startDate: '2024-08-31',
- endDate: '2024-09-15',
- status: ['待启动', '进行中', '已完成'][index % 3],
- memberCount: Math.floor(Math.random() * 10) + 3,
- createdBy: '张三',
- }))
- tableData.value = fakeData
- total.value = fakeData.length
+ const res = await projectApi.listProject({
+ ...searchForm,
+ pageNum: pageNum.value,
+ pageSize: pageSize.value,
+ })
+ tableData.value = res.rows
+ total.value = res.total
}
onMounted(() => {
@@ -278,4 +354,4 @@ onMounted(() => {
left: 50%;
transform: translate(-50%, -50%);
}
-
+
\ No newline at end of file
diff --git a/vite.config.js b/vite.config.js
index b5f9299..376fca1 100644
--- a/vite.config.js
+++ b/vite.config.js
@@ -60,17 +60,6 @@ export default ({ mode }) => {
},
// 设置代理
proxy: {
- '/upload': {
- target: 'http://111.10.228.245:8088/external',
- changeOrigin: true,
- secure: false,
- rewrite: path => path.replace('/upload/', '/upload/'),
- },
- '/aiopsfile': {
- target: 'http://111.10.228.245:8088/external',
- changeOrigin: true,
- secure: false,
- },
[env.VITE_APP_REQUESTURL]: {
target: env.VITE_APP_PROXYURL,