Browse Source

1

yuhongzhe
于宏哲PHP 10 months ago
parent
commit
0ed8684db6
  1. 29
      admin/src/app/api/reimbursement.ts
  2. 31
      admin/src/app/api/salary.ts
  3. 15
      admin/src/app/lang/zh-cn/reimbursement.reimbursement.json
  4. 16
      admin/src/app/lang/zh-cn/salary.salary.json
  5. 16
      admin/src/app/views/campus_person_role/campus_person_role.vue
  6. 2
      admin/src/app/views/course/components/course-edit.vue
  7. 62
      admin/src/app/views/course/course.vue
  8. 141
      admin/src/app/views/reimbursement/components/reimbursement-edit.vue
  9. 193
      admin/src/app/views/reimbursement/reimbursement.vue
  10. 281
      admin/src/app/views/salary/components/salary-edit.vue
  11. 312
      admin/src/app/views/salary/salary.vue
  12. 12
      niucloud/app/adminapi/controller/reimbursement/Reimbursement.php
  13. 32
      niucloud/app/adminapi/controller/salary/Salary.php
  14. 6
      niucloud/app/adminapi/route/reimbursement.php
  15. 8
      niucloud/app/adminapi/route/salary.php
  16. 80
      niucloud/app/model/reimbursement/Reimbursement.php
  17. 138
      niucloud/app/model/salary/Salary.php
  18. 10
      niucloud/app/service/admin/reimbursement/ReimbursementService.php
  19. 20
      niucloud/app/service/admin/salary/SalaryService.php
  20. 6
      niucloud/app/validate/reimbursement/Reimbursement.php
  21. 10
      niucloud/app/validate/salary/Salary.php

29
admin/src/app/api/reimbursement.ts

@ -1,5 +1,13 @@
import request from '@/utils/request'
// USER_CODE_BEGIN -- reimbursement
/**
*
@ -16,7 +24,7 @@ export function getReimbursementList(params: Record<string, any>) {
* @returns
*/
export function getReimbursementInfo(id: number) {
return request.get(`reimbursement/reimbursement/${id}`)
return request.get(`reimbursement/reimbursement/${id}`);
}
/**
@ -25,10 +33,7 @@ export function getReimbursementInfo(id: number) {
* @returns
*/
export function addReimbursement(params: Record<string, any>) {
return request.post('reimbursement/reimbursement', params, {
showErrorMessage: true,
showSuccessMessage: true,
})
return request.post('reimbursement/reimbursement', params, { showErrorMessage: true, showSuccessMessage: true })
}
/**
@ -38,10 +43,7 @@ export function addReimbursement(params: Record<string, any>) {
* @returns
*/
export function editReimbursement(params: Record<string, any>) {
return request.put(`reimbursement/reimbursement/${params.id}`, params, {
showErrorMessage: true,
showSuccessMessage: true,
})
return request.put(`reimbursement/reimbursement/${params.id}`, params, { showErrorMessage: true, showSuccessMessage: true })
}
/**
@ -50,10 +52,11 @@ export function editReimbursement(params: Record<string, any>) {
* @returns
*/
export function deleteReimbursement(id: number) {
return request.delete(`reimbursement/reimbursement/${id}`, {
showErrorMessage: true,
showSuccessMessage: true,
})
return request.delete(`reimbursement/reimbursement/${id}`, { showErrorMessage: true, showSuccessMessage: true })
}
export function getWithPersonnelList(params: Record<string,any>){
return request.get('reimbursement/personnel_all', {params})
}
// USER_CODE_END -- reimbursement

31
admin/src/app/api/salary.ts

@ -1,5 +1,13 @@
import request from '@/utils/request'
// USER_CODE_BEGIN -- salary
/**
*
@ -16,7 +24,7 @@ export function getSalaryList(params: Record<string, any>) {
* @returns
*/
export function getSalaryInfo(id: number) {
return request.get(`salary/salary/${id}`)
return request.get(`salary/salary/${id}`);
}
/**
@ -25,10 +33,7 @@ export function getSalaryInfo(id: number) {
* @returns
*/
export function addSalary(params: Record<string, any>) {
return request.post('salary/salary', params, {
showErrorMessage: true,
showSuccessMessage: true,
})
return request.post('salary/salary', params, { showErrorMessage: true, showSuccessMessage: true })
}
/**
@ -38,10 +43,7 @@ export function addSalary(params: Record<string, any>) {
* @returns
*/
export function editSalary(params: Record<string, any>) {
return request.put(`salary/salary/${params.id}`, params, {
showErrorMessage: true,
showSuccessMessage: true,
})
return request.put(`salary/salary/${params.id}`, params, { showErrorMessage: true, showSuccessMessage: true })
}
/**
@ -50,10 +52,13 @@ export function editSalary(params: Record<string, any>) {
* @returns
*/
export function deleteSalary(id: number) {
return request.delete(`salary/salary/${id}`, {
showErrorMessage: true,
showSuccessMessage: true,
})
return request.delete(`salary/salary/${id}`, { showErrorMessage: true, showSuccessMessage: true })
}
export function getWithPersonnelList(params: Record<string,any>){
return request.get('salary/personnel_all', {params})
}export function getWithDepartmentsList(params: Record<string,any>){
return request.get('salary/departments_all', {params})
}
// USER_CODE_END -- salary

15
admin/src/app/lang/zh-cn/reimbursement.reimbursement.json

@ -1,18 +1,17 @@
{
"id": "报销编号",
"idPlaceholder": "请输入报销编号",
"applicantId": "申请人ID",
"applicantIdPlaceholder": "请输入申请人ID",
"applicantId":"申请人",
"applicantIdPlaceholder":"请输入申请人",
"amount":"报销金额",
"amountPlaceholder":"请输入报销金额",
"description":"报销描述",
"descriptionPlaceholder":"请输入报销描述",
"receiptUrl": "发票或收据URL",
"receiptUrlPlaceholder": "请输入发票或收据URL",
"receiptUrl":"发票或收据",
"receiptUrlPlaceholder":"请输入发票或收据",
"status":"状态",
"statusPlaceholder":"请输入状态",
"processId": "关联的审批流程ID",
"processIdPlaceholder": "请输入关联的审批流程ID",
"createdAt":"创建时间",
"createdAtPlaceholder":"请输入创建时间",
"updatedAt":"修改时间",
"addReimbursement":"添加报销记录",
"updateReimbursement":"编辑报销记录",
"reimbursementDeleteTips":"确定要删除该数据吗?",

16
admin/src/app/lang/zh-cn/salary.salary.json

@ -1,8 +1,8 @@
{
"id": "工资编号",
"idPlaceholder": "请输入工资编号",
"staffId": "员工ID",
"staffIdPlaceholder": "请输入员工ID",
"staffId":"员工",
"staffIdPlaceholder":"全部",
"departmentId":"部门",
"departmentIdPlaceholder":"全部",
"baseSalary":"底薪",
"baseSalaryPlaceholder":"请输入底薪",
"performanceBonus":"绩效",
@ -12,7 +12,6 @@
"otherSubsidies":"其他补贴",
"otherSubsidiesPlaceholder":"请输入其他补贴",
"netSalary":"实发工资",
"netSalaryPlaceholder": "请输入实发工资",
"paymentStatus":"发放状态",
"paymentStatusPlaceholder":"请输入发放状态",
"paymentMethod":"发放方式",
@ -21,10 +20,9 @@
"remarksPlaceholder":"请输入备注",
"salaryMonth":"工资月份",
"salaryMonthPlaceholder":"请输入工资月份",
"departmentId": "部门ID",
"departmentIdPlaceholder": "请输入部门ID",
"processId": "关联的审批流程ID",
"processIdPlaceholder": "请输入关联的审批流程ID",
"createdAt":"创建时间",
"createdAtPlaceholder":"请输入创建时间",
"updatedAt":"修改时间",
"addSalary":"添加工资",
"updateSalary":"编辑工资",
"salaryDeleteTips":"确定要删除该数据吗?",

16
admin/src/app/views/campus_person_role/campus_person_role.vue

@ -65,7 +65,7 @@
</el-select>
</el-form-item>
<el-form-item :label="t('deptId')" prop="dept_id">
<!-- <el-form-item :label="t('deptId')" prop="dept_id">
<el-select
class="w-[280px]"
v-model="campusPersonRoleTable.searchParam.dept_id"
@ -79,7 +79,7 @@
:value="item['id']"
/>
</el-select>
</el-form-item>
</el-form-item> -->
<el-form-item>
<el-button type="primary" @click="loadCampusPersonRoleList()">{{
@ -186,7 +186,6 @@ const route = useRoute()
const pageName = route.meta.title
// ?dept_id=1
const dept_id = pageName == '市场人员列表' ? 1 : 2;
let campusPersonRoleTable = reactive({
page: 1,
limit: 10,
@ -197,10 +196,19 @@ let campusPersonRoleTable = reactive({
campus_id: '',
person_id: '',
role_id: '',
dept_id: dept_id,
dept_id: '',
},
})
if(pageName == '市场人员列表'){
campusPersonRoleTable.searchParam.dept_id = 1;
}else if(pageName == '销售人员列表'){
campusPersonRoleTable.searchParam.dept_id = 2;
}else if(pageName == '教练管理'){
campusPersonRoleTable.searchParam.role_id = 5;
}
const searchFormRef = ref<FormInstance>()
//

2
admin/src/app/views/course/components/course-edit.vue

@ -33,7 +33,7 @@
v-for="(item, index) in courseTypeList"
:key="index"
:label="item.name"
:value="item.value"
:value="item.name"
/>
</el-select>
</el-form-item>

62
admin/src/app/views/course/course.vue

@ -31,56 +31,12 @@
<el-option
v-for="item in courseTypeList"
:key="item.value"
:label="item.label"
:value="item.value"
:label="item.name"
:value="item.name"
/>
</el-select>
</el-form-item>
<el-form-item :label="t('duration')" prop="duration">
<el-input
v-model="courseTable.searchParam.duration"
:placeholder="t('durationPlaceholder')"
/>
</el-form-item>
<el-form-item :label="t('sessionCount')" prop="session_count">
<el-input
v-model="courseTable.searchParam.session_count"
:placeholder="t('sessionCountPlaceholder')"
/>
</el-form-item>
<el-form-item
:label="t('singleSessionCount')"
prop="single_session_count"
>
<el-input
v-model="courseTable.searchParam.single_session_count"
:placeholder="t('singleSessionCountPlaceholder')"
/>
</el-form-item>
<el-form-item :label="t('price')" prop="price">
<el-input
v-model="courseTable.searchParam.price"
:placeholder="t('pricePlaceholder')"
/>
</el-form-item>
<el-form-item :label="t('internalReminder')" prop="internal_reminder">
<el-input
v-model="courseTable.searchParam.internal_reminder"
:placeholder="t('internalReminderPlaceholder')"
/>
</el-form-item>
<el-form-item :label="t('customerReminder')" prop="customer_reminder">
<el-input
v-model="courseTable.searchParam.customer_reminder"
:placeholder="t('customerReminderPlaceholder')"
/>
</el-form-item>
<el-form-item :label="t('remarks')" prop="remarks">
<el-input
v-model="courseTable.searchParam.remarks"
:placeholder="t('remarksPlaceholder')"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="loadCourseList()">{{
@ -227,7 +183,17 @@ let courseTable = reactive({
remarks: '',
},
})
const courseTypeList = useDictionary('course_type')
// const courseTypeList = useDictionary('course_type')
const courseTypeList = ref([])
const getcourseTypeList = async () => {
courseTypeList.value = await (
await useDictionary('course_type')
).data.dictionary
}
getcourseTypeList()
const searchFormRef = ref<FormInstance>()
//

141
admin/src/app/views/reimbursement/components/reimbursement-edit.vue

@ -1,83 +1,50 @@
<template>
<el-dialog
v-model="showDialog"
:title="formData.id ? t('updateReimbursement') : t('addReimbursement')"
width="50%"
class="diy-dialog-wrap"
:destroy-on-close="true"
>
<el-form
:model="formData"
label-width="120px"
ref="formRef"
:rules="formRules"
class="page-form"
v-loading="loading"
>
<el-dialog v-model="showDialog" :title="formData.id ? t('updateReimbursement') : t('addReimbursement')" width="50%" class="diy-dialog-wrap" :destroy-on-close="true">
<el-form :model="formData" label-width="120px" ref="formRef" :rules="formRules" class="page-form" v-loading="loading">
<el-form-item :label="t('applicantId')" prop="applicant_id">
<el-input
v-model="formData.applicant_id"
clearable
:placeholder="t('applicantIdPlaceholder')"
class="input-width"
<el-select class="input-width" v-model="formData.applicant_id" clearable :placeholder="t('applicantIdPlaceholder')">
<el-option label="请选择" value=""></el-option>
<el-option
v-for="(item, index) in applicantIdList"
:key="index"
:label="item['name']"
:value="item['id']"
/>
</el-select>
</el-form-item>
<el-form-item :label="t('amount')" prop="amount">
<el-input
v-model="formData.amount"
clearable
:placeholder="t('amountPlaceholder')"
class="input-width"
/>
<el-input v-model="formData.amount" clearable :placeholder="t('amountPlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('description')" prop="description">
<el-input
v-model="formData.description"
clearable
:placeholder="t('descriptionPlaceholder')"
class="input-width"
/>
<el-input v-model="formData.description" clearable :placeholder="t('descriptionPlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('receiptUrl')">
<el-input
v-model="formData.receipt_url"
clearable
:placeholder="t('receiptUrlPlaceholder')"
class="input-width"
/>
<upload-file v-model="formData.receipt_url" />
</el-form-item>
<el-form-item :label="t('status')" prop="status">
<el-input
v-model="formData.status"
clearable
:placeholder="t('statusPlaceholder')"
class="input-width"
<el-select class="input-width" v-model="formData.status" clearable :placeholder="t('statusPlaceholder')">
<el-option label="请选择" value=""></el-option>
<el-option
v-for="(item, index) in statusList"
:key="index"
:label="item.name"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item :label="t('processId')" prop="process_id">
<el-input
v-model="formData.process_id"
clearable
:placeholder="t('processIdPlaceholder')"
class="input-width"
/>
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="showDialog = false">{{ t('cancel') }}</el-button>
<el-button
type="primary"
:loading="loading"
@click="confirm(formRef)"
>{{ t('confirm') }}</el-button
>
<el-button type="primary" :loading="loading" @click="confirm(formRef)">{{
t('confirm')
}}</el-button>
</span>
</template>
</el-dialog>
@ -88,11 +55,7 @@ import { ref, reactive, computed, watch } from 'vue'
import { useDictionary } from '@/app/api/dict'
import { t } from '@/lang'
import type { FormInstance } from 'element-plus'
import {
addReimbursement,
editReimbursement,
getReimbursementInfo,
} from '@/app/api/reimbursement'
import { addReimbursement, editReimbursement, getReimbursementInfo, getWithPersonnelList } from '@/app/api/reimbursement'
let showDialog = ref(false)
const loading = ref(false)
@ -107,7 +70,6 @@ const initialFormData = {
description: '',
receipt_url: '',
status: '',
process_id: '',
}
const formData: Record<string, any> = reactive({ ...initialFormData })
@ -118,22 +80,29 @@ const formRules = computed(() => {
return {
applicant_id: [
{ required: true, message: t('applicantIdPlaceholder'), trigger: 'blur' },
],
]
,
amount: [
{ required: true, message: t('amountPlaceholder'), trigger: 'blur' },
],
]
,
description: [
{ required: true, message: t('descriptionPlaceholder'), trigger: 'blur' },
],
]
,
receipt_url: [
{ required: true, message: t('receiptUrlPlaceholder'), trigger: 'blur' },
],
]
,
status: [
{ required: true, message: t('statusPlaceholder'), trigger: 'blur' },
],
process_id: [
{ required: true, message: t('processIdPlaceholder'), trigger: 'blur' },
],
]
,
}
})
@ -153,13 +122,11 @@ const confirm = async (formEl: FormInstance | undefined) => {
let data = formData
save(data)
.then((res) => {
save(data).then(res => {
loading.value = false
showDialog.value = false
emit('complete')
})
.catch((err) => {
}).catch(err => {
loading.value = false
})
}
@ -167,14 +134,25 @@ const confirm = async (formEl: FormInstance | undefined) => {
}
//
let statusList = ref([])
const statusDictList = async () => {
statusList.value = await (await useDictionary('sp_status')).data.dictionary
}
statusDictList();
watch(() => statusList.value, () => { formData.status = statusList.value[0].value })
const applicantIdList = ref([] as any[])
const setApplicantIdList = async () => {
applicantIdList.value = await (await getWithPersonnelList({})).data
}
setApplicantIdList()
const setFormData = async (row: any = null) => {
Object.assign(formData, initialFormData)
loading.value = true
if(row){
const data = await (await getReimbursementInfo(row.id)).data
if (data)
Object.keys(formData).forEach((key: string) => {
if (data) Object.keys(formData).forEach((key: string) => {
if (data[key] != undefined) formData[key] = data[key]
})
}
@ -192,12 +170,7 @@ const mobileVerify = (rule: any, value: any, callback: any) => {
//
const idCardVerify = (rule: any, value: any, callback: any) => {
if (
value &&
!/^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}([0-9]|X)$/.test(
value
)
) {
if (value && !/^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}([0-9]|X)$/.test(value)) {
callback(new Error(t('generateIdCard')))
} else {
callback()
@ -224,7 +197,7 @@ const numberVerify = (rule: any, value: any, callback: any) => {
defineExpose({
showDialog,
setFormData,
setFormData
})
</script>

193
admin/src/app/views/reimbursement/reimbursement.vue

@ -1,6 +1,7 @@
<template>
<div class="main-container">
<el-card class="box-card !border-none" shadow="never">
<div class="flex justify-between items-center">
<span class="text-lg">{{pageName}}</span>
<el-button type="primary" @click="addEvent">
@ -8,138 +9,68 @@
</el-button>
</div>
<el-card
class="box-card !border-none my-[10px] table-search-wrap"
shadow="never"
>
<el-form
:inline="true"
:model="reimbursementTable.searchParam"
ref="searchFormRef"
>
<el-form-item :label="t('applicantId')" prop="applicant_id">
<el-input
v-model="reimbursementTable.searchParam.applicant_id"
:placeholder="t('applicantIdPlaceholder')"
/>
</el-form-item>
<el-form-item :label="t('amount')" prop="amount">
<el-input
v-model="reimbursementTable.searchParam.amount"
:placeholder="t('amountPlaceholder')"
/>
</el-form-item>
<el-form-item :label="t('description')" prop="description">
<el-input
v-model="reimbursementTable.searchParam.description"
:placeholder="t('descriptionPlaceholder')"
/>
</el-form-item>
<el-form-item :label="t('receiptUrl')" prop="receipt_url">
<el-input
v-model="reimbursementTable.searchParam.receipt_url"
:placeholder="t('receiptUrlPlaceholder')"
/>
</el-form-item>
<el-card class="box-card !border-none my-[10px] table-search-wrap" shadow="never">
<el-form :inline="true" :model="reimbursementTable.searchParam" ref="searchFormRef">
<el-form-item :label="t('status')" prop="status">
<el-input
v-model="reimbursementTable.searchParam.status"
:placeholder="t('statusPlaceholder')"
<el-select class="w-[280px]" v-model="reimbursementTable.searchParam.status" clearable :placeholder="t('statusPlaceholder')">
<el-option label="全部" value=""></el-option>
<el-option
v-for="(item, index) in statusList"
:key="index"
:label="item.name"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item :label="t('processId')" prop="process_id">
<el-input
v-model="reimbursementTable.searchParam.process_id"
:placeholder="t('processIdPlaceholder')"
/>
<el-form-item :label="t('createdAt')" prop="created_at">
<el-date-picker v-model="reimbursementTable.searchParam.created_at" type="datetimerange" format="YYYY-MM-DD hh:mm:ss"
:start-placeholder="t('startDate')" :end-placeholder="t('endDate')" />
</el-form-item>
<el-form-item>
<el-button type="primary" @click="loadReimbursementList()">{{
t('search')
}}</el-button>
<el-button @click="resetForm(searchFormRef)">{{
t('reset')
}}</el-button>
<el-button type="primary" @click="loadReimbursementList()">{{ t('search') }}</el-button>
<el-button @click="resetForm(searchFormRef)">{{ t('reset') }}</el-button>
</el-form-item>
</el-form>
</el-card>
<div class="mt-[10px]">
<el-table
:data="reimbursementTable.data"
size="large"
v-loading="reimbursementTable.loading"
>
<el-table :data="reimbursementTable.data" size="large" v-loading="reimbursementTable.loading">
<template #empty>
<span>{{ !reimbursementTable.loading ? t('emptyData') : '' }}</span>
</template>
<el-table-column
prop="applicant_id"
:label="t('applicantId')"
min-width="120"
:show-overflow-tooltip="true"
/>
<el-table-column prop="applicant_id_name" :label="t('applicantId')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column
prop="amount"
:label="t('amount')"
min-width="120"
:show-overflow-tooltip="true"
/>
<el-table-column prop="amount" :label="t('amount')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column
prop="description"
:label="t('description')"
min-width="120"
:show-overflow-tooltip="true"
/>
<el-table-column prop="description" :label="t('description')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column
prop="receipt_url"
:label="t('receiptUrl')"
min-width="120"
:show-overflow-tooltip="true"
/>
<el-table-column :label="t('status')" min-width="180" align="center" :show-overflow-tooltip="true">
<template #default="{ row }">
<div v-for="(item, index) in statusList">
<div v-if="item.value == row.status">{{ item.name }}</div>
</div>
</template>
</el-table-column>
<el-table-column
prop="status"
:label="t('status')"
min-width="120"
:show-overflow-tooltip="true"
/>
<el-table-column prop="created_at" :label="t('createdAt')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column
prop="process_id"
:label="t('processId')"
min-width="120"
:show-overflow-tooltip="true"
/>
<el-table-column prop="updated_at" :label="t('updatedAt')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column
:label="t('operation')"
fixed="right"
min-width="120"
>
<el-table-column :label="t('operation')" fixed="right" min-width="120">
<template #default="{ row }">
<el-button type="primary" link @click="editEvent(row)">{{
t('edit')
}}</el-button>
<el-button type="primary" link @click="deleteEvent(row.id)">{{
t('delete')
}}</el-button>
<el-button type="primary" link @click="editEvent(row)">{{ t('edit') }}</el-button>
<el-button type="primary" link @click="deleteEvent(row.id)">{{ t('delete') }}</el-button>
</template>
</el-table-column>
</el-table>
<div class="mt-[16px] flex justify-end">
<el-pagination
v-model:current-page="reimbursementTable.page"
v-model:page-size="reimbursementTable.limit"
layout="total, sizes, prev, pager, next, jumper"
:total="reimbursementTable.total"
@size-change="loadReimbursementList()"
@current-change="loadReimbursementList"
/>
<el-pagination v-model:current-page="reimbursementTable.page" v-model:page-size="reimbursementTable.limit"
layout="total, sizes, prev, pager, next, jumper" :total="reimbursementTable.total"
@size-change="loadReimbursementList()" @current-change="loadReimbursementList" />
</div>
</div>
@ -152,16 +83,13 @@
import { reactive, ref, watch } from 'vue'
import { t } from '@/lang'
import { useDictionary } from '@/app/api/dict'
import {
getReimbursementList,
deleteReimbursement,
} from '@/app/api/reimbursement'
import { getReimbursementList, deleteReimbursement, getWithPersonnelList } from '@/app/api/reimbursement'
import { img } from '@/utils/common'
import { ElMessageBox,FormInstance } from 'element-plus'
import Edit from '@/app/views/reimbursement/components/reimbursement-edit.vue'
import { useRoute } from 'vue-router'
const route = useRoute()
const pageName = route.meta.title
const pageName = route.meta.title;
let reimbursementTable = reactive({
page: 1,
@ -170,13 +98,9 @@ let reimbursementTable = reactive({
loading: true,
data: [],
searchParam:{
applicant_id: '',
amount: '',
description: '',
receipt_url: '',
status: '',
process_id: '',
},
"status":"",
"created_at":[]
}
})
const searchFormRef = ref<FormInstance>()
@ -185,6 +109,11 @@ const searchFormRef = ref<FormInstance>()
const selectData = ref<any[]>([])
//
const statusList = ref([] as any[])
const statusDictList = async () => {
statusList.value = await (await useDictionary('sp_status')).data.dictionary
}
statusDictList();
/**
* 获取报销记录列表
@ -196,14 +125,12 @@ const loadReimbursementList = (page: number = 1) => {
getReimbursementList({
page: reimbursementTable.page,
limit: reimbursementTable.limit,
...reimbursementTable.searchParam,
})
.then((res) => {
...reimbursementTable.searchParam
}).then(res => {
reimbursementTable.loading = false
reimbursementTable.data = res.data.data
reimbursementTable.total = res.data.total
})
.catch(() => {
}).catch(() => {
reimbursementTable.loading = false
})
}
@ -232,19 +159,27 @@ const editEvent = (data: any) => {
* 删除报销记录
*/
const deleteEvent = (id: number) => {
ElMessageBox.confirm(t('reimbursementDeleteTips'), t('warning'), {
ElMessageBox.confirm(t('reimbursementDeleteTips'), t('warning'),
{
confirmButtonText: t('confirm'),
cancelButtonText: t('cancel'),
type: 'warning',
}).then(() => {
deleteReimbursement(id)
.then(() => {
}
).then(() => {
deleteReimbursement(id).then(() => {
loadReimbursementList()
}).catch(() => {
})
.catch(() => {})
})
}
const applicantIdList = ref([])
const setApplicantIdList = async () => {
applicantIdList.value = await (await getWithPersonnelList({})).data
}
setApplicantIdList()
const resetForm = (formEl: FormInstance | undefined) => {
if (!formEl) return
formEl.resetFields()

281
admin/src/app/views/salary/components/salary-edit.vue

@ -1,137 +1,91 @@
<template>
<el-dialog
v-model="showDialog"
:title="formData.id ? t('updateSalary') : t('addSalary')"
width="50%"
class="diy-dialog-wrap"
:destroy-on-close="true"
>
<el-form
:model="formData"
label-width="120px"
ref="formRef"
:rules="formRules"
class="page-form"
v-loading="loading"
>
<el-dialog v-model="showDialog" :title="formData.id ? t('updateSalary') : t('addSalary')" width="50%" class="diy-dialog-wrap" :destroy-on-close="true">
<el-form :model="formData" label-width="120px" ref="formRef" :rules="formRules" class="page-form" v-loading="loading">
<el-form-item :label="t('staffId')" prop="staff_id">
<el-input
v-model="formData.staff_id"
clearable
:placeholder="t('staffIdPlaceholder')"
class="input-width"
<el-select class="input-width" v-model="formData.staff_id" clearable :placeholder="t('staffIdPlaceholder')">
<el-option label="请选择" value=""></el-option>
<el-option
v-for="(item, index) in staffIdList"
:key="index"
:label="item['name']"
:value="item['id']"
/>
</el-select>
</el-form-item>
<el-form-item :label="t('baseSalary')" prop="base_salary">
<el-input
v-model="formData.base_salary"
clearable
:placeholder="t('baseSalaryPlaceholder')"
class="input-width"
<el-form-item :label="t('departmentId')" prop="department_id">
<el-select class="input-width" v-model="formData.department_id" clearable :placeholder="t('departmentIdPlaceholder')">
<el-option label="请选择" value=""></el-option>
<el-option
v-for="(item, index) in departmentIdList"
:key="index"
:label="item['department_name']"
:value="item['id']"
/>
</el-select>
</el-form-item>
<el-form-item :label="t('performanceBonus')" prop="performance_bonus">
<el-input
v-model="formData.performance_bonus"
clearable
:placeholder="t('performanceBonusPlaceholder')"
class="input-width"
/>
<el-form-item :label="t('baseSalary')" prop="base_salary">
<el-input v-model="formData.base_salary" clearable :placeholder="t('baseSalaryPlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('deductions')" prop="deductions">
<el-input
v-model="formData.deductions"
clearable
:placeholder="t('deductionsPlaceholder')"
class="input-width"
/>
<el-form-item :label="t('performanceBonus')" prop="performance_bonus">
<el-input v-model="formData.performance_bonus" clearable :placeholder="t('performanceBonusPlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('otherSubsidies')">
<el-input
v-model="formData.other_subsidies"
clearable
:placeholder="t('otherSubsidiesPlaceholder')"
class="input-width"
/>
<el-form-item :label="t('deductions')" prop="deductions">
<el-input v-model="formData.deductions" clearable :placeholder="t('deductionsPlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('netSalary')">
<el-input
v-model="formData.net_salary"
clearable
:placeholder="t('netSalaryPlaceholder')"
class="input-width"
/>
<el-form-item :label="t('otherSubsidies')" prop="other_subsidies">
<el-input v-model="formData.other_subsidies" clearable :placeholder="t('otherSubsidiesPlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('paymentStatus')" prop="payment_status">
<el-input
v-model="formData.payment_status"
clearable
:placeholder="t('paymentStatusPlaceholder')"
class="input-width"
<el-select class="input-width" v-model="formData.payment_status" clearable :placeholder="t('paymentStatusPlaceholder')">
<el-option label="请选择" value=""></el-option>
<el-option
v-for="(item, index) in payment_statusList"
:key="index"
:label="item.name"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item :label="t('paymentMethod')">
<el-input
v-model="formData.payment_method"
clearable
:placeholder="t('paymentMethodPlaceholder')"
class="input-width"
<el-form-item :label="t('paymentMethod')" prop="payment_method">
<el-select class="input-width" v-model="formData.payment_method" clearable :placeholder="t('paymentMethodPlaceholder')">
<el-option label="请选择" value=""></el-option>
<el-option
v-for="(item, index) in payment_methodList"
:key="index"
:label="item.name"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item :label="t('remarks')" >
<el-input
v-model="formData.remarks"
clearable
:placeholder="t('remarksPlaceholder')"
class="input-width"
/>
<el-input v-model="formData.remarks" type="textarea" rows="4" clearable :placeholder="t('remarksPlaceholder')" class="input-width"/>
</el-form-item>
<el-form-item :label="t('salaryMonth')" prop="salary_month">
<el-input
<el-form-item :label="t('salaryMonth')" prop="salary_month" class="input-width">
<el-date-picker
class="flex-1 !flex"
v-model="formData.salary_month"
clearable
:placeholder="t('salaryMonthPlaceholder')"
class="input-width"
/>
</el-form-item>
<el-form-item :label="t('departmentId')">
<el-input
v-model="formData.department_id"
clearable
:placeholder="t('departmentIdPlaceholder')"
class="input-width"
/>
</el-form-item>
<el-form-item :label="t('processId')">
<el-input
v-model="formData.process_id"
clearable
:placeholder="t('processIdPlaceholder')"
class="input-width"
/>
type="date"
value-format="YYYY-MM-DD"
:placeholder="t('salaryMonthPlaceholder')">
</el-date-picker>
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="showDialog = false">{{ t('cancel') }}</el-button>
<el-button
type="primary"
:loading="loading"
@click="confirm(formRef)"
>{{ t('confirm') }}</el-button
>
<el-button type="primary" :loading="loading" @click="confirm(formRef)">{{
t('confirm')
}}</el-button>
</span>
</template>
</el-dialog>
@ -142,7 +96,7 @@ import { ref, reactive, computed, watch } from 'vue'
import { useDictionary } from '@/app/api/dict'
import { t } from '@/lang'
import type { FormInstance } from 'element-plus'
import { addSalary, editSalary, getSalaryInfo } from '@/app/api/salary'
import { addSalary, editSalary, getSalaryInfo, getWithPersonnelList, getWithDepartmentsList } from '@/app/api/salary'
let showDialog = ref(false)
const loading = ref(false)
@ -153,17 +107,15 @@ const loading = ref(false)
const initialFormData = {
id: '',
staff_id: '',
department_id: '',
base_salary: '',
performance_bonus: '',
deductions: '',
other_subsidies: '',
net_salary: '',
payment_status: '',
payment_method: '',
remarks: '',
salary_month: '',
department_id: '',
process_id: '',
}
const formData: Record<string, any> = reactive({ ...initialFormData })
@ -174,60 +126,54 @@ const formRules = computed(() => {
return {
staff_id: [
{ required: true, message: t('staffIdPlaceholder'), trigger: 'blur' },
],
]
,
department_id: [
{ required: true, message: t('departmentIdPlaceholder'), trigger: 'blur' },
]
,
base_salary: [
{ required: true, message: t('baseSalaryPlaceholder'), trigger: 'blur' },
],
]
,
performance_bonus: [
{
required: true,
message: t('performanceBonusPlaceholder'),
trigger: 'blur',
},
],
{ required: true, message: t('performanceBonusPlaceholder'), trigger: 'blur' },
]
,
deductions: [
{ required: true, message: t('deductionsPlaceholder'), trigger: 'blur' },
],
]
,
other_subsidies: [
{
required: true,
message: t('otherSubsidiesPlaceholder'),
trigger: 'blur',
},
],
net_salary: [
{ required: true, message: t('netSalaryPlaceholder'), trigger: 'blur' },
],
{ required: true, message: t('otherSubsidiesPlaceholder'), trigger: 'blur' },
]
,
payment_status: [
{
required: true,
message: t('paymentStatusPlaceholder'),
trigger: 'blur',
},
],
{ required: true, message: t('paymentStatusPlaceholder'), trigger: 'blur' },
]
,
payment_method: [
{
required: true,
message: t('paymentMethodPlaceholder'),
trigger: 'blur',
},
],
{ required: true, message: t('paymentMethodPlaceholder'), trigger: 'blur' },
]
,
remarks: [
{ required: true, message: t('remarksPlaceholder'), trigger: 'blur' },
],
]
,
salary_month: [
{ required: true, message: t('salaryMonthPlaceholder'), trigger: 'blur' },
],
department_id: [
{
required: true,
message: t('departmentIdPlaceholder'),
trigger: 'blur',
},
],
process_id: [
{ required: true, message: t('processIdPlaceholder'), trigger: 'blur' },
],
]
,
}
})
@ -247,13 +193,11 @@ const confirm = async (formEl: FormInstance | undefined) => {
let data = formData
save(data)
.then((res) => {
save(data).then(res => {
loading.value = false
showDialog.value = false
emit('complete')
})
.catch((err) => {
}).catch(err => {
loading.value = false
})
}
@ -261,14 +205,36 @@ const confirm = async (formEl: FormInstance | undefined) => {
}
//
let payment_statusList = ref([])
const payment_statusDictList = async () => {
payment_statusList.value = await (await useDictionary('payment_status')).data.dictionary
}
payment_statusDictList();
watch(() => payment_statusList.value, () => { formData.payment_status = payment_statusList.value[0].value })
let payment_methodList = ref([])
const payment_methodDictList = async () => {
payment_methodList.value = await (await useDictionary('payment_method')).data.dictionary
}
payment_methodDictList();
watch(() => payment_methodList.value, () => { formData.payment_method = payment_methodList.value[0].value })
const staffIdList = ref([] as any[])
const setStaffIdList = async () => {
staffIdList.value = await (await getWithPersonnelList({})).data
}
setStaffIdList()
const departmentIdList = ref([] as any[])
const setDepartmentIdList = async () => {
departmentIdList.value = await (await getWithDepartmentsList({})).data
}
setDepartmentIdList()
const setFormData = async (row: any = null) => {
Object.assign(formData, initialFormData)
loading.value = true
if(row){
const data = await (await getSalaryInfo(row.id)).data
if (data)
Object.keys(formData).forEach((key: string) => {
if (data) Object.keys(formData).forEach((key: string) => {
if (data[key] != undefined) formData[key] = data[key]
})
}
@ -286,12 +252,7 @@ const mobileVerify = (rule: any, value: any, callback: any) => {
//
const idCardVerify = (rule: any, value: any, callback: any) => {
if (
value &&
!/^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}([0-9]|X)$/.test(
value
)
) {
if (value && !/^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}([0-9]|X)$/.test(value)) {
callback(new Error(t('generateIdCard')))
} else {
callback()
@ -318,7 +279,7 @@ const numberVerify = (rule: any, value: any, callback: any) => {
defineExpose({
showDialog,
setFormData,
setFormData
})
</script>

312
admin/src/app/views/salary/salary.vue

@ -1,6 +1,7 @@
<template>
<div class="main-container">
<el-card class="box-card !border-none" shadow="never">
<div class="flex justify-between items-center">
<span class="text-lg">{{pageName}}</span>
<el-button type="primary" @click="addEvent">
@ -8,216 +9,102 @@
</el-button>
</div>
<el-card
class="box-card !border-none my-[10px] table-search-wrap"
shadow="never"
>
<el-form
:inline="true"
:model="salaryTable.searchParam"
ref="searchFormRef"
>
<el-card class="box-card !border-none my-[10px] table-search-wrap" shadow="never">
<el-form :inline="true" :model="salaryTable.searchParam" ref="searchFormRef">
<el-form-item :label="t('staffId')" prop="staff_id">
<el-input
v-model="salaryTable.searchParam.staff_id"
:placeholder="t('staffIdPlaceholder')"
/>
</el-form-item>
<el-form-item :label="t('baseSalary')" prop="base_salary">
<el-input
v-model="salaryTable.searchParam.base_salary"
:placeholder="t('baseSalaryPlaceholder')"
/>
</el-form-item>
<el-form-item :label="t('performanceBonus')" prop="performance_bonus">
<el-input
v-model="salaryTable.searchParam.performance_bonus"
:placeholder="t('performanceBonusPlaceholder')"
/>
</el-form-item>
<el-form-item :label="t('deductions')" prop="deductions">
<el-input
v-model="salaryTable.searchParam.deductions"
:placeholder="t('deductionsPlaceholder')"
/>
<el-select class="w-[280px]" v-model="salaryTable.searchParam.staff_id" clearable :placeholder="t('staffIdPlaceholder')">
<el-option
v-for="(item, index) in staffIdList"
:key="index"
:label="item['name']"
:value="item['id']"
/>
</el-select>
</el-form-item>
<el-form-item :label="t('otherSubsidies')" prop="other_subsidies">
<el-input
v-model="salaryTable.searchParam.other_subsidies"
:placeholder="t('otherSubsidiesPlaceholder')"
/>
</el-form-item>
<el-form-item :label="t('netSalary')" prop="net_salary">
<el-input
v-model="salaryTable.searchParam.net_salary"
:placeholder="t('netSalaryPlaceholder')"
/>
<el-form-item :label="t('departmentId')" prop="department_id">
<el-select class="w-[280px]" v-model="salaryTable.searchParam.department_id" clearable :placeholder="t('departmentIdPlaceholder')">
<el-option
v-for="(item, index) in departmentIdList"
:key="index"
:label="item['department_name']"
:value="item['id']"
/>
</el-select>
</el-form-item>
<el-form-item :label="t('paymentStatus')" prop="payment_status">
<el-input
v-model="salaryTable.searchParam.payment_status"
:placeholder="t('paymentStatusPlaceholder')"
/>
</el-form-item>
<el-form-item :label="t('paymentMethod')" prop="payment_method">
<el-input
v-model="salaryTable.searchParam.payment_method"
:placeholder="t('paymentMethodPlaceholder')"
/>
</el-form-item>
<el-form-item :label="t('remarks')" prop="remarks">
<el-input
v-model="salaryTable.searchParam.remarks"
:placeholder="t('remarksPlaceholder')"
/>
</el-form-item>
<el-form-item :label="t('salaryMonth')" prop="salary_month">
<el-input
v-model="salaryTable.searchParam.salary_month"
:placeholder="t('salaryMonthPlaceholder')"
/>
</el-form-item>
<el-form-item :label="t('departmentId')" prop="department_id">
<el-input
v-model="salaryTable.searchParam.department_id"
:placeholder="t('departmentIdPlaceholder')"
/>
<el-select class="w-[280px]" v-model="salaryTable.searchParam.payment_status" clearable :placeholder="t('paymentStatusPlaceholder')">
<el-option label="全部" value=""></el-option>
<el-option
v-for="(item, index) in payment_statusList"
:key="index"
:label="item.name"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item :label="t('processId')" prop="process_id">
<el-input
v-model="salaryTable.searchParam.process_id"
:placeholder="t('processIdPlaceholder')"
/>
<el-form-item :label="t('createdAt')" prop="created_at">
<el-date-picker v-model="salaryTable.searchParam.created_at" type="datetimerange" format="YYYY-MM-DD hh:mm:ss"
:start-placeholder="t('startDate')" :end-placeholder="t('endDate')" />
</el-form-item>
<el-form-item>
<el-button type="primary" @click="loadSalaryList()">{{
t('search')
}}</el-button>
<el-button @click="resetForm(searchFormRef)">{{
t('reset')
}}</el-button>
<el-button type="primary" @click="loadSalaryList()">{{ t('search') }}</el-button>
<el-button @click="resetForm(searchFormRef)">{{ t('reset') }}</el-button>
</el-form-item>
</el-form>
</el-card>
<div class="mt-[10px]">
<el-table
:data="salaryTable.data"
size="large"
v-loading="salaryTable.loading"
>
<el-table :data="salaryTable.data" size="large" v-loading="salaryTable.loading">
<template #empty>
<span>{{ !salaryTable.loading ? t('emptyData') : '' }}</span>
</template>
<el-table-column
prop="staff_id"
:label="t('staffId')"
min-width="120"
:show-overflow-tooltip="true"
/>
<el-table-column prop="staff_id_name" :label="t('staffId')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column
prop="base_salary"
:label="t('baseSalary')"
min-width="120"
:show-overflow-tooltip="true"
/>
<el-table-column prop="department_id_name" :label="t('departmentId')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column
prop="performance_bonus"
:label="t('performanceBonus')"
min-width="120"
:show-overflow-tooltip="true"
/>
<el-table-column prop="net_salary" :label="t('netSalary')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column
prop="deductions"
:label="t('deductions')"
min-width="120"
:show-overflow-tooltip="true"
/>
<el-table-column
prop="other_subsidies"
:label="t('otherSubsidies')"
min-width="120"
:show-overflow-tooltip="true"
/>
<el-table-column
prop="net_salary"
:label="t('netSalary')"
min-width="120"
:show-overflow-tooltip="true"
/>
<el-table-column
prop="payment_status"
:label="t('paymentStatus')"
min-width="120"
:show-overflow-tooltip="true"
/>
<el-table-column
prop="payment_method"
:label="t('paymentMethod')"
min-width="120"
:show-overflow-tooltip="true"
/>
<el-table-column :label="t('paymentStatus')" min-width="180" align="center" :show-overflow-tooltip="true">
<template #default="{ row }">
<div v-for="(item, index) in payment_statusList">
<div v-if="item.value == row.payment_status">{{ item.name }}</div>
</div>
</template>
</el-table-column>
<el-table-column
prop="remarks"
:label="t('remarks')"
min-width="120"
:show-overflow-tooltip="true"
/>
<el-table-column :label="t('paymentMethod')" min-width="180" align="center" :show-overflow-tooltip="true">
<template #default="{ row }">
<div v-for="(item, index) in payment_methodList">
<div v-if="item.value == row.payment_method">{{ item.name }}</div>
</div>
</template>
</el-table-column>
<el-table-column
prop="salary_month"
:label="t('salaryMonth')"
min-width="120"
:show-overflow-tooltip="true"
/>
<el-table-column prop="salary_month" :label="t('salaryMonth')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column
prop="department_id"
:label="t('departmentId')"
min-width="120"
:show-overflow-tooltip="true"
/>
<el-table-column prop="created_at" :label="t('createdAt')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column
prop="process_id"
:label="t('processId')"
min-width="120"
:show-overflow-tooltip="true"
/>
<el-table-column prop="updated_at" :label="t('updatedAt')" min-width="120" :show-overflow-tooltip="true"/>
<el-table-column
:label="t('operation')"
fixed="right"
min-width="120"
>
<el-table-column :label="t('operation')" fixed="right" min-width="120">
<template #default="{ row }">
<el-button type="primary" link @click="editEvent(row)">{{
t('edit')
}}</el-button>
<el-button type="primary" link @click="deleteEvent(row.id)">{{
t('delete')
}}</el-button>
<el-button type="primary" link @click="editEvent(row)">{{ t('edit') }}</el-button>
<el-button type="primary" link @click="deleteEvent(row.id)">{{ t('delete') }}</el-button>
</template>
</el-table-column>
</el-table>
<div class="mt-[16px] flex justify-end">
<el-pagination
v-model:current-page="salaryTable.page"
v-model:page-size="salaryTable.limit"
layout="total, sizes, prev, pager, next, jumper"
:total="salaryTable.total"
@size-change="loadSalaryList()"
@current-change="loadSalaryList"
/>
<el-pagination v-model:current-page="salaryTable.page" v-model:page-size="salaryTable.limit"
layout="total, sizes, prev, pager, next, jumper" :total="salaryTable.total"
@size-change="loadSalaryList()" @current-change="loadSalaryList" />
</div>
</div>
@ -230,13 +117,13 @@
import { reactive, ref, watch } from 'vue'
import { t } from '@/lang'
import { useDictionary } from '@/app/api/dict'
import { getSalaryList, deleteSalary } from '@/app/api/salary'
import { getSalaryList, deleteSalary, getWithPersonnelList, getWithDepartmentsList } from '@/app/api/salary'
import { img } from '@/utils/common'
import { ElMessageBox,FormInstance } from 'element-plus'
import Edit from '@/app/views/salary/components/salary-edit.vue'
import { useRoute } from 'vue-router'
const route = useRoute()
const pageName = route.meta.title
const pageName = route.meta.title;
let salaryTable = reactive({
page: 1,
@ -245,19 +132,11 @@ let salaryTable = reactive({
loading: true,
data: [],
searchParam:{
staff_id: '',
base_salary: '',
performance_bonus: '',
deductions: '',
other_subsidies: '',
net_salary: '',
payment_status: '',
payment_method: '',
remarks: '',
salary_month: '',
department_id: '',
process_id: '',
},
"staff_id":"",
"department_id":"",
"payment_status":"",
"created_at":[]
}
})
const searchFormRef = ref<FormInstance>()
@ -266,6 +145,16 @@ const searchFormRef = ref<FormInstance>()
const selectData = ref<any[]>([])
//
const payment_statusList = ref([] as any[])
const payment_statusDictList = async () => {
payment_statusList.value = await (await useDictionary('payment_status')).data.dictionary
}
payment_statusDictList();
const payment_methodList = ref([] as any[])
const payment_methodDictList = async () => {
payment_methodList.value = await (await useDictionary('payment_method')).data.dictionary
}
payment_methodDictList();
/**
* 获取工资列表
@ -277,14 +166,12 @@ const loadSalaryList = (page: number = 1) => {
getSalaryList({
page: salaryTable.page,
limit: salaryTable.limit,
...salaryTable.searchParam,
})
.then((res) => {
...salaryTable.searchParam
}).then(res => {
salaryTable.loading = false
salaryTable.data = res.data.data
salaryTable.total = res.data.total
})
.catch(() => {
}).catch(() => {
salaryTable.loading = false
})
}
@ -313,19 +200,32 @@ const editEvent = (data: any) => {
* 删除工资
*/
const deleteEvent = (id: number) => {
ElMessageBox.confirm(t('salaryDeleteTips'), t('warning'), {
ElMessageBox.confirm(t('salaryDeleteTips'), t('warning'),
{
confirmButtonText: t('confirm'),
cancelButtonText: t('cancel'),
type: 'warning',
}).then(() => {
deleteSalary(id)
.then(() => {
}
).then(() => {
deleteSalary(id).then(() => {
loadSalaryList()
}).catch(() => {
})
.catch(() => {})
})
}
const staffIdList = ref([])
const setStaffIdList = async () => {
staffIdList.value = await (await getWithPersonnelList({})).data
}
setStaffIdList()
const departmentIdList = ref([])
const setDepartmentIdList = async () => {
departmentIdList.value = await (await getWithDepartmentsList({})).data
}
setDepartmentIdList()
const resetForm = (formEl: FormInstance | undefined) => {
if (!formEl) return
formEl.resetFields()

12
niucloud/app/adminapi/controller/reimbursement/Reimbursement.php

@ -28,12 +28,8 @@ class Reimbursement extends BaseAdminController
*/
public function lists(){
$data = $this->request->params([
["applicant_id",""],
["amount",""],
["description",""],
["receipt_url",""],
["status",""],
["process_id",""]
["created_at",["",""]]
]);
return success((new ReimbursementService())->getPage($data));
}
@ -58,7 +54,6 @@ class Reimbursement extends BaseAdminController
["description",""],
["receipt_url",""],
["status",""],
["process_id",0],
]);
$this->validate($data, 'app\validate\reimbursement\Reimbursement.add');
@ -78,7 +73,6 @@ class Reimbursement extends BaseAdminController
["description",""],
["receipt_url",""],
["status",""],
["process_id",0],
]);
$this->validate($data, 'app\validate\reimbursement\Reimbursement.edit');
@ -97,4 +91,8 @@ class Reimbursement extends BaseAdminController
}
public function getPersonnelAll(){
return success(( new ReimbursementService())->getPersonnelAll());
}
}

32
niucloud/app/adminapi/controller/salary/Salary.php

@ -29,17 +29,9 @@ class Salary extends BaseAdminController
public function lists(){
$data = $this->request->params([
["staff_id",""],
["base_salary",""],
["performance_bonus",""],
["deductions",""],
["other_subsidies",""],
["net_salary",""],
["payment_status",""],
["payment_method",""],
["remarks",""],
["salary_month",""],
["department_id",""],
["process_id",""]
["payment_status",""],
["created_at",["",""]]
]);
return success((new SalaryService())->getPage($data));
}
@ -60,17 +52,15 @@ class Salary extends BaseAdminController
public function add(){
$data = $this->request->params([
["staff_id",0],
["department_id",0],
["base_salary",0.00],
["performance_bonus",0.00],
["deductions",0.00],
["other_subsidies",0.00],
["net_salary",0.00],
["payment_status",""],
["payment_method",""],
["remarks",""],
["salary_month","2025-05-16 17:53:32"],
["department_id",0],
["process_id",0],
["salary_month","2025-05-22 18:20:42"],
]);
$this->validate($data, 'app\validate\salary\Salary.add');
@ -86,17 +76,15 @@ class Salary extends BaseAdminController
public function edit(int $id){
$data = $this->request->params([
["staff_id",0],
["department_id",0],
["base_salary",0.00],
["performance_bonus",0.00],
["deductions",0.00],
["other_subsidies",0.00],
["net_salary",0.00],
["payment_status",""],
["payment_method",""],
["remarks",""],
["salary_month","2025-05-16 17:53:32"],
["department_id",0],
["process_id",0],
["salary_month","2025-05-22 18:20:42"],
]);
$this->validate($data, 'app\validate\salary\Salary.edit');
@ -115,4 +103,12 @@ class Salary extends BaseAdminController
}
public function getPersonnelAll(){
return success(( new SalaryService())->getPersonnelAll());
}
public function getDepartmentsAll(){
return success(( new SalaryService())->getDepartmentsAll());
}
}

6
niucloud/app/adminapi/route/reimbursement.php

@ -14,6 +14,10 @@ use think\facade\Route;
use app\adminapi\middleware\AdminCheckRole;
use app\adminapi\middleware\AdminCheckToken;
use app\adminapi\middleware\AdminLog;
// USER_CODE_BEGIN -- reimbursement
Route::group('reimbursement', function () {
@ -29,6 +33,8 @@ Route::group('reimbursement', function () {
//删除报销记录
Route::delete('reimbursement/:id', 'reimbursement.Reimbursement/del');
Route::get('personnel_all','reimbursement.Reimbursement/getPersonnelAll');
})->middleware([
AdminCheckToken::class,
AdminCheckRole::class,

8
niucloud/app/adminapi/route/salary.php

@ -14,6 +14,10 @@ use think\facade\Route;
use app\adminapi\middleware\AdminCheckRole;
use app\adminapi\middleware\AdminCheckToken;
use app\adminapi\middleware\AdminLog;
// USER_CODE_BEGIN -- salary
Route::group('salary', function () {
@ -29,6 +33,10 @@ Route::group('salary', function () {
//删除工资
Route::delete('salary/:id', 'salary.Salary/del');
Route::get('personnel_all','salary.Salary/getPersonnelAll');
Route::get('departments_all','salary.Salary/getDepartmentsAll');
})->middleware([
AdminCheckToken::class,
AdminCheckRole::class,

80
niucloud/app/model/reimbursement/Reimbursement.php

@ -16,6 +16,8 @@ use think\model\concern\SoftDelete;
use think\model\relation\HasMany;
use think\model\relation\HasOne;
use app\model\personnel\Personnel;
/**
* 报销记录模型
* Class Reimbursement
@ -42,66 +44,6 @@ class Reimbursement extends BaseModel
/**
* 搜索器:报销记录报销编号
* @param $value
* @param $data
*/
public function searchIdAttr($query, $value, $data)
{
if ($value) {
$query->where("id", $value);
}
}
/**
* 搜索器:报销记录申请人ID
* @param $value
* @param $data
*/
public function searchApplicantIdAttr($query, $value, $data)
{
if ($value) {
$query->where("applicant_id", $value);
}
}
/**
* 搜索器:报销记录报销金额
* @param $value
* @param $data
*/
public function searchAmountAttr($query, $value, $data)
{
if ($value) {
$query->where("amount", $value);
}
}
/**
* 搜索器:报销记录报销描述
* @param $value
* @param $data
*/
public function searchDescriptionAttr($query, $value, $data)
{
if ($value) {
$query->where("description", $value);
}
}
/**
* 搜索器:报销记录发票或收据URL
* @param $value
* @param $data
*/
public function searchReceiptUrlAttr($query, $value, $data)
{
if ($value) {
$query->where("receipt_url", $value);
}
}
/**
* 搜索器:报销记录状态
* @param $value
@ -115,14 +57,20 @@ class Reimbursement extends BaseModel
}
/**
* 搜索器:报销记录关联的审批流程ID
* 搜索器:报销记录创建时间
* @param $value
* @param $data
*/
public function searchProcessIdAttr($query, $value, $data)
public function searchCreatedAtAttr($query, $value, $data)
{
if ($value) {
$query->where("process_id", $value);
$start = empty($value[0]) ? 0 : strtotime($value[0]);
$end = empty($value[1]) ? 0 : strtotime($value[1]);
if ($start > 0 && $end > 0) {
$query->where([["created_at", "between", [$start, $end]]]);
} else if ($start > 0 && $end == 0) {
$query->where([["created_at", ">=", $start]]);
} else if ($start == 0 && $end > 0) {
$query->where([["created_at", "<=", $end]]);
}
}
@ -131,4 +79,8 @@ class Reimbursement extends BaseModel
public function personnel(){
return $this->hasOne(Personnel::class, 'id', 'applicant_id')->joinType('left')->withField('name,id')->bind(['applicant_id_name'=>'name']);
}
}

138
niucloud/app/model/salary/Salary.php

@ -16,6 +16,10 @@ use think\model\concern\SoftDelete;
use think\model\relation\HasMany;
use think\model\relation\HasOne;
use app\model\personnel\Personnel;
use app\model\departments\Departments;
/**
* 工资模型
* Class Salary
@ -43,19 +47,7 @@ class Salary extends BaseModel
/**
* 搜索器:工资工资编号
* @param $value
* @param $data
*/
public function searchIdAttr($query, $value, $data)
{
if ($value) {
$query->where("id", $value);
}
}
/**
* 搜索器:工资员工ID
* 搜索器:工资员工
* @param $value
* @param $data
*/
@ -67,62 +59,14 @@ class Salary extends BaseModel
}
/**
* 搜索器:工资底薪
* @param $value
* @param $data
*/
public function searchBaseSalaryAttr($query, $value, $data)
{
if ($value) {
$query->where("base_salary", $value);
}
}
/**
* 搜索器:工资绩效
* @param $value
* @param $data
*/
public function searchPerformanceBonusAttr($query, $value, $data)
{
if ($value) {
$query->where("performance_bonus", $value);
}
}
/**
* 搜索器:工资扣款
* @param $value
* @param $data
*/
public function searchDeductionsAttr($query, $value, $data)
{
if ($value) {
$query->where("deductions", $value);
}
}
/**
* 搜索器:工资其他补贴
* @param $value
* @param $data
*/
public function searchOtherSubsidiesAttr($query, $value, $data)
{
if ($value) {
$query->where("other_subsidies", $value);
}
}
/**
* 搜索器:工资实发工资
* 搜索器:工资部门
* @param $value
* @param $data
*/
public function searchNetSalaryAttr($query, $value, $data)
public function searchDepartmentIdAttr($query, $value, $data)
{
if ($value) {
$query->where("net_salary", $value);
$query->where("department_id", $value);
}
}
@ -139,68 +83,34 @@ class Salary extends BaseModel
}
/**
* 搜索器:工资发放方式
* @param $value
* @param $data
*/
public function searchPaymentMethodAttr($query, $value, $data)
{
if ($value) {
$query->where("payment_method", $value);
}
}
/**
* 搜索器:工资备注
* @param $value
* @param $data
*/
public function searchRemarksAttr($query, $value, $data)
{
if ($value) {
$query->where("remarks", $value);
}
}
/**
* 搜索器:工资工资月份
* 搜索器:工资创建时间
* @param $value
* @param $data
*/
public function searchSalaryMonthAttr($query, $value, $data)
public function searchCreatedAtAttr($query, $value, $data)
{
if ($value) {
$query->where("salary_month", $value);
$start = empty($value[0]) ? 0 : strtotime($value[0]);
$end = empty($value[1]) ? 0 : strtotime($value[1]);
if ($start > 0 && $end > 0) {
$query->where([["created_at", "between", [$start, $end]]]);
} else if ($start > 0 && $end == 0) {
$query->where([["created_at", ">=", $start]]);
} else if ($start == 0 && $end > 0) {
$query->where([["created_at", "<=", $end]]);
}
}
/**
* 搜索器:工资部门ID
* @param $value
* @param $data
*/
public function searchDepartmentIdAttr($query, $value, $data)
{
if ($value) {
$query->where("department_id", $value);
}
}
/**
* 搜索器:工资关联的审批流程ID
* @param $value
* @param $data
*/
public function searchProcessIdAttr($query, $value, $data)
{
if ($value) {
$query->where("process_id", $value);
}
}
public function personnel(){
return $this->hasOne(Personnel::class, 'id', 'staff_id')->joinType('left')->withField('name,id')->bind(['staff_id_name'=>'name']);
}
public function departments(){
return $this->hasOne(Departments::class, 'id', 'department_id')->joinType('left')->withField('department_name,id')->bind(['department_id_name'=>'department_name']);
}
}

10
niucloud/app/service/admin/reimbursement/ReimbursementService.php

@ -12,6 +12,7 @@
namespace app\service\admin\reimbursement;
use app\model\reimbursement\Reimbursement;
use app\model\personnel\Personnel;
use core\base\BaseAdminService;
@ -39,7 +40,7 @@ class ReimbursementService extends BaseAdminService
$field = 'id,applicant_id,amount,description,receipt_url,status,process_id,created_at,updated_at';
$order = 'id desc';
$search_model = $this->model->withSearch(["id","applicant_id","amount","description","receipt_url","status","process_id"], $where)->field($field)->order($order);
$search_model = $this->model->withSearch(["status","created_at"], $where)->with(['personnel'])->field($field)->order($order);
$list = $this->pageQuery($search_model);
return $list;
}
@ -53,7 +54,7 @@ class ReimbursementService extends BaseAdminService
{
$field = 'id,applicant_id,amount,description,receipt_url,status,process_id,created_at,updated_at';
$info = $this->model->field($field)->where([['id', "=", $id]])->findOrEmpty()->toArray();
$info = $this->model->field($field)->where([['id', "=", $id]])->with(['personnel'])->findOrEmpty()->toArray();
return $info;
}
@ -95,5 +96,10 @@ class ReimbursementService extends BaseAdminService
}
public function getPersonnelAll(){
$personnelModel = new Personnel();
return $personnelModel->select()->toArray();
}
}

20
niucloud/app/service/admin/salary/SalaryService.php

@ -12,6 +12,8 @@
namespace app\service\admin\salary;
use app\model\salary\Salary;
use app\model\personnel\Personnel;
use app\model\departments\Departments;
use core\base\BaseAdminService;
@ -36,10 +38,10 @@ class SalaryService extends BaseAdminService
*/
public function getPage(array $where = [])
{
$field = 'id,staff_id,base_salary,performance_bonus,deductions,other_subsidies,net_salary,payment_status,payment_method,remarks,salary_month,department_id,process_id,created_at,updated_at';
$field = 'id,staff_id,department_id,base_salary,performance_bonus,deductions,other_subsidies,net_salary,payment_status,payment_method,remarks,salary_month,process_id,created_at,updated_at';
$order = 'id desc';
$search_model = $this->model->withSearch(["id","staff_id","base_salary","performance_bonus","deductions","other_subsidies","net_salary","payment_status","payment_method","remarks","salary_month","department_id","process_id"], $where)->field($field)->order($order);
$search_model = $this->model->withSearch(["staff_id","department_id","payment_status","created_at"], $where)->with(['personnel','departments'])->field($field)->order($order);
$list = $this->pageQuery($search_model);
return $list;
}
@ -51,9 +53,9 @@ class SalaryService extends BaseAdminService
*/
public function getInfo(int $id)
{
$field = 'id,staff_id,base_salary,performance_bonus,deductions,other_subsidies,net_salary,payment_status,payment_method,remarks,salary_month,department_id,process_id,created_at,updated_at';
$field = 'id,staff_id,department_id,base_salary,performance_bonus,deductions,other_subsidies,net_salary,payment_status,payment_method,remarks,salary_month,process_id,created_at,updated_at';
$info = $this->model->field($field)->where([['id', "=", $id]])->findOrEmpty()->toArray();
$info = $this->model->field($field)->where([['id', "=", $id]])->with(['personnel','departments'])->findOrEmpty()->toArray();
return $info;
}
@ -95,5 +97,15 @@ class SalaryService extends BaseAdminService
}
public function getPersonnelAll(){
$personnelModel = new Personnel();
return $personnelModel->select()->toArray();
}
public function getDepartmentsAll(){
$departmentsModel = new Departments();
return $departmentsModel->select()->toArray();
}
}

6
niucloud/app/validate/reimbursement/Reimbursement.php

@ -24,7 +24,6 @@ class Reimbursement extends BaseValidate
'amount' => 'require',
'description' => 'require',
'status' => 'require',
'process_id' => 'require',
];
protected $message = [
@ -32,12 +31,11 @@ class Reimbursement extends BaseValidate
'amount.require' => ['common_validate.require', ['amount']],
'description.require' => ['common_validate.require', ['description']],
'status.require' => ['common_validate.require', ['status']],
'process_id.require' => ['common_validate.require', ['process_id']],
];
protected $scene = [
"add" => ['applicant_id', 'amount', 'description', 'receipt_url', 'status', 'process_id'],
"edit" => ['applicant_id', 'amount', 'description', 'receipt_url', 'status', 'process_id']
"add" => ['applicant_id', 'amount', 'description', 'receipt_url', 'status'],
"edit" => ['applicant_id', 'amount', 'description', 'receipt_url', 'status']
];
}

10
niucloud/app/validate/salary/Salary.php

@ -21,25 +21,31 @@ class Salary extends BaseValidate
protected $rule = [
'staff_id' => 'require',
'department_id' => 'require',
'base_salary' => 'require',
'performance_bonus' => 'require',
'deductions' => 'require',
'other_subsidies' => 'require',
'payment_status' => 'require',
'payment_method' => 'require',
'salary_month' => 'require',
];
protected $message = [
'staff_id.require' => ['common_validate.require', ['staff_id']],
'department_id.require' => ['common_validate.require', ['department_id']],
'base_salary.require' => ['common_validate.require', ['base_salary']],
'performance_bonus.require' => ['common_validate.require', ['performance_bonus']],
'deductions.require' => ['common_validate.require', ['deductions']],
'other_subsidies.require' => ['common_validate.require', ['other_subsidies']],
'payment_status.require' => ['common_validate.require', ['payment_status']],
'payment_method.require' => ['common_validate.require', ['payment_method']],
'salary_month.require' => ['common_validate.require', ['salary_month']],
];
protected $scene = [
"add" => ['staff_id', 'base_salary', 'performance_bonus', 'deductions', 'other_subsidies', 'net_salary', 'payment_status', 'payment_method', 'remarks', 'salary_month', 'department_id', 'process_id'],
"edit" => ['staff_id', 'base_salary', 'performance_bonus', 'deductions', 'other_subsidies', 'net_salary', 'payment_status', 'payment_method', 'remarks', 'salary_month', 'department_id', 'process_id']
"add" => ['staff_id', 'department_id', 'base_salary', 'performance_bonus', 'deductions', 'other_subsidies', 'payment_status', 'payment_method', 'remarks', 'salary_month'],
"edit" => ['staff_id', 'department_id', 'base_salary', 'performance_bonus', 'deductions', 'other_subsidies', 'payment_status', 'payment_method', 'remarks', 'salary_month']
];
}

Loading…
Cancel
Save