xy 12 months ago
parent ad890adb34
commit 4586a00a57

@ -0,0 +1 @@
<svg t="1734411841031" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="6269" width="200" height="200"><path d="M326.2 648.6h-0.5C178.9 640.8 64 519.6 64 372.5c0-73.9 28.8-143.3 81-195.5 52.2-52.2 121.7-81 195.5-81 8.9 0 17.8 0.4 26.5 1.3 4.3 0.4 7.8 3.5 8.8 7.7s-0.8 8.5-4.4 10.8C320 148 284.3 198.3 270.8 257.4s-3.2 120 29 171.3c8.8 14 19.2 27.1 30.8 38.9 3.9 3.9 3.8 10.3-0.1 14.1-3.9 3.9-10.3 3.8-14.1-0.1-12.7-12.8-23.9-27.1-33.5-42.3-35.1-55.9-46.3-122.1-31.6-186.4 12.5-54.6 42.4-102.2 85.3-136.8C196.9 118.2 84 232.4 84 372.5c0 136.4 106.6 248.9 242.7 256.1 5.5 0.3 9.7 5 9.5 10.5-0.3 5.4-4.7 9.5-10 9.5zM496.1 257.5c-8.2 0-14.6-8-17.3-11.3-6.7-8.3-14.1-10.5-24.2-7.2-4.7 1.5-17.3 5.7-23.8-2.9-6.6-8.5 0.6-19.6 3.3-23.8 5.8-8.9 5.6-16.7-0.7-25.3-2.9-4-10.7-14.7-4.6-23.6 6.1-8.9 18.9-5.5 23.7-4.2 10.2 2.7 17.6 0.1 23.8-8.5 2.9-4 10.6-14.7 21-11.7 10.3 3 11 16.2 11.3 21.2 0.6 10.6 5.3 16.8 15.4 20.1 4.7 1.5 17.3 5.6 17.6 16.4 0.3 10.8-12 15.5-16.7 17.3-9.9 3.8-14.3 10.3-14.3 20.9 0 5 0 18.2-10.1 21.8-1.6 0.6-3 0.8-4.4 0.8z m-33-40c10.4 0 19.8 4.1 27.7 12.1 1.4-14.6 8.9-25.5 22-32.1-13.4-5.8-21.5-16.4-23.7-30.8-9.7 10.9-22.2 15.4-36.6 13 7.4 12.6 7.8 25.9 1.1 38.9 3.2-0.7 6.4-1.1 9.5-1.1z m58.1-12.8z" p-id="6270"></path><path d="M939.7 831.7h-47.3c-5.5 0-10-4.5-10-10s4.5-10 10-10h47.3v-472h-600V478c0 5.5-4.5 10-10 10s-10-4.5-10-10V339.6c0-11 9-20 20-20h600c11 0 20 9 20 20v472c0 11.1-9 20.1-20 20.1z m-168.7 0H339.7c-11 0-20-9-20-20V641c0-5.5 4.5-10 10-10s10 4.5 10 10v170.7H771c5.5 0 10 4.5 10 10s-4.5 10-10 10z" p-id="6271"></path><path d="M327 563m-16 0a16 16 0 1 0 32 0 16 16 0 1 0-32 0Z" p-id="6272"></path><path d="M833 821m-16 0a16 16 0 1 0 32 0 16 16 0 1 0-32 0Z" p-id="6273"></path><path d="M335 764h612" p-id="6274"></path><path d="M947 774H335c-5.5 0-10-4.5-10-10s4.5-10 10-10h612c5.5 0 10 4.5 10 10s-4.5 10-10 10zM924 928H356c-19.9 0-36-16.1-36-36s16.1-36 36-36h568c19.9 0 36 16.1 36 36s-16.1 36-36 36z m-568-52c-8.8 0-16 7.2-16 16s7.2 16 16 16h568c8.8 0 16-7.2 16-16s-7.2-16-16-16H356zM640.5 716.3c-92.5 0-167.8-75.3-167.8-167.8 0-92.5 75.3-167.8 167.8-167.8S808.3 456 808.3 548.5c0 92.5-75.3 167.8-167.8 167.8z m0-315.6c-81.5 0-147.8 66.3-147.8 147.8 0 81.5 66.3 147.8 147.8 147.8S788.3 630 788.3 548.5c0-81.5-66.3-147.8-147.8-147.8z" p-id="6275"></path><path d="M640.1 561.9l-59-0.1c-5.5 0-10-4.5-10-10s4.5-10 10-10l48.9 0.1V455c0-5.5 4.5-10 10-10s10 4.5 10 10l0.1 96.9c0 2.7-1.1 5.2-2.9 7.1-1.9 1.8-4.5 2.9-7.1 2.9z" p-id="6276"></path><path d="M746.2 632.4c-1.9 0-3.9-0.5-5.6-1.7L638 561.8a9.99 9.99 0 0 1-2.7-13.9c3.1-4.6 9.3-5.8 13.9-2.7l102.6 68.9c4.6 3.1 5.8 9.3 2.7 13.9-1.9 2.8-5.1 4.4-8.3 4.4z" p-id="6277"></path></svg>

After

Width:  |  Height:  |  Size: 2.6 KiB

@ -518,7 +518,6 @@ export default function formBuilder(device, info, h, row, pWrite = false,pReadab
custom_model_id: info.stub
}).then(res => {
this.$set(this.flows, info.name, res.data.data)
console.log(this.flows)
})
}
formItem = h(
@ -648,11 +647,13 @@ export default function formBuilder(device, info, h, row, pWrite = false,pReadab
const $table = this.$refs[`subForm-${info.name}`];
if ($table) {
const record = {};
const { row: newRow } = await $table.insert(
record
);
this.form[info.name].unshift(record)
// 临时数据不好验证长度
// const { row: newRow } = await $table.insert(
// record
// );
await this.$nextTick();
await $table.setEditRow(newRow);
await $table.setEditRow(record);
}
},
},
@ -789,7 +790,6 @@ export default function formBuilder(device, info, h, row, pWrite = false,pReadab
custom_model_id: info.stub
}).then(res => {
this.$set(this.flows, info.name, res.data.data)
console.log(this.flows)
})
}
formItem = h(
@ -901,10 +901,12 @@ export default function formBuilder(device, info, h, row, pWrite = false,pReadab
if (formItem) {
let jointlySignContent = []
let isJointly = false
this.jointlySignLog.forEach(log => {
const data = JSON.parse(log.data)
Object.entries(data).forEach(([key, value]) => {
if (value.hasOwnProperty('custom_field_id') && (value['custom_field_id'] === info.id)) {
isJointly = log.is_jointly_sign
jointlySignContent.push(h('div',[
h('span', value.value),
h('br'),
@ -946,8 +948,8 @@ export default function formBuilder(device, info, h, row, pWrite = false,pReadab
"grid-row-end": info.gs_y + 1 + (info.name === 'flow_title' ? 0 : 1) + info.gs_height,
},
},
[(/\/detail/.test(this.$route.path) && this.$route.query.flow_id && jointlySignContent.length > 0) ? '' : formItem,(() => {
if (info.is_sign && !(/\/detail/.test(this.$route.path) && this.$route.query.flow_id && jointlySignContent.length > 0)) {
isJointly ? [(/\/detail/.test(this.$route.path) && this.$route.query.flow_id && jointlySignContent.length > 0) ? '' : formItem,(() => {
if (info.is_sign && !(/\/detail/.test(this.$route.path && this.$route.query.flow_id && jointlySignContent.length > 0))) {
let log = this.logs.find(log => log.node?.fields?.findIndex(field => field?.field?.name === info.name) !== -1) && (row ? row[info.name] : this.form[info.name])
if (log && log.user) {
return h('div',[
@ -965,11 +967,36 @@ export default function formBuilder(device, info, h, row, pWrite = false,pReadab
src: log.user?.sign_file?.url,
alt: log.user?.name
}
})
}),
h('div', this.$moment(log.updated_at).format('YYYY年MM月DD日 HH时mm分'))
])
}
}
})(),jointlySignContent] : [formItem,(() => {
if (info.is_sign) {
let log = this.logs.find(log => log.node?.fields?.findIndex(field => field?.field?.name === info.name) !== -1 && (row ? row[info.name] : this.form[info.name]))
if (log && log.user) {
return h('div',[
h('el-image',{
style: {
'max-height': '80px',
'max-width': '120px'
},
props: {
src: log.user?.sign_file?.url,
fit: 'contain',
alt: log.user?.name
},
attrs: {
src: log.user?.sign_file?.url,
alt: log.user?.name
}
}),
h('div', this.$moment(log.updated_at).format('YYYY年MM月DD日 HH时mm分'))
])
}
}
})(),jointlySignContent]
})()]
);
}
}
@ -1280,7 +1307,6 @@ export default function formBuilder(device, info, h, row, pWrite = false,pReadab
custom_model_id: info.stub
}).then(res => {
this.$set(this.flows, info.name, res.data.data)
console.log(this.flows)
})
}
formItem = h("van-field", {
@ -1565,7 +1591,6 @@ export default function formBuilder(device, info, h, row, pWrite = false,pReadab
custom_model_id: info.stub
}).then(res => {
this.$set(this.flows, info.name, res.data.data)
console.log(this.flows)
})
}
formItem = h(

@ -0,0 +1,152 @@
<template>
<div>
<card-container>
<vxe-toolbar print custom export>
<template #buttons>
<el-button icon="el-icon-search" type="primary" plain size="small" @click="getList"></el-button>
</template>
</vxe-toolbar>
<vxe-table
ref="table"
stripe
style="margin-top: 10px;"
:loading="loading"
keep-source
show-overflow
:max-height="800"
:export-config="{}"
:print-config="{}"
:column-config="{resizable: true}"
:scroll-y="{enabled: true, gt: 100}"
:data="tableData"
>
<vxe-column type="seq" width="58" align="center" />
<vxe-column
min-width="180"
header-align="center"
field="title"
title="工作名称"
></vxe-column>
<vxe-column
align="center"
width="140"
field="current_node.name"
title="当前节点"
></vxe-column>
<vxe-column
width="200"
align="center"
field="created_at"
title="发起日期"
:formatter="
({ cellValue }) =>
$moment(cellValue).format('YYYY-MM-DD HH:mm:ss')
"
:export-method="
({ row, column, options }) =>
$moment(row['created_at']).format('YYYY-MM-DD HH:mm:ss')
"
></vxe-column>
<vxe-column
width="80"
align="center"
field="status"
title="当前状态"
:formatter="({ cellValue }) => myStatus.get(cellValue)"
:export-method="
({ row, column, options }) => myStatus.get(row['status'])
"
>
<template #default="{ row }">
<el-tag
size="mini"
:type="statusColor.get(row.status)"
effect="dark"
>{{ myStatus.get(row.status) }}</el-tag
>
</template>
</vxe-column>
<vxe-column
min-width="80"
align="center"
field="operate"
title="操作"
fixed="right"
>
<template #default="{ row }">
<el-button plain type="success" size="mini" @click="detail(row)"
>查看</el-button>
</template>
</vxe-column>
</vxe-table>
</card-container>
</div>
</template>
<script>
import { flowList } from "@/api/flow"
export default {
data() {
return {
myStatus: new Map([
[-1, "已退回"],
[0, "办理中"],
[1, "已完成"],
]),
statusColor: new Map([
[-1, "warning"],
[0, ""],
[1, "success"],
]),
loading: false,
tableData: [],
select: {
page: 1,
page_size: 9999,
sort_name: "",
sort_type: "",
keyword: "",
department_id: "",
is_fav: "",
custom_model_id: "69",
date_range: "",
date_type: "create_date",
},
}
},
methods: {
detail(row) {
this.$router.push(
`/flow/detail?module_id=${row.custom_model.id}&flow_id=${row.id}`
);
},
async getList() {
this.loading = true;
try {
const res = await flowList('my', this.select, false);
console.log(res);
this.tableData = res?.data?.data || [];
this.total = res?.data?.total ?? 0;
this.loading = false;
} catch (err) {
console.error(err);
this.loading = false;
}
}
},
computed: {},
created() {
this.getList()
},
mounted() {
this.$nextTick(() => {
if (this.$refs["table"] && this.$refs["toolbar"]) {
this.$refs["table"].connect(this.$refs["toolbar"]);
}
});
},
}
</script>
<style scoped lang="scss">
</style>

@ -5,6 +5,9 @@
<div @click="selectDay = data.day,isShow = true">
<div>{{ data.day.split('-')[2] }}</div>
<div v-if="dayAttendances(data.day) && dayAttendances(data.day).attendance" class="clock-in">
<el-tag v-if="dayAttendances(data.day).attendance.jiaban && dayAttendances(data.day).attendance.jiaban instanceof Array && dayAttendances(data.day).attendance.jiaban.filter(i => i).length > 0" effect="dark" size="mini" type="danger" color="#9f2222">
加班
</el-tag>
<el-tag v-if="dayAttendances(data.day).on_duty_schedules" effect="dark" size="mini" type="danger">
{{ dayAttendances(data.day).on_duty_schedules.status ? '已值班' : '待值班' }}
</el-tag>
@ -66,6 +69,19 @@
</el-descriptions>
</template>
<template v-if="selectDay && dayAttendances(selectDay).attendance.jiaban && dayAttendances(selectDay).attendance.jiaban instanceof Array && dayAttendances(selectDay).attendance.jiaban.filter(i => i).length > 0">
<el-descriptions :column="2" size="mini" border v-for="item in dayAttendances(selectDay).attendance.jiaban.filter(i => i)" :key="item.id">
<template #title>
<el-tag effect="dark" type="danger" color="#9f2222" size="mini">加班</el-tag>
</template>
<el-descriptions-item label="标题">{{ item.title }}</el-descriptions-item>
<el-descriptions-item label="加班时长">{{ item.jiabanshichang }}小时</el-descriptions-item>
<el-descriptions-item label="开始时间">{{ item.kaishiriqi ? $moment(item.kaishiriqi).format('YYYY年MM月DD日 HH时mm分') : '' }}</el-descriptions-item>
<el-descriptions-item label="结束时间">{{ item.jieshushijian ? $moment(item.jieshushijian).format('YYYY年MM月DD日 HH时mm分') : '' }}</el-descriptions-item>
<el-descriptions-item span="2" label="原因说明">{{ item.yuanyinshuoming }}</el-descriptions-item>
</el-descriptions>
</template>
<template v-if="selectDay && dayAttendances(selectDay).attendance.qingxiujia && dayAttendances(selectDay).attendance.qingxiujia instanceof Array && dayAttendances(selectDay).attendance.qingxiujia[0]">
<el-descriptions :column="2" size="mini" border>
<template #title>

@ -1,7 +1,7 @@
<template>
<div>
<card-container>
<vxe-toolbar export print ref="toolbar">
<vxe-toolbar export print custom ref="toolbar">
<template #buttons>
<el-date-picker v-model="select.month" type="month" size="small" value-format="yyyy-MM"></el-date-picker>
<el-button icon="el-icon-search" type="primary" plain size="small" style="margin-left: 6px;" @click="getStatistics"></el-button>
@ -24,40 +24,56 @@
:column-config="{ resizable: true }"
:data="tableData.admins">
<vxe-column type="seq" width="50" align="center" fixed="left"></vxe-column>
<vxe-column field="name" title="姓名" fixed="left" align="center" width="120"></vxe-column>
<vxe-column field="name" title="姓名"
fixed="left"
align="center"
width="120">
</vxe-column>
<vxe-column field="department.name" title="所在部门" align="center" width="150"></vxe-column>
<vxe-colgroup v-for="item in dateTableColumns" align="center" :title="item.title">
<vxe-column title="上午" width="160" align="center">
<template #default="{ row }">
<div v-if="row.attendance[item.date]['qingxiujia'] && row.attendance[item.date]['qingxiujia'][0]">
{{ row.attendance[item.date]['qingxiujia'][0].qingjialeibie }}
</div>
<div v-else-if="row.attendance[item.date]['chuchai'] && row.attendance[item.date]['chuchai'][0]">
出差
</div>
<div>
<div v-if="row.attendance[item.date]['qingxiujia'] && row.attendance[item.date]['qingxiujia'][0]">
{{ row.attendance[item.date]['qingxiujia'][0].qingjialeibie }}
</div>
<div v-else-if="row.attendance[item.date]['chuchai'] && row.attendance[item.date]['chuchai'][0]">
出差
</div>
<div v-else-if="(row.attendance[item.date].hasOwnProperty('0')) && row.attendance[item.date]['0'].sign_in_at">
</div>
<div v-else>
<div v-else-if="(row.attendance[item.date].hasOwnProperty('0')) && row.attendance[item.date]['0'].sign_in_at">
</div>
<div v-else>
</div>
<div v-if="row.attendance[item.date]['jiaban'] instanceof Array && row.attendance[item.date]['jiaban'].filter(i => i) && row.attendance[item.date]['jiaban'].filter(i => i).find(i => i.kaishiriqi && $moment(i.kaishiriqi).isBefore($moment().hours(11).minutes(30)))">
加班
</div>
</div>
</template>
</vxe-column>
<vxe-column title="下午" width="160" align="center">
<template #default="{ row }">
<div v-if="row.attendance[item.date]['qingxiujia'] && row.attendance[item.date]['qingxiujia'][1]">
{{ row.attendance[item.date]['qingxiujia'][1].qingjialeibie }}
</div>
<div v-else-if="row.attendance[item.date]['chuchai'] && row.attendance[item.date]['chuchai'][1]">
出差
</div>
<div>
<div v-if="row.attendance[item.date]['qingxiujia'] && row.attendance[item.date]['qingxiujia'][1]">
{{ row.attendance[item.date]['qingxiujia'][1].qingjialeibie }}
</div>
<div v-else-if="row.attendance[item.date]['chuchai'] && row.attendance[item.date]['chuchai'][1]">
出差
</div>
<div v-else-if="(row.attendance[item.date].hasOwnProperty('0')) && row.attendance[item.date]['0'].sign_out_at">
</div>
<div v-else>
<div v-else-if="(row.attendance[item.date].hasOwnProperty('0')) && row.attendance[item.date]['0'].sign_out_at">
</div>
<div v-else>
</div>
<div v-if="row.attendance[item.date]['jiaban'] instanceof Array && row.attendance[item.date]['jiaban'].filter(i => i) && row.attendance[item.date]['jiaban'].filter(i => i).find(i => i.kaishiriqi && $moment(i.kaishiriqi).isBefore($moment().hours(14)))">
加班
</div>
</div>
</template>
</vxe-column>
@ -111,11 +127,13 @@ export default {
let leave = new Map(this.tableData.leave_types.map(i => [i, 0]))
let signDay = Object.entries(row.attendance).reduce((pre, [key, value]) => {
if (value['qingxiujia'][0]) {
console.log(value['qingxiujia'][0])
leave.set(value['qingxiujia'][0]['qingjialeibie'], Number(leave.get(value['qingxiujia'][0]['qingjialeibie']) ?? 0) + Number(value['qingxiujia'][0]['day'] ?? 0))
leave.set(value['qingxiujia'][0]['qingjialeibie'], Number(leave.get(value['qingxiujia'][0]['qingjialeibie']) ?? 0) + (value['qingxiujia'][0]['qingjialeibie'] === '调休' ? Number(value['qingxiujia'][0]['qingjiashijian'] ?? 0) : Number(value['qingxiujia'][0]['day'] ?? 0)))
}
if (value['qingxiujia'][1]) {
leave.set(value['qingxiujia'][1]['qingjialeibie'], Number(leave.get(value['qingxiujia'][1]['qingjialeibie']) ?? 0) + Number(value['qingxiujia'][1]['day'] ?? 0))
leave.set(value['qingxiujia'][1]['qingjialeibie'], Number(leave.get(value['qingxiujia'][1]['qingjialeibie']) ?? 0) + (value['qingxiujia'][1]['qingjialeibie'] === '调休' ? Number(value['qingxiujia'][1]['qingjiashijian'] ?? 0) : Number(value['qingxiujia'][1]['day'] ?? 0)))
}
if (value['jiaban'] instanceof Array && value['jiaban'].filter(i => i).length > 0) {
overtimeDay += value['jiaban'].filter(i => i).reduce((pre1, cur1) => pre1 + (isNaN(Number(cur1.jiabanshichang)) ? 0 : Number(cur1.jiabanshichang)), 0) ?? 0
}
return pre + (!value.hasOwnProperty('0') ? 0 : (
this.workDates.indexOf(key) !== -1 ? (
@ -125,20 +143,18 @@ export default {
temp += value['0'].sign_out_at ? 0.5 : 0
return temp
})()
) : ((
(() => {
overtimeDay += value['0'].sign_in_at ? 0.5 : 0
overtimeDay += value['0'].sign_out_at ? 0.5 : 0
return 0
})()
)??0)
) : 0
))
}, 0)
result += signDay === this.workDates.length ? '全勤' : `缺勤${this.workDates.length-signDay}`
result += overtimeDay ? `,加班${overtimeDay}` : ''
result += overtimeDay ? `,加班${overtimeDay}` : ''
Array.from(leave).forEach(([name, day]) => {
if (day) {
result += `,${name}${day}`
if (name === '调休') {
result += `,${name}${day}小时`
} else {
result += `,${name}${day}`
}
}
})
return result

@ -72,6 +72,14 @@
{{ data.day.split("-")[2] }}
<template v-if="getTodayAttendance(data.day)">
<div
class="work-overtime"
v-if="
getTodayAttendance(data.day) && getTodayAttendance(data.day).jiaban instanceof Array && getTodayAttendance(data.day).jiaban.filter(i => i).length > 0
"
>
加班
</div>
<div
class="sign-duty"
v-if="
@ -930,6 +938,16 @@ $btn-colors: linear-gradient(90deg, #d4bbfd 0%, #af7bff 100%),
justify-content: flex-end;
position: relative;
}
.work-overtime {
margin-top: 4px;
color: #fff;
font-size: 10px;
border-radius: 3px;
background: #9f2222;
padding: 2px 4px;
margin-left: auto;
text-align: center;
}
.sign-duty {
margin-top: 4px;
color: #fff;
@ -985,6 +1003,7 @@ $btn-colors: linear-gradient(90deg, #d4bbfd 0%, #af7bff 100%),
.sign-status {
display: block !important;
}
.work-overtime,
.sign-in,
.sign-out,
.sign-leave,

@ -433,11 +433,25 @@ export default {
this.rules[field.name] = field.rules.map((rule) => {
switch (rule) {
case "required":
return {
required: true,
message: `请填写${field.label}`,
trigger: "blur",
};
if (field.type === 'relation') {
return {
validator: (myRule, value, callback) => {
if (value instanceof Array && value.length > 0) {
callback()
} else {
callback(`请填写${field.label}`)
}
},
message: `请填写${field.label}`,
trigger: "blur",
};
} else {
return {
required: true,
message: `请填写${field.label}`,
trigger: "blur",
};
}
default:
return {
validator: (myRule, value, callback) => {

Loading…
Cancel
Save