This commit is contained in:
THK3121 2023-07-15 17:27:06 +08:00
commit 67f00bf81f
20 changed files with 4034 additions and 0 deletions

17
App.vue Normal file
View File

@ -0,0 +1,17 @@
<script>
export default {
onLaunch: function() {
console.log('App Launch')
},
onShow: function() {
console.log('App Show')
},
onHide: function() {
console.log('App Hide')
}
}
</script>
<style>
/*每个页面公共css */
</style>

20
index.html Normal file
View File

@ -0,0 +1,20 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<script>
var coverSupport = 'CSS' in window && typeof CSS.supports === 'function' && (CSS.supports('top: env(a)') ||
CSS.supports('top: constant(a)'))
document.write(
'<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0' +
(coverSupport ? ', viewport-fit=cover' : '') + '" />')
</script>
<title></title>
<!--preload-links-->
<!--app-context-->
</head>
<body>
<div id="app"><!--app-html--></div>
<script type="module" src="/main.js"></script>
</body>
</html>

50
main.js Normal file
View File

@ -0,0 +1,50 @@
import App from './App'
// #ifndef VUE3
import Vue from 'vue'
Vue.config.productionTip = false
App.mpType = 'app'
try {
function isPromise(obj) {
return (
!!obj &&
(typeof obj === "object" || typeof obj === "function") &&
typeof obj.then === "function"
);
}
// 统一 vue2 API Promise 化返回格式与 vue3 保持一致
uni.addInterceptor({
returnValue(res) {
if (!isPromise(res)) {
return res;
}
return new Promise((resolve, reject) => {
res.then((res) => {
if (res[0]) {
reject(res[0]);
} else {
resolve(res[1]);
}
});
});
},
});
} catch (error) { }
const app = new Vue({
...App
})
app.$mount()
// #endif
// #ifdef VUE3
import { createSSRApp } from 'vue'
export function createApp() {
const app = createSSRApp(App)
return {
app
}
}
// #endif

72
manifest.json Normal file
View File

@ -0,0 +1,72 @@
{
"name" : "OfficeApp",
"appid" : "",
"description" : "",
"versionName" : "1.0.0",
"versionCode" : "100",
"transformPx" : false,
/* 5+App */
"app-plus" : {
"usingComponents" : true,
"nvueStyleCompiler" : "uni-app",
"compilerVersion" : 3,
"splashscreen" : {
"alwaysShowBeforeRender" : true,
"waiting" : true,
"autoclose" : true,
"delay" : 0
},
/* */
"modules" : {},
/* */
"distribute" : {
/* android */
"android" : {
"permissions" : [
"<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
"<uses-permission android:name=\"android.permission.VIBRATE\"/>",
"<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
"<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.CAMERA\"/>",
"<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
"<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
"<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
"<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
"<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
"<uses-feature android:name=\"android.hardware.camera\"/>",
"<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
]
},
/* ios */
"ios" : {},
/* SDK */
"sdkConfigs" : {}
}
},
/* */
"quickapp" : {},
/* */
"mp-weixin" : {
"appid" : "",
"setting" : {
"urlCheck" : false
},
"usingComponents" : true
},
"mp-alipay" : {
"usingComponents" : true
},
"mp-baidu" : {
"usingComponents" : true
},
"mp-toutiao" : {
"usingComponents" : true
},
"uniStatistics" : {
"enable" : false
},
"vueVersion" : "2"
}

20
pages.json Normal file
View File

@ -0,0 +1,20 @@
{
"pages": [ //pageshttps://uniapp.dcloud.io/collocation/pages
{
"path": "pages/office_app/oaHome/oaHome",
"style": {
"navigationBarTitleText": "首页",
"enablePullDownRefresh": true
}
},
],
"globalStyle": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "uni-app",
"navigationBarBackgroundColor": "#F8F8F8",
"backgroundColor": "#F8F8F8"
},
"uniIdRouter": {}
}

View File

@ -0,0 +1,102 @@
<template>
<view class="application">
<block v-for="item in appDataList" :key="item.title">
<view class="apply_line">
<view class="title flex_a_c">
<view class="text flex_a_c">
{{ item.title }}
</view>
</view>
<view class="line_cent">
<block v-for="(itemData,i) in item.data" :key="i">
<view class="line_item" @click="lineCentClick(itemData.url)">
<u--image :showLoading="true" :src="itemData.src" width="77.19rpx" height="77.19rpx"></u--image>
<view class="name">{{ itemData.name }}</view>
</view>
</block>
</view>
</view>
</block>
</view>
</template>
<script>
import { Toast } from '@/libs/uniApi.js'
import { appDataList } from '@/static/server/server.js'
export default {
data() {
return {
appDataList: appDataList,
src: 'https://cdn.uviewui.com/uview/album/1.jpg'
}
},
onReady() {
uni.setNavigationBarColor({
frontColor: '#ffffff',
backgroundColor: '#3175f9'
})
},
onLoad() {},
onShow() {},
methods: {
lineCentClick(url) {
url.length > 0 ? uni.navigateTo({
url: url
}) : Toast('暂未开放')
}
},
onPullDownRefresh() {
uni.stopPullDownRefresh()
}
}
</script>
<style lang="scss">
.application {}
.apply_line {
width: 100%;
padding: 0 28.07rpx;
background-color: #fff;
margin-bottom: 31.58rpx;
.title {
width: 100%;
height: 77.19rpx;
border-bottom: 1px solid rgba(204, 204, 204, 0.5);
.text {
font-size: 31.58rpx;
&::before {
content: '';
display: inline-block;
width: 2px;
height: 33.33rpx;
background-color: $theme-oa-color;
margin-right: 10.53rpx;
}
}
}
.line_cent {
display: flex;
flex-wrap: wrap;
.line_item {
width: 231.58rpx;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 28.07rpx 0;
.name {
font-size: 24.56rpx;
margin-top: 14.04rpx;
}
}
}
}
</style>

View File

@ -0,0 +1,195 @@
<template>
<view class="">
<view class="content_card">
<view class="cont_header flex_a_c_j_sb">
<view class="task_name">任务名称</view>
<view class="is_matter">任务审批</view>
</view>
<view class="cont_details">
审批内容
<view class="">审批详细描述</view>
</view>
</view>
<view class="content_card">
<!-- 头部 -->
<view class="cont_header">
<view class="flex_a_c_j_sb">
<view class="approver">当前审批人张三</view>
<view class="audit_store">审核状态<text>已通过</text> </view>
</view>
<view class="make_copy">抄送人李四</view>
</view>
<!-- 内容 -->
<view class="cont_details">
<view class="examine">审批流程</view>
<view class="examine">审批记录</view>
<block v-for="(item,i) in 3" :key="i">
<view class="record flex">
<view class="circle"></view>
<text class="text">2023-03-24 :09:40 张三 提交 了此申请操作意见提交申请</text>
</view>
</block>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
}
},
onLoad() {},
onShow() {},
methods: {},
onPullDownRefresh() {
uni.stopPullDownRefresh()
}
}
</script>
<style lang="scss">
.content_card {
width: 695rpx;
margin: 0 auto;
margin-top: 24.56rpx;
padding: 0 28.07rpx;
background-color: #fff;
border-radius: 4px;
}
.cont_header {
padding: 21.05rpx 0;
font-size: 31.58rpx;
min-height: 82.46rpx;
width: 100%;
border-bottom: 1px solid rgba(204, 204, 204, 0.5);
.task_name {
width: 526.32rpx;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.is_matter {
font-size: 24.56rpx;
border-radius: 4px;
// padding: 3.51rpx 17.54rpx;
color: $theme-oa-color;
// background-color: #E4EDFF;
}
//
.approver {
font-size: 28.07rpx;
}
.audit_store {
font-size: 31.58rpx;
}
.make_copy {
color: #999;
margin-top: 14.04rpx;
font-size: 24.56rpx;
}
}
.cont_details {
padding: 24.56rpx 0;
font-size: 28.07rpx;
//
.finish_time {
font-size: 24.56rpx;
color: #999;
}
text {
display: block;
margin-bottom: 7.02rpx;
}
.upload_box {
padding: 17.54rpx;
background-color: #F7F7F7;
border-radius: 4px;
.title {
font-size: 28.07rpx;
}
.text {
margin-top: 7.02rpx;
font-size: 21.05rpx;
color: #999;
}
}
.file {
padding: 17.54rpx;
border-radius: 4px;
border: 1px solid #F2F2F2;
margin-bottom: 17.54rpx;
.file_size {
margin-top: 7.02rpx;
}
.file_size,
.upload_people {
font-size: 21.05rpx;
color: #999;
}
}
//
.examine {
margin-bottom: 17.54rpx;
}
.record {
position: relative;
margin-bottom: 14.04rpx;
.circle {
width: 31.58rpx;
height: 31.58rpx;
background-color: #fff;
border: 2px solid #34A853;
border-radius: 50%;
margin: 5px;
display: flex;
flex-direction: column;
align-items: center;
&::before {
content: "";
display: block;
position: absolute;
clear: both;
width: 1px;
height: 100%;
background-color: rgba(204, 204, 204, 0.5);
margin: 31.58rpx;
}
}
.text {
flex: 1;
margin-left: 7.02rpx;
}
}
:last-child {
.circle {
&::before {
display: none;
}
}
}
}
</style>

View File

@ -0,0 +1,154 @@
<template>
<view>
<view :class="[isFixed ? 'f-fixed' : '']">
<!-- 二次封装tabbar -->
<!-- @change="onTabbar" -->
<u-tabbar ref="tabBarRef" :value="tabIndex" @change="onTabbar" :fixed="false" :placeholder="false"
:safeAreaInsetBottom="safeAreaInsetBottom" :activeColor="activeColor || PrimaryColor"
:inactiveColor="inactiveColor" :border="border">
<!-- list 改为 list -->
<block v-for="(item, index) in list" :key="item.name">
<!-- 自定义icon -->
<u-tabbar-item :text="item.name">
<view slot="active-icon">
<view class="iconfont2" :class="['custom-icon' + item.iconFill]" style="font-size: 20px;"
:style="{ color: activeColor || PrimaryColor }"></view>
<!-- 自定义图标 -->
<!-- <f-icon :name="item.iconFill" size="40" :color="activeColor || PrimaryColor"></f-icon> -->
<!-- 图片路径 -->
<!-- <image class="icon" :src="item.iconFill"></image> -->
</view>
<view slot="inactive-icon">
<view class="iconfont2" :class="['custom-icon' + item.icon]" style="font-size: 20px;"
:style="{ color: inactiveColor }"></view>
<!-- 自定义图标 -->
<!-- <f-icon :name="item.icon" size="40" :color="inactiveColor"></f-icon> -->
<!-- 图片路径 -->
<!-- <image class="icon" :src="item.icon"></image> -->
</view>
</u-tabbar-item>
</block>
</u-tabbar>
<!-- 苹果安全距离-默认20px -->
<view :style="{ paddingBottom: systemInfo.tabbarPaddingB + 'px', background: '#fff' }"></view>
</view>
<!-- 防止塌陷高度 -->
<view v-if="isFixed && isFillHeight" :style="{ height: systemInfo.tabbarH + 'px' }"></view>
<!-- #ifdef H5 -->
<u-safe-bottom></u-safe-bottom>
<!-- #endif -->
</view>
</template>
<script>
import { mapState, mapMutations, mapGetters } from 'vuex';
import base from '@/config/baseUrl.js';
export default {
name: 'f-tabbar',
props: {
//
isFixed: {
type: Boolean,
default: true
},
//
isFillHeight: {
type: Boolean,
default: true
},
// --
activeColor: {
type: String,
default: '#3175f9'
},
//
inactiveColor: {
type: String,
default: '#606266'
},
//
border: {
type: Boolean,
default: function() {
return true;
}
}
},
data() {
return {
PrimaryColor: '#3175f9',
safeAreaInsetBottom: false,
systemInfo: base.systemInfo,
tabIndex: 0,
path: '', //
list: [{
name: '首页',
url: 'pages/office_app/oaHome/oaHome',
icon: 'oah',
iconFill: 'oaha'
},
{
name: '审批',
url: 'pages/office_app/oaExamine/oaExamine',
icon: 'oas',
iconFill: 'oasa'
},
{
name: '任务',
url: 'pages/office_app/oaTask/oaTask',
icon: 'oar',
iconFill: 'oara'
},
{
name: '我的',
url: 'pages/office_app/oaMy/oaMy',
icon: 'oamya',
iconFill: 'oamy'
}
]
};
},
created() {
//
let currentPages = getCurrentPages();
let page = currentPages[currentPages.length - 1];
this.path = page.route;
this.list.forEach((item, index) => {
if (this.path == item.url) {
this.tabIndex = index;
}
});
// #ifdef H5
this.safeAreaInsetBottom = true;
// #endif
},
methods: {
onTabbar(index) {
if (this.path !== this.list[index].url) {
uni.redirectTo({
url: '/' + this.list[index].url
});
}
}
}
};
</script>
<style lang="scss" scoped>
@import '@/static/tabbar_icon/iconfont.css';
.f-fixed {
position: fixed;
bottom: 0;
left: 0;
right: 0;
z-index: 1000;
.icon {
width: 20px;
height: 20px;
}
}
</style>

View File

@ -0,0 +1,537 @@
<template>
<view class="leave_request">
<view class="leave_box">
<view class="leava_type flex_a_c">
<view class="title">请假类型</view>
<input type="text" v-model="leavaTypeVal" placeholder="请选择" disabled @click="leavaTypeShow = true">
</view>
<block v-for="(item,i) in timeData" :key="item.title">
<view class="cont_cell">
<view class="title">{{ item.title }}</view>
<input type="text" v-model="item.time" placeholder="请选择时间" disabled @click="selectTime(item)">
</view>
</block>
<view class="cont_cell">
<view class="title">请假工时</view>
<input type="text" v-model="manHour" disabled placeholder="请假工时">
</view>
<view class="cont_cell">
<view class="title">请假天数</view>
<input type="text" v-model="daysNum" disabled placeholder="请假天数">
</view>
<view class="cont_cell">
<view class="title">请假事由</view>
<input type="text" v-model="reason" placeholder="请输入请假事由">
</view>
<!-- 附件 -->
<block v-for="(item, i) in fileArray" :key="i">
<view class="file flex_a_c_j_sb">
<view class="l_file">
<view class="file_name">{{ item.name }}</view>
<view class="file_size">{{ item.filesize | formatBytes }}</view>
<view class="upload_people">上传人{{ item.admin_name }}</view>
</view>
<u-icon @click="delImg(i)" name="close-circle" color="#333333" size="28"></u-icon>
</view>
</block>
<view class="upload_box flex_a_c_j_sb" @click="seleckImage">
<view>
<view class="title">选择文件并上传</view>
<view class="text">
上传前请规范命名最大只能上传100M的文件<br />
超过请压缩成多个文件上传
</view>
</view>
<u-icon name="plus-circle" color="#333333" size="28"></u-icon>
</view>
</view>
<view class="flow_path">
<view class="cont_cell">
<view class="title">选择审批流程</view>
<input type="text" v-model="flowPath" placeholder="请选择" disabled @click="flowPathShow = true">
</view>
<view class="cont_cell">
<view class="title">审核人</view>
<input v-if="flowDate === false" type="text" v-model="auditor" placeholder="请选择" disabled
@click="branchShow = true">
<view v-else class="audit_process">
<view v-for="(item,i) in flowDate" :key="i" class="process_item flex">
<view class="circle"></view>
<view class="right">
<view v-if="item.flow_type==1">
{{i+1}}级审批
<view class="verifier">当前部门负责人</view>
</view>
<view v-else-if="item.flow_type==2">
{{i+1}}级审批
<view class="verifier">上级部门负责人</view>
</view>
<view v-else>
<view v-if="item.flow_type==3">
{{i+1}}级审批
<text class="tag">或签</text>
</view>
<view v-if="item.flow_type==4">
{{i+1}}级审批
<text class="tag">会签</text>
</view>
<view v-for="(info,b) in item.user_id_info" :key="b" class="verifier">
{{ info.name }}
</view>
</view>
</view>
</view>
</view>
</view>
<view class="cont_cell">
<view class="title">抄送人</view>
<input type="text" v-model="carbon" placeholder="请选择" disabled>
</view>
</view>
<view class="bot_btn">
<view class="reset" @click="reset">重置</view>
<view class="submit_btn" @click="submiteBtn">立即提交</view>
</view>
<u-picker :show="leavaTypeShow" keyName="name" :columns="columns" @cancel="leavaTypeShow = false"
@confirm="leavaType">
</u-picker>
<!-- 选择审批流程 -->
<u-action-sheet :actions="flowPathSheet" @select="flowPathSelect" title="选择审批流程" :show="flowPathShow"
@close="flowPathShow=false" :closeOnClickOverlay="true" :closeOnClickAction="true">
</u-action-sheet>
<!-- 部门选择 -->
<u-picker :show="branchShow" :defaultIndex=[0,0] ref="branchRef" :columns="branchColumns" @confirm="branchConfirm"
@change="branchHandler" :closeOnClickOverlay="true" @close="branchShow=false" keyName="name">
</u-picker>
<!-- 选择时间 -->
<block v-for="(item,i) in timeData" :key="i">
<u-datetime-picker :show="item.timeShow" v-model="item.timeVal" mode="datetime" :maxDate="1786778555000"
:minDate="timestamp" closeOnClickOverlay @confirm="timeConfirm($event,i)" @cancel="item.timeShow = false"
@close="item.timeShow = false"></u-datetime-picker>
</block>
</view>
</template>
<script>
import { getFlowAPI, getFlowUsersAPI, getDepartmentTreeAPI, getEmployeeAPI, PostApproveAddAPI } from '@/api/oaApi.js'
import { leaveTime } from '@/plugin/utils.js'
import { oaLeaveData } from '@/static/server/server.js'
import { oaUploads } from '../../api/upload'
import { Toast } from '../../libs/uniApi'
export default {
data() {
return {
timestamp: '', //
flowPath: '', //
flow_id: '', // id
auditor: '', //
carbon: '', //
copy_uids: '', // id
manHour: '', //
daysNum: '', //
reason: '', //
flowPathShow: false,
flowPathSheet: [],
timeData: [{
title: '开始时间:',
timeShow: false,
timeVal: '', //
time: '', //
timeDay: '', //
timeHour: '', //
},
{
title: '结束时间:',
timeShow: false,
timeVal: '', //
time: '', //
timeDay: '', //
timeHour: '', //
}
],
leavaTypeShow: false,
leavaTypeVal: '',
leavaTypeId: '',
columns: [oaLeaveData],
//
branchShow: false,
branchColumns: [],
isflowDate: true,
flowDate: [],
fileArray: []
}
},
onLoad() {},
onShow() {
this.getFlow()
//
this.timestamp = Date.parse(new Date());
},
watch: {
timeData: {
handler(newVal, oldVal) {
if (newVal[0].time.length > 0 && newVal[1].time.length > 0) {
const { leaveDays, leaveHours } = this.calculateLeaveDaysAndHours(this.timeData[0].time, this.timeData[1]
.time)
this.manHour = leaveHours + '小时'
this.daysNum = leaveDays + '天'
}
},
deep: true
}
},
methods: {
selectTime(item) {
item.timeShow = true
},
async branchHandler(e) {
const {
columnIndex,
value,
values, // values
index,
// pickerref
picker = this.$refs.branchRef
} = e
// ()
if (columnIndex === 0) {
// pickerthis
let res = await getEmployeeAPI({ did: value[0].id })
if (res.length < 1) {
res[0] = { name: '无' }
}
picker.setColumnValues(1, res)
}
},
// columnIndexvaluevalues
branchConfirm(e) {
console.log('confirm', e)
this.auditor = e.value[1].name
this.branchShow = false
},
/** 请假类型 */
leavaType(e) {
this.leavaTypeVal = e.value[0].name
this.leavaTypeId = e.value[0].id
this.leavaTypeShow = false
},
/** 选择审核人 */
async getFlowUsers(id) {
const flowUsers = await getFlowUsersAPI({ id: id })
console.log(flowUsers.data);
this.flowDate = flowUsers.data.flow_data
//
if (!flowUsers.data.flow_data) {
const tree = await getDepartmentTreeAPI()
const picker = this.$refs.branchRef
picker.setColumnValues(0, tree[0].children)
let res = await getEmployeeAPI({ did: tree[0].children[0].id })
picker.setColumnValues(1, res)
this.carbon = ''
} else {
this.carbon = flowUsers.data.copy_unames
this.copy_uids = flowUsers.data.copy_uids
}
},
flowPathSelect(value) {
this.flowPath = value.name
this.flow_id = value.id
this.getFlowUsers(value.id)
},
async getFlow() {
const flow = await getFlowAPI({ type: 1, flow_cate: 1 })
this.flowPathSheet = flow
},
timeConfirm(e, i) {
this.timeData[i].time = uni.$u.timeFormat(e.value, 'yyyy-mm-dd hh:MM:ss')
this.timeData[i].timeDay = uni.$u.timeFormat(e.value, 'yyyy-mm-dd')
this.timeData[i].timeHour = uni.$u.timeFormat(e.value, 'hh:MM')
this.timeData[i].timeShow = false
},
async submiteBtn() {
let fileIds = [];
this.fileArray.map((item, i) => {
fileIds.push(item.id)
});
let subData = {
detail_type: this.leavaTypeId,
end_time_a: this.timeData[1].timeDay,
end_time_b: this.timeData[1].timeHour,
start_time_a: this.timeData[0].timeDay,
start_time_b: this.timeData[0].timeHour,
duration: this.manHour,
content: this.reason,
flow_id: this.flow_id,
file_ids: fileIds.join(','),
copy_names: this.carbon,
copy_uids: this.copy_uids,
type: '1',
id: 0
}
try {
const res = await PostApproveAddAPI(subData)
Toast('提交成功')
} catch (e) {
Toast('提交失败')
}
},
reset() {
this.flowPath = ''
this.flowDate = []
this.leavaTypeVal = ''
this.leavaTypeId = ''
this.daysNum = ''
this.timeData[0].time = ''
this.timeData[0].time = ''
this.timeData[1].time = ''
this.timeData[1].time = ''
this.manHour = ''
this.reason = ''
this.flow_id = ''
this.carbon = ''
this.copy_uids = ''
},
seleckImage(i) {
let that = this
uni.chooseImage({
count: 1,
sizeType: ['original', 'compressed'],
sourceType: ['album', 'camera'],
success: function(res) {
that.loading = true
let objImg = {}
objImg.filesize = res.tempFiles[0].size
objImg.admin_name = '马开明'
oaUploads(res.tempFilePaths[0], 'img').then(res => {
objImg.name = res.filename
that.fileArray.push(res)
that.loading = false
Toast('上传成功')
}).catch(err => {
Toast('上传失败')
that.loading = false
console.log('上传失败', err)
})
},
fail: function(err) {
Toast('添加失败')
console.log('失败', err)
}
});
},
delImg(i) {
let that = this
uni.showModal({
title: '删除图片',
content: '确定删除图片?',
success: res => {
if (res.confirm) {
that.fileArray.splice((i, 1))
} else if (res.cancel) {
console.log('用户点击取消');
}
}
})
},
/**
* 计算两个时间戳之间相差的小时数
* */
calculateLeaveDaysAndHours(leaveStartTime, leaveEndTime, hoursPerDay = 8) {
const startDate = new Date(leaveStartTime);
const endDate = new Date(leaveEndTime);
//
const leaveDays = Math.floor((endDate.getTime() - startDate.getTime()) / (24 * 60 * 60 * 1000)) + 1;
//
const leaveHours = leaveDays * hoursPerDay;
//
return {
leaveDays,
leaveHours,
};
}
},
filters: {
// MB
formatBytes(bytes, decimals = 2) {
if (bytes === 0) return '0 MB';
const k = 1024;
const sizes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
const i = Math.floor(Math.log(bytes) / Math.log(k));
return parseFloat((bytes / Math.pow(k, i)).toFixed(decimals)) + ' ' + sizes[i];
}
},
onPullDownRefresh() {
uni.stopPullDownRefresh()
}
}
</script>
<style lang="scss">
.leave_request {
position: relative;
padding-bottom: 100px;
}
.leave_box,
.flow_path {
width: 100%;
padding: 0 28.07rpx;
background: #fff;
margin-bottom: 35.09rpx;
padding-bottom: 28.07rpx;
}
.bot_btn {
position: fixed;
bottom: 0;
left: 0;
width: 100%;
display: flex;
align-items: center;
justify-content: space-between;
height: 87.72rpx;
>view {
width: 50%;
text-align: center;
line-height: 87.72rpx;
}
.reset {
background-color: #fff;
}
.submit_btn {
color: #fff;
height: 87.72rpx;
background: $theme-oa-color;
}
}
.leava_type {
height: 100rpx;
border-bottom: 1px solid #999;
.title {
font-size: 31.58rpx;
}
}
.cont_cell {
display: flex;
align-items: center;
width: 100%;
min-height: 87.72rpx;
border-bottom: 1px solid #f7f7f7;
.title {
font-size: 31.58rpx;
}
}
//
.audit_process {
.process_item {
position: relative;
height: 100%;
margin: 17.54rpx 0;
}
:last-child {
.circle {
&::before {
display: none;
}
}
}
.tag {
font-size: 21.05rpx;
color: #fff;
padding: 0 4px;
margin-left: 10.53rpx;
background-color: #3c9cff;
border-radius: 2px;
}
.verifier {
margin: 17.54rpx 0;
}
}
.circle {
width: 31.58rpx;
height: 31.58rpx;
background-color: #fff;
border: 2px solid #34A853;
border-radius: 50%;
margin: 0 5px;
display: flex;
flex-direction: column;
align-items: center;
&::before {
content: "";
display: block;
position: absolute;
clear: both;
width: 1px;
height: 100%;
background-color: rgba(204, 204, 204, 0.5);
margin: 31.58rpx;
}
}
//
.upload_box {
padding: 17.54rpx;
background-color: #F7F7F7;
border-radius: 4px;
.title {
font-size: 28.07rpx;
}
.text {
margin-top: 7.02rpx;
font-size: 21.05rpx;
color: #999;
}
}
.file_name {
width: 526.32rpx;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.file {
padding: 17.54rpx;
border-radius: 4px;
border: 1px solid #F2F2F2;
margin: 17.54rpx 0;
.file_size {
margin-top: 7.02rpx;
}
.file_size,
.upload_people {
font-size: 21.05rpx;
color: #999;
}
}
</style>

View File

@ -0,0 +1,259 @@
<template>
<view class="all_box">
<!-- 审批选项 -->
<view class="examine_box">
<u-tabs :list="list1" @click="click" lineColor='#3274F9' lineWidth='77rpx' inactiveStyle='color:#666'
activeStyle="color:#3274F9"></u-tabs>
</view>
<!-- 事项 -->
<view class="out_box">
<view class="eventList_box" v-for="item in myEventList" :key="item.id">
<view class="banner">
<view class="title">{{item.name}}</view>
<view class="department">{{item.department_name ? item.department_name : '' }}</view>
<view v-if="item.check_status==0" class="wait">待审核</view>
<view v-if="item.check_status==1" class="underway">审核中</view>
<view v-if="item.check_status==2" class="pass">审核通过</view>
<view v-if="item.check_status==3" class="refuse">审核不通过</view>
<view v-if="item.check_status==4" class="withdraw">撤回审核</view>
</view>
<view class="line"></view>
<view class="task_approval">{{item.content}}</view>
<view class="approval_time">{{item.create_time}}</view>
</view>
</view>
<u-loadmore :status="status" :loading-text="loadingText" :loadmore-text="loadmoreText"
:nomore-text="nomoreText" />
<tabbar></tabbar>
</view>
</template>
<script>
import {
getApproveMyListAPI,
getHandleListAPI,
getCopyOfMyListAPI
} from '@/api/oaApi.js'
import tabbar from '../components/tabbar'
export default {
components: {
tabbar
},
data() {
return {
list1: [{
name: '我发起的',
}, {
name: '我处理的',
}, {
name: '抄送给我的'
}, ],
myEventList: [],
params: {
limit: '8', //
page: '1',
},
last_page: '',
status: 'loadmore',
loadingText: '努力加载中',
loadmoreText: '轻轻上拉',
nomoreText: '我也是有底线的~~',
flag: '0', //
}
},
onReady() {
uni.setNavigationBarColor({
frontColor: '#ffffff',
backgroundColor: '#3175f9'
})
},
onLoad() {
this.myEventList = []
this.getApproveMyList(this.params)
},
onShow() {
},
methods: {
//
async getHandleList(data) {
const res = await getHandleListAPI(data)
this.publicMethods(res)
},
//
async getApproveMyList(data) {
const res = await getApproveMyListAPI(data)
this.publicMethods(res)
},
//
async getCopyOfMyList(data) {
const res = await getCopyOfMyListAPI(data)
this.publicMethods(res)
},
//1
publicMethods(res) {
console.log(res);
this.myEventList = [...this.myEventList, ...res.data]
if (this.myEventList.length < this.params.limit) {
this.status = 'nomore'
}
this.last_page = res.last_page
},
//2
publicMethods2(fun) {
if (this.params.page < this.last_page) {
this.params.page++
fun(this.params)
} else {
this.status = 'nomore'
return
}
},
click(item) {
this.myEventList = []
this.params.page = '1'
switch (item.index) {
case 0:
this.flag = '0'
this.getApproveMyList(this.params)
break;
case 1:
this.flag = '1'
this.getHandleList(this.params)
break;
case 2:
this.flag = '2'
this.getCopyOfMyList(this.params)
break;
}
}
},
onPullDownRefresh() {
uni.stopPullDownRefresh()
},
onReachBottom() {
if (this.flag == '0') {
this.publicMethods2(this.getApproveMyList)
} else if (this.flag == '1') {
this.publicMethods2(this.getHandleList)
} else {
this.publicMethods2(this.getCopyOfMyList)
}
},
filters: {
formatDate(nS, format) {
return new Date(nS).format('yyyy-MM-dd hh:mm:ss');
}
}
}
</script>
<style lang="scss" scoped>
/deep/.u-tabs__wrapper__nav__item {
// padding: 0 56rpx;
height: 77rpx !important;
}
/deep/.u-tabs__wrapper__nav__item__text {
font-size: 32rpx;
}
/deep/.u-tabs__wrapper__nav {
height: 77rpx;
// justify-content: space-between;
}
/deep/.u-tabs__wrapper__nav__item-1 {
flex-grow: 2;
}
.all_box {
padding-bottom: 21rpx;
}
.examine_box {
position: fixed;
top: 0;
width: 750rpx;
height: 77rpx;
background: #FFFFFF;
}
.out_box{
padding-top: 75rpx;
}
.eventList_box {
margin: 0 auto;
margin-top: 21rpx;
width: 694rpx;
min-height: 221rpx;
background: #FFFFFF;
border-radius: 7rpx;
padding: 0 24.53rpx 10.53rpx 24.53rpx;
.banner {
display: flex;
align-items: center;
flex: 1 1 3;
width: 100%;
height: 82rpx;
font-size: 32rpx;
.title {
// width: 438.6rpx;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.department {
color: $theme-oa-color;
font-size: 25rpx;
margin-left: 17.52rpx;
flex-grow: 2;
}
.underway {
color: #34A853;
}
.pass {
color: $theme-oa-color;
}
.wait {
color: #F9AA32;
}
.refuse {
color: #F02828;
}
.withdraw {
color: #CCCCCC;
}
}
.line {
margin: 0 auto;
width: 646rpx;
height: 0rpx;
border-bottom: 1rpx solid #CCCCCC;
margin-bottom: 14.02rpx;
}
.task_approval {
font-size: 28rpx;
margin-bottom: 26rpx;
}
.approval_time {
font-size: 25rpx;
color: #999;
// position: relative;
}
}
</style>

View File

@ -0,0 +1,390 @@
<template>
<view class="oa_home" style="oaColor">
<view class="home_header">
<view class="my_info flex_a_c">
<view class="">
<u--image :showLoading="true" :src="myOaInfo.thumb" width="64px" height="64px" shape="circle"></u--image>
</view>
<view class="mesg_box">
<view class="name">{{ myOaInfo.name }} {{ myOaInfo.mobile }}</view>
<view class="duty">({{ myOaInfo.did_name }}){{myOaInfo.label_name}}</view>
</view>
</view>
<view class="task_panel">
<block v-for="(item,index) in assessData" :key="index">
<view class="task_item">
<view class="plan">{{ item.num }}</view>
<view class="">{{ item.name }}</view>
</view>
</block>
</view>
<view class="backlog">
<view class="">待办事项</view>
<block v-for="(item,index) in ApproveList.slice(0,2)" :key="index">
<view class="backlog_item flex_a_c_j_sb" @click="backlogDetails">
<view class="text">{{ item.content }}</view>
<i class="iconfont icon-you"></i>
</view>
</block>
</view>
</view>
<view class="fast_track">
<block v-for="(item,index) in oaHomeData" :key="index">
<view class="track_item" @click="navTo(item.url)">
<u--image :showLoading="true" :src="item.icon" width="77.19rpx" height="77.19rpx"></u--image>
<view class="title">{{ item.text }}</view>
</view>
</block>
</view>
<view class="my_task">
<view class="head_title flex_a_c_j_sb">
<view class="">我的任务</view>
<view class="flex_a_c" @click="test">更多 <view class="iconfont icon-you"></view>
</view>
</view>
<block v-for="(item,index) in myTaskList" :key="index">
<view class="task_list" @click="naviTaskDetails(item.id)">
<view class="title flex_a_c_j_sb">
<view class="flex_a_c">
<view v-if="item.priority==4" class="tag">{{ item.priority_name }}</view>
<view v-else class="tag1">{{ item.priority_name }}</view>
<view class="text">{{ item.title }}</view>
</view>
<view v-if="item.flow_status==1" class="if_take take1">{{ item.flow_name }}</view>
<view v-else-if="item.flow_status==2" class="if_take take2">{{ item.flow_name }}</view>
<view v-else="item.flow_status==3" class="if_take take3">{{ item.flow_name }}</view>
</view>
<view class="describe">{{ item.content }}</view>
<view class="task_deta flex_a_c_j_sb">
<view class="">任务性质{{ item.is_bug }}</view>
<view class="">计划完成日期{{ item.end_time }}</view>
</view>
</view>
</block>
</view>
<tabbar></tabbar>
</view>
</template>
<script>
import { Toast } from '@/libs/uniApi.js'
import { oaHomeData } from '@/static/server/server.js'
import tabbar from '../components/tabbar'
import { getIndexListAPI, getTaskListAPI, getMyTaskListAPI, getApproveListAPI, getUserIndexAPI } from '@/api/oaApi.js'
export default {
components: {
tabbar
},
data() {
return {
oaHomeData: oaHomeData,
src: 'https://cdn.uviewui.com/uview/album/1.jpg',
assessData: [{
num: '8',
name: '部门计划'
},
{
num: '8',
name: '已完成'
},
{
num: '0',
name: '未完成'
},
{
num: '100%',
name: '完成率'
},
{
num: '10',
name: '岗位任务'
},
{
num: '10',
name: '岗位任务'
},
{
num: '0',
name: '未完成'
},
{
num: '100%',
name: '完成率'
}
],
project: {},
task: {},
page: 1,
myTaskList: [],
flowState: '#47B347', //
priority: '', //
myOaInfo: {
thumb: '',
name: '',
mobile: '',
did_name: '',
label_name: '',
},
ApproveList: []
}
},
onReady() {
uni.setNavigationBarColor({
frontColor: '#ffffff',
backgroundColor: '#3175f9'
})
},
onLoad() {},
onShow() {
this.getUserIndex()
this.getIndexList()
this.getApproveList()
},
computed: {},
methods: {
test(){
wx.chooseMessageFile({
count: 1,//
type: 'all',//,all
//type:'video',//
//type:'image',//
success (res) {
const tempFilePaths = res.tempFiles
console.log(res);
}
})
},
async getApproveList() {
const res = await getApproveListAPI({ status: 1 })
this.ApproveList = res.data
},
async getIndexList() {
const { project, task } = await getIndexListAPI()
console.log(task,'222');
this.assessData[0].num = project.count
this.assessData[1].num = project.count_ok
this.assessData[2].num = project.count_no
this.assessData[3].num = project.count_lv + '%'
this.assessData[4].num = task.count
this.assessData[5].num = task.count_ok
this.assessData[6].num = task.count_no
this.assessData[7].num = task.count_lv + '%'
this.myTaskList = task.list
},
async getMyTask() {
let data = {
page: this.page,
limit: 10
}
const res = getMyTaskListAPI(data)
},
naviTaskDetails(id) {
uni.navigateTo({
url: `/pages/office_app/task_details?id=${id}`
})
},
navTo(url) {
url ?
uni.navigateTo({
url: url
}) : Toast('暂未开放')
},
backlogDetails() {
Toast('点击待办事项')
},
async getUserIndex() {
const res = await getUserIndexAPI()
this.myOaInfo = res
}
},
onPullDownRefresh() {
this.getIndexList()
uni.stopPullDownRefresh()
}
}
</script>
<style lang="scss">
.oa_home {
padding-bottom: 120rpx;
}
.home_header {
position: relative;
padding: 28.07rpx;
height: 607.02rpx;
width: 100%;
background-color: $theme-oa-color;
margin-bottom: 133.33rpx;
.my_info {
.mesg_box {
color: #fff;
margin-left: 31.58rpx;
.duty {
margin-top: 10.53rpx;
}
}
}
.task_panel {
color: #fff;
display: flex;
justify-content: space-between;
flex-wrap: wrap;
align-content: space-between;
text-align: center;
.task_item {
margin-top: 42.11rpx;
.plan {
width: 173.68rpx;
font-size: 38.6rpx;
margin-bottom: 21.05rpx;
}
}
}
.backlog {
position: absolute;
left: 50%;
bottom: -101.75rpx;
transform: translate(-50%);
width: 694.74rpx;
min-height: 221.05rpx;
background: #FFFFFF;
border-radius: 12px;
padding: 28.07rpx;
display: flex;
flex-direction: column;
justify-content: space-between;
&_item {
margin-top: 19.3rpx;
color: #666666;
.text {
&::before {
content: '提醒';
display: inline-block;
color: #FF8C1A;
padding: 2px 8px;
border-radius: 4px;
border: 1px solid #FF8C1A;
margin-right: 14.04rpx;
}
}
}
}
}
.fast_track {
width: 694.74rpx;
height: 361.4rpx;
display: flex;
flex-wrap: wrap;
justify-content: space-between;
align-content: space-between;
margin: 0 auto;
padding: 28.07rpx 38.6rpx;
background-color: #fff;
border-radius: 12px;
.track_item {
width: 154.39rpx;
font-size: 24.56rpx;
display: flex;
flex-direction: column;
align-items: center;
.title {
margin-top: 14.04rpx;
}
}
}
.my_task {
width: 694.74rpx;
margin: 0 auto;
margin-top: 31.58rpx;
background-color: #fff;
border-radius: 12px;
padding: 28.07rpx;
.task_list {
height: 196.49rpx;
border-bottom: 1px solid #CCCCCC;
padding: 21.05rpx 0;
display: flex;
flex-direction: column;
justify-content: space-between;
.title {
.tag {
color: #F24848;
font-size: 24.56rpx;
padding: 0 7.02rpx;
margin-right: 14.04rpx;
background: #FFE4E4;
border-radius: 4px;
}
.tag1 {
color: #3274F9;
font-size: 24.56rpx;
padding: 0 7.02rpx;
margin-right: 14.04rpx;
background: #E4EDFF;
border-radius: 4px;
}
.text {
font-size: 28.07rpx;
width: 403.51rpx;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.if_take {
font-size: 28.07rpx;
text-align: center;
line-height: 49.12rpx;
width: 115.79rpx;
height: 49.12rpx;
border-radius: 100px;
}
.take1 {
color: #47B347;
background: #DFFCDF;
}
.take2 {
color: #3274F9;
background: #E4EDFF;
}
.take3 {
color: #999999;
background: #F5F5F5;
}
}
.describe {
font-size: 24.56rpx;
}
.task_deta {
color: #999;
font-size: 24.56rpx;
}
}
}
</style>

View File

@ -0,0 +1,218 @@
<template>
<view class="">
<view class="my_head">
<!-- <view class="department flex_a_c">
<view class="section">产品技术部</view>
<view class="">直属领导XXX</view>
</view> -->
</view>
<view class="personage">
<view class="my_msg flex_a_c_j_sb">
<view class="flex_a_c">
<u--image :showLoading="true" :src="oaUserInfo.thumb" width="112.28rpx" height="112.28rpx" shape="circle">
</u--image>
<view class="name_work">
<view class="name">
<text>{{ oaUserInfo.did_leader }}</text>
<text>{{ oaUserInfo.mobile }}</text>
</view>
<view class="work">
{{ oaUserInfo.did_name }}({{ oaUserInfo.label_name }})
</view>
</view>
</view>
<view class="compile" @click="alterMyInfo">
<view class="iconfont icon-bianji"></view>
<view class="">编辑</view>
</view>
</view>
<view class="assess">
<view class="ass_cent flex_a_c_j_sb">
<view class="cent_item">
<view class="num">{{ oaUserInfo.achievements_money }}</view>
<view class="name">绩效考核</view>
</view>
<view class="cent_item">
<view class="num">{{ oaUserInfo.department_money }}</view>
<view class="name">部门奖金</view>
</view>
<view class="cent_item">
<view class="num">{{ oaUserInfo.company_money }}</view>
<view class="name">公司奖金</view>
</view>
</view>
</view>
</view>
<view class="other_guide">
<block v-for="(item,i) in myOaData" :key="i">
<view class="other_item flex_a_c_j_sb" @click="naviTo(item.url)">
<view class="flex_a_c">
<view class="iconfont2" :class="item.icon"></view>
<view class="text">{{ item.name }}</view>
</view>
<view class="iconfont icon-you"></view>
</view>
</block>
</view>
<view class="log_out">退出登录</view>
<tabbar></tabbar>
</view>
</template>
<script>
import { getUserIndexAPI } from '@/api/oaApi.js'
import { Toast } from '@/libs/uniApi.js'
import { myOaData } from '@/static/server/server.js'
import tabbar from '../components/tabbar'
export default {
components: {
tabbar
},
data() {
return {
myOaData: myOaData,
src: 'https://cdn.uviewui.com/uview/album/1.jpg',
oaUserInfo: {}
}
},
onReady() {
uni.setNavigationBarColor({
frontColor: '#ffffff',
backgroundColor: '#3175f9'
})
},
onLoad() {
this.getOaUserInfo()
},
onShow() {},
methods: {
async getOaUserInfo() {
const res = await getUserIndexAPI()
console.log(res,'111');
this.oaUserInfo = res
},
naviTo(url) {
url ?
uni.navigateTo({
url: url
}) : Toast('暂未开放')
},
alterMyInfo() {
uni.navigateTo({
url: '/pages/office_app/personal_center'
})
}
},
onPullDownRefresh() {
this.getOaUserInfo()
uni.stopPullDownRefresh()
}
}
</script>
<style lang="scss">
.my_head {
padding: 0 28.07rpx;
height: 154.39rpx;
background-color: $theme-oa-color;
.department {
padding-top: 38.6rpx;
font-size: 31.58rpx;
color: #fff;
.section {
margin-right: 57.89rpx;
}
}
}
.personage {
position: relative;
padding: 42.11rpx 28.07rpx;
border-radius: 12px;
background-color: #fff;
width: 694.74rpx;
margin-left: 50%;
transform: translate(-50%, -43.86rpx);
.name_work {
margin-left: 31.58rpx;
font-size: 28.07rpx;
.work {
margin-top: 14.04rpx;
}
}
.my_msg {
.compile {
display: flex;
flex-direction: column;
align-items: center;
}
}
.assess {
height: 170.18rpx;
}
.ass_cent {
width: 100%;
padding: 31.58rpx 66.67rpx;
position: absolute;
left: 0;
bottom: 0;
height: 170.18rpx;
border-radius: 12px;
background-color: $theme-oa-color;
.cent_item {
font-size: 24.56rpx;
color: #fff;
text-align: center;
.num {
font-size: 38.6rpx;
margin-bottom: 21.05rpx;
}
}
}
}
.other_guide {
width: 694.74rpx;
margin: 0 auto;
padding: 28.07rpx;
background-color: #fff;
border-radius: 12px;
.other_item {
height: 87.72rpx;
border-bottom: 1px solid #F0F5F7;
.text {
font-size: 28.07rpx;
margin-left: 24.56rpx;
}
.iconfont2 {
font-size: 42.11rpx;
}
}
}
.log_out {
color: #fff;
border-radius: 100px;
text-align: center;
line-height: 84.21rpx;
margin: 0 auto;
margin-top: 84.21rpx;
width: 614.04rpx;
height: 84.21rpx;
background: #3274F9;
box-shadow: 0px 9px 26px 1px #E9EFF5;
}
</style>

View File

@ -0,0 +1,605 @@
<template>
<!-- 新建任务 -->
<view>
<view class="task_box">
<!-- 主题 -->
<!-- 信息填写表单 -->
<view class="u-page">
<view class="u-demo-block">
<view class="u-demo-block__content">
<u--form labelPosition="left" :model="model1" ref="form1">
<u-form-item label="任务主题:" prop="userInfo.title" borderBottom ref="item">
<u--input v-model="model1.userInfo.title" border="none" placeholder="请输入"></u--input>
</u-form-item>
<u-cell-group>
<view class="cell" v-for="(item, index) in list" :key="index">
<u-cell @click="showPicker(index)" :title="item.title" isLink :value="item.value"
:label="item.value?'':'请选择'">
</u-cell>
</view>
</u-cell-group>
<!-- 指派给 -->
<u-picker :show="flag1" :columns="columns3" ref="uPicker4" @cancel="cancel" closeOnClickOverlay
@close="flag1 = false" @confirm="confirm" @change="changeHandler1" keyName="name" :defaultIndex=[0,0]>
</u-picker>
<!-- 协作人 -->
<u-picker :show="flag2" :columns="columns3" ref="uPicker5" @cancel="cancel" @close="flag2 = false"
@confirm="confirm" @change="changeHandler2" keyName="name" closeOnClickOverlay :defaultIndex=[0,0]>
</u-picker>
<!-- 验收人 -->
<u-picker :show="flag3" :columns="columns3" ref="uPicker6" @cancel="cancel" @close="flag3 = false"
@confirm="confirm" @change="changeHandler3" keyName="name" closeOnClickOverlay :defaultIndex=[0,0]>
</u-picker>
<!-- 任务性质 -->
<u-form-item label="任务性质:" prop="userInfo.isbug" borderBottom @click="show3 = true; hideKeyboard()"
ref="item3">
<u--input v-model="model1.userInfo.isbug" disabled disabledColor="#ffffff" placeholder="请选择"
border="none"></u--input>
</u-form-item>
<!-- 开始时间 -->
<u-form-item label="任务开始时间:" prop="userInfo.start_time" borderBottom
@click="starttime = true; hideKeyboard()" ref="item8">
<u--input v-model="model1.userInfo.start_time" disabled disabledColor="#ffffff" placeholder="请选择"
border="none"></u--input>
</u-form-item>
<!-- 预计结束日期 -->
<u-form-item label="预计结束日期:" prop="userInfo.end_time" borderBottom @click="endtime = true; hideKeyboard()"
ref="item4">
<u--input v-model="model1.userInfo.end_time" disabled disabledColor="#ffffff" placeholder="请选择"
border="none"></u--input>
</u-form-item>
<!-- 月份 -->
<u-form-item label="月份:" prop="userInfo.demo1" borderBottom @click="endmonth = true; hideKeyboard()"
ref="item5">
<u--input v-model="model1.userInfo.demo1" disabled disabledColor="#ffffff" placeholder="请选择"
border="none"></u--input>
</u-form-item>
<!-- 关联项目 -->
<u-form-item label="关联项目:" prop="userInfo.project" borderBottom @click="show4 = true; hideKeyboard()"
ref="item6">
<u--input v-model="model1.userInfo.project" disabled disabledColor="#ffffff" placeholder="请选择"
border="none"></u--input>
</u-form-item>
<!-- 优先级 -->
<u-form-item label="优先级:" prop="userInfo.priority_status" borderBottom
@click="show5 = true; hideKeyboard()" ref="item7">
<u--input v-model="model1.userInfo.priority_status" disabled disabledColor="#ffffff" placeholder="请选择"
border="none"></u--input>
</u-form-item>
<view class="gray"></view>
<!-- 详细描述 -->
<view class="elaborate_box">
<view class="elaborate">详细描述:</view>
<u-form-item prop="userInfo.docContent_markdown_doc" ref="item8">
<u--textarea v-model="model1.userInfo.docContent_markdown_doc" count autoHeight maxlength='200'></u--textarea>
</u-form-item>
</view>
</u--form>
</u-action-sheet>
<!-- 任务性质 -->
<u-action-sheet :show="show3" :actions="actions3" title="请选择任务性质" @close="show3 = false" @select="Select3">
</u-action-sheet>
<!-- 关联项目 -->
<u-action-sheet :show="show4" :actions="actions4" title="请选择关联项目" @close="show4 = false" @select="Select4">
</u-action-sheet>
<!-- 优先级 -->
<u-action-sheet :show="show5" :actions="actions5" title="请选择优先级" @close="show5 = false" @select="Select5">
</u-action-sheet>
<!-- 开始时间 -->
<u-datetime-picker :show="starttime" :value="start_time" mode="datetime" closeOnClickOverlay
@confirm="start_timeConfirm" @cancel="start_timeClose" @close="start_timeClose"></u-datetime-picker>
<!-- 结束日期 -->
<u-datetime-picker :show="endtime" :value="end_time" mode="datetime" closeOnClickOverlay
@confirm="end_timeConfirm" @cancel="end_timeClose" @close="end_timeClose"></u-datetime-picker>
<!-- 结束月份 -->
<u-datetime-picker :show="endmonth" :value="demo1" mode="date" closeOnClickOverlay
@confirm="end_monthConfirm" @cancel="end_monthClose" @close="end_monthClose"></u-datetime-picker>
</view>
</view>
</view>
<!-- 信息填写表单 end-->
<!-- 提交按钮 -->
<view class="btn_box">
<u-button type="error" class="btn reset" text="重置" @click="reset"></u-button>
<u-button type="primary" class="btn sub" text="立即提交" @click="submit"></u-button>
</view>
</view>
</view>
</template>
<script>
import {
addNewTaskApi,
getDepartmentApi,
getDepartmentPersonApi
} from '@/api/oa.js'
import { Toast } from '../../../libs/uniApi'
import {
data
} from '../../../uni_modules/uview-ui/libs/mixin/mixin'
export default {
data() {
return {
index: 0,
loading: false,
columnData: [
],
columns3: [],
model1: {
userInfo: {
title: '', //
director_name: '', //
assist_admin_names: '', //
isbug: '', //
start_time: '', //
end_time: '', //
demo1: '', //
project: '', //
priority_status: '', //
assist_check_names: '', //
docContent_markdown_doc: '', //
},
},
flag1: false, //
flag2: false, //
flag3: false, //
show3: false, //
show4: false, //
show5: false, //
list: [{
title: '指派给:',
value: '',
},
{
title: '协作人:',
value: ''
},
{
title: '验收人:',
value: ''
},
],
starttime: false, //
endtime: false, //
endmonth: false, //
start_time: Number(new Date()), //
end_time: Number(new Date()),
demo1: Number(new Date()),
actions3: [{
name: '部门工作',
index: '0'
}, {
name: '部门协助',
index: '1'
}, ],
actions4: [{
name: '项目1',
id: '78'
}, ],
actions5: [{
name: '一般',
id: '1',
}, {
name: '紧急',
id: '4'
}],
rules: {
},
}
},
onLoad() {
this.getDepartment()
},
onShow() {},
methods: {
groupChange(n) {
// console.log('groupChange', n);
},
navigateBack() {
uni.navigateBack()
},
Select3(e) {
this.model1.userInfo.isbug = e.name
this.model1.userInfo.is_bug = e.index //id
this.$refs.form1.validateField('userInfo.is_bug')
},
Select4(e) {
this.model1.userInfo.project = e.name
this.model1.userInfo.project_id = e.id //id
this.$refs.form1.validateField('userInfo.project')
},
Select5(e) {
this.model1.userInfo.priority_status = e.name
this.model1.userInfo.priority = e.id //id
this.$refs.form1.validateField('userInfo.priority')
},
change(e) {
// console.log(e);
},
//
start_timeClose() {
this.starttime = false
this.$refs.form1.validateField('userInfo.start_time')
},
start_timeConfirm(e) {
this.starttime = false
this.model1.userInfo.start_time = uni.$u.timeFormat(e.value, 'yyyy-mm-dd')
this.$refs.form1.validateField('userInfo.start_time')
},
//
end_timeClose() {
this.endtime = false
this.$refs.form1.validateField('userInfo.end_time')
},
end_timeConfirm(e) {
this.endtime = false
this.model1.userInfo.end_time = uni.$u.timeFormat(e.value, 'yyyy-mm-dd hh:MM:ss')
this.$refs.form1.validateField('userInfo.end_time')
},
//
end_monthClose() {
this.endmonth = false
this.$refs.form1.validateField('userInfo.demo1')
},
end_monthConfirm(e) {
this.endmonth = false
this.model1.userInfo.demo1 = uni.$u.timeFormat(e.value, 'yyyy-mm')
this.$refs.form1.validateField('userInfo.demo1')
},
//
async addNewTask(data) {
const res = await addNewTaskApi(data)
Toast('slkdff')
},
//
async getDepartment() {
const res = await getDepartmentApi()
const deArr = res[0].children
this.columns3.push(deArr)
let id = deArr[0].id
this.getDepartmentPerson(id)
},
//
async getDepartmentPerson(id) {
const data = {
did: id
}
const res = await getDepartmentPersonApi(data)
const nameArr = []
res.forEach(item => {
let obj = {}
obj.name = item.name
obj.id = item.id
nameArr.push(obj)
})
this.columnData = []
this.columnData = nameArr
// this.columnData = res
if (this.columns3[1]) {
return
} else {
this.columns3.push(nameArr)
// this.columns3.push(res)
}
},
async submit() {
//
var d1 = new Date( this.model1.userInfo.start_time)
const date1 =d1.getTime()
var d2 = new Date( this.model1.userInfo.end_time)
const date2 =d2.getTime()
if(date1>date2){
Toast('结束时间不低于开始时间')
this.model1.userInfo.end_time = ''
return
}
this.model1.userInfo.director_name = this.list[0].value
this.model1.userInfo.assist_admin_names = this.list[1].value
this.model1.userInfo.assist_check_names = this.list[2].value
let userInfo = this.model1.userInfo
const arr = Object.values(userInfo)
const bool = arr.every(item => item)
if (bool) {
this.model1.userInfo.director_uid = this.list[0].id+''
this.model1.userInfo.assist_admin_ids = this.list[1].id+''
this.model1.userInfo.assist_check_ids = this.list[2].id+''
this.model1.userInfo.ueditorcontent = this.model1.userInfo.docContent_markdown_doc
// const { msg } = await this.addNewTask(this.model1.userInfo)
console.log(this.model1.userInfo);
const res = await addNewTaskApi(this.model1.userInfo)
if(res.code==0){
uni.$u.toast('验收时间不能大于本月月底18点')
return
}else{
//
uni.showToast({
title: '已提交',
});
setTimeout(function() {
uni.navigateBack({
delta: 1
});
}, 1000)
}
} else {
uni.$u.toast('请填写所有信息')
return
}
},
reset() {
this.list.forEach(item => {
item.value = ''
})
for (let i in this.model1.userInfo) {
this.model1.userInfo[i] = ''
}
},
hideKeyboard() {
uni.hideKeyboard()
},
//picker
showPicker(index) {
console.log(index);
this.index = index + 1
this[`show${index + 1}`] = true
},
//
changeHandler1(e) {
this.change(e)
const {
columnIndex,
value,
values,
index,
// pickerref
picker = this.$refs.uPicker4
} = e
let id = e.value[0].id
if (columnIndex === 0) {
this.getDepartmentPerson(id)
this.loading = true
uni.$u.sleep(500).then(() => {
picker.setColumnValues(1, this.columnData)
this.loading = false
})
}
},
changeHandler2(e) {
this.change(e)
const {
columnIndex,
value,
values,
index,
// pickerref
picker = this.$refs.uPicker5
} = e
let id = e.value[0].id
if (columnIndex === 0) {
this.getDepartmentPerson(id)
this.loading = true
uni.$u.sleep(500).then(() => {
picker.setColumnValues(1, this.columnData)
this.loading = false
})
}
},
changeHandler3(e) {
this.change(e)
const {
columnIndex,
value,
values,
index,
// pickerref
picker = this.$refs.uPicker6
} = e
let id = e.value[0].id
if (columnIndex === 0) {
this.getDepartmentPerson(id)
this.loading = true
uni.$u.sleep(500).then(() => {
picker.setColumnValues(1, this.columnData)
this.loading = false
})
}
},
change(e) {
// console.log('change', e);
},
showPicker(index) {
this.index = index + 1
this[`flag${index + 1}`] = true
},
close() {
// console.log('close');
this[`flag${this.index}`] = false
},
confirm(e) {
const num = this.index - 1
const name = e.value[1]
if (name == undefined) {
this.list[num].value = '暂无'
} else {
this.list[num].value = name.name
this.list[num].id = name.id
}
this[`flag${this.index}`] = false
},
cancel() {
// console.log('cancel');
this[`flag${this.index}`] = false
},
},
onReady() {
// setRules
this.$refs.form1.setRules(this.rules)
},
}
</script>
<style lang="scss" scoped>
/deep/.u-form {
background-color: #fff;
}
/deep/.uicon-arrow-right {
display: none;
}
/deep/.u-cell__right-icon-wrap {
display: none !important;
}
/deep/.u-form-item {
padding: 0 28rpx;
}
/deep/.u-form-item__body__left {
width: 220rpx !important;
// background-color: pink;
}
/deep/.input-placeholder,
/deep/.u-input__content,
/deep/.uni-input-wrapper {
font-size: 28rpx !important;
}
/deep/.u-textarea {
padding: 0 !important;
}
/deep/.u-form-item__body__right__message {
margin-left: 220rpx !important;
}
/deep/.u-cell__title {
display: inline-block !important;
flex: none;
}
/deep/.u-cell__body {
padding: 21rpx 0 !important;
}
/deep/.u-line:first-child {
border-bottom: none !important;
}
/deep/.u-cell__value {
color: black !important;
}
/deep/.u-cell__title-text {
display: inline-block !important;
width: 220rpx !important;
}
/deep/.u-cell__label {
font-size: 28rpx !important;
color: #CCCCCC !important;
}
/deep/.u-cell__body__content {
flex: none !important;
}
.cell {
margin: 0 auto;
width: 694rpx;
// background-color: pink;
}
.row {
margin: 0 auto;
margin-top: 21rpx;
width: 694rpx;
height: 0rpx;
border-bottom: 1rpx solid #CCCCCC;
}
.de {
font-size: 28rpx;
.miaoshu {
font-size: 28rpx;
color: #CCCCCC;
}
}
.ch {
color: rgb(192, 196, 204);
}
.gray {
// width: 750rpx;
height: 35rpx;
background-color: #F5F5F5;
}
.elaborate_box {
background-color: #fff;
padding: 35.5rpx 28rpx;
margin-bottom: 200rpx;
overflow: hidden;
.elaborate {
color: #666666;
font-size: 32rpx;
}
.elaborate_info {
width: 100%;
// height: 350rpx;
font-size: 28rpx;
}
}
.btn_box {
z-index: 9999;
position: fixed;
bottom: 0;
width: 750rpx;
height: 156rpx;
background: #FFFFFF;
display: flex;
.btn {
text-align: center;
line-height: 88rpx;
// width: 375rpx;
height: 88rpx;
}
.reset {
border: none;
background-color: #fff;
color: #999999;
}
.sub {
color: #fff;
background-color: $theme-oa-color;
}
}
</style>

View File

@ -0,0 +1,349 @@
<template>
<view class="all_box">
<!-- 任务搜索框 -->
<view class="task_box">
<u-search shape="round" placeholder="搜索任务状态、优先级、部门等"></u-search>
<!-- 筛选按钮 -->
<view>
<u-popup :show="show" @close="close" @open="open" mode="top" overlayStyle="position: fixed;top:100rpx">
<view class="search_box">
<view class="">
<view class="first_order" v-for="item in orderData" :key="item.id" :class="item.id==typeid?'choose':''">
<text>{{item.first_order}}</text>
</view>
</view>
<view class="second_order">
<view class="second" v-for="item in orderList" :key="item.id" @click="getInfo(item.info,item.id)">
{{item.info}}
</view>
</view>
</view>
</u-popup>
<view @click="show = true" class="screening" :class="show?'choose_style':''">筛选</view>
</view>
</view>
<!-- 新建任务 -->
<view class="new_task" @click="goNewTask">+新建任务</view>
<!-- 事件列表 -->
<view class="eventList_box" v-for="item in eventData" :key="item.id">
<view class="head_box">
<text class="title">{{item.title}}</text>
<text class="status" :class="item.status=='驳回'?'another_color':''">{{item.flow_name}}</text>
</view>
<view class="line"></view>
<view class="responsible">
<text>负责人:{{item.director_name}}</text>
<text class="department">{{item.did_name ? item.did_name :'' }}</text>
</view>
<view class="responsible">
<text>协办人:{{item.assist_admin_names}}</text>
</view>
<view class="responsible">
<text>发布人:{{item.admin_name}}</text>
</view>
<view class="responsible">
<text v-if="item.is_bug==0">任务性质:部门工作</text>
<text v-if="item.is_bug==1">任务性质:部门协助</text>
<text v-if="item.is_bug==2">任务性质:临时任务</text>
</view>
<view class="end_time">预计结束时间:{{item.end_time}}</view>
</view>
<u-loadmore :status="status" :loading-text="loadingText" :loadmore-text="loadmoreText" :nomore-text="nomoreText" />
<tabbar></tabbar>
</view>
</template>
<script>
import {
getTaskListApi
} from '../../../api/oa'
import {
data
} from '../../../uni_modules/uview-ui/libs/mixin/mixin'
import tabbar from '../components/tabbar'
export default {
components: {
tabbar
},
data() {
return {
status: 'loadmore',
params: {
page: '1',
limit: '10',
flow_status: "1",
},
lastpage: '',
loadingText: '努力加载中',
loadmoreText: '轻轻上拉',
nomoreText: '我也是有底线的~~',
orderList: [{
id: 1,
info: '未开始'
}, {
id: 2,
info: '进行中'
}, {
id: 3,
info: '待验收'
}, {
id: 5,
info: '已关闭'
}, {
id: 6,
info: '已验收'
}, ],
orderData: [{
id: 1,
first_order: '任务状态',
}, ],
show: false,
typeid: 1,
eventData: [],
}
},
onReady() {
uni.setNavigationBarColor({
frontColor: '#ffffff',
backgroundColor: '#3175f9'
})
},
onLoad() {
},
onShow() {
this.params.page = '1'
this.eventData = []
//
this.getTaskList(this.params)
},
onPageScroll() {
//
this.close()
},
methods: {
//
async getTaskList(data) {
const res = await getTaskListApi(data)
this.eventData = [...this.eventData, ...res.data]
if (this.eventData.length < this.params.limit) {
this.status = 'nomore'
}
this.lastpage = res.last_page
},
open() {
},
close() {
this.show = false
},
//
getInfo(val, status) {
this.eventData = []
this.params = {
page: '1',
limit: '10',
flow_status: status
}
this.params.flow_status = status + ''
this.getTaskList(this.params)
this.close()
},
//
goNewTask() {
uni.navigateTo({
url: "/pages/office_app/oaTask/new_task"
})
}
},
onPullDownRefresh() {
this.close()
uni.stopPullDownRefresh()
},
onReachBottom() {
if (this.params.page < this.lastpage) {
this.params.page++
this.getTaskList(this.params)
// this.status = 'loading'
} else {
this.status = 'nomore'
return
}
},
}
</script>
<style lang="scss" scoped>
/deep/.u-search__content {
width: 527rpx;
height: 63rpx;
}
/deep/.u-search__action--active {
display: none;
}
/deep/.u-search {
width: 527rpx;
height: 63rpx;
display: flex;
flex: none;
}
/deep/.u-popup__content {
top: 100rpx;
}
.all_box {
padding-bottom: 21rpx;
}
.task_box {
margin: 0 auto;
width: 750rpx;
height: 98rpx;
background: #FFFFFF;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 28rpx;
.screening {
margin-left: 10px;
width: 149rpx;
height: 63rpx;
line-height: 63rpx;
text-align: center;
background: #FFFFFF;
border-radius: 35rpx;
border: 2rpx solid #E6E5E5;
color: #666;
font-size: 28rpx;
}
.choose_style {
background-color: #3274F9;
color: #fff;
}
}
//
.search_box {
width: 750rpx;
// height: 368rpx;
background: #FFFFFF;
display: flex;
.first_order {
width: 250rpx;
height: 73rpx;
text-align: center;
color: #666666;
font-size: 28rpx;
line-height: 73rpx;
background-color: #f5f5f5;
}
.choose {
background-color: #fff;
color: #3274F9;
}
.second_order {
text-align: center;
width: 500rpx;
.second {
line-height: 73rpx;
height: 73rpx;
border-bottom: 2rpx solid #E6E6E6;
}
}
}
//
.new_task {
margin: 0 auto;
margin-top: 21rpx;
width: 500rpx;
height: 66rpx;
line-height: 66rpx;
color: #fff;
text-align: center;
border-radius: 30rpx;
background-color: $theme-oa-color;
}
.eventList_box {
margin: 0 auto;
margin-top: 21rpx;
width: 694rpx;
height: 345rpx;
background: #FFFFFF;
padding: 0 24.5rpx;
border-radius: 7rpx;
.head_box {
width: 100%;
height: 82rpx;
display: flex;
align-items: center;
justify-content: space-between;
.title {
text-overflow: ellipsis;
/* 溢出显示省略号 */
overflow: hidden;
/* 溢出隐藏 */
white-space: nowrap;
/* 强制不换行 */
color: #333333;
width: 445rpx;
font-weight: 500;
font-size: 32rpx;
}
.status {
font-size: 32rpx;
color: #34A853;
}
.another_color {
color: #F9AA32;
}
}
.line {
width: 646rpx;
height: 0rpx;
border-bottom: 1rpx solid #CCCCCC;
margin-bottom: 14.02rpx;
}
.responsible {
width: 100%;
display: flex;
justify-content: space-between;
align-items: center;
height: 39rpx;
font-size: 28rpx;
margin-bottom: 7.01rpx;
.department {
font-size: 25rpx;
color: $theme-oa-color;
}
}
.end_time {
margin-top: 14rpx;
font-size: 25rpx;
color: #999;
}
}
</style>

View File

@ -0,0 +1,181 @@
<template>
<!-- 个人中心-修改个人信息 -->
<view class="all_box">
<!-- 头像 -->
<view class="header_box">
<u--image v-if="changeAvatar!==''" :showLoading="true" :src="changeAvatar" width="182rpx" height="182rpx"
shape="circle">
</u--image>
<u--image v-else :showLoading="true" :src="personInfo.img" width="182rpx" height="182rpx" shape="circle">
</u--image>
<text @click="seleckImage">修改头像</text>
</view>
<!-- 基本信息 -->
<view class="bases_info">
<view class="name">
<text>姓名</text>
<input type="text" value="" class="n_input" v-model="personInfo.name" placeholder="请输入姓名" />
</view>
<view class="name">
<text>昵称</text>
<input type="text" value="" class="n_input" v-model="personInfo.nickname" placeholder="请输入昵称" />
</view>
<view class="name">
<text>电话</text>
<input type="text" value="" class="n_input" v-model="personInfo.mobile" placeholder="请输入电话" />
</view>
</view>
<view class="btn" @click="savePersonInfo">保存</view>
</view>
</template>
<script>
import {
Toast
} from '@/libs/uniApi.js'
import {
getPersonInfoApi
} from '@/api/oa.js'
import {
PostUserPerSubmitAPI
} from '@/api/oaApi.js'
import {
oaUploads,
uploads
} from '@/api/upload.js'
export default {
data() {
return {
fileList5: [],
personInfo: {
thumb: ''
},
changeAvatar: ''
};
},
onShow() {
this.getPersonInfo()
},
methods: {
//
async getPersonInfo() {
const res = await getPersonInfoApi()
this.personInfo = res
this.personInfo.img = res.thumb
console.log('个人信息', this.personInfo.thumb);
},
//
async savePersonInfo() {
// //thump
let str1 = this.personInfo.thumb
let str2 = str1.slice(0, 26)
//
if (str2 == 'http://ceshi-oa.lihaink.cn') {
this.personInfo.thumb = str1.substring(26)
}
console.log('提交', this.personInfo.thumb);
try {
//
const reg_phone = /^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\d{8}$/;
if (!reg_phone.test(this.personInfo.mobile)) {
throw Error()
}
//
const reg_name = /^[\u4e00-\u9fa5]{2,4}$/;
if(!reg_name.test(this.personInfo.name)){
throw Error()
}
const res = await PostUserPerSubmitAPI(this.personInfo)
Toast('修改成功')
} catch (e) {
//TODO handle the exception
Toast('修改失败,请重试')
}
},
seleckImage(i) {
let that = this
uni.chooseImage({
count: 1,
sizeType: ['original', 'compressed'],
sourceType: ['album', 'camera'],
success: function(res) {
oaUploads(res.tempFilePaths[0], 'img').then(res => {
that.personInfo.thumb = res.filepath
that.changeAvatar = res.url + res.filepath
console.log('res', res);
Toast('上传成功')
}).catch(err => {
console.log('err', err);
Toast('上传失败')
})
},
fail: function(err) {
console.log('choose失败');
Toast('添加失败')
}
});
},
}
}
</script>
<style lang="scss" scoped>
/deep/.u-upload__button {
width: 182rpx !important;
height: 182rpx !important;
// background-color: pink;
margin: 0;
}
/deep/.u-upload__wrap__preview__image {
width: 182rpx !important;
height: 182rpx !important;
}
.all_box {
height: 1623rpx;
background-color: #fff;
padding: 0 28rpx;
padding-top: 74rpx;
}
.header_box {
color: $theme-oa-color;
font-size: 28rpx;
display: flex;
flex-direction: column;
align-items: center;
}
.bases_info {
font-size: 32rpx;
.name {
margin-top: 42.11rpx;
}
.n_input {
padding-left: 20rpx;
margin-top: 17.5rpx;
width: 694.74rpx;
height: 94.74rpx;
background: #F3F4F8;
border-radius: 12px;
}
}
.btn {
margin: 0 auto;
border-radius: 100px;
width: 614.04rpx;
height: 84.21rpx;
text-align: center;
line-height: 84.21rpx;
color: #fff;
background: #3274F9;
box-shadow: 0px 9px 26px 1px #E9EFF5;
margin-top: 84.21rpx
}
</style>

View File

@ -0,0 +1,219 @@
<template>
<!-- 个人中心 2 -->
<view>
<!-- 绩效考核 -->
<view class="assessment_box">
<view class="title_box">
<text class="line"></text>
<text>绩效考核</text>
</view>
<view class="detail_box">
<view class="assessment">
<view class="num">{{salaryInfo.cs_salary}}</view>
<view class="tip">绩效考核</view>
</view>
<view class="jian">-</view>
<view class="assessment">
<view class="num">{{salaryInfo.work_deduction_money}}</view>
<view class="tip">延期任务扣除</view>
</view>
<view class="jian">*</view>
<view class="assessment">
<view class="num">{{salaryInfo.rw}}</view>
<view class="tip">任务完成率</view>
</view>
<view class="jian">=</view>
<view class="assessment last_box">
<view class="num last">{{salaryInfo.salary}}</view>
</view>
</view>
<view class="deduction_box">
<text class="deduction_info">扣除详情:</text>
<text></text>
</view>
</view>
<!-- 部门奖金 -->
<view class="assessment_box">
<view class="title_box">
<text class="line"></text>
<text>部门奖金</text>
</view>
<view class="detail_box bonus">
<view class="assessment">
<view class="num1 num">{{salaryInfo.cs_department_money}}</view>
<view class="tip">部门奖金</view>
</view>
<view class="jian">-</view>
<view class="assessment">
<view class="num1 num">{{salaryInfo.project}}</view>
<view class="tip">项目完成率</view>
</view>
<view class="jian">=</view>
<view class="assessment last_box">
<view class="num1 num last">{{salaryInfo.department_money}}</view>
</view>
</view>
<view class="deduction_box">
<text>部门计划完成率必须大于50%</text>
</view>
</view>
<!-- 公司奖金 -->
<view class="com_box">
<view class="company">
<text class="line"></text>
<text>公司奖金</text>
</view>
<view class="company_bonus">
<view class="" class="bonus">{{salaryInfo.company_money}}</view>
<view class="com_tip">公司目标低于百分之百无公司奖金</view>
</view>
</view>
</view>
</template>
<script>
import {
getSalaryDeatilsApi
} from '@/api/oa.js'
export default {
data() {
return {
salaryInfo: {}
};
},
onLoad() {},
onShow() {
this.getSalaryList()
},
methods: {
//
async getSalaryList() {
const res = await getSalaryDeatilsApi()
console.log(res);
this.salaryInfo = res
}
}
}
</script>
<style lang="scss" scoped>
.line {
display: inline-block;
width: 4rpx;
height: 33rpx;
background: #3274F9;
border-radius: 2rpx;
margin-right: 11rpx;
}
.assessment_box {
color: #333333;
font-weight: 500;
font-size: 32rpx;
width: 750rpx;
height: 335rpx;
background: #FFFFFF;
padding: 0 28rpx;
margin-bottom: 28rpx;
.title_box {
width: 100%;
height: 77rpx;
display: flex;
align-items: center;
}
.detail_box {
padding-top: 28rpx;
width: 100%;
.assessment {
display: inline-block;
text-align: center;
.num {
width: 158rpx;
height: 81rpx;
line-height: 81rpx;
background: #F3F4F8;
border-radius: 7rpx;
display: inline-block;
}
.num1 {
width: 212rpx;
}
.tip {
height: 35rpx;
color: #666666;
font-size: 25rpx;
}
}
.jian {
font-weight: 500;
font-size: 32rpx;
display: inline-block;
transform: translateY(-50rpx);
}
.last_box {
color: #3274F9;
display: inline-block;
transform: translateY(-50rpx);
}
}
.deduction_box {
margin-top: 31.54rpx;
font-weight: 500;
font-size: 28rpx;
.deduction_info {
font-size: 32rpx;
}
}
}
.com_box {
width: 750rpx;
height: 280rpx;
.company {
padding: 0 28rpx;
width: 750rpx;
height: 77rpx;
background: #FFFFFF;
display: flex;
align-items: center;
font-size: 32rpx;
}
.company_bonus {
width: 750rpx;
height: 203rpx;
background: #FFFFFF;
padding: 0 28rpx;
padding-top: 28rpx;
.bonus {
width: 694rpx;
height: 81rpx;
line-height: 81rpx;
padding-left: 23rpx;
background: #F3F4F8;
border-radius: 7rpx;
}
.com_tip {
margin-top: 28rpx;
font-size: 28rpx;
}
}
}
</style>

View File

@ -0,0 +1,178 @@
<template>
<!-- 公司公示文档 -->
<view class="all_box">
<view class="nav_box">
<view class="task_box">
<u-search shape="round" placeholder="搜索任务状态、优先级、部门等"></u-search>
<!-- 新建按钮 -->
<view class="newly_built">+新建</view>
</view>
</view>
<!-- 公司公告详情 -->
<view class="notice_box" v-for="item in noticeData" :key="item.id">
<view class="title">{{item.title}}</view>
<view class="row"></view>
<view class="info">{{item.desc}}
</view>
<view class="row"></view>
<view class="notice_bottom">
<view class="n_left">
<text class="chapter">{{item.sections}}</text>
<text>浏览{{item.is_share}}</text>
</view>
<view class="n_right">
<view class="btn btn_1">编辑</view>
<view class="btn">详情</view>
</view>
</view>
</view>
</view>
</template>
<script>
import { getDocumentListApi } from '@/api/oa.js'
export default {
data() {
return {
keyword: '',
noticeData: [{
id: 1,
title:'泸州里海农业科技有限公司内部制度流程管fafasf',
info:'本制度流程管理内容是劳动合同的补充约定,是公司、员工共同就劳资关系在不违反劳动法的基础上作出的意识自制约定;本制度经公司与在职员工全员共同会审通过,并总经理批准,自发布之日起施行。',
total:'35',
nice:'43'
},
{
id: 2,
title:'泸州里海农业科技有限公司内部制度流程管fafasf',
info:'本制度流程管理内容是劳动合同的补充约定,是公司、员工共同就劳资关系在不违反劳动法的基础上作出的意识自制约定;本制度经公司与在职员工全员共同会审通过,并总经理批准,自发布之日起施行。',
total:'35',
nice:'43'
}]
};
},
onLoad() {
},
onShow() {
this.getDocumentList()
},
methods:{
//
async getDocumentList(){
let data={share:1}
const res = await getDocumentListApi(data)
this.noticeData = res
}
}
}
</script>
<style lang="scss" scoped>
/deep/.u-search {
width: 527rpx;
}
/deep/.u-search__action--active {
display: none;
}
.all_box{
padding-bottom: 21rpx;
}
.nav_box {
width: 750rpx;
height: 98rpx;
background: #FFFFFF;
.task_box {
margin: 0 auto;
width: 750rpx;
height: 98rpx;
background: #FFFFFF;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 28rpx;
.newly_built {
width: 149rpx;
height: 63rpx;
background: #34A853;
border-radius: 35rpx;
color: #fff;
text-align: center;
line-height: 63rpx;
margin-left: 17.5rpx;
}
}
}
.notice_box {
margin: 0 auto;
margin-top: 21rpx;
width: 694rpx;
// height: 342rpx;
background: #FFFFFF;
border-radius: 7rpx;
padding: 0 24.5rpx;
padding-bottom: 25rpx;
padding-top: 24.5rpx;
.title {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
width: 624rpx;
height: 44rpx;
font-size: 32rpx;
}
.row {
margin: 14rpx 0;
width: 646rpx;
height: 0rpx;
opacity: 1;
border-bottom: 1rpx solid #CCCCCC;
}
.info {
width: 645rpx;
color: #999999;
font-size: 25rpx;
}
.notice_bottom {
display: flex;
justify-content: space-between;
align-items: center;
.n_left {
color: #999999;
font-size: 25rpx;
.chapter {
margin-right: 60rpx;
}
}
.n_right {
.btn {
display: inline-block;
width: 158rpx;
height: 53rpx;
line-height: 53rpx;
text-align: center;
background: $theme-oa-color;
border-radius: 4rpx;
color: #fff;
}
.btn_1 {
background: #34A853;
margin-right: 14rpx;
}
}
}
}
</style>

View File

@ -0,0 +1,392 @@
<template>
<view class="task_details">
<view class="content_card">
<!-- 头部 -->
<view class="cont_header flex_a_c_j_sb">
<view class="task_name">{{ detail.title }}</view>
<view class="is_matter">{{ detail.priority_name }}</view>
</view>
<!-- 内容 -->
<view class="cont_details">
<text class="">任务人{{ detail.director_name }}</text>
<text class="">协办人{{ detail.assist_admin_names }}</text>
<text class="">发布人{{ detail.admin_name }}</text>
<text class="">工作性质{{ detail.is_bug }}</text>
<text class="">计划完成日期{{ detail.end_time }}</text>
<text class="">任务状态{{ detail.flow_name }}</text>
<text class="">任务验收截止时间{{ detail.initial_end_time }}</text>
<text class="finish_time">初始完成日期{{ detail.end_time }}</text>
<text class="finish_time">实际完成日期{{ detail.over_time }}</text>
</view>
</view>
<view class="content_card">
<!-- 头部 -->
<view class="cont_header flex_a_c">任务描述</view>
<!-- 内容 -->
<view class="cont_details">
{{ detail.content}}
</view>
</view>
<view class="content_card">
<!-- 头部 -->
<view class="cont_header flex_a_c">文件附件</view>
<!-- 内容 -->
<view class="cont_details">
<block v-for="(item, i) in fileArray" :key="i">
<view class="file flex_a_c_j_sb">
<view class="l_file">
<view class="file_name">{{ item.name }}</view>
<view class="file_size">{{ item.filesize | formatBytes }}</view>
<!-- <view class="upload_people">上传人{{ item.admin_name }}</view> -->
</view>
<u-icon @click="delImg(i)" name="close-circle" color="#333333" size="28"></u-icon>
</view>
</block>
<view class="upload_box flex_a_c_j_sb" @click="seleckImage">
<view>
<view class="title">选择文件并上传</view>
<view class="text">
上传前请规范命名最大只能上传100M的文件<br />
超过请压缩成多个文件上传
</view>
</view>
<u-icon name="plus-circle" color="#333333" size="28"></u-icon>
</view>
</view>
</view>
<view class="content_card">
<!-- 头部 -->
<view class="cont_header">
<view class="flex_a_c_j_sb">
<view class="approver">当前审批人张三</view>
<view class="audit_store">审核状态<text>已通过</text> </view>
</view>
<view class="make_copy">抄送人李四</view>
</view>
<!-- 内容 -->
<view class="cont_details">
<view class="examine">审批流程</view>
<view class="flow_path">
<block v-if="flowNodes[0].user_id_info.length>0">
<block v-for="(item, i) in flowNodes[0].user_id_info">
<view class="flex_a_c">
<u-icon name="plus-circle" color="#34A853" size="20"></u-icon>
<view class="name">{{ item.name }}</view>
<view class="status_tag">创建</view>
<u-icon name="arrow-right" color="#999999" size="16"></u-icon>
</view>
</block>
</block>
</view>
<view class="examine">审批记录</view>
<block v-if="flowNodes[0].check_list.length>0">
<block v-for="(item,i) in flowNodes[0].check_list" :key="i">
<view class="record flex">
<view class="circle"></view>
<text class="text">
<text>{{ item.check_time_str }}</text>
<text>{{ item.name }}</text>
2023-03-24 :09:40 张三 提交 了此申请操作意见
<text>{{ item.content }}</text>
</text>
</view>
</block>
</block>
</view>
</view>
<view class="bott_btn flex_a_c">
<view class="icons flex_a_c">
<u-icon name="chat" size="28"></u-icon>
<u-icon name="order" size="28"></u-icon>
</view>
<view class="turn_down">驳回记录{{detail.count_bohui > 0 ? detail.count_bohui:0 }}</view>
</view>
</view>
</template>
<script>
import { Toast } from '@/libs/uniApi.js'
import { oaUploads, uploads } from '@/api/upload'
import { getTaskDetailsAPI } from '@/api/oaApi.js'
export default {
data() {
return {
taskId: '',
attachment: [],
loading: false,
detail: {},
fileArray: [], //
flowNodes: [{
check_list: [],
user_id_info: []
}] //
}
},
onLoad(e) {
this.taskId = e.id
this.getTaskDetails()
},
onShow() {},
methods: {
async getTaskDetails() {
const { detail, file_array, flow_nodes } = await getTaskDetailsAPI({ id: this.taskId })
this.detail = detail
this.fileArray = file_array
flow_nodes.length > 0 ? this.flowNodes = flow_nodes : ''
},
seleckImage(i) {
let that = this
uni.chooseImage({
count: 1,
sizeType: ['original', 'compressed'],
sourceType: ['album', 'camera'],
success: function(res) {
that.loading = true
let objImg = {}
objImg.name = res.tempFiles[0].name
objImg.filesize = res.tempFiles[0].size
objImg.admin_name = '马开明'
oaUploads(res.tempFilePaths[0], 'img').then(res => {
that.fileArray.push(res)
that.loading = false
Toast('上传成功')
}).catch(err => {
Toast('上传失败')
that.loading = false
console.log('上传失败', err)
})
},
fail: function(err) {
Toast('添加失败')
console.log('失败', err)
}
});
},
delImg(i) {
let that = this
uni.showModal({
title: '删除图片',
content: '确定删除图片?',
success: res => {
if (res.confirm) {
that.fileArray.splice(i, 1)
} else if (res.cancel) {
console.log('用户点击取消');
}
}
})
}
},
filters: {
// MB
formatBytes(bytes, decimals = 2) {
if (bytes === 0) return '0 MB';
const k = 1024;
const sizes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
const i = Math.floor(Math.log(bytes) / Math.log(k));
return parseFloat((bytes / Math.pow(k, i)).toFixed(decimals)) + ' ' + sizes[i];
}
},
onPullDownRefresh() {
uni.stopPullDownRefresh()
}
}
</script>
<style lang="scss">
.task_details {
position: relative;
padding: 26.32rpx 0 100rpx 0;
}
.content_card {
width: 695rpx;
margin: 0 auto;
margin-bottom: 24.56rpx;
padding: 0 28.07rpx;
background-color: #fff;
border-radius: 4px;
.cont_header {
padding: 21.05rpx 0;
font-size: 31.58rpx;
min-height: 82.46rpx;
width: 100%;
border-bottom: 1px solid rgba(204, 204, 204, 0.5);
.task_name {
width: 526.32rpx;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.is_matter {
font-size: 24.56rpx;
border-radius: 4px;
padding: 3.51rpx 17.54rpx;
color: $theme-oa-color;
background-color: #E4EDFF;
}
//
.approver {
font-size: 28.07rpx;
}
.audit_store {
font-size: 31.58rpx;
}
.make_copy {
color: #999;
margin-top: 14.04rpx;
font-size: 24.56rpx;
}
}
.cont_details {
padding: 24.56rpx 0;
font-size: 28.07rpx;
//
.finish_time {
font-size: 24.56rpx;
color: #999;
}
text {
display: block;
margin-bottom: 7.02rpx;
}
.upload_box {
padding: 17.54rpx;
background-color: #F7F7F7;
border-radius: 4px;
.title {
font-size: 28.07rpx;
}
.text {
margin-top: 7.02rpx;
font-size: 21.05rpx;
color: #999;
}
}
.file {
padding: 17.54rpx;
border-radius: 4px;
border: 1px solid #F2F2F2;
margin-bottom: 17.54rpx;
.file_size {
margin-top: 7.02rpx;
}
.file_name {
width: 525.7rpx;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.file_size,
.upload_people {
font-size: 21.05rpx;
color: #999;
}
}
//
.examine {
margin-bottom: 17.54rpx;
}
.flow_path {
margin-bottom: 14.04rpx;
.name {
margin: 0 14.04rpx 0 8.77rpx;
}
.status_tag {
color: #999;
margin-right: 8.77rpx;
}
}
.record {
position: relative;
margin-bottom: 14.04rpx;
.circle {
width: 31.58rpx;
height: 31.58rpx;
background-color: #fff;
border: 2px solid #34A853;
border-radius: 50%;
margin: 5px;
display: flex;
flex-direction: column;
align-items: center;
&::before {
content: "";
display: block;
position: absolute;
clear: both;
width: 1px;
height: 100%;
background-color: rgba(204, 204, 204, 0.5);
margin: 31.58rpx;
}
}
.text {
flex: 1;
margin-left: 7.02rpx;
}
}
:last-child {
.circle {
&::before {
display: none;
}
}
}
}
}
.bott_btn {
position: fixed;
left: 0;
bottom: 0;
width: 100%;
height: 87.72rpx;
display: flex;
align-items: center;
.icons {
flex: 1;
justify-content: space-around;
height: 87.72rpx;
background-color: #fff;
}
.turn_down {
width: 421.05rpx;
height: 87.72rpx;
text-align: center;
line-height: 87.72rpx;
background: #3274F9;
color: #fff;
}
}
</style>

BIN
static/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

76
uni.scss Normal file
View File

@ -0,0 +1,76 @@
/**
* 这里是uni-app内置的常用样式变量
*
* uni-app 官方扩展插件及插件市场https://ext.dcloud.net.cn上很多三方插件均使用了这些样式变量
* 如果你是插件开发者建议你使用scss预处理并在插件代码中直接使用这些变量无需 import 这个文件方便用户通过搭积木的方式开发整体风格一致的App
*
*/
/**
* 如果你是App开发者插件使用者你可以通过修改这些变量来定制自己的插件主题实现自定义主题功能
*
* 如果你的项目同样使用了scss预处理你也可以直接在你的 scss 代码中使用如下变量同时无需 import 这个文件
*/
/* 颜色变量 */
/* 行为相关颜色 */
$uni-color-primary: #007aff;
$uni-color-success: #4cd964;
$uni-color-warning: #f0ad4e;
$uni-color-error: #dd524d;
/* 文字基本颜色 */
$uni-text-color:#333;//基本色
$uni-text-color-inverse:#fff;//反色
$uni-text-color-grey:#999;//辅助灰色如加载更多的提示信息
$uni-text-color-placeholder: #808080;
$uni-text-color-disable:#c0c0c0;
/* 背景颜色 */
$uni-bg-color:#ffffff;
$uni-bg-color-grey:#f8f8f8;
$uni-bg-color-hover:#f1f1f1;//点击状态颜色
$uni-bg-color-mask:rgba(0, 0, 0, 0.4);//遮罩颜色
/* 边框颜色 */
$uni-border-color:#c8c7cc;
/* 尺寸变量 */
/* 文字尺寸 */
$uni-font-size-sm:12px;
$uni-font-size-base:14px;
$uni-font-size-lg:16;
/* 图片尺寸 */
$uni-img-size-sm:20px;
$uni-img-size-base:26px;
$uni-img-size-lg:40px;
/* Border Radius */
$uni-border-radius-sm: 2px;
$uni-border-radius-base: 3px;
$uni-border-radius-lg: 6px;
$uni-border-radius-circle: 50%;
/* 水平间距 */
$uni-spacing-row-sm: 5px;
$uni-spacing-row-base: 10px;
$uni-spacing-row-lg: 15px;
/* 垂直间距 */
$uni-spacing-col-sm: 4px;
$uni-spacing-col-base: 8px;
$uni-spacing-col-lg: 12px;
/* 透明度 */
$uni-opacity-disabled: 0.3; // 组件禁用态的透明度
/* 文章场景相关 */
$uni-color-title: #2C405A; // 文章标题颜色
$uni-font-size-title:20px;
$uni-color-subtitle: #555555; // 二级标题颜色
$uni-font-size-subtitle:26px;
$uni-color-paragraph: #3F536E; // 文章段落颜色
$uni-font-size-paragraph:15px;