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

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

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

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

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

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

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

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

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

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

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

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

@ -31,56 +31,12 @@
<el-option <el-option
v-for="item in courseTypeList" v-for="item in courseTypeList"
:key="item.value" :key="item.value"
:label="item.label" :label="item.name"
:value="item.value" :value="item.name"
/> />
</el-select> </el-select>
</el-form-item> </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-form-item>
<el-button type="primary" @click="loadCourseList()">{{ <el-button type="primary" @click="loadCourseList()">{{
@ -227,7 +183,17 @@ let courseTable = reactive({
remarks: '', 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>() const searchFormRef = ref<FormInstance>()
// //

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

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

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

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

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

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

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

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

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

@ -28,12 +28,8 @@ class Reimbursement extends BaseAdminController
*/ */
public function lists(){ public function lists(){
$data = $this->request->params([ $data = $this->request->params([
["applicant_id",""],
["amount",""],
["description",""],
["receipt_url",""],
["status",""], ["status",""],
["process_id",""] ["created_at",["",""]]
]); ]);
return success((new ReimbursementService())->getPage($data)); return success((new ReimbursementService())->getPage($data));
} }
@ -58,7 +54,6 @@ class Reimbursement extends BaseAdminController
["description",""], ["description",""],
["receipt_url",""], ["receipt_url",""],
["status",""], ["status",""],
["process_id",0],
]); ]);
$this->validate($data, 'app\validate\reimbursement\Reimbursement.add'); $this->validate($data, 'app\validate\reimbursement\Reimbursement.add');
@ -78,7 +73,6 @@ class Reimbursement extends BaseAdminController
["description",""], ["description",""],
["receipt_url",""], ["receipt_url",""],
["status",""], ["status",""],
["process_id",0],
]); ]);
$this->validate($data, 'app\validate\reimbursement\Reimbursement.edit'); $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(){ public function lists(){
$data = $this->request->params([ $data = $this->request->params([
["staff_id",""], ["staff_id",""],
["base_salary",""],
["performance_bonus",""],
["deductions",""],
["other_subsidies",""],
["net_salary",""],
["payment_status",""],
["payment_method",""],
["remarks",""],
["salary_month",""],
["department_id",""], ["department_id",""],
["process_id",""] ["payment_status",""],
["created_at",["",""]]
]); ]);
return success((new SalaryService())->getPage($data)); return success((new SalaryService())->getPage($data));
} }
@ -60,17 +52,15 @@ class Salary extends BaseAdminController
public function add(){ public function add(){
$data = $this->request->params([ $data = $this->request->params([
["staff_id",0], ["staff_id",0],
["department_id",0],
["base_salary",0.00], ["base_salary",0.00],
["performance_bonus",0.00], ["performance_bonus",0.00],
["deductions",0.00], ["deductions",0.00],
["other_subsidies",0.00], ["other_subsidies",0.00],
["net_salary",0.00],
["payment_status",""], ["payment_status",""],
["payment_method",""], ["payment_method",""],
["remarks",""], ["remarks",""],
["salary_month","2025-05-16 17:53:32"], ["salary_month","2025-05-22 18:20:42"],
["department_id",0],
["process_id",0],
]); ]);
$this->validate($data, 'app\validate\salary\Salary.add'); $this->validate($data, 'app\validate\salary\Salary.add');
@ -86,17 +76,15 @@ class Salary extends BaseAdminController
public function edit(int $id){ public function edit(int $id){
$data = $this->request->params([ $data = $this->request->params([
["staff_id",0], ["staff_id",0],
["department_id",0],
["base_salary",0.00], ["base_salary",0.00],
["performance_bonus",0.00], ["performance_bonus",0.00],
["deductions",0.00], ["deductions",0.00],
["other_subsidies",0.00], ["other_subsidies",0.00],
["net_salary",0.00],
["payment_status",""], ["payment_status",""],
["payment_method",""], ["payment_method",""],
["remarks",""], ["remarks",""],
["salary_month","2025-05-16 17:53:32"], ["salary_month","2025-05-22 18:20:42"],
["department_id",0],
["process_id",0],
]); ]);
$this->validate($data, 'app\validate\salary\Salary.edit'); $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\AdminCheckRole;
use app\adminapi\middleware\AdminCheckToken; use app\adminapi\middleware\AdminCheckToken;
use app\adminapi\middleware\AdminLog; use app\adminapi\middleware\AdminLog;
// USER_CODE_BEGIN -- reimbursement // USER_CODE_BEGIN -- reimbursement
Route::group('reimbursement', function () { Route::group('reimbursement', function () {
@ -29,6 +33,8 @@ Route::group('reimbursement', function () {
//删除报销记录 //删除报销记录
Route::delete('reimbursement/:id', 'reimbursement.Reimbursement/del'); Route::delete('reimbursement/:id', 'reimbursement.Reimbursement/del');
Route::get('personnel_all','reimbursement.Reimbursement/getPersonnelAll');
})->middleware([ })->middleware([
AdminCheckToken::class, AdminCheckToken::class,
AdminCheckRole::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\AdminCheckRole;
use app\adminapi\middleware\AdminCheckToken; use app\adminapi\middleware\AdminCheckToken;
use app\adminapi\middleware\AdminLog; use app\adminapi\middleware\AdminLog;
// USER_CODE_BEGIN -- salary // USER_CODE_BEGIN -- salary
Route::group('salary', function () { Route::group('salary', function () {
@ -29,6 +33,10 @@ Route::group('salary', function () {
//删除工资 //删除工资
Route::delete('salary/:id', 'salary.Salary/del'); Route::delete('salary/:id', 'salary.Salary/del');
Route::get('personnel_all','salary.Salary/getPersonnelAll');
Route::get('departments_all','salary.Salary/getDepartmentsAll');
})->middleware([ })->middleware([
AdminCheckToken::class, AdminCheckToken::class,
AdminCheckRole::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\HasMany;
use think\model\relation\HasOne; use think\model\relation\HasOne;
use app\model\personnel\Personnel;
/** /**
* 报销记录模型 * 报销记录模型
* Class Reimbursement * 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 * @param $value
@ -115,14 +57,20 @@ class Reimbursement extends BaseModel
} }
/** /**
* 搜索器:报销记录关联的审批流程ID * 搜索器:报销记录创建时间
* @param $value * @param $value
* @param $data * @param $data
*/ */
public function searchProcessIdAttr($query, $value, $data) public function searchCreatedAtAttr($query, $value, $data)
{ {
if ($value) { $start = empty($value[0]) ? 0 : strtotime($value[0]);
$query->where("process_id", $value); $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\HasMany;
use think\model\relation\HasOne; use think\model\relation\HasOne;
use app\model\personnel\Personnel;
use app\model\departments\Departments;
/** /**
* 工资模型 * 工资模型
* Class Salary * 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 $value
* @param $data * @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 $value
* @param $data * @param $data
*/ */
public function searchNetSalaryAttr($query, $value, $data) public function searchDepartmentIdAttr($query, $value, $data)
{ {
if ($value) { 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 $value
* @param $data * @param $data
*/ */
public function searchSalaryMonthAttr($query, $value, $data) public function searchCreatedAtAttr($query, $value, $data)
{ {
if ($value) { $start = empty($value[0]) ? 0 : strtotime($value[0]);
$query->where("salary_month", $value); $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; namespace app\service\admin\reimbursement;
use app\model\reimbursement\Reimbursement; use app\model\reimbursement\Reimbursement;
use app\model\personnel\Personnel;
use core\base\BaseAdminService; 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'; $field = 'id,applicant_id,amount,description,receipt_url,status,process_id,created_at,updated_at';
$order = 'id desc'; $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); $list = $this->pageQuery($search_model);
return $list; 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'; $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; 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; namespace app\service\admin\salary;
use app\model\salary\Salary; use app\model\salary\Salary;
use app\model\personnel\Personnel;
use app\model\departments\Departments;
use core\base\BaseAdminService; use core\base\BaseAdminService;
@ -36,10 +38,10 @@ class SalaryService extends BaseAdminService
*/ */
public function getPage(array $where = []) 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'; $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); $list = $this->pageQuery($search_model);
return $list; return $list;
} }
@ -51,9 +53,9 @@ class SalaryService extends BaseAdminService
*/ */
public function getInfo(int $id) 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; 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', 'amount' => 'require',
'description' => 'require', 'description' => 'require',
'status' => 'require', 'status' => 'require',
'process_id' => 'require',
]; ];
protected $message = [ protected $message = [
@ -32,12 +31,11 @@ class Reimbursement extends BaseValidate
'amount.require' => ['common_validate.require', ['amount']], 'amount.require' => ['common_validate.require', ['amount']],
'description.require' => ['common_validate.require', ['description']], 'description.require' => ['common_validate.require', ['description']],
'status.require' => ['common_validate.require', ['status']], 'status.require' => ['common_validate.require', ['status']],
'process_id.require' => ['common_validate.require', ['process_id']],
]; ];
protected $scene = [ protected $scene = [
"add" => ['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', 'process_id'] "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 = [ protected $rule = [
'staff_id' => 'require', 'staff_id' => 'require',
'department_id' => 'require',
'base_salary' => 'require', 'base_salary' => 'require',
'performance_bonus' => 'require', 'performance_bonus' => 'require',
'deductions' => 'require', 'deductions' => 'require',
'other_subsidies' => 'require',
'payment_status' => 'require', 'payment_status' => 'require',
'payment_method' => 'require',
'salary_month' => 'require', 'salary_month' => 'require',
]; ];
protected $message = [ protected $message = [
'staff_id.require' => ['common_validate.require', ['staff_id']], 'staff_id.require' => ['common_validate.require', ['staff_id']],
'department_id.require' => ['common_validate.require', ['department_id']],
'base_salary.require' => ['common_validate.require', ['base_salary']], 'base_salary.require' => ['common_validate.require', ['base_salary']],
'performance_bonus.require' => ['common_validate.require', ['performance_bonus']], 'performance_bonus.require' => ['common_validate.require', ['performance_bonus']],
'deductions.require' => ['common_validate.require', ['deductions']], 'deductions.require' => ['common_validate.require', ['deductions']],
'other_subsidies.require' => ['common_validate.require', ['other_subsidies']],
'payment_status.require' => ['common_validate.require', ['payment_status']], 'payment_status.require' => ['common_validate.require', ['payment_status']],
'payment_method.require' => ['common_validate.require', ['payment_method']],
'salary_month.require' => ['common_validate.require', ['salary_month']], 'salary_month.require' => ['common_validate.require', ['salary_month']],
]; ];
protected $scene = [ 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'], "add" => ['staff_id', 'department_id', 'base_salary', 'performance_bonus', 'deductions', 'other_subsidies', 'payment_status', 'payment_method', 'remarks', 'salary_month'],
"edit" => ['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', 'department_id', 'base_salary', 'performance_bonus', 'deductions', 'other_subsidies', 'payment_status', 'payment_method', 'remarks', 'salary_month']
]; ];
} }

Loading…
Cancel
Save