接入oa-api
This commit is contained in:
52
api/oa/dept.js
Normal file
52
api/oa/dept.js
Normal file
@@ -0,0 +1,52 @@
|
||||
import request from "@/util/oaRequest"
|
||||
|
||||
// 查询部门列表
|
||||
export function listDept(query) {
|
||||
return request({
|
||||
url: '/system/dept/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 查询部门列表(排除节点)
|
||||
export function listDeptExcludeChild(deptId) {
|
||||
return request({
|
||||
url: '/system/dept/list/exclude/' + deptId,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 查询部门详细
|
||||
export function getDept(deptId) {
|
||||
return request({
|
||||
url: '/system/dept/' + deptId,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 新增部门
|
||||
export function addDept(data) {
|
||||
return request({
|
||||
url: '/system/dept',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 修改部门
|
||||
export function updateDept(data) {
|
||||
return request({
|
||||
url: '/system/dept',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 删除部门
|
||||
export function delDept(deptId) {
|
||||
return request({
|
||||
url: '/system/dept/' + deptId,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
53
api/oa/login.js
Normal file
53
api/oa/login.js
Normal file
@@ -0,0 +1,53 @@
|
||||
import service from "@/util/oaRequest"
|
||||
import { setToken } from "../../util/auth"
|
||||
|
||||
// 获取oa系统的验证码(走个形式)
|
||||
export const getSMSCodeFromOa = async (phoneNumber) => {
|
||||
const option = {
|
||||
url: '/fadapp/auth/send-code',
|
||||
data: {
|
||||
phone: phoneNumber
|
||||
},
|
||||
headers: {
|
||||
isToken: false
|
||||
},
|
||||
method: 'post'
|
||||
}
|
||||
const result = await service(option)
|
||||
console.log('验证码获取结果')
|
||||
return result
|
||||
}
|
||||
|
||||
// 通过手机号自动登录oa系统
|
||||
export const loginOaByPhone = async (phoneNumber) => {
|
||||
try {
|
||||
// 准备登录oa
|
||||
const data = {
|
||||
url: '/fadapp/auth/login-by-code',
|
||||
data: {
|
||||
phone: phoneNumber,
|
||||
code: '666666'
|
||||
},
|
||||
headers: {
|
||||
isToken: false
|
||||
},
|
||||
method: 'post'
|
||||
}
|
||||
const response = await service(data)
|
||||
console.log(response)
|
||||
// 响应拦截器已经处理了响应,直接返回 res.data
|
||||
if (response && response.data.token) {
|
||||
setToken(response.data.token)
|
||||
// localStorage.setItem('oaToken', response.data.token)
|
||||
return {
|
||||
token: response.data.token,
|
||||
userInfo: response.data
|
||||
}
|
||||
}
|
||||
|
||||
throw new Error('登录失败:未获取到token')
|
||||
} catch (error) {
|
||||
console.error('OA系统登录失败:', error)
|
||||
throw error
|
||||
}
|
||||
}
|
||||
133
api/oa/project.js
Normal file
133
api/oa/project.js
Normal file
@@ -0,0 +1,133 @@
|
||||
import request from "@/util/oaRequest"
|
||||
|
||||
// 查询项目管理列表
|
||||
export function listProject(query) {
|
||||
return request({
|
||||
url: '/oa/project/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
// 查询项目管理列表
|
||||
export function listWareProject(query) {
|
||||
return request({
|
||||
url: '/oa/project/ware-list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
// 查询项目管理列表
|
||||
export function filesProject(query) {
|
||||
return request({
|
||||
url: '/oa/project/files',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 查询项目管理详细
|
||||
export function getProject(projectId) {
|
||||
return request({
|
||||
url: '/oa/project/' + projectId,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
// 查询项目管理详细
|
||||
export function projectData(date) {
|
||||
return request({
|
||||
url: '/oa/project/projectDataByMonth/'+date,
|
||||
method: 'get',
|
||||
})
|
||||
}
|
||||
|
||||
export function projectData2(date){
|
||||
return request({
|
||||
url: '/oa/project/projectData',
|
||||
method: 'get',
|
||||
params: { date }
|
||||
});
|
||||
}
|
||||
|
||||
// 查询项目管理详细
|
||||
export function projectDataByMonthAndDate() {
|
||||
return request({
|
||||
url: '/oa/project/projectDataByMonthAndDate',
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 新增项目管理
|
||||
export function addProject(data) {
|
||||
return request({
|
||||
url: '/oa/project',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 修改项目管理
|
||||
export function updateProject(data) {
|
||||
return request({
|
||||
url: '/oa/project',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 删除项目管理
|
||||
export function delProject(projectId) {
|
||||
return request({
|
||||
url: '/oa/project/' + projectId,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
|
||||
export function getProjectList(query) {
|
||||
return request({
|
||||
url: '/oa/project/progress-list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 获取外贸中心仪表盘四项指标
|
||||
* @param {Object} query 传参示例:{ start: '2024/01/01', end: '2024/01/18' }
|
||||
*/
|
||||
export function getDashboardMetrics(query) {
|
||||
return request({
|
||||
url: '/oa/project/metrics',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取外贸中心三张图表数据(折线、饼图、柱状)
|
||||
* @param {Object} query 传参示例:{ start: '2024/01/01', end: '2024/01/18' }
|
||||
*/
|
||||
export function getDashboardCharts(query) {
|
||||
return request({
|
||||
url: '/oa/project/charts',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取外贸中心临期项目列表
|
||||
* @param {Object} query 传参示例:{ days: 7 }
|
||||
*/
|
||||
export function listExpiringProjects(query) {
|
||||
return request({
|
||||
url: '/oa/project/expiring',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
130
api/oa/projectReport.js
Normal file
130
api/oa/projectReport.js
Normal file
@@ -0,0 +1,130 @@
|
||||
import request from "@/util/oaRequest"
|
||||
|
||||
// 查询项目报工列表
|
||||
export function listProjectReport(query) {
|
||||
return request({
|
||||
url: '/oa/projectReport/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 查询项目报工详细
|
||||
export function getProjectReport(reportId) {
|
||||
return request({
|
||||
url: '/oa/projectReport/' + reportId,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 查询项目报工详细
|
||||
export function getCardData() {
|
||||
return request({
|
||||
url: '/oa/projectReport/card',
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 查询项目报工详细
|
||||
export function getTrendData(start,end) {
|
||||
return request({
|
||||
url: '/oa/projectReport/trend',
|
||||
method: 'get',
|
||||
params: {
|
||||
start:start,
|
||||
end:end
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 查询项目报工详细
|
||||
export function getRankData(start,end) {
|
||||
return request({
|
||||
url: '/oa/projectReport/rank',
|
||||
method: 'get',
|
||||
params: {
|
||||
start:start,
|
||||
end:end
|
||||
}
|
||||
})
|
||||
}// 查询项目报工详细
|
||||
export function getSummaryList(start,end) {
|
||||
return request({
|
||||
url: '/oa/projectReport/summary',
|
||||
method: 'get',
|
||||
params: {
|
||||
start:start,
|
||||
end:end
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 查询项目报工详细
|
||||
export function getProjectData(start,end) {
|
||||
return request({
|
||||
url: '/oa/projectReport/projects',
|
||||
method: 'get',
|
||||
params: {
|
||||
start:start,
|
||||
end:end
|
||||
}
|
||||
})
|
||||
}
|
||||
// 查询项目报工详细
|
||||
export function listClearProjectReport(start,end) {
|
||||
return request({
|
||||
url: '/oa/projectReport/report',
|
||||
method: 'get',
|
||||
params: {
|
||||
start:start,
|
||||
end:end
|
||||
}
|
||||
})
|
||||
}
|
||||
// 查询项目报工详细
|
||||
export function getPieData(start,end) {
|
||||
return request({
|
||||
url: '/oa/projectReport/distribution',
|
||||
method: 'get',
|
||||
params: {
|
||||
start:start,
|
||||
end:end
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 新增项目报工
|
||||
export function addProjectReport(data) {
|
||||
return request({
|
||||
url: '/oa/projectReport',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 修改项目报工
|
||||
export function updateProjectReport(data) {
|
||||
return request({
|
||||
url: '/oa/projectReport',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 删除项目报工
|
||||
export function delProjectReport(reportId) {
|
||||
return request({
|
||||
url: '/oa/projectReport/' + reportId,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
|
||||
// 导出项目报工数据
|
||||
export function exportProjectReport(params) {
|
||||
return request({
|
||||
url: '/oa/projectReport/export',
|
||||
method: 'post',
|
||||
data: params,
|
||||
responseType: 'blob'
|
||||
})
|
||||
}
|
||||
25
pages.json
25
pages.json
@@ -242,9 +242,25 @@
|
||||
{
|
||||
"path": "pages/workbench/index/index",
|
||||
"style": {
|
||||
"navigationBarTitleText": "",
|
||||
"navigationBarTitleText": "工作台",
|
||||
"enablePullDownRefresh": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"path" : "pages/workbench/reportWork/reportWork",
|
||||
"style" :
|
||||
{
|
||||
"navigationBarTitleText": "每日报工",
|
||||
"navigationStyle": "default"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path" : "pages/workbench/construction/construction",
|
||||
"style" :
|
||||
{
|
||||
"navigationBarTitleText" : "施工进度",
|
||||
"navigationStyle": "default"
|
||||
}
|
||||
}
|
||||
],
|
||||
"tabBar": {
|
||||
@@ -266,7 +282,12 @@
|
||||
"selectedIconPath": "static/images/tabbar_contacts_active.png",
|
||||
"text": "通讯录"
|
||||
},
|
||||
|
||||
{
|
||||
"pagePath": "pages/workbench/index/index",
|
||||
"iconPath": "/static/images/tabbar_workbench.png",
|
||||
"selectedIconPath": "/static/images/tabbar_workbench_active.png",
|
||||
"text": "工作台"
|
||||
},
|
||||
{
|
||||
"pagePath": "pages/profile/index/index",
|
||||
"iconPath": "./static/images/tabbar_profile.png",
|
||||
|
||||
@@ -109,6 +109,7 @@ import AreaPicker from "@/components/AreaPicker";
|
||||
import { checkLoginError } from "@/util/common";
|
||||
import { SmsUserFor } from "@/constant";
|
||||
import IMSDK from "openim-uniapp-polyfill";
|
||||
import { getSMSCodeFromOa, loginOaByPhone } from "../../api/oa/login";
|
||||
|
||||
let timer;
|
||||
|
||||
@@ -219,6 +220,8 @@ export default {
|
||||
uni.switchTab({
|
||||
url: "/pages/conversation/conversationList/index",
|
||||
});
|
||||
await getSMSCodeFromOa(this.loginInfo.phoneNumber);
|
||||
await loginOaByPhone(this.loginInfo.phoneNumber)
|
||||
this.loginInfo.password = "";
|
||||
|
||||
this.loading = false;
|
||||
|
||||
22
pages/workbench/construction/construction.vue
Normal file
22
pages/workbench/construction/construction.vue
Normal file
@@ -0,0 +1,22 @@
|
||||
<template>
|
||||
<view>
|
||||
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
</style>
|
||||
@@ -1,31 +1,84 @@
|
||||
<template>
|
||||
<web-view :src="linkUrl"></web-view>
|
||||
<view class="workbench-container">
|
||||
<custom-nav-bar>
|
||||
<view class="workbench-title" slot="left">
|
||||
<text>工作台</text>
|
||||
</view>
|
||||
</custom-nav-bar>
|
||||
<view class="entry-list">
|
||||
<view class="entry-item" @click="goReportWork">
|
||||
<image class="entry-icon" src="/static/images/baogong.png" mode="aspectFit" />
|
||||
<text class="entry-text">每日报工</text>
|
||||
</view>
|
||||
<view class="divider"></view>
|
||||
<view class="entry-item" @click="goConstruction">
|
||||
<image class="entry-icon" src="/static/images/shigong.png" mode="aspectFit" />
|
||||
<text class="entry-text">施工进度</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import CustomNavBar from '@/components/CustomNavBar/index.vue';
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
linkUrl: "",
|
||||
};
|
||||
},
|
||||
onShow() {
|
||||
this.linkUrl = 'https://doc.rentsoft.cn/'
|
||||
},
|
||||
onReady() {
|
||||
// #ifdef APP-PLUS
|
||||
setTimeout(() => {
|
||||
this.$scope
|
||||
.$getAppWebview()
|
||||
.children()[0]
|
||||
.setStyle({
|
||||
top: uni.getWindowInfo().statusBarHeight,
|
||||
height: uni.getWindowInfo().safeArea.height,
|
||||
});
|
||||
});
|
||||
// #endif
|
||||
name: "WorkbenchIndex",
|
||||
components: {
|
||||
CustomNavBar,
|
||||
},
|
||||
methods: {
|
||||
goReportWork() {
|
||||
uni.navigateTo({
|
||||
url: '/pages/workbench/reportWork/reportWork'
|
||||
});
|
||||
},
|
||||
goConstruction() {
|
||||
uni.navigateTo({
|
||||
url: '/pages/workbench/construction/construction'
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss"></style>
|
||||
<style lang="scss" scoped>
|
||||
.workbench-container {
|
||||
min-height: 100vh;
|
||||
background: #fff;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.workbench-title {
|
||||
padding-left: 44rpx;
|
||||
font-size: 40rpx;
|
||||
font-weight: 600;
|
||||
color: #0c1c33;
|
||||
}
|
||||
.entry-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin-top: 40rpx;
|
||||
}
|
||||
.entry-item {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
padding: 32rpx 44rpx;
|
||||
background: #fff;
|
||||
}
|
||||
.entry-icon {
|
||||
width: 56rpx;
|
||||
height: 56rpx;
|
||||
margin-right: 32rpx;
|
||||
}
|
||||
.entry-text {
|
||||
color: #333;
|
||||
font-size: 32rpx;
|
||||
}
|
||||
.divider {
|
||||
height: 1px;
|
||||
background: #f0f0f0;
|
||||
margin-left: 44rpx;
|
||||
margin-right: 44rpx;
|
||||
}
|
||||
</style>
|
||||
|
||||
498
pages/workbench/reportWork/reportWork.vue
Normal file
498
pages/workbench/reportWork/reportWork.vue
Normal file
@@ -0,0 +1,498 @@
|
||||
<template>
|
||||
<view class="container">
|
||||
<!-- 操作按钮 -->
|
||||
<view class="action-buttons">
|
||||
<u-button type="primary" @click="handleAdd" size="medium">新增</u-button>
|
||||
<u-button type="error" @click="handleDelete" size="medium" :disabled="!selectedIds.length">删除</u-button>
|
||||
</view>
|
||||
|
||||
<!-- 数据列表 -->
|
||||
<view class="table-container">
|
||||
<view class="table-header">
|
||||
<view class="header-cell checkbox">
|
||||
<u-checkbox v-model="selectAll" @change="handleSelectAll"></u-checkbox>
|
||||
</view>
|
||||
<view class="header-cell">项目代号</view>
|
||||
<view class="header-cell">项目名称</view>
|
||||
<view class="header-cell">项目编号</view>
|
||||
<view class="header-cell">经办人</view>
|
||||
<view class="header-cell">工作地点</view>
|
||||
<view class="header-cell">国内/国外</view>
|
||||
<view class="header-cell">报工时间</view>
|
||||
</view>
|
||||
|
||||
<view class="table-body">
|
||||
<view
|
||||
v-for="(item, index) in projectReportList"
|
||||
:key="item.reportId"
|
||||
class="table-row"
|
||||
>
|
||||
<view class="table-cell checkbox">
|
||||
<u-checkbox
|
||||
v-model="item.selected"
|
||||
@change="handleSelectionChange"
|
||||
></u-checkbox>
|
||||
</view>
|
||||
<view class="table-cell">
|
||||
<u-tag v-if="!item.projectCode" type="error" text="无"></u-tag>
|
||||
<u-tag v-else :text="item.projectCode"></u-tag>
|
||||
</view>
|
||||
<view class="table-cell">
|
||||
<text v-if="item.prePay > 0">⭐</text>
|
||||
<text>{{ item.projectName }}</text>
|
||||
</view>
|
||||
<view class="table-cell">{{ item.projectNum }}</view>
|
||||
<view class="table-cell">
|
||||
<text>{{ item.nickName }}</text>
|
||||
<text v-if="item.deptName">({{ item.deptName }})</text>
|
||||
</view>
|
||||
<view class="table-cell">{{ item.workPlace }}</view>
|
||||
<view class="table-cell">
|
||||
<u-tag :type="item.workType === 0 ? 'primary' : 'warning'" :text="item.workType === 0 ? '国内' : '国外'"></u-tag>
|
||||
</view>
|
||||
<view class="table-cell">{{ formatDate(item.createTime) }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 分页 -->
|
||||
<u-loadmore
|
||||
v-if="total > 0"
|
||||
:status="loadMoreStatus"
|
||||
@loadmore="loadMore"
|
||||
></u-loadmore>
|
||||
|
||||
<!-- 新增弹窗 -->
|
||||
<u-popup v-model="showForm" mode="center" width="600rpx" height="800rpx">
|
||||
<view class="form-popup">
|
||||
<view class="popup-header">
|
||||
<text class="popup-title">{{ title }}</text>
|
||||
<u-icon name="close" @click="cancel" size="40"></u-icon>
|
||||
</view>
|
||||
|
||||
<scroll-view scroll-y class="form-content">
|
||||
<u-form :model="form" ref="form" label-width="180rpx">
|
||||
<u-form-item label="工作地点" prop="workPlace">
|
||||
<u-input v-model="form.workPlace" placeholder="请输入工作地点"></u-input>
|
||||
</u-form-item>
|
||||
|
||||
<u-form-item label="是否出差" prop="isTrip">
|
||||
<u-radio-group v-model="form.isTrip">
|
||||
<u-radio :name="1" label="是"></u-radio>
|
||||
<u-radio :name="0" label="否"></u-radio>
|
||||
</u-radio-group>
|
||||
</u-form-item>
|
||||
|
||||
<u-form-item v-if="form.isTrip === 1" label="国内/国外" prop="workType">
|
||||
<u-radio-group v-model="form.workType">
|
||||
<u-radio :name="0" label="国内"></u-radio>
|
||||
<u-radio :name="1" label="国外"></u-radio>
|
||||
</u-radio-group>
|
||||
</u-form-item>
|
||||
|
||||
<u-form-item label="请选择项目" prop="projectId">
|
||||
<u-select
|
||||
v-model="form.projectId"
|
||||
:list="projectList"
|
||||
placeholder="请选择项目"
|
||||
label-name="projectName"
|
||||
value-name="projectId"
|
||||
></u-select>
|
||||
</u-form-item>
|
||||
|
||||
<u-form-item label="报工内容" prop="content">
|
||||
<u-textarea
|
||||
v-model="form.content"
|
||||
placeholder="请输入报工内容"
|
||||
:height="200"
|
||||
></u-textarea>
|
||||
</u-form-item>
|
||||
|
||||
<u-form-item label="备注" prop="remark">
|
||||
<u-input v-model="form.remark" placeholder="请输入备注"></u-input>
|
||||
</u-form-item>
|
||||
</u-form>
|
||||
</scroll-view>
|
||||
|
||||
<view class="popup-footer">
|
||||
<u-button type="primary" @click="submitForm" :loading="buttonLoading">确定</u-button>
|
||||
<u-button @click="cancel">取消</u-button>
|
||||
</view>
|
||||
</view>
|
||||
</u-popup>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { listProjectReport, addProjectReport, delProjectReport } from '@/api/oa/projectReport'
|
||||
import { listProject } from '@/api/oa/project'
|
||||
import { listDept } from '@/api/oa/dept'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
// 按钮loading
|
||||
buttonLoading: false,
|
||||
// 遮罩层
|
||||
loading: true,
|
||||
// 选中数组
|
||||
selectedIds: [],
|
||||
// 全选状态
|
||||
selectAll: false,
|
||||
// 总条数
|
||||
total: 0,
|
||||
// 项目报工表格数据
|
||||
projectReportList: [],
|
||||
// 弹出层标题
|
||||
title: "",
|
||||
// 是否显示弹出层
|
||||
showForm: false,
|
||||
// 项目列表
|
||||
projectList: [],
|
||||
// 部门列表
|
||||
deptList: [],
|
||||
// 表单参数
|
||||
form: {},
|
||||
// 加载更多状态
|
||||
loadMoreStatus: 'loadmore',
|
||||
// 分页参数
|
||||
queryParams: {
|
||||
pageNum: 1,
|
||||
pageSize: 10
|
||||
},
|
||||
// 表单校验规则
|
||||
rules: {
|
||||
workPlace: [
|
||||
{ required: true, message: "工作地点不能为空", trigger: "blur" }
|
||||
],
|
||||
projectId: [
|
||||
{ required: true, message: "项目不能为空", trigger: "blur" }
|
||||
],
|
||||
content: [
|
||||
{ required: true, message: "报工内容不能为空", trigger: "blur" }
|
||||
],
|
||||
isTrip: [
|
||||
{ required: true, message: '请选择是否出差', trigger: 'change' }
|
||||
],
|
||||
workType: [
|
||||
{
|
||||
required: true,
|
||||
message: '请选择出差地点',
|
||||
trigger: 'change',
|
||||
validator: (rule, value, callback) => {
|
||||
if (this.form.isTrip === 1 && !value && value !== 0) {
|
||||
callback(new Error('请选择出差地点'));
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
onLoad() {
|
||||
this.getList();
|
||||
},
|
||||
methods: {
|
||||
// 格式化日期
|
||||
formatDate(date) {
|
||||
if (!date) return '';
|
||||
const d = new Date(date);
|
||||
return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`;
|
||||
},
|
||||
|
||||
// 获取项目列表
|
||||
getProjectList() {
|
||||
listProject({ pageNum: 1, pageSize: 9999 }).then(res => {
|
||||
this.projectList = res.rows || [];
|
||||
}).catch(err => {
|
||||
console.error('获取项目列表失败:', err);
|
||||
uni.showToast({
|
||||
title: '获取项目列表失败',
|
||||
icon: 'none'
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
// 获取部门列表
|
||||
getDeptList() {
|
||||
listDept().then(res => {
|
||||
this.deptList = res.data || [];
|
||||
}).catch(err => {
|
||||
console.error('获取部门列表失败:', err);
|
||||
});
|
||||
},
|
||||
|
||||
// 查询项目报工列表
|
||||
getList() {
|
||||
this.loading = true;
|
||||
listProjectReport(this.queryParams).then(response => {
|
||||
this.projectReportList = (response.rows || []).map(item => ({
|
||||
...item,
|
||||
selected: false
|
||||
}));
|
||||
this.total = response.total || 0;
|
||||
this.loading = false;
|
||||
this.getProjectList();
|
||||
// this.getDeptList();
|
||||
}).catch(err => {
|
||||
console.error('获取报工列表失败:', err);
|
||||
this.loading = false;
|
||||
uni.showToast({
|
||||
title: '获取数据失败',
|
||||
icon: 'none'
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
// 全选/取消全选
|
||||
handleSelectAll(value) {
|
||||
this.projectReportList.forEach(item => {
|
||||
item.selected = value;
|
||||
});
|
||||
this.updateSelectedIds();
|
||||
},
|
||||
|
||||
// 选择变化
|
||||
handleSelectionChange() {
|
||||
this.updateSelectedIds();
|
||||
// 更新全选状态
|
||||
const selectedCount = this.projectReportList.filter(item => item.selected).length;
|
||||
this.selectAll = selectedCount === this.projectReportList.length && this.projectReportList.length > 0;
|
||||
},
|
||||
|
||||
// 更新选中ID数组
|
||||
updateSelectedIds() {
|
||||
this.selectedIds = this.projectReportList
|
||||
.filter(item => item.selected)
|
||||
.map(item => item.reportId);
|
||||
},
|
||||
|
||||
// 新增
|
||||
handleAdd() {
|
||||
this.reset();
|
||||
this.showForm = true;
|
||||
this.title = "添加项目报工";
|
||||
},
|
||||
|
||||
// 删除
|
||||
handleDelete() {
|
||||
if (!this.selectedIds.length) {
|
||||
uni.showToast({
|
||||
title: '请选择要删除的数据',
|
||||
icon: 'none'
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
uni.showModal({
|
||||
title: '确认删除',
|
||||
content: `是否确认删除项目报工编号为"${this.selectedIds.join(',')}"的数据项?`,
|
||||
success: (res) => {
|
||||
if (res.confirm) {
|
||||
this.loading = true;
|
||||
// 批量删除
|
||||
const deletePromises = this.selectedIds.map(id => delProjectReport(id));
|
||||
|
||||
Promise.all(deletePromises).then(() => {
|
||||
this.loading = false;
|
||||
this.selectedIds = [];
|
||||
this.selectAll = false;
|
||||
uni.showToast({
|
||||
title: '删除成功',
|
||||
icon: 'success'
|
||||
});
|
||||
this.getList(); // 重新获取列表
|
||||
}).catch(err => {
|
||||
this.loading = false;
|
||||
console.error('删除失败:', err);
|
||||
uni.showToast({
|
||||
title: '删除失败',
|
||||
icon: 'none'
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
// 提交表单
|
||||
submitForm() {
|
||||
this.$refs.form.validate(valid => {
|
||||
if (valid) {
|
||||
this.buttonLoading = true;
|
||||
|
||||
// 获取选中的项目信息
|
||||
const selectedProject = this.projectList.find(p => p.projectId === this.form.projectId);
|
||||
|
||||
const submitData = {
|
||||
...this.form,
|
||||
projectName: selectedProject?.projectName || '',
|
||||
projectNum: selectedProject?.projectNum || '',
|
||||
projectCode: selectedProject?.projectCode || null
|
||||
};
|
||||
|
||||
addProjectReport(submitData).then(response => {
|
||||
this.buttonLoading = false;
|
||||
uni.showToast({
|
||||
title: '新增成功',
|
||||
icon: 'success'
|
||||
});
|
||||
this.showForm = false;
|
||||
this.getList(); // 重新获取列表
|
||||
}).catch(err => {
|
||||
this.buttonLoading = false;
|
||||
console.error('新增失败:', err);
|
||||
uni.showToast({
|
||||
title: '新增失败',
|
||||
icon: 'none'
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
// 取消
|
||||
cancel() {
|
||||
this.showForm = false;
|
||||
this.reset();
|
||||
},
|
||||
|
||||
// 重置表单
|
||||
reset() {
|
||||
this.form = {
|
||||
workPlace: '',
|
||||
projectId: null,
|
||||
content: '',
|
||||
remark: '',
|
||||
isTrip: undefined,
|
||||
workType: undefined
|
||||
};
|
||||
},
|
||||
|
||||
// 加载更多
|
||||
loadMore() {
|
||||
if (this.projectReportList.length >= this.total) {
|
||||
this.loadMoreStatus = 'nomore';
|
||||
return;
|
||||
}
|
||||
|
||||
this.queryParams.pageNum++;
|
||||
this.loadMoreStatus = 'loading';
|
||||
|
||||
listProjectReport(this.queryParams).then(response => {
|
||||
const newData = (response.rows || []).map(item => ({
|
||||
...item,
|
||||
selected: false
|
||||
}));
|
||||
this.projectReportList = [...this.projectReportList, ...newData];
|
||||
this.loadMoreStatus = 'loadmore';
|
||||
}).catch(err => {
|
||||
console.error('加载更多失败:', err);
|
||||
this.loadMoreStatus = 'loadmore';
|
||||
uni.showToast({
|
||||
title: '加载失败',
|
||||
icon: 'none'
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.container {
|
||||
padding: 20rpx;
|
||||
background-color: #f5f5f5;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
.action-buttons {
|
||||
display: flex;
|
||||
gap: 20rpx;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.table-container {
|
||||
background-color: #fff;
|
||||
border-radius: 10rpx;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.table-header {
|
||||
display: flex;
|
||||
background-color: #f8f9fa;
|
||||
border-bottom: 1rpx solid #e9ecef;
|
||||
|
||||
.header-cell {
|
||||
flex: 1;
|
||||
padding: 20rpx 10rpx;
|
||||
text-align: center;
|
||||
font-weight: bold;
|
||||
font-size: 28rpx;
|
||||
|
||||
&.checkbox {
|
||||
flex: 0.5;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.table-body {
|
||||
.table-row {
|
||||
display: flex;
|
||||
border-bottom: 1rpx solid #e9ecef;
|
||||
|
||||
&:hover {
|
||||
background-color: #f8f9fa;
|
||||
}
|
||||
|
||||
.table-cell {
|
||||
flex: 1;
|
||||
padding: 20rpx 10rpx;
|
||||
text-align: center;
|
||||
font-size: 26rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
|
||||
&.checkbox {
|
||||
flex: 0.5;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.form-popup {
|
||||
background-color: #fff;
|
||||
border-radius: 20rpx;
|
||||
overflow: hidden;
|
||||
|
||||
.popup-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 30rpx;
|
||||
border-bottom: 1rpx solid #e9ecef;
|
||||
|
||||
.popup-title {
|
||||
font-size: 32rpx;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
|
||||
.form-content {
|
||||
padding: 30rpx;
|
||||
max-height: 600rpx;
|
||||
}
|
||||
|
||||
.popup-footer {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
gap: 20rpx;
|
||||
padding: 30rpx;
|
||||
border-top: 1rpx solid #e9ecef;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
BIN
static/images/baogong.png
Normal file
BIN
static/images/baogong.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.2 KiB |
BIN
static/images/shigong.png
Normal file
BIN
static/images/shigong.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.3 KiB |
13
util/auth.js
Normal file
13
util/auth.js
Normal file
@@ -0,0 +1,13 @@
|
||||
const TokenKey = 'oaToken'
|
||||
|
||||
export function getToken() {
|
||||
return uni.getStorageSync(TokenKey)
|
||||
}
|
||||
|
||||
export function setToken(token) {
|
||||
return uni.setStorageSync(TokenKey, token)
|
||||
}
|
||||
|
||||
export function removeToken() {
|
||||
return uni.removeStorageSync(TokenKey)
|
||||
}
|
||||
@@ -210,4 +210,59 @@ export const checkLoginError = (error) => {
|
||||
default:
|
||||
return "操作失败";
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* 显示消息提示框
|
||||
* @param content 提示的标题
|
||||
*/
|
||||
export function toast(content) {
|
||||
uni.showToast({
|
||||
icon: 'none',
|
||||
title: content
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 显示模态弹窗
|
||||
* @param content 提示的标题
|
||||
*/
|
||||
export function showConfirm(content) {
|
||||
return new Promise((resolve, reject) => {
|
||||
uni.showModal({
|
||||
title: '提示',
|
||||
content: content,
|
||||
cancelText: '取消',
|
||||
confirmText: '确定',
|
||||
success: function(res) {
|
||||
resolve(res)
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 参数处理
|
||||
* @param params 参数
|
||||
*/
|
||||
export function tansParams(params) {
|
||||
let result = ''
|
||||
for (const propName of Object.keys(params)) {
|
||||
const value = params[propName]
|
||||
var part = encodeURIComponent(propName) + "="
|
||||
if (value !== null && value !== "" && typeof (value) !== "undefined") {
|
||||
if (typeof value === 'object') {
|
||||
for (const key of Object.keys(value)) {
|
||||
if (value[key] !== null && value[key] !== "" && typeof (value[key]) !== 'undefined') {
|
||||
let params = propName + '[' + key + ']'
|
||||
var subPart = encodeURIComponent(params) + "="
|
||||
result += subPart + encodeURIComponent(value[key]) + "&"
|
||||
}
|
||||
}
|
||||
} else {
|
||||
result += part + encodeURIComponent(value) + "&"
|
||||
}
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
6
util/errorCode.js
Normal file
6
util/errorCode.js
Normal file
@@ -0,0 +1,6 @@
|
||||
export default {
|
||||
'401': '认证失败,无法访问系统资源',
|
||||
'403': '当前操作没有权限',
|
||||
'404': '访问资源不存在',
|
||||
'default': '系统未知错误,请反馈给管理员'
|
||||
}
|
||||
73
util/oaRequest.js
Normal file
73
util/oaRequest.js
Normal file
@@ -0,0 +1,73 @@
|
||||
import { getToken } from './auth'
|
||||
import errorCode from './errorCode'
|
||||
import { toast, showConfirm, tansParams } from './common'
|
||||
|
||||
let timeout = 10000
|
||||
const baseUrl = 'http://110.41.139.73:8080'
|
||||
// const baseUrl = 'http://localhost:8080'
|
||||
|
||||
const request = config => {
|
||||
// 是否需要设置 token
|
||||
const isToken = (config.headers || {}).isToken === false
|
||||
config.header = config.header || {}
|
||||
if (getToken() && !isToken) {
|
||||
config.header['Authorization'] = 'Bearer ' + getToken()
|
||||
}
|
||||
// get请求映射params参数
|
||||
if (config.params) {
|
||||
let url = config.url + '?' + tansParams(config.params)
|
||||
url = url.slice(0, -1)
|
||||
config.url = url
|
||||
}
|
||||
return new Promise((resolve, reject) => {
|
||||
uni.request({
|
||||
method: config.method || 'get',
|
||||
timeout: config.timeout || timeout,
|
||||
url: config.baseUrl || baseUrl + config.url,
|
||||
data: config.data,
|
||||
header: config.header,
|
||||
dataType: 'json'
|
||||
}).then(response => {
|
||||
let [error, res] = response
|
||||
if (error) {
|
||||
console.log(error)
|
||||
toast('后端接口连接异常')
|
||||
reject('后端接口连接异常')
|
||||
return
|
||||
}
|
||||
const code = res.data.code || 200
|
||||
const msg = errorCode[code] || res.data.msg || errorCode['default']
|
||||
if (code === 401) {
|
||||
showConfirm('登录状态已过期,您可以继续留在该页面,或者重新登录?').then(res => {
|
||||
if (res.confirm) {
|
||||
// store.dispatch('LogOut').then(res => {
|
||||
// uni.reLaunch({ url: '/pages/login' })
|
||||
// })
|
||||
}
|
||||
})
|
||||
reject('无效的会话,或者会话已过期,请重新登录。')
|
||||
} else if (code === 500) {
|
||||
toast(msg)
|
||||
reject('500')
|
||||
} else if (code !== 200) {
|
||||
toast(msg)
|
||||
reject(code)
|
||||
}
|
||||
resolve(res.data)
|
||||
})
|
||||
.catch(error => {
|
||||
let { message } = error
|
||||
if (message === 'Network Error') {
|
||||
message = '后端接口连接异常'
|
||||
} else if (message.includes('timeout')) {
|
||||
message = '系统接口请求超时'
|
||||
} else if (message.includes('Request failed with status code')) {
|
||||
message = '系统接口' + message.substr(message.length - 3) + '异常'
|
||||
}
|
||||
toast(message)
|
||||
reject(error)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
export default request
|
||||
Reference in New Issue
Block a user