Commit 1830067081d4de1f4355539fb498a46d4aa97aaf
1 parent
d4a6b78f
工作单功能处理中
Showing
24 changed files
with
2948 additions
and
105 deletions
src/api/oa/addWorkApi.js
0 → 100644
| 1 | +import request from '@/utils/request' | ||
| 2 | +import { getCommunityId } from '@/api/community/communityApi' | ||
| 3 | + | ||
| 4 | +// 保存工作单 | ||
| 5 | +export function saveWorkPool(data) { | ||
| 6 | + return new Promise((resolve, reject) => { | ||
| 7 | + request({ | ||
| 8 | + url: '/work.saveWorkPool', | ||
| 9 | + method: 'post', | ||
| 10 | + data: { | ||
| 11 | + ...data, | ||
| 12 | + communityId: getCommunityId() | ||
| 13 | + } | ||
| 14 | + }).then(response => { | ||
| 15 | + resolve(response.data) | ||
| 16 | + }).catch(error => { | ||
| 17 | + reject(error) | ||
| 18 | + }) | ||
| 19 | + }) | ||
| 20 | +} | ||
| 21 | + | ||
| 22 | +// 获取工作单类型列表 | ||
| 23 | +export function listWorkType(params) { | ||
| 24 | + return new Promise((resolve, reject) => { | ||
| 25 | + request({ | ||
| 26 | + url: '/workType.listWorkType', | ||
| 27 | + method: 'get', | ||
| 28 | + params: { | ||
| 29 | + ...params, | ||
| 30 | + communityId: getCommunityId() | ||
| 31 | + } | ||
| 32 | + }).then(response => { | ||
| 33 | + resolve(response.data) | ||
| 34 | + }).catch(error => { | ||
| 35 | + reject(error) | ||
| 36 | + }) | ||
| 37 | + }) | ||
| 38 | +} | ||
| 39 | + | ||
| 40 | +// 获取组织树 | ||
| 41 | +export function listOrgTree() { | ||
| 42 | + return new Promise((resolve, reject) => { | ||
| 43 | + request({ | ||
| 44 | + url: '/org.listOrgTree', | ||
| 45 | + method: 'get', | ||
| 46 | + params: { | ||
| 47 | + communityId: getCommunityId() | ||
| 48 | + } | ||
| 49 | + }).then(response => { | ||
| 50 | + resolve(response.data) | ||
| 51 | + }).catch(error => { | ||
| 52 | + reject(error) | ||
| 53 | + }) | ||
| 54 | + }) | ||
| 55 | +} | ||
| 56 | + | ||
| 57 | +// 查询员工信息 | ||
| 58 | +export function queryStaffInfos(params) { | ||
| 59 | + return new Promise((resolve, reject) => { | ||
| 60 | + request({ | ||
| 61 | + url: '/query.staff.infos', | ||
| 62 | + method: 'get', | ||
| 63 | + params: { | ||
| 64 | + ...params, | ||
| 65 | + communityId: getCommunityId() | ||
| 66 | + } | ||
| 67 | + }).then(response => { | ||
| 68 | + resolve(response.data) | ||
| 69 | + }).catch(error => { | ||
| 70 | + reject(error) | ||
| 71 | + }) | ||
| 72 | + }) | ||
| 73 | +} | ||
| 74 | + | ||
| 75 | +// 上传文件 | ||
| 76 | +export function uploadFile(data) { | ||
| 77 | + return new Promise((resolve, reject) => { | ||
| 78 | + request({ | ||
| 79 | + url: '/upload', | ||
| 80 | + method: 'post', | ||
| 81 | + data, | ||
| 82 | + headers: { | ||
| 83 | + 'Content-Type': 'multipart/form-data' | ||
| 84 | + } | ||
| 85 | + }).then(response => { | ||
| 86 | + resolve(response.data) | ||
| 87 | + }).catch(error => { | ||
| 88 | + reject(error) | ||
| 89 | + }) | ||
| 90 | + }) | ||
| 91 | +} | ||
| 0 | \ No newline at end of file | 92 | \ No newline at end of file |
src/api/oa/editWorkApi.js
0 → 100644
| 1 | +import request from '@/utils/request' | ||
| 2 | + | ||
| 3 | +// 获取工作单类型列表 | ||
| 4 | +export function listWorkType(params) { | ||
| 5 | + return new Promise((resolve, reject) => { | ||
| 6 | + request({ | ||
| 7 | + url: '/workType.listWorkType', | ||
| 8 | + method: 'get', | ||
| 9 | + params | ||
| 10 | + }).then(response => { | ||
| 11 | + const res = response.data | ||
| 12 | + resolve(res) | ||
| 13 | + }).catch(error => { | ||
| 14 | + reject(error) | ||
| 15 | + }) | ||
| 16 | + }) | ||
| 17 | +} | ||
| 18 | + | ||
| 19 | +// 查询工作单详情 | ||
| 20 | +export function queryStartWork(params) { | ||
| 21 | + return new Promise((resolve, reject) => { | ||
| 22 | + request({ | ||
| 23 | + url: '/work.queryStartWork', | ||
| 24 | + method: 'get', | ||
| 25 | + params | ||
| 26 | + }).then(response => { | ||
| 27 | + const res = response.data | ||
| 28 | + resolve(res) | ||
| 29 | + }).catch(error => { | ||
| 30 | + reject(error) | ||
| 31 | + }) | ||
| 32 | + }) | ||
| 33 | +} | ||
| 34 | + | ||
| 35 | +// 获取工作单处理人列表 | ||
| 36 | +export function listWorkTask(params) { | ||
| 37 | + return new Promise((resolve, reject) => { | ||
| 38 | + request({ | ||
| 39 | + url: '/work.listWorkTask', | ||
| 40 | + method: 'get', | ||
| 41 | + params | ||
| 42 | + }).then(response => { | ||
| 43 | + const res = response.data | ||
| 44 | + resolve(res) | ||
| 45 | + }).catch(error => { | ||
| 46 | + reject(error) | ||
| 47 | + }) | ||
| 48 | + }) | ||
| 49 | +} | ||
| 50 | + | ||
| 51 | +// 获取工作单抄送人列表 | ||
| 52 | +export function listWorkCopy(params) { | ||
| 53 | + return new Promise((resolve, reject) => { | ||
| 54 | + request({ | ||
| 55 | + url: '/work.listWorkCopy', | ||
| 56 | + method: 'get', | ||
| 57 | + params | ||
| 58 | + }).then(response => { | ||
| 59 | + const res = response.data | ||
| 60 | + resolve(res) | ||
| 61 | + }).catch(error => { | ||
| 62 | + reject(error) | ||
| 63 | + }) | ||
| 64 | + }) | ||
| 65 | +} | ||
| 66 | + | ||
| 67 | +// 获取工作单周期信息 | ||
| 68 | +export function listWorkCycle(params) { | ||
| 69 | + return new Promise((resolve, reject) => { | ||
| 70 | + request({ | ||
| 71 | + url: '/workCycle.listWorkCycle', | ||
| 72 | + method: 'get', | ||
| 73 | + params | ||
| 74 | + }).then(response => { | ||
| 75 | + const res = response.data | ||
| 76 | + resolve(res) | ||
| 77 | + }).catch(error => { | ||
| 78 | + reject(error) | ||
| 79 | + }) | ||
| 80 | + }) | ||
| 81 | +} | ||
| 82 | + | ||
| 83 | +// 更新工作单 | ||
| 84 | +export function updateWorkPool(data) { | ||
| 85 | + return new Promise((resolve, reject) => { | ||
| 86 | + request({ | ||
| 87 | + url: '/work.updateWorkPool', | ||
| 88 | + method: 'post', | ||
| 89 | + data | ||
| 90 | + }).then(response => { | ||
| 91 | + const res = response.data | ||
| 92 | + resolve(res) | ||
| 93 | + }).catch(error => { | ||
| 94 | + reject(error) | ||
| 95 | + }) | ||
| 96 | + }) | ||
| 97 | +} | ||
| 98 | + | ||
| 99 | +// 查询员工信息 | ||
| 100 | +export function queryStaffInfos(params) { | ||
| 101 | + return new Promise((resolve, reject) => { | ||
| 102 | + request({ | ||
| 103 | + url: '/query.staff.infos', | ||
| 104 | + method: 'get', | ||
| 105 | + params | ||
| 106 | + }).then(response => { | ||
| 107 | + const res = response.data | ||
| 108 | + resolve(res) | ||
| 109 | + }).catch(error => { | ||
| 110 | + reject(error) | ||
| 111 | + }) | ||
| 112 | + }) | ||
| 113 | +} | ||
| 114 | + | ||
| 115 | +// 获取组织树 | ||
| 116 | +export function listOrgTree(params) { | ||
| 117 | + return new Promise((resolve, reject) => { | ||
| 118 | + request({ | ||
| 119 | + url: '/org.listOrgTree', | ||
| 120 | + method: 'get', | ||
| 121 | + params | ||
| 122 | + }).then(response => { | ||
| 123 | + const res = response.data | ||
| 124 | + resolve(res) | ||
| 125 | + }).catch(error => { | ||
| 126 | + reject(error) | ||
| 127 | + }) | ||
| 128 | + }) | ||
| 129 | +} | ||
| 130 | + | ||
| 131 | +// 上传文件 | ||
| 132 | +export function uploadFile(data, config) { | ||
| 133 | + return new Promise((resolve, reject) => { | ||
| 134 | + request({ | ||
| 135 | + url: '/upload', | ||
| 136 | + method: 'post', | ||
| 137 | + data, | ||
| 138 | + onUploadProgress: config.onUploadProgress, | ||
| 139 | + headers: { | ||
| 140 | + 'Content-Type': 'multipart/form-data' | ||
| 141 | + } | ||
| 142 | + }).then(response => { | ||
| 143 | + const res = response.data | ||
| 144 | + resolve(res) | ||
| 145 | + }).catch(error => { | ||
| 146 | + reject(error) | ||
| 147 | + }) | ||
| 148 | + }) | ||
| 149 | +} | ||
| 150 | + | ||
| 151 | +// 上传图片 | ||
| 152 | +export function uploadImage(data) { | ||
| 153 | + return new Promise((resolve, reject) => { | ||
| 154 | + request({ | ||
| 155 | + url: '/uploadImage', | ||
| 156 | + method: 'post', | ||
| 157 | + data, | ||
| 158 | + headers: { | ||
| 159 | + 'Content-Type': 'multipart/form-data' | ||
| 160 | + } | ||
| 161 | + }).then(response => { | ||
| 162 | + const res = response.data | ||
| 163 | + resolve(res) | ||
| 164 | + }).catch(error => { | ||
| 165 | + reject(error) | ||
| 166 | + }) | ||
| 167 | + }) | ||
| 168 | +} | ||
| 0 | \ No newline at end of file | 169 | \ No newline at end of file |
src/api/oa/startWorkApi.js
0 → 100644
| 1 | +import request from '@/utils/request' | ||
| 2 | +import { getCommunityId } from '@/api/community/communityApi' | ||
| 3 | + | ||
| 4 | +// 查询发起工作单列表 | ||
| 5 | +export function queryStartWork(params) { | ||
| 6 | + return new Promise((resolve, reject) => { | ||
| 7 | + request({ | ||
| 8 | + url: '/work.queryStartWork', | ||
| 9 | + method: 'get', | ||
| 10 | + params: { | ||
| 11 | + ...params, | ||
| 12 | + communityId: getCommunityId() | ||
| 13 | + } | ||
| 14 | + }).then(response => { | ||
| 15 | + const res = response.data | ||
| 16 | + resolve({ | ||
| 17 | + data: res.data, | ||
| 18 | + total: res.total | ||
| 19 | + }) | ||
| 20 | + }).catch(error => { | ||
| 21 | + reject(error) | ||
| 22 | + }) | ||
| 23 | + }) | ||
| 24 | +} | ||
| 25 | + | ||
| 26 | +// 删除工作单 | ||
| 27 | +export function deleteWorkPool(data) { | ||
| 28 | + return new Promise((resolve, reject) => { | ||
| 29 | + request({ | ||
| 30 | + url: '/work.deleteWorkPool', | ||
| 31 | + method: 'post', | ||
| 32 | + data: { | ||
| 33 | + ...data, | ||
| 34 | + communityId: getCommunityId() | ||
| 35 | + } | ||
| 36 | + }).then(response => { | ||
| 37 | + const res = response.data | ||
| 38 | + if (res.code === 0) { | ||
| 39 | + resolve(res) | ||
| 40 | + } else { | ||
| 41 | + reject(new Error(res.msg)) | ||
| 42 | + } | ||
| 43 | + }).catch(error => { | ||
| 44 | + reject(error) | ||
| 45 | + }) | ||
| 46 | + }) | ||
| 47 | +} | ||
| 48 | + | ||
| 49 | +// 启动/停止工作单 | ||
| 50 | +export function updateWorkState(data) { | ||
| 51 | + return new Promise((resolve, reject) => { | ||
| 52 | + request({ | ||
| 53 | + url: '/work.startOrStopWorkPool', | ||
| 54 | + method: 'post', | ||
| 55 | + data: { | ||
| 56 | + ...data, | ||
| 57 | + communityId: getCommunityId() | ||
| 58 | + } | ||
| 59 | + }).then(response => { | ||
| 60 | + const res = response.data | ||
| 61 | + if (res.code === 0) { | ||
| 62 | + resolve(res) | ||
| 63 | + } else { | ||
| 64 | + reject(new Error(res.msg)) | ||
| 65 | + } | ||
| 66 | + }).catch(error => { | ||
| 67 | + reject(error) | ||
| 68 | + }) | ||
| 69 | + }) | ||
| 70 | +} | ||
| 0 | \ No newline at end of file | 71 | \ No newline at end of file |
src/api/oa/workTypeApi.js
0 → 100644
| 1 | +import request from '@/utils/request' | ||
| 2 | + | ||
| 3 | +// 获取工作单类型列表 | ||
| 4 | +export function listWorkType(params) { | ||
| 5 | + return new Promise((resolve, reject) => { | ||
| 6 | + request({ | ||
| 7 | + url: '/workType.listWorkType', | ||
| 8 | + method: 'get', | ||
| 9 | + params | ||
| 10 | + }).then(response => { | ||
| 11 | + const res = response.data | ||
| 12 | + resolve(res) | ||
| 13 | + }).catch(error => { | ||
| 14 | + reject(error) | ||
| 15 | + }) | ||
| 16 | + }) | ||
| 17 | +} | ||
| 18 | + | ||
| 19 | +// 添加工作单类型 | ||
| 20 | +export function saveWorkType(data) { | ||
| 21 | + return new Promise((resolve, reject) => { | ||
| 22 | + request({ | ||
| 23 | + url: '/workType.saveWorkType', | ||
| 24 | + method: 'post', | ||
| 25 | + data | ||
| 26 | + }).then(response => { | ||
| 27 | + const res = response.data | ||
| 28 | + resolve(res) | ||
| 29 | + }).catch(error => { | ||
| 30 | + reject(error) | ||
| 31 | + }) | ||
| 32 | + }) | ||
| 33 | +} | ||
| 34 | + | ||
| 35 | +// 更新工作单类型 | ||
| 36 | +export function updateWorkType(data) { | ||
| 37 | + return new Promise((resolve, reject) => { | ||
| 38 | + request({ | ||
| 39 | + url: '/workType.updateWorkType', | ||
| 40 | + method: 'post', | ||
| 41 | + data | ||
| 42 | + }).then(response => { | ||
| 43 | + const res = response.data | ||
| 44 | + resolve(res) | ||
| 45 | + }).catch(error => { | ||
| 46 | + reject(error) | ||
| 47 | + }) | ||
| 48 | + }) | ||
| 49 | +} | ||
| 50 | + | ||
| 51 | +// 删除工作单类型 | ||
| 52 | +export function deleteWorkType(data) { | ||
| 53 | + return new Promise((resolve, reject) => { | ||
| 54 | + request({ | ||
| 55 | + url: '/workType.deleteWorkType', | ||
| 56 | + method: 'post', | ||
| 57 | + data | ||
| 58 | + }).then(response => { | ||
| 59 | + const res = response.data | ||
| 60 | + resolve(res) | ||
| 61 | + }).catch(error => { | ||
| 62 | + reject(error) | ||
| 63 | + }) | ||
| 64 | + }) | ||
| 65 | +} | ||
| 0 | \ No newline at end of file | 66 | \ No newline at end of file |
src/api/system/paymentPoolApi.js
| @@ -153,7 +153,7 @@ export function listFeeConfigs(params) { | @@ -153,7 +153,7 @@ export function listFeeConfigs(params) { | ||
| 153 | export function uploadFile(data, config) { | 153 | export function uploadFile(data, config) { |
| 154 | return new Promise((resolve, reject) => { | 154 | return new Promise((resolve, reject) => { |
| 155 | request({ | 155 | request({ |
| 156 | - url: '/uploadVedio/upload', | 156 | + url: '/callComponent/upload/uploadVedio/upload', |
| 157 | method: 'post', | 157 | method: 'post', |
| 158 | data, | 158 | data, |
| 159 | headers: { | 159 | headers: { |
src/components/oa/addWorkType.vue
0 → 100644
| 1 | +<template> | ||
| 2 | + <el-dialog | ||
| 3 | + :title="$t('workType.add.title')" | ||
| 4 | + :visible.sync="visible" | ||
| 5 | + width="50%" | ||
| 6 | + @close="handleClose" | ||
| 7 | + > | ||
| 8 | + <el-form ref="form" :model="formData" :rules="rules" label-width="120px"> | ||
| 9 | + <el-form-item :label="$t('workType.form.typeName')" prop="typeName"> | ||
| 10 | + <el-input | ||
| 11 | + v-model.trim="formData.typeName" | ||
| 12 | + :placeholder="$t('workType.placeholder.typeName')" | ||
| 13 | + /> | ||
| 14 | + </el-form-item> | ||
| 15 | + | ||
| 16 | + <el-form-item :label="$t('workType.form.deduction')" prop="deduction"> | ||
| 17 | + <el-select | ||
| 18 | + v-model="formData.deduction" | ||
| 19 | + :placeholder="$t('workType.placeholder.deduction')" | ||
| 20 | + style="width:100%" | ||
| 21 | + > | ||
| 22 | + <el-option | ||
| 23 | + v-for="item in deductionOptions" | ||
| 24 | + :key="item.value" | ||
| 25 | + :label="item.label" | ||
| 26 | + :value="item.value" | ||
| 27 | + /> | ||
| 28 | + </el-select> | ||
| 29 | + <div class="el-form-item__tip" v-if="formData.deduction === 'Y'"> | ||
| 30 | + {{ $t('workType.tip.deduction') }} | ||
| 31 | + </div> | ||
| 32 | + </el-form-item> | ||
| 33 | + | ||
| 34 | + <el-form-item :label="$t('workType.form.smsWay')" prop="smsWay"> | ||
| 35 | + <el-select | ||
| 36 | + v-model="formData.smsWay" | ||
| 37 | + :placeholder="$t('workType.placeholder.smsWay')" | ||
| 38 | + style="width:100%" | ||
| 39 | + > | ||
| 40 | + <el-option | ||
| 41 | + v-for="item in smsWayOptions" | ||
| 42 | + :key="item.value" | ||
| 43 | + :label="item.label" | ||
| 44 | + :value="item.value" | ||
| 45 | + /> | ||
| 46 | + </el-select> | ||
| 47 | + <div class="el-form-item__tip" v-if="formData.smsWay === 'WECHAT'"> | ||
| 48 | + {{ $t('workType.tip.wechat') }} | ||
| 49 | + </div> | ||
| 50 | + <div class="el-form-item__tip" v-else-if="formData.smsWay === 'ALI_SMS'"> | ||
| 51 | + {{ $t('workType.tip.aliSms') }} | ||
| 52 | + </div> | ||
| 53 | + </el-form-item> | ||
| 54 | + | ||
| 55 | + <el-form-item :label="$t('workType.form.remark')"> | ||
| 56 | + <el-input | ||
| 57 | + v-model.trim="formData.remark" | ||
| 58 | + type="textarea" | ||
| 59 | + :rows="3" | ||
| 60 | + :placeholder="$t('workType.placeholder.remark')" | ||
| 61 | + maxlength="500" | ||
| 62 | + show-word-limit | ||
| 63 | + /> | ||
| 64 | + </el-form-item> | ||
| 65 | + </el-form> | ||
| 66 | + | ||
| 67 | + <span slot="footer" class="dialog-footer"> | ||
| 68 | + <el-button @click="visible = false">{{ $t('common.cancel') }}</el-button> | ||
| 69 | + <el-button type="primary" @click="handleSubmit">{{ $t('common.confirm') }}</el-button> | ||
| 70 | + </span> | ||
| 71 | + </el-dialog> | ||
| 72 | +</template> | ||
| 73 | + | ||
| 74 | +<script> | ||
| 75 | +import { saveWorkType } from '@/api/oa/workTypeApi' | ||
| 76 | +import { getCommunityId } from '@/api/community/communityApi' | ||
| 77 | + | ||
| 78 | +export default { | ||
| 79 | + name: 'AddWorkType', | ||
| 80 | + data() { | ||
| 81 | + return { | ||
| 82 | + visible: false, | ||
| 83 | + formData: { | ||
| 84 | + typeName: '', | ||
| 85 | + deduction: '', | ||
| 86 | + smsWay: '', | ||
| 87 | + remark: '' | ||
| 88 | + }, | ||
| 89 | + deductionOptions: [ | ||
| 90 | + { value: 'Y', label: this.$t('workType.yes') }, | ||
| 91 | + { value: 'N', label: this.$t('workType.no') } | ||
| 92 | + ], | ||
| 93 | + smsWayOptions: [ | ||
| 94 | + { value: 'WECHAT', label: this.$t('workType.wechat') }, | ||
| 95 | + { value: 'ALI_SMS', label: this.$t('workType.aliSms') }, | ||
| 96 | + { value: 'WORK_LICENSE', label: this.$t('workType.workLicense') } | ||
| 97 | + ], | ||
| 98 | + rules: { | ||
| 99 | + typeName: [ | ||
| 100 | + { required: true, message: this.$t('workType.validate.typeName'), trigger: 'blur' }, | ||
| 101 | + { max: 200, message: this.$t('workType.validate.typeNameMax'), trigger: 'blur' } | ||
| 102 | + ], | ||
| 103 | + deduction: [ | ||
| 104 | + { required: true, message: this.$t('workType.validate.deduction'), trigger: 'change' } | ||
| 105 | + ], | ||
| 106 | + smsWay: [ | ||
| 107 | + { required: true, message: this.$t('workType.validate.smsWay'), trigger: 'change' } | ||
| 108 | + ] | ||
| 109 | + } | ||
| 110 | + } | ||
| 111 | + }, | ||
| 112 | + methods: { | ||
| 113 | + open() { | ||
| 114 | + this.visible = true | ||
| 115 | + }, | ||
| 116 | + handleClose() { | ||
| 117 | + this.$refs.form.resetFields() | ||
| 118 | + }, | ||
| 119 | + handleSubmit() { | ||
| 120 | + this.$refs.form.validate(async valid => { | ||
| 121 | + if (valid) { | ||
| 122 | + try { | ||
| 123 | + const params = { | ||
| 124 | + ...this.formData, | ||
| 125 | + communityId: getCommunityId() | ||
| 126 | + } | ||
| 127 | + await saveWorkType(params) | ||
| 128 | + this.$message.success(this.$t('workType.add.success')) | ||
| 129 | + this.visible = false | ||
| 130 | + this.$emit('success') | ||
| 131 | + } catch (error) { | ||
| 132 | + this.$message.error(error.message || this.$t('workType.add.error')) | ||
| 133 | + } | ||
| 134 | + } | ||
| 135 | + }) | ||
| 136 | + } | ||
| 137 | + } | ||
| 138 | +} | ||
| 139 | +</script> | ||
| 140 | + | ||
| 141 | +<style scoped> | ||
| 142 | +.el-form-item__tip { | ||
| 143 | + font-size: 12px; | ||
| 144 | + color: #999; | ||
| 145 | + margin-top: 5px; | ||
| 146 | +} | ||
| 147 | +</style> | ||
| 0 | \ No newline at end of file | 148 | \ No newline at end of file |
src/components/oa/deleteWork.vue
0 → 100644
| 1 | +<template> | ||
| 2 | + <el-dialog | ||
| 3 | + :title="$t('startWork.delete.title')" | ||
| 4 | + :visible.sync="visible" | ||
| 5 | + width="30%" | ||
| 6 | + @close="handleClose" | ||
| 7 | + > | ||
| 8 | + <div class="delete-content"> | ||
| 9 | + <p>{{ $t('startWork.delete.confirm') }}</p> | ||
| 10 | + </div> | ||
| 11 | + <span slot="footer" class="dialog-footer"> | ||
| 12 | + <el-button @click="handleClose">{{ $t('common.cancel') }}</el-button> | ||
| 13 | + <el-button type="primary" @click="handleConfirm">{{ $t('common.confirm') }}</el-button> | ||
| 14 | + </span> | ||
| 15 | + </el-dialog> | ||
| 16 | +</template> | ||
| 17 | + | ||
| 18 | +<script> | ||
| 19 | +import { deleteWorkPool } from '@/api/oa/startWorkApi' | ||
| 20 | +import { getCommunityId } from '@/api/community/communityApi' | ||
| 21 | + | ||
| 22 | +export default { | ||
| 23 | + name: 'DeleteWork', | ||
| 24 | + data() { | ||
| 25 | + return { | ||
| 26 | + visible: false, | ||
| 27 | + currentWork: null, | ||
| 28 | + communityId: '' | ||
| 29 | + } | ||
| 30 | + }, | ||
| 31 | + created() { | ||
| 32 | + this.communityId = getCommunityId() | ||
| 33 | + }, | ||
| 34 | + methods: { | ||
| 35 | + open(work) { | ||
| 36 | + this.currentWork = work | ||
| 37 | + this.visible = true | ||
| 38 | + }, | ||
| 39 | + handleClose() { | ||
| 40 | + this.visible = false | ||
| 41 | + this.currentWork = null | ||
| 42 | + }, | ||
| 43 | + async handleConfirm() { | ||
| 44 | + try { | ||
| 45 | + await deleteWorkPool({ | ||
| 46 | + workId: this.currentWork.workId, | ||
| 47 | + communityId: this.communityId | ||
| 48 | + }) | ||
| 49 | + this.$message.success(this.$t('startWork.delete.success')) | ||
| 50 | + this.$emit('success') | ||
| 51 | + this.handleClose() | ||
| 52 | + } catch (error) { | ||
| 53 | + this.$message.error(this.$t('startWork.delete.error')) | ||
| 54 | + } | ||
| 55 | + } | ||
| 56 | + } | ||
| 57 | +} | ||
| 58 | +</script> | ||
| 59 | + | ||
| 60 | +<style lang="scss" scoped> | ||
| 61 | +.delete-content { | ||
| 62 | + text-align: center; | ||
| 63 | + font-size: 16px; | ||
| 64 | + padding: 20px 0; | ||
| 65 | +} | ||
| 66 | +</style> | ||
| 0 | \ No newline at end of file | 67 | \ No newline at end of file |
src/components/oa/deleteWorkType.vue
0 → 100644
| 1 | +<template> | ||
| 2 | + <el-dialog | ||
| 3 | + :title="$t('workType.delete.title')" | ||
| 4 | + :visible.sync="visible" | ||
| 5 | + width="30%" | ||
| 6 | + @close="handleClose" | ||
| 7 | + > | ||
| 8 | + <div class="delete-content"> | ||
| 9 | + <i class="el-icon-warning" style="color:#E6A23C;font-size:24px;"></i> | ||
| 10 | + <span style="margin-left:10px;">{{ $t('workType.delete.confirm') }}</span> | ||
| 11 | + </div> | ||
| 12 | + | ||
| 13 | + <span slot="footer" class="dialog-footer"> | ||
| 14 | + <el-button @click="visible = false">{{ $t('common.cancel') }}</el-button> | ||
| 15 | + <el-button type="primary" @click="handleConfirm">{{ $t('common.confirm') }}</el-button> | ||
| 16 | + </span> | ||
| 17 | + </el-dialog> | ||
| 18 | +</template> | ||
| 19 | + | ||
| 20 | +<script> | ||
| 21 | +import { deleteWorkType } from '@/api/oa/workTypeApi' | ||
| 22 | +import { getCommunityId } from '@/api/community/communityApi' | ||
| 23 | + | ||
| 24 | +export default { | ||
| 25 | + name: 'DeleteWorkType', | ||
| 26 | + data() { | ||
| 27 | + return { | ||
| 28 | + visible: false, | ||
| 29 | + currentRow: null | ||
| 30 | + } | ||
| 31 | + }, | ||
| 32 | + methods: { | ||
| 33 | + open(row) { | ||
| 34 | + this.currentRow = row | ||
| 35 | + this.visible = true | ||
| 36 | + }, | ||
| 37 | + handleClose() { | ||
| 38 | + this.currentRow = null | ||
| 39 | + }, | ||
| 40 | + async handleConfirm() { | ||
| 41 | + try { | ||
| 42 | + const params = { | ||
| 43 | + wtId: this.currentRow.wtId, | ||
| 44 | + communityId: getCommunityId() | ||
| 45 | + } | ||
| 46 | + await deleteWorkType(params) | ||
| 47 | + this.$message.success(this.$t('workType.delete.success')) | ||
| 48 | + this.visible = false | ||
| 49 | + this.$emit('success') | ||
| 50 | + } catch (error) { | ||
| 51 | + this.$message.error(error.message || this.$t('workType.delete.error')) | ||
| 52 | + } | ||
| 53 | + } | ||
| 54 | + } | ||
| 55 | +} | ||
| 56 | +</script> | ||
| 57 | + | ||
| 58 | +<style scoped> | ||
| 59 | +.delete-content { | ||
| 60 | + display: flex; | ||
| 61 | + align-items: center; | ||
| 62 | + justify-content: center; | ||
| 63 | + padding: 20px 0; | ||
| 64 | +} | ||
| 65 | +</style> | ||
| 0 | \ No newline at end of file | 66 | \ No newline at end of file |
src/components/oa/editWorkType.vue
0 → 100644
| 1 | +<template> | ||
| 2 | + <el-dialog | ||
| 3 | + :title="$t('workType.edit.title')" | ||
| 4 | + :visible.sync="visible" | ||
| 5 | + width="50%" | ||
| 6 | + @close="handleClose" | ||
| 7 | + > | ||
| 8 | + <el-form ref="form" :model="formData" :rules="rules" label-width="120px"> | ||
| 9 | + <el-form-item :label="$t('workType.form.typeName')" prop="typeName"> | ||
| 10 | + <el-input | ||
| 11 | + v-model.trim="formData.typeName" | ||
| 12 | + :placeholder="$t('workType.placeholder.typeName')" | ||
| 13 | + /> | ||
| 14 | + </el-form-item> | ||
| 15 | + | ||
| 16 | + <el-form-item :label="$t('workType.form.deduction')" prop="deduction"> | ||
| 17 | + <el-select | ||
| 18 | + v-model="formData.deduction" | ||
| 19 | + :placeholder="$t('workType.placeholder.deduction')" | ||
| 20 | + style="width:100%" | ||
| 21 | + > | ||
| 22 | + <el-option | ||
| 23 | + v-for="item in deductionOptions" | ||
| 24 | + :key="item.value" | ||
| 25 | + :label="item.label" | ||
| 26 | + :value="item.value" | ||
| 27 | + /> | ||
| 28 | + </el-select> | ||
| 29 | + <div class="el-form-item__tip" v-if="formData.deduction === 'Y'"> | ||
| 30 | + {{ $t('workType.tip.deduction') }} | ||
| 31 | + </div> | ||
| 32 | + </el-form-item> | ||
| 33 | + | ||
| 34 | + <el-form-item :label="$t('workType.form.smsWay')" prop="smsWay"> | ||
| 35 | + <el-select | ||
| 36 | + v-model="formData.smsWay" | ||
| 37 | + :placeholder="$t('workType.placeholder.smsWay')" | ||
| 38 | + style="width:100%" | ||
| 39 | + > | ||
| 40 | + <el-option | ||
| 41 | + v-for="item in smsWayOptions" | ||
| 42 | + :key="item.value" | ||
| 43 | + :label="item.label" | ||
| 44 | + :value="item.value" | ||
| 45 | + /> | ||
| 46 | + </el-select> | ||
| 47 | + </el-form-item> | ||
| 48 | + | ||
| 49 | + <el-form-item :label="$t('workType.form.remark')"> | ||
| 50 | + <el-input | ||
| 51 | + v-model.trim="formData.remark" | ||
| 52 | + type="textarea" | ||
| 53 | + :rows="3" | ||
| 54 | + :placeholder="$t('workType.placeholder.remark')" | ||
| 55 | + maxlength="500" | ||
| 56 | + show-word-limit | ||
| 57 | + /> | ||
| 58 | + </el-form-item> | ||
| 59 | + </el-form> | ||
| 60 | + | ||
| 61 | + <span slot="footer" class="dialog-footer"> | ||
| 62 | + <el-button @click="visible = false">{{ $t('common.cancel') }}</el-button> | ||
| 63 | + <el-button type="primary" @click="handleSubmit">{{ $t('common.confirm') }}</el-button> | ||
| 64 | + </span> | ||
| 65 | + </el-dialog> | ||
| 66 | +</template> | ||
| 67 | + | ||
| 68 | +<script> | ||
| 69 | +import { updateWorkType } from '@/api/oa/workTypeApi' | ||
| 70 | +import { getCommunityId } from '@/api/community/communityApi' | ||
| 71 | + | ||
| 72 | +export default { | ||
| 73 | + name: 'EditWorkType', | ||
| 74 | + data() { | ||
| 75 | + return { | ||
| 76 | + visible: false, | ||
| 77 | + formData: { | ||
| 78 | + wtId: '', | ||
| 79 | + typeName: '', | ||
| 80 | + deduction: '', | ||
| 81 | + smsWay: '', | ||
| 82 | + remark: '' | ||
| 83 | + }, | ||
| 84 | + deductionOptions: [ | ||
| 85 | + { value: 'Y', label: this.$t('workType.yes') }, | ||
| 86 | + { value: 'N', label: this.$t('workType.no') } | ||
| 87 | + ], | ||
| 88 | + smsWayOptions: [ | ||
| 89 | + { value: 'WECHAT', label: this.$t('workType.wechat') }, | ||
| 90 | + { value: 'ALI_SMS', label: this.$t('workType.aliSms') }, | ||
| 91 | + { value: 'WORK_LICENSE', label: this.$t('workType.workLicense') } | ||
| 92 | + ], | ||
| 93 | + rules: { | ||
| 94 | + typeName: [ | ||
| 95 | + { required: true, message: this.$t('workType.validate.typeName'), trigger: 'blur' }, | ||
| 96 | + { max: 200, message: this.$t('workType.validate.typeNameMax'), trigger: 'blur' } | ||
| 97 | + ], | ||
| 98 | + deduction: [ | ||
| 99 | + { required: true, message: this.$t('workType.validate.deduction'), trigger: 'change' } | ||
| 100 | + ], | ||
| 101 | + smsWay: [ | ||
| 102 | + { required: true, message: this.$t('workType.validate.smsWay'), trigger: 'change' } | ||
| 103 | + ], | ||
| 104 | + wtId: [ | ||
| 105 | + { required: true, message: this.$t('workType.validate.wtId'), trigger: 'blur' } | ||
| 106 | + ] | ||
| 107 | + } | ||
| 108 | + } | ||
| 109 | + }, | ||
| 110 | + methods: { | ||
| 111 | + open(row) { | ||
| 112 | + this.formData = { | ||
| 113 | + wtId: row.wtId, | ||
| 114 | + typeName: row.typeName, | ||
| 115 | + deduction: row.deduction, | ||
| 116 | + smsWay: row.smsWay, | ||
| 117 | + remark: row.remark | ||
| 118 | + } | ||
| 119 | + this.visible = true | ||
| 120 | + }, | ||
| 121 | + handleClose() { | ||
| 122 | + this.$refs.form.resetFields() | ||
| 123 | + }, | ||
| 124 | + handleSubmit() { | ||
| 125 | + this.$refs.form.validate(async valid => { | ||
| 126 | + if (valid) { | ||
| 127 | + try { | ||
| 128 | + const params = { | ||
| 129 | + ...this.formData, | ||
| 130 | + communityId: getCommunityId() | ||
| 131 | + } | ||
| 132 | + await updateWorkType(params) | ||
| 133 | + this.$message.success(this.$t('workType.edit.success')) | ||
| 134 | + this.visible = false | ||
| 135 | + this.$emit('success') | ||
| 136 | + } catch (error) { | ||
| 137 | + this.$message.error(error.message || this.$t('workType.edit.error')) | ||
| 138 | + } | ||
| 139 | + } | ||
| 140 | + }) | ||
| 141 | + } | ||
| 142 | + } | ||
| 143 | +} | ||
| 144 | +</script> | ||
| 145 | + | ||
| 146 | +<style scoped> | ||
| 147 | +.el-form-item__tip { | ||
| 148 | + font-size: 12px; | ||
| 149 | + color: #999; | ||
| 150 | + margin-top: 5px; | ||
| 151 | +} | ||
| 152 | +</style> | ||
| 0 | \ No newline at end of file | 153 | \ No newline at end of file |
src/components/oa/orgTreeShow.vue
| 1 | <template> | 1 | <template> |
| 2 | - <div class="org-tree-container"> | 2 | + <div class="org-tree-show"> |
| 3 | <el-tree | 3 | <el-tree |
| 4 | ref="orgTree" | 4 | ref="orgTree" |
| 5 | - :data="orgData" | ||
| 6 | - :props="defaultProps" | 5 | + :data="orgTreeShowInfo.orgs" |
| 7 | node-key="id" | 6 | node-key="id" |
| 8 | - default-expand-all | ||
| 9 | - highlight-current | ||
| 10 | - :expand-on-click-node="false" | 7 | + :props="defaultProps" |
| 8 | + :default-expand-all="true" | ||
| 9 | + :highlight-current="true" | ||
| 11 | @node-click="handleNodeClick" | 10 | @node-click="handleNodeClick" |
| 12 | - ></el-tree> | 11 | + /> |
| 13 | </div> | 12 | </div> |
| 14 | </template> | 13 | </template> |
| 15 | 14 | ||
| 16 | <script> | 15 | <script> |
| 17 | -import { listOrgTree } from '@/api/oa/addAttendanceClassesStaffApi' | 16 | +import { listOrgTree } from '@/api/oa/editWorkApi' |
| 18 | import { getCommunityId } from '@/api/community/communityApi' | 17 | import { getCommunityId } from '@/api/community/communityApi' |
| 19 | 18 | ||
| 20 | export default { | 19 | export default { |
| 21 | name: 'OrgTreeShow', | 20 | name: 'OrgTreeShow', |
| 21 | + props: { | ||
| 22 | + callBackListener: { | ||
| 23 | + type: String, | ||
| 24 | + required: true | ||
| 25 | + } | ||
| 26 | + }, | ||
| 22 | data() { | 27 | data() { |
| 23 | return { | 28 | return { |
| 24 | - orgData: [], | 29 | + orgTreeShowInfo: { |
| 30 | + orgs: [], | ||
| 31 | + orgId: '', | ||
| 32 | + curOrg: {} | ||
| 33 | + }, | ||
| 25 | defaultProps: { | 34 | defaultProps: { |
| 26 | children: 'children', | 35 | children: 'children', |
| 27 | label: 'text' | 36 | label: 'text' |
| 28 | - }, | ||
| 29 | - communityId: getCommunityId() | 37 | + } |
| 30 | } | 38 | } |
| 31 | }, | 39 | }, |
| 40 | + mounted() { | ||
| 41 | + this._loadOrgsShow() | ||
| 42 | + }, | ||
| 32 | methods: { | 43 | methods: { |
| 33 | - async refreshTree() { | 44 | + refreshTree() { |
| 45 | + this._loadOrgsShow() | ||
| 46 | + }, | ||
| 47 | + async _loadOrgsShow() { | ||
| 34 | try { | 48 | try { |
| 35 | const params = { | 49 | const params = { |
| 36 | - communityId: this.communityId | 50 | + communityId: getCommunityId() |
| 37 | } | 51 | } |
| 38 | - const res = await listOrgTree(params) | ||
| 39 | - this.orgData = res.data | 52 | + const { data } = await listOrgTree(params) |
| 53 | + this.orgTreeShowInfo.orgs = data | ||
| 40 | } catch (error) { | 54 | } catch (error) { |
| 41 | - this.$message.error(this.$t('orgTree.loadFailed')) | 55 | + console.error('加载组织树失败:', error) |
| 42 | } | 56 | } |
| 43 | }, | 57 | }, |
| 44 | handleNodeClick(data) { | 58 | handleNodeClick(data) { |
| 45 | - this.$emit('switchOrg', { | 59 | + this.orgTreeShowInfo.curOrg = data |
| 60 | + this.orgTreeShowInfo.curOrg.orgId = data.id | ||
| 61 | + this.$emit(this.callBackListener, 'switchOrg', { | ||
| 46 | orgId: data.id, | 62 | orgId: data.id, |
| 47 | orgName: data.text | 63 | orgName: data.text |
| 48 | }) | 64 | }) |
| 49 | } | 65 | } |
| 50 | - }, | ||
| 51 | - mounted() { | ||
| 52 | - this.refreshTree() | ||
| 53 | } | 66 | } |
| 54 | } | 67 | } |
| 55 | </script> | 68 | </script> |
| 56 | 69 | ||
| 57 | <style lang="scss" scoped> | 70 | <style lang="scss" scoped> |
| 58 | -.org-tree-container { | ||
| 59 | - height: 500px; | ||
| 60 | - overflow-y: auto; | ||
| 61 | - padding: 10px; | ||
| 62 | - | 71 | +.org-tree-show { |
| 63 | ::v-deep .el-tree { | 72 | ::v-deep .el-tree { |
| 64 | - background-color: transparent; | ||
| 65 | - | 73 | + background: transparent; |
| 66 | .el-tree-node__content { | 74 | .el-tree-node__content { |
| 67 | height: 36px; | 75 | height: 36px; |
| 68 | - | ||
| 69 | &:hover { | 76 | &:hover { |
| 70 | background-color: #f5f7fa; | 77 | background-color: #f5f7fa; |
| 71 | } | 78 | } |
| 72 | } | 79 | } |
| 73 | - | ||
| 74 | .is-current > .el-tree-node__content { | 80 | .is-current > .el-tree-node__content { |
| 75 | background-color: #ecf5ff; | 81 | background-color: #ecf5ff; |
| 82 | + color: #409eff; | ||
| 76 | } | 83 | } |
| 77 | } | 84 | } |
| 78 | } | 85 | } |
src/components/oa/selectStaff.vue
| 1 | <template> | 1 | <template> |
| 2 | - <el-dialog | ||
| 3 | - :title="$t('selectStaff.title')" | ||
| 4 | - :visible.sync="visible" | 2 | + <el-dialog |
| 3 | + :title="$t('selectStaff.title')" | ||
| 4 | + :visible.sync="visible" | ||
| 5 | width="70%" | 5 | width="70%" |
| 6 | - :close-on-click-modal="false" | 6 | + top="5vh" |
| 7 | > | 7 | > |
| 8 | <el-row :gutter="20"> | 8 | <el-row :gutter="20"> |
| 9 | <el-col :span="12" class="border-right"> | 9 | <el-col :span="12" class="border-right"> |
| 10 | - <div class="text-center mb-20"> | ||
| 11 | - <h4>{{ $t('selectStaff.orgInfo') }}</h4> | 10 | + <div class="text-center section-title"> |
| 11 | + {{ $t('selectStaff.orgInfo') }} | ||
| 12 | + </div> | ||
| 13 | + <div class="org-tree-container"> | ||
| 14 | + <org-tree-show | ||
| 15 | + ref="orgTree" | ||
| 16 | + :call-back-listener="'selectStaff'" | ||
| 17 | + /> | ||
| 12 | </div> | 18 | </div> |
| 13 | - <org-tree-show | ||
| 14 | - ref="orgTree" | ||
| 15 | - @switchOrg="handleSwitchOrg" | ||
| 16 | - ></org-tree-show> | ||
| 17 | </el-col> | 19 | </el-col> |
| 18 | - | ||
| 19 | <el-col :span="12"> | 20 | <el-col :span="12"> |
| 20 | - <div class="text-center mb-20"> | ||
| 21 | - <h4>{{ $t('selectStaff.staffInfo') }}</h4> | 21 | + <div class="text-center section-title"> |
| 22 | + {{ $t('selectStaff.staffInfo') }} | ||
| 22 | </div> | 23 | </div> |
| 23 | <div class="staff-list"> | 24 | <div class="staff-list"> |
| 24 | - <div | ||
| 25 | - v-for="(staff, index) in staffList" | ||
| 26 | - :key="index" | ||
| 27 | - class="staff-item" | ||
| 28 | - :class="{ 'selected': currentStaffId === staff.staffId }" | ||
| 29 | - @click="handleSelectStaff(staff)" | 25 | + <div |
| 26 | + v-for="(item, index) in selectStaffInfo.staffs" | ||
| 27 | + :key="index" | ||
| 28 | + class="staff-item" | ||
| 29 | + :class="{ 'selected': selectStaffInfo.curStaffId === item.staffId }" | ||
| 30 | + @click="_changeStaff(item)" | ||
| 30 | > | 31 | > |
| 31 | <div> | 32 | <div> |
| 32 | <i class="el-icon-user"></i> | 33 | <i class="el-icon-user"></i> |
| 33 | - {{ staff.name }} | 34 | + {{ item.name }} |
| 34 | </div> | 35 | </div> |
| 35 | - <div>{{ staff.tel }}</div> | 36 | + <div>{{ item.tel }}</div> |
| 36 | </div> | 37 | </div> |
| 37 | </div> | 38 | </div> |
| 38 | </el-col> | 39 | </el-col> |
| 39 | </el-row> | 40 | </el-row> |
| 40 | - | ||
| 41 | - <div | ||
| 42 | - v-if="staffData.from === 'bpmn' || staffData.from === 'purchase' || staffData.from === 'contract'" | ||
| 43 | - slot="footer" | 41 | + <div |
| 42 | + v-if="selectStaffInfo.staff.from === 'bpmn' || | ||
| 43 | + selectStaffInfo.staff.from === 'purchase' || | ||
| 44 | + selectStaffInfo.staff.from === 'contract'" | ||
| 45 | + slot="footer" | ||
| 44 | class="dialog-footer" | 46 | class="dialog-footer" |
| 45 | > | 47 | > |
| 46 | - <el-button @click="handleFirstUser">{{ $t('selectStaff.submitter') }}</el-button> | ||
| 47 | - <el-button @click="handleCustomUser">{{ $t('selectStaff.dynamicAssign') }}</el-button> | 48 | + <el-button @click="_firstUser"> |
| 49 | + {{ $t('selectStaff.submitter') }} | ||
| 50 | + </el-button> | ||
| 51 | + <el-button @click="_customUser"> | ||
| 52 | + {{ $t('selectStaff.dynamicAssign') }} | ||
| 53 | + </el-button> | ||
| 48 | </div> | 54 | </div> |
| 49 | </el-dialog> | 55 | </el-dialog> |
| 50 | </template> | 56 | </template> |
| 51 | 57 | ||
| 52 | <script> | 58 | <script> |
| 59 | +import { queryStaffInfos } from '@/api/oa/editWorkApi' | ||
| 53 | import OrgTreeShow from './OrgTreeShow' | 60 | import OrgTreeShow from './OrgTreeShow' |
| 54 | -import { queryStaffInfos } from '@/api/oa/addAttendanceClassesStaffApi' | ||
| 55 | 61 | ||
| 56 | export default { | 62 | export default { |
| 57 | name: 'SelectStaff', | 63 | name: 'SelectStaff', |
| @@ -61,95 +67,108 @@ export default { | @@ -61,95 +67,108 @@ export default { | ||
| 61 | data() { | 67 | data() { |
| 62 | return { | 68 | return { |
| 63 | visible: false, | 69 | visible: false, |
| 64 | - staffData: {}, | ||
| 65 | - staffList: [], | ||
| 66 | - currentStaffId: '', | ||
| 67 | - currentOrgId: '' | 70 | + selectStaffInfo: { |
| 71 | + staffs: [], | ||
| 72 | + curStaffId: '', | ||
| 73 | + curStaffName: '', | ||
| 74 | + staff: {} | ||
| 75 | + } | ||
| 68 | } | 76 | } |
| 69 | }, | 77 | }, |
| 70 | methods: { | 78 | methods: { |
| 71 | open(staff) { | 79 | open(staff) { |
| 72 | - this.staffData = staff | 80 | + this.selectStaffInfo.staff = staff || {} |
| 73 | this.visible = true | 81 | this.visible = true |
| 74 | this.$nextTick(() => { | 82 | this.$nextTick(() => { |
| 75 | this.$refs.orgTree.refreshTree() | 83 | this.$refs.orgTree.refreshTree() |
| 76 | }) | 84 | }) |
| 77 | }, | 85 | }, |
| 78 | - async handleSwitchOrg(org) { | ||
| 79 | - this.currentOrgId = org.orgId | 86 | + _changeStaff(item) { |
| 87 | + this.selectStaffInfo.staff.staffId = item.userId | ||
| 88 | + this.selectStaffInfo.staff.staffName = item.userName | ||
| 89 | + this.selectStaffInfo.staff.staffTel = item.tel | ||
| 90 | + this.visible = false | ||
| 91 | + if (typeof this.selectStaffInfo.staff.call === 'function') { | ||
| 92 | + this.selectStaffInfo.staff.call(this.selectStaffInfo.staff) | ||
| 93 | + } | ||
| 94 | + }, | ||
| 95 | + async loadStaff(org) { | ||
| 80 | try { | 96 | try { |
| 81 | const params = { | 97 | const params = { |
| 82 | page: 1, | 98 | page: 1, |
| 99 | + rows: 50, | ||
| 83 | row: 50, | 100 | row: 50, |
| 84 | orgId: org.orgId | 101 | orgId: org.orgId |
| 85 | } | 102 | } |
| 86 | - const res = await queryStaffInfos(params) | ||
| 87 | - this.staffList = res.data.staffs | ||
| 88 | - if (this.staffList.length > 0) { | ||
| 89 | - this.currentStaffId = this.staffList[0].staffId | 103 | + const { data } = await queryStaffInfos(params) |
| 104 | + this.selectStaffInfo.staffs = data.staffs | ||
| 105 | + if (data.staffs.length > 0) { | ||
| 106 | + this.selectStaffInfo.curStaffId = data.staffs[0].orgId | ||
| 90 | } | 107 | } |
| 91 | } catch (error) { | 108 | } catch (error) { |
| 92 | - this.$message.error(this.$t('selectStaff.loadStaffFailed')) | 109 | + console.error('加载员工失败:', error) |
| 93 | } | 110 | } |
| 94 | }, | 111 | }, |
| 95 | - handleSelectStaff(staff) { | ||
| 96 | - this.$emit('change', { | ||
| 97 | - staffId: staff.userId, | ||
| 98 | - staffName: staff.userName, | ||
| 99 | - staffTel: staff.tel | ||
| 100 | - }) | ||
| 101 | - this.visible = false | ||
| 102 | - }, | ||
| 103 | - handleFirstUser() { | ||
| 104 | - this.$emit('change', { | ||
| 105 | - staffId: '${startUserId}', | ||
| 106 | - staffName: this.$t('selectStaff.submitter') | ||
| 107 | - }) | 112 | + _firstUser() { |
| 113 | + this.selectStaffInfo.staff.staffId = '${startUserId}' | ||
| 114 | + this.selectStaffInfo.staff.staffName = this.$t('selectStaff.submitter') | ||
| 108 | this.visible = false | 115 | this.visible = false |
| 116 | + if (typeof this.selectStaffInfo.staff.call === 'function') { | ||
| 117 | + this.selectStaffInfo.staff.call(this.selectStaffInfo.staff) | ||
| 118 | + } | ||
| 109 | }, | 119 | }, |
| 110 | - handleCustomUser() { | ||
| 111 | - this.$emit('change', { | ||
| 112 | - staffId: '${nextUserId}', | ||
| 113 | - staffName: this.$t('selectStaff.dynamicAssign') | ||
| 114 | - }) | 120 | + _customUser() { |
| 121 | + this.selectStaffInfo.staff.staffId = '${nextUserId}' | ||
| 122 | + this.selectStaffInfo.staff.staffName = this.$t('selectStaff.dynamicAssign') | ||
| 115 | this.visible = false | 123 | this.visible = false |
| 124 | + if (typeof this.selectStaffInfo.staff.call === 'function') { | ||
| 125 | + this.selectStaffInfo.staff.call(this.selectStaffInfo.staff) | ||
| 126 | + } | ||
| 116 | } | 127 | } |
| 128 | + }, | ||
| 129 | + created() { | ||
| 130 | + this.$on('selectStaff', 'switchOrg', this.loadStaff) | ||
| 117 | } | 131 | } |
| 118 | } | 132 | } |
| 119 | </script> | 133 | </script> |
| 120 | 134 | ||
| 121 | <style lang="scss" scoped> | 135 | <style lang="scss" scoped> |
| 122 | .border-right { | 136 | .border-right { |
| 123 | - border-right: 1px solid #ebeef5; | 137 | + border-right: 1px solid #eee; |
| 124 | } | 138 | } |
| 125 | 139 | ||
| 126 | -.text-center { | ||
| 127 | - text-align: center; | 140 | +.section-title { |
| 141 | + font-weight: bold; | ||
| 142 | + margin-bottom: 15px; | ||
| 128 | } | 143 | } |
| 129 | 144 | ||
| 130 | -.mb-20 { | ||
| 131 | - margin-bottom: 20px; | 145 | +.org-tree-container { |
| 146 | + padding: 10px; | ||
| 147 | + height: 500px; | ||
| 148 | + overflow-y: auto; | ||
| 132 | } | 149 | } |
| 133 | 150 | ||
| 134 | .staff-list { | 151 | .staff-list { |
| 135 | - max-height: 500px; | 152 | + padding: 10px; |
| 153 | + height: 500px; | ||
| 136 | overflow-y: auto; | 154 | overflow-y: auto; |
| 137 | } | 155 | } |
| 138 | 156 | ||
| 139 | .staff-item { | 157 | .staff-item { |
| 140 | padding: 10px; | 158 | padding: 10px; |
| 141 | margin-bottom: 5px; | 159 | margin-bottom: 5px; |
| 142 | - border: 1px solid #ebeef5; | ||
| 143 | border-radius: 4px; | 160 | border-radius: 4px; |
| 144 | cursor: pointer; | 161 | cursor: pointer; |
| 145 | - | ||
| 146 | &:hover { | 162 | &:hover { |
| 147 | background-color: #f5f7fa; | 163 | background-color: #f5f7fa; |
| 148 | } | 164 | } |
| 149 | - | ||
| 150 | &.selected { | 165 | &.selected { |
| 151 | background-color: #ecf5ff; | 166 | background-color: #ecf5ff; |
| 152 | - border-color: #d9ecff; | 167 | + color: #409eff; |
| 153 | } | 168 | } |
| 154 | } | 169 | } |
| 170 | + | ||
| 171 | +.dialog-footer { | ||
| 172 | + text-align: right; | ||
| 173 | +} | ||
| 155 | </style> | 174 | </style> |
| 156 | \ No newline at end of file | 175 | \ No newline at end of file |
src/components/oa/textarea.vue
0 → 100644
| 1 | +<template> | ||
| 2 | + <div class="textarea-container"> | ||
| 3 | + <div ref="editor" class="editor"></div> | ||
| 4 | + </div> | ||
| 5 | +</template> | ||
| 6 | + | ||
| 7 | +<script> | ||
| 8 | +import { uploadImage } from '@/api/oa/editWorkApi' | ||
| 9 | +import { getCommunityId } from '@/api/community/communityApi' | ||
| 10 | + | ||
| 11 | +export default { | ||
| 12 | + name: 'TextareaEditor', | ||
| 13 | + data() { | ||
| 14 | + return { | ||
| 15 | + content: '' | ||
| 16 | + } | ||
| 17 | + }, | ||
| 18 | + mounted() { | ||
| 19 | + this._initEditor() | ||
| 20 | + }, | ||
| 21 | + methods: { | ||
| 22 | + _initEditor() { | ||
| 23 | + $(this.$refs.editor).summernote({ | ||
| 24 | + lang: 'zh-CN', | ||
| 25 | + height: 300, | ||
| 26 | + placeholder: this.$t('textarea.placeholder'), | ||
| 27 | + callbacks: { | ||
| 28 | + onImageUpload: (files) => { | ||
| 29 | + this._uploadImage(files[0]) | ||
| 30 | + }, | ||
| 31 | + onChange: (contents) => { | ||
| 32 | + this.content = contents.replace(/ /g, '').replace(/\s/gi, '') | ||
| 33 | + this.$emit('change', this.content) | ||
| 34 | + } | ||
| 35 | + }, | ||
| 36 | + toolbar: [ | ||
| 37 | + ['style', ['style']], | ||
| 38 | + ['font', ['bold', 'italic', 'underline', 'clear']], | ||
| 39 | + ['fontname', ['fontname']], | ||
| 40 | + ['color', ['color']], | ||
| 41 | + ['para', ['ul', 'ol', 'paragraph']], | ||
| 42 | + ['height', ['height']], | ||
| 43 | + ['table', ['table']], | ||
| 44 | + ['insert', ['link', 'picture']] | ||
| 45 | + ] | ||
| 46 | + }) | ||
| 47 | + }, | ||
| 48 | + setText(content) { | ||
| 49 | + $(this.$refs.editor).summernote('code', content) | ||
| 50 | + }, | ||
| 51 | + async _uploadImage(file) { | ||
| 52 | + const formData = new FormData() | ||
| 53 | + formData.append('uploadFile', file) | ||
| 54 | + formData.append('communityId', getCommunityId()) | ||
| 55 | + | ||
| 56 | + try { | ||
| 57 | + const res = await uploadImage(formData) | ||
| 58 | + $(this.$refs.editor).summernote('insertImage', res.url) | ||
| 59 | + } catch (error) { | ||
| 60 | + console.error('上传图片失败:', error) | ||
| 61 | + this.$message.error(this.$t('textarea.uploadFailed')) | ||
| 62 | + } | ||
| 63 | + } | ||
| 64 | + } | ||
| 65 | +} | ||
| 66 | +</script> | ||
| 67 | + | ||
| 68 | +<style lang="scss" scoped> | ||
| 69 | +.textarea-container { | ||
| 70 | + .editor { | ||
| 71 | + width: 100%; | ||
| 72 | + } | ||
| 73 | +} | ||
| 74 | +</style> | ||
| 0 | \ No newline at end of file | 75 | \ No newline at end of file |
src/components/oa/uploadFile.vue
0 → 100644
| 1 | +<template> | ||
| 2 | + <div class="upload-file-container"> | ||
| 3 | + <el-progress | ||
| 4 | + v-if="uploadFileInfo.progress > 0" | ||
| 5 | + :percentage="uploadFileInfo.progress" | ||
| 6 | + :stroke-width="2" | ||
| 7 | + /> | ||
| 8 | + <div v-if="uploadFileInfo.progress > 0" class="file-name"> | ||
| 9 | + {{ uploadFileInfo.fileName }} | ||
| 10 | + </div> | ||
| 11 | + <div> | ||
| 12 | + <el-button | ||
| 13 | + type="primary" | ||
| 14 | + size="small" | ||
| 15 | + @click="_uploadFile" | ||
| 16 | + > | ||
| 17 | + {{ $t('uploadFile.upload') }} | ||
| 18 | + </el-button> | ||
| 19 | + <input | ||
| 20 | + ref="fileInput" | ||
| 21 | + type="file" | ||
| 22 | + class="file-input" | ||
| 23 | + accept="*" | ||
| 24 | + capture="camcorder" | ||
| 25 | + @change="_chooseFile" | ||
| 26 | + > | ||
| 27 | + </div> | ||
| 28 | + </div> | ||
| 29 | +</template> | ||
| 30 | + | ||
| 31 | +<script> | ||
| 32 | +import { uploadFile } from '@/api/oa/editWorkApi' | ||
| 33 | + | ||
| 34 | +export default { | ||
| 35 | + name: 'UploadFile', | ||
| 36 | + props: { | ||
| 37 | + callBackListener: { | ||
| 38 | + type: String, | ||
| 39 | + default: '' | ||
| 40 | + }, | ||
| 41 | + callBackFunction: { | ||
| 42 | + type: String, | ||
| 43 | + default: '' | ||
| 44 | + } | ||
| 45 | + }, | ||
| 46 | + data() { | ||
| 47 | + return { | ||
| 48 | + uploadFileInfo: { | ||
| 49 | + vedio: {}, | ||
| 50 | + fileName: '', | ||
| 51 | + realFileName: '', | ||
| 52 | + progress: 0 | ||
| 53 | + } | ||
| 54 | + } | ||
| 55 | + }, | ||
| 56 | + watch: { | ||
| 57 | + uploadFileInfo: { | ||
| 58 | + deep: true, | ||
| 59 | + handler(newVal) { | ||
| 60 | + this.$emit(this.callBackListener, this.callBackFunction, newVal) | ||
| 61 | + } | ||
| 62 | + } | ||
| 63 | + }, | ||
| 64 | + methods: { | ||
| 65 | + notifyVedio(fileName) { | ||
| 66 | + this.uploadFileInfo = { | ||
| 67 | + vedio: {}, | ||
| 68 | + fileName: fileName, | ||
| 69 | + realFileName: fileName, | ||
| 70 | + progress: 100 | ||
| 71 | + } | ||
| 72 | + }, | ||
| 73 | + clearVedio() { | ||
| 74 | + this.uploadFileInfo = { | ||
| 75 | + vedio: {}, | ||
| 76 | + fileName: '', | ||
| 77 | + realFileName: '', | ||
| 78 | + progress: 0 | ||
| 79 | + } | ||
| 80 | + }, | ||
| 81 | + _uploadFile() { | ||
| 82 | + this.$refs.fileInput.click() | ||
| 83 | + }, | ||
| 84 | + _chooseFile(event) { | ||
| 85 | + const files = event.target.files | ||
| 86 | + if (files && files.length > 0) { | ||
| 87 | + const file = files[0] | ||
| 88 | + if (file.size > 1024 * 1024 * 20) { | ||
| 89 | + this.$message.error(this.$t('uploadFile.sizeLimit')) | ||
| 90 | + return false | ||
| 91 | + } | ||
| 92 | + this.uploadFileInfo.fileName = file.name | ||
| 93 | + this._doUploadFile(file) | ||
| 94 | + } | ||
| 95 | + }, | ||
| 96 | + async _doUploadFile(file) { | ||
| 97 | + const formData = new FormData() | ||
| 98 | + formData.append('uploadFile', file) | ||
| 99 | + | ||
| 100 | + try { | ||
| 101 | + const res = await uploadFile(formData, { | ||
| 102 | + onUploadProgress: (progressEvent) => { | ||
| 103 | + const rate = progressEvent.loaded / progressEvent.total | ||
| 104 | + if (rate < 0.9) { | ||
| 105 | + this.uploadFileInfo.progress = Math.floor(rate * 100) | ||
| 106 | + } | ||
| 107 | + } | ||
| 108 | + }) | ||
| 109 | + | ||
| 110 | + this.uploadFileInfo.progress = 100 | ||
| 111 | + this.$message.success(this.$t('uploadFile.success')) | ||
| 112 | + this.uploadFileInfo.fileName = res.fileName | ||
| 113 | + this.uploadFileInfo.realFileName = res.realFileName | ||
| 114 | + this.$emit(this.callBackListener, this.callBackFunction, res) | ||
| 115 | + } catch (error) { | ||
| 116 | + console.error('上传失败:', error) | ||
| 117 | + this.$message.error(this.$t('uploadFile.failed')) | ||
| 118 | + } | ||
| 119 | + } | ||
| 120 | + } | ||
| 121 | +} | ||
| 122 | +</script> | ||
| 123 | + | ||
| 124 | +<style lang="scss" scoped> | ||
| 125 | +.upload-file-container { | ||
| 126 | + .file-name { | ||
| 127 | + margin-bottom: 5px; | ||
| 128 | + } | ||
| 129 | + | ||
| 130 | + .file-input { | ||
| 131 | + display: none; | ||
| 132 | + } | ||
| 133 | +} | ||
| 134 | +</style> | ||
| 0 | \ No newline at end of file | 135 | \ No newline at end of file |
src/components/system/uploadFile.vue renamed to src/components/upload/uploadFile.vue
| @@ -71,7 +71,7 @@ export default { | @@ -71,7 +71,7 @@ export default { | ||
| 71 | } | 71 | } |
| 72 | } | 72 | } |
| 73 | 73 | ||
| 74 | - const { data } = await uploadFile(formData, config) | 74 | + const data = await uploadFile(formData, config) |
| 75 | this.progress = 100 | 75 | this.progress = 100 |
| 76 | this.realFileName = data.realFileName | 76 | this.realFileName = data.realFileName |
| 77 | this.$emit('notify', data) | 77 | this.$emit('notify', data) |
src/i18n/oaI18n.js
| @@ -37,7 +37,10 @@ import { messages as addAttendanceClassesStaffMessages } from '../views/oa/addAt | @@ -37,7 +37,10 @@ import { messages as addAttendanceClassesStaffMessages } from '../views/oa/addAt | ||
| 37 | import { messages as monthAttendanceManageMessages } from '../views/oa/monthAttendanceManageLang' | 37 | import { messages as monthAttendanceManageMessages } from '../views/oa/monthAttendanceManageLang' |
| 38 | import { messages as staffAttendanceManageMessages } from '../views/oa/staffAttendanceManageLang' | 38 | import { messages as staffAttendanceManageMessages } from '../views/oa/staffAttendanceManageLang' |
| 39 | import { messages as attendanceLogManageMessages } from '../views/oa/attendanceLogManageLang' | 39 | import { messages as attendanceLogManageMessages } from '../views/oa/attendanceLogManageLang' |
| 40 | - | 40 | +import { messages as workTypeMessages } from '../views/oa/workTypeLang' |
| 41 | +import { messages as startWorkMessages } from '../views/oa/startWorkLang' | ||
| 42 | +import { messages as addWorkMessages } from '../views/oa/addWorkLang' | ||
| 43 | +import { messages as editWorkMessages } from '../views/oa/editWorkLang' | ||
| 41 | export const messages ={ | 44 | export const messages ={ |
| 42 | en:{ | 45 | en:{ |
| 43 | ...activitiesTypeManageMessages.en, | 46 | ...activitiesTypeManageMessages.en, |
| @@ -78,6 +81,10 @@ export const messages ={ | @@ -78,6 +81,10 @@ export const messages ={ | ||
| 78 | ...monthAttendanceManageMessages.en, | 81 | ...monthAttendanceManageMessages.en, |
| 79 | ...staffAttendanceManageMessages.en, | 82 | ...staffAttendanceManageMessages.en, |
| 80 | ...attendanceLogManageMessages.en, | 83 | ...attendanceLogManageMessages.en, |
| 84 | + ...workTypeMessages.en, | ||
| 85 | + ...startWorkMessages.en, | ||
| 86 | + ...addWorkMessages.en, | ||
| 87 | + ...editWorkMessages.en, | ||
| 81 | }, | 88 | }, |
| 82 | zh:{ | 89 | zh:{ |
| 83 | ...activitiesTypeManageMessages.zh, | 90 | ...activitiesTypeManageMessages.zh, |
| @@ -118,5 +125,9 @@ export const messages ={ | @@ -118,5 +125,9 @@ export const messages ={ | ||
| 118 | ...monthAttendanceManageMessages.zh, | 125 | ...monthAttendanceManageMessages.zh, |
| 119 | ...staffAttendanceManageMessages.zh, | 126 | ...staffAttendanceManageMessages.zh, |
| 120 | ...attendanceLogManageMessages.zh, | 127 | ...attendanceLogManageMessages.zh, |
| 128 | + ...workTypeMessages.zh, | ||
| 129 | + ...startWorkMessages.zh, | ||
| 130 | + ...addWorkMessages.zh, | ||
| 131 | + ...editWorkMessages.zh, | ||
| 121 | } | 132 | } |
| 122 | } | 133 | } |
| 123 | \ No newline at end of file | 134 | \ No newline at end of file |
src/router/oaRouter.js
| @@ -165,13 +165,33 @@ export default [ | @@ -165,13 +165,33 @@ export default [ | ||
| 165 | component: () => import('@/views/oa/monthAttendanceManageList.vue') | 165 | component: () => import('@/views/oa/monthAttendanceManageList.vue') |
| 166 | }, | 166 | }, |
| 167 | { | 167 | { |
| 168 | - path:'/pages/property/staffAttendanceManage', | ||
| 169 | - name:'/pages/property/staffAttendanceManage', | 168 | + path: '/pages/property/staffAttendanceManage', |
| 169 | + name: '/pages/property/staffAttendanceManage', | ||
| 170 | component: () => import('@/views/oa/staffAttendanceManageList.vue') | 170 | component: () => import('@/views/oa/staffAttendanceManageList.vue') |
| 171 | + }, | ||
| 172 | + { | ||
| 173 | + path: '/pages/property/attendanceLogManage', | ||
| 174 | + name: '/pages/property/attendanceLogManage', | ||
| 175 | + component: () => import('@/views/oa/attendanceLogManageList.vue') | ||
| 176 | + }, | ||
| 177 | + { | ||
| 178 | + path: '/pages/oa/workType', | ||
| 179 | + name: '/pages/oa/workType', | ||
| 180 | + component: () => import('@/views/oa/workTypeList.vue') | ||
| 181 | + }, | ||
| 182 | + { | ||
| 183 | + path: '/pages/oa/startWork', | ||
| 184 | + name: '/pages/oa/startWork', | ||
| 185 | + component: () => import('@/views/oa/startWorkList.vue') | ||
| 186 | + }, | ||
| 187 | + { | ||
| 188 | + path:'/views/oa/addWork', | ||
| 189 | + name:'/views/oa/addWork', | ||
| 190 | + component: () => import('@/views/oa/addWorkList.vue') | ||
| 171 | }, | 191 | }, |
| 172 | { | 192 | { |
| 173 | - path:'/pages/property/attendanceLogManage', | ||
| 174 | - name:'/pages/property/attendanceLogManage', | ||
| 175 | - component: () => import('@/views/oa/attendanceLogManageList.vue') | 193 | + path:'/views/oa/editWork', |
| 194 | + name:'/views/oa/editWork', | ||
| 195 | + component: () => import('@/views/oa/editWorkList.vue') | ||
| 176 | }, | 196 | }, |
| 177 | ] | 197 | ] |
| 178 | \ No newline at end of file | 198 | \ No newline at end of file |
src/views/oa/addWorkLang.js
0 → 100644
| 1 | +export const messages = { | ||
| 2 | + en: { | ||
| 3 | + addWork: { | ||
| 4 | + title: 'Create Work Order', | ||
| 5 | + workName: 'Title', | ||
| 6 | + workNamePlaceholder: 'Required, please enter title', | ||
| 7 | + workType: 'Work Order Type', | ||
| 8 | + workTypePlaceholder: 'Required, please select work order type', | ||
| 9 | + processor: 'Processor', | ||
| 10 | + cc: 'CC', | ||
| 11 | + choose: 'Choose', | ||
| 12 | + workCycle: 'Work Order Flag', | ||
| 13 | + workCyclePlaceholder: 'Required, please select work order flag', | ||
| 14 | + onceWork: 'One-time Work Order', | ||
| 15 | + periodWork: 'Periodic Work Order', | ||
| 16 | + attachment: 'Attachment', | ||
| 17 | + startTime: 'Start Time', | ||
| 18 | + startTimePlaceholder: 'Required, please enter start time', | ||
| 19 | + endTime: 'End Time', | ||
| 20 | + endTimePlaceholder: 'Required, please enter end time', | ||
| 21 | + period: 'Period', | ||
| 22 | + periodPlaceholder: 'Required, please select task period', | ||
| 23 | + monthDay: 'Month/Day', | ||
| 24 | + week: 'By Week', | ||
| 25 | + hours: 'Work Order', | ||
| 26 | + hoursPlaceholder: 'Required, please enter hours', | ||
| 27 | + hoursUnit: 'hours to complete', | ||
| 28 | + month: 'Month', | ||
| 29 | + monthUnit: 'Month', | ||
| 30 | + day: 'Day', | ||
| 31 | + dayUnit: 'Day', | ||
| 32 | + monday: 'Monday', | ||
| 33 | + tuesday: 'Tuesday', | ||
| 34 | + wednesday: 'Wednesday', | ||
| 35 | + thursday: 'Thursday', | ||
| 36 | + friday: 'Friday', | ||
| 37 | + saturday: 'Saturday', | ||
| 38 | + sunday: 'Sunday', | ||
| 39 | + content: 'Content', | ||
| 40 | + contentPlaceholder: 'Required, please enter content', | ||
| 41 | + addContent: 'Add', | ||
| 42 | + deleteContent: 'Delete' | ||
| 43 | + }, | ||
| 44 | + uploadFile: { | ||
| 45 | + upload: 'Upload Attachment', | ||
| 46 | + sizeLimit: 'File size cannot exceed 20MB', | ||
| 47 | + success: 'File uploaded successfully', | ||
| 48 | + failed: 'File upload failed' | ||
| 49 | + }, | ||
| 50 | + selectStaff: { | ||
| 51 | + title: 'Select Staff', | ||
| 52 | + orgInfo: 'Organization Information', | ||
| 53 | + staffInfo: 'Staff Information', | ||
| 54 | + submitter: 'Submitter', | ||
| 55 | + dynamicAssign: 'Dynamic Assignment' | ||
| 56 | + } | ||
| 57 | + }, | ||
| 58 | + zh: { | ||
| 59 | + addWork: { | ||
| 60 | + title: '发起工作单', | ||
| 61 | + workName: '标题', | ||
| 62 | + workNamePlaceholder: '必填,请填写标题', | ||
| 63 | + workType: '工作单类型', | ||
| 64 | + workTypePlaceholder: '必填,请选择工作单类型', | ||
| 65 | + processor: '处理人', | ||
| 66 | + cc: '抄送人', | ||
| 67 | + choose: '选择', | ||
| 68 | + workCycle: '工作单标识', | ||
| 69 | + workCyclePlaceholder: '必填,请选择工作单标识', | ||
| 70 | + onceWork: '一次性工单', | ||
| 71 | + periodWork: '周期性工单', | ||
| 72 | + attachment: '附件', | ||
| 73 | + startTime: '开始时间', | ||
| 74 | + startTimePlaceholder: '必填,请填写开始时间', | ||
| 75 | + endTime: '结束时间', | ||
| 76 | + endTimePlaceholder: '必填,请填写结束时间', | ||
| 77 | + period: '周期', | ||
| 78 | + periodPlaceholder: '必填,请选择任务周期', | ||
| 79 | + monthDay: '月/天', | ||
| 80 | + week: '按周', | ||
| 81 | + hours: '工作单', | ||
| 82 | + hoursPlaceholder: '必填,请输入小时数', | ||
| 83 | + hoursUnit: '小时内完成', | ||
| 84 | + month: '月', | ||
| 85 | + monthUnit: '月', | ||
| 86 | + day: '日', | ||
| 87 | + dayUnit: '日', | ||
| 88 | + monday: '星期一', | ||
| 89 | + tuesday: '星期二', | ||
| 90 | + wednesday: '星期三', | ||
| 91 | + thursday: '星期四', | ||
| 92 | + friday: '星期五', | ||
| 93 | + saturday: '星期六', | ||
| 94 | + sunday: '星期日', | ||
| 95 | + content: '内容', | ||
| 96 | + contentPlaceholder: '必填,请输入内容', | ||
| 97 | + addContent: '添加', | ||
| 98 | + deleteContent: '删除' | ||
| 99 | + }, | ||
| 100 | + uploadFile: { | ||
| 101 | + upload: '上传附件', | ||
| 102 | + sizeLimit: '文件大小不能超过20MB', | ||
| 103 | + success: '文件上传成功', | ||
| 104 | + failed: '文件上传失败' | ||
| 105 | + }, | ||
| 106 | + selectStaff: { | ||
| 107 | + title: '选择员工', | ||
| 108 | + orgInfo: '组织信息', | ||
| 109 | + staffInfo: '员工信息', | ||
| 110 | + submitter: '提交者', | ||
| 111 | + dynamicAssign: '动态指定' | ||
| 112 | + } | ||
| 113 | + } | ||
| 114 | +} | ||
| 0 | \ No newline at end of file | 115 | \ No newline at end of file |
src/views/oa/addWorkList.vue
0 → 100644
| 1 | +<template> | ||
| 2 | + <div class="add-work-container"> | ||
| 3 | + <el-card class="box-card"> | ||
| 4 | + <div slot="header" class="clearfix"> | ||
| 5 | + <span>{{ $t('addWork.title') }}</span> | ||
| 6 | + </div> | ||
| 7 | + | ||
| 8 | + <el-form ref="form" :model="addWorkInfo" label-width="120px" label-position="right"> | ||
| 9 | + <el-row :gutter="20"> | ||
| 10 | + <el-col :span="12"> | ||
| 11 | + <el-form-item :label="$t('addWork.workName')" prop="workName"> | ||
| 12 | + <el-input v-model.trim="addWorkInfo.workName" :placeholder="$t('addWork.workNamePlaceholder')" | ||
| 13 | + maxlength="20" clearable /> | ||
| 14 | + </el-form-item> | ||
| 15 | + </el-col> | ||
| 16 | + <el-col :span="12"> | ||
| 17 | + <el-form-item :label="$t('addWork.workType')" prop="wtId"> | ||
| 18 | + <el-select v-model="addWorkInfo.wtId" :placeholder="$t('addWork.workTypePlaceholder')" style="width:100%" | ||
| 19 | + clearable> | ||
| 20 | + <el-option v-for="item in addWorkInfo.workTypes" :key="item.wtId" :label="item.typeName" | ||
| 21 | + :value="item.wtId" /> | ||
| 22 | + </el-select> | ||
| 23 | + </el-form-item> | ||
| 24 | + </el-col> | ||
| 25 | + </el-row> | ||
| 26 | + | ||
| 27 | + <el-row :gutter="20"> | ||
| 28 | + <el-col :span="12"> | ||
| 29 | + <el-form-item :label="$t('addWork.processor')"> | ||
| 30 | + <div class="staff-tags"> | ||
| 31 | + <el-tag v-for="(staff, index) in addWorkInfo.staffs" :key="index" closable | ||
| 32 | + @close="_deleteWorkStaff(staff)"> | ||
| 33 | + {{ staff.staffName }} | ||
| 34 | + </el-tag> | ||
| 35 | + <el-button type="text" @click="_chooseWorkStaff"> | ||
| 36 | + <i class="el-icon-search"></i>{{ $t('addWork.choose') }} | ||
| 37 | + </el-button> | ||
| 38 | + </div> | ||
| 39 | + </el-form-item> | ||
| 40 | + </el-col> | ||
| 41 | + <el-col :span="12"> | ||
| 42 | + <el-form-item :label="$t('addWork.cc')"> | ||
| 43 | + <div class="staff-tags"> | ||
| 44 | + <el-tag v-for="(staff, index) in addWorkInfo.copyStaffs" :key="index" closable | ||
| 45 | + @close="_deleteCopyWorkStaff(staff)"> | ||
| 46 | + {{ staff.staffName }} | ||
| 47 | + </el-tag> | ||
| 48 | + <el-button type="text" @click="_chooseCopyWorkStaff"> | ||
| 49 | + <i class="el-icon-search"></i>{{ $t('addWork.choose') }} | ||
| 50 | + </el-button> | ||
| 51 | + </div> | ||
| 52 | + </el-form-item> | ||
| 53 | + </el-col> | ||
| 54 | + </el-row> | ||
| 55 | + | ||
| 56 | + <el-row :gutter="20"> | ||
| 57 | + <el-col :span="12"> | ||
| 58 | + <el-form-item :label="$t('addWork.workCycle')" prop="workCycle"> | ||
| 59 | + <el-select v-model="addWorkInfo.workCycle" :placeholder="$t('addWork.workCyclePlaceholder')" | ||
| 60 | + style="width:100%" @change="handleWorkCycleChange"> | ||
| 61 | + <el-option :label="$t('addWork.onceWork')" value="1001" /> | ||
| 62 | + <el-option :label="$t('addWork.periodWork')" value="2002" /> | ||
| 63 | + </el-select> | ||
| 64 | + </el-form-item> | ||
| 65 | + </el-col> | ||
| 66 | + <el-col :span="12"> | ||
| 67 | + <el-form-item :label="$t('addWork.attachment')"> | ||
| 68 | + <upload-file ref="uploadFile" @notifyFile="notifyFile" /> | ||
| 69 | + </el-form-item> | ||
| 70 | + </el-col> | ||
| 71 | + </el-row> | ||
| 72 | + | ||
| 73 | + <el-row :gutter="20"> | ||
| 74 | + <el-col :span="12"> | ||
| 75 | + <el-form-item :label="$t('addWork.startTime')" prop="startTime"> | ||
| 76 | + <el-date-picker v-model="addWorkInfo.startTime" type="datetime" value-format="yyyy-MM-dd HH:mm:ss" | ||
| 77 | + :placeholder="$t('addWork.startTimePlaceholder')" style="width:100%" /> | ||
| 78 | + </el-form-item> | ||
| 79 | + </el-col> | ||
| 80 | + <el-col :span="12"> | ||
| 81 | + <el-form-item :label="$t('addWork.endTime')" prop="endTime"> | ||
| 82 | + <el-date-picker v-model="addWorkInfo.endTime" type="datetime" value-format="yyyy-MM-dd HH:mm:ss" | ||
| 83 | + :placeholder="$t('addWork.endTimePlaceholder')" style="width:100%" /> | ||
| 84 | + </el-form-item> | ||
| 85 | + </el-col> | ||
| 86 | + </el-row> | ||
| 87 | + | ||
| 88 | + <template v-if="addWorkInfo.workCycle === '2002'"> | ||
| 89 | + <el-row :gutter="20"> | ||
| 90 | + <el-col :span="12"> | ||
| 91 | + <el-form-item :label="$t('addWork.period')" prop="period"> | ||
| 92 | + <el-select v-model="addWorkInfo.period" :placeholder="$t('addWork.periodPlaceholder')" | ||
| 93 | + style="width:100%"> | ||
| 94 | + <el-option :label="$t('addWork.monthDay')" value="2020022" /> | ||
| 95 | + <el-option :label="$t('addWork.week')" value="2020023" /> | ||
| 96 | + </el-select> | ||
| 97 | + </el-form-item> | ||
| 98 | + </el-col> | ||
| 99 | + <el-col :span="12"> | ||
| 100 | + <el-form-item :label="$t('addWork.hours')" prop="hours"> | ||
| 101 | + <el-input v-model.trim="addWorkInfo.hours" :placeholder="$t('addWork.hoursPlaceholder')"> | ||
| 102 | + <template slot="append">{{ $t('addWork.hoursUnit') }}</template> | ||
| 103 | + </el-input> | ||
| 104 | + </el-form-item> | ||
| 105 | + </el-col> | ||
| 106 | + </el-row> | ||
| 107 | + | ||
| 108 | + <template v-if="addWorkInfo.period === '2020022'"> | ||
| 109 | + <el-row :gutter="20"> | ||
| 110 | + <el-col :span="24"> | ||
| 111 | + <el-form-item :label="$t('addWork.month')"> | ||
| 112 | + <el-checkbox-group v-model="addWorkInfo.months"> | ||
| 113 | + <el-checkbox v-for="index in 12" :key="index" :label="index"> | ||
| 114 | + {{ index }}{{ $t('addWork.monthUnit') }} | ||
| 115 | + </el-checkbox> | ||
| 116 | + </el-checkbox-group> | ||
| 117 | + </el-form-item> | ||
| 118 | + </el-col> | ||
| 119 | + </el-row> | ||
| 120 | + | ||
| 121 | + <el-row :gutter="20"> | ||
| 122 | + <el-col :span="24"> | ||
| 123 | + <el-form-item :label="$t('addWork.day')"> | ||
| 124 | + <el-checkbox-group v-model="addWorkInfo.days"> | ||
| 125 | + <el-checkbox v-for="index in 31" :key="index" :label="index"> | ||
| 126 | + {{ index }}{{ $t('addWork.dayUnit') }} | ||
| 127 | + </el-checkbox> | ||
| 128 | + </el-checkbox-group> | ||
| 129 | + </el-form-item> | ||
| 130 | + </el-col> | ||
| 131 | + </el-row> | ||
| 132 | + </template> | ||
| 133 | + | ||
| 134 | + <template v-if="addWorkInfo.period === '2020023'"> | ||
| 135 | + <el-row :gutter="20"> | ||
| 136 | + <el-col :span="24"> | ||
| 137 | + <el-form-item :label="$t('addWork.week')"> | ||
| 138 | + <el-checkbox-group v-model="addWorkInfo.workdays"> | ||
| 139 | + <el-checkbox v-for="(day, index) in weekDays" :key="index" :label="index + 1"> | ||
| 140 | + {{ day }} | ||
| 141 | + </el-checkbox> | ||
| 142 | + </el-checkbox-group> | ||
| 143 | + </el-form-item> | ||
| 144 | + </el-col> | ||
| 145 | + </el-row> | ||
| 146 | + </template> | ||
| 147 | + </template> | ||
| 148 | + | ||
| 149 | + <el-row v-for="(item, index) in addWorkInfo.contents" :key="item.id" :gutter="20"> | ||
| 150 | + <el-col :span="18"> | ||
| 151 | + <el-form-item :label="`${$t('addWork.content')}${index + 1}`"> | ||
| 152 | + <el-input v-model="item.content" type="textarea" :rows="5" | ||
| 153 | + :placeholder="$t('addWork.contentPlaceholder')" /> | ||
| 154 | + </el-form-item> | ||
| 155 | + </el-col> | ||
| 156 | + <el-col :span="6" class="flex align-center"> | ||
| 157 | + <el-button v-if="index === 0" type="text" @click="addWorkContent"> | ||
| 158 | + {{ $t('addWork.addContent') }} | ||
| 159 | + </el-button> | ||
| 160 | + <el-button v-else type="text" @click="deleteWorkContent(item)"> | ||
| 161 | + {{ $t('addWork.deleteContent') }} | ||
| 162 | + </el-button> | ||
| 163 | + </el-col> | ||
| 164 | + </el-row> | ||
| 165 | + | ||
| 166 | + <el-row> | ||
| 167 | + <el-col :span="24" class="text-right"> | ||
| 168 | + <el-button type="warning" @click="goBack"> | ||
| 169 | + <i class="el-icon-arrow-left"></i>{{ $t('common.back') }} | ||
| 170 | + </el-button> | ||
| 171 | + <el-button type="primary" @click="saveWorkPool"> | ||
| 172 | + <i class="el-icon-check"></i>{{ $t('common.submit') }} | ||
| 173 | + </el-button> | ||
| 174 | + </el-col> | ||
| 175 | + </el-row> | ||
| 176 | + </el-form> | ||
| 177 | + </el-card> | ||
| 178 | + | ||
| 179 | + <select-staff ref="selectStaff" @selectStaff="selectStaff" /> | ||
| 180 | + </div> | ||
| 181 | +</template> | ||
| 182 | + | ||
| 183 | +<script> | ||
| 184 | +import { saveWorkPool, listWorkType } from '@/api/oa/addWorkApi' | ||
| 185 | +import { getCommunityId } from '@/api/community/communityApi' | ||
| 186 | +import SelectStaff from '@/components/staff/SelectStaff' | ||
| 187 | +import UploadFile from '@/components/upload/uploadFile' | ||
| 188 | +import { getUuid } from '@/utils/commonUtil' | ||
| 189 | +import { dateFormat } from '@/utils/dateUtil' | ||
| 190 | + | ||
| 191 | +export default { | ||
| 192 | + name: 'AddWorkList', | ||
| 193 | + components: { | ||
| 194 | + SelectStaff, | ||
| 195 | + UploadFile | ||
| 196 | + }, | ||
| 197 | + data() { | ||
| 198 | + return { | ||
| 199 | + chooseStaffFlag:'1', | ||
| 200 | + addWorkInfo: { | ||
| 201 | + workName: '', | ||
| 202 | + workTypes: [], | ||
| 203 | + wtId: '', | ||
| 204 | + workCycle: '1001', | ||
| 205 | + startTime: '', | ||
| 206 | + endTime: '', | ||
| 207 | + staffs: [], | ||
| 208 | + copyStaffs: [], | ||
| 209 | + pathUrls: [], | ||
| 210 | + contents: [], | ||
| 211 | + period: '', | ||
| 212 | + months: [], | ||
| 213 | + days: [], | ||
| 214 | + workdays: [], | ||
| 215 | + hours: '24', | ||
| 216 | + communityId: '' | ||
| 217 | + }, | ||
| 218 | + weekDays: [ | ||
| 219 | + this.$t('addWork.monday'), | ||
| 220 | + this.$t('addWork.tuesday'), | ||
| 221 | + this.$t('addWork.wednesday'), | ||
| 222 | + this.$t('addWork.thursday'), | ||
| 223 | + this.$t('addWork.friday'), | ||
| 224 | + this.$t('addWork.saturday'), | ||
| 225 | + this.$t('addWork.sunday') | ||
| 226 | + ] | ||
| 227 | + } | ||
| 228 | + }, | ||
| 229 | + created() { | ||
| 230 | + this.addWorkInfo.communityId = getCommunityId() | ||
| 231 | + this._listWorkTypes() | ||
| 232 | + this.addWorkContent() | ||
| 233 | + this.initDateTime() | ||
| 234 | + }, | ||
| 235 | + methods: { | ||
| 236 | + initDateTime() { | ||
| 237 | + const now = new Date() | ||
| 238 | + this.addWorkInfo.startTime = dateFormat(now) | ||
| 239 | + const tomorrow = new Date(now) | ||
| 240 | + tomorrow.setDate(tomorrow.getDate() + 1) | ||
| 241 | + this.addWorkInfo.endTime = dateFormat(tomorrow) | ||
| 242 | + }, | ||
| 243 | + addWorkValidate() { | ||
| 244 | + return this.$refs.form.validate() | ||
| 245 | + }, | ||
| 246 | + async saveWorkPool() { | ||
| 247 | + try { | ||
| 248 | + const valid = await this.addWorkValidate() | ||
| 249 | + if (!valid) return | ||
| 250 | + | ||
| 251 | + const params = { | ||
| 252 | + ...this.addWorkInfo, | ||
| 253 | + } | ||
| 254 | + | ||
| 255 | + const res = await saveWorkPool(params) | ||
| 256 | + if (res.code === 0) { | ||
| 257 | + this.$message.success(this.$t('common.submitSuccess')) | ||
| 258 | + this.goBack() | ||
| 259 | + } else { | ||
| 260 | + this.$message.error(res.msg) | ||
| 261 | + } | ||
| 262 | + } catch (error) { | ||
| 263 | + console.error('保存工作单失败:', error) | ||
| 264 | + this.$message.error(this.$t('common.submitFailed')) | ||
| 265 | + } | ||
| 266 | + }, | ||
| 267 | + async _listWorkTypes() { | ||
| 268 | + try { | ||
| 269 | + const params = { | ||
| 270 | + page: 1, | ||
| 271 | + row: 100, | ||
| 272 | + communityId: this.addWorkInfo.communityId | ||
| 273 | + } | ||
| 274 | + const res = await listWorkType(params) | ||
| 275 | + this.addWorkInfo.workTypes = res.data | ||
| 276 | + } catch (error) { | ||
| 277 | + console.error('获取工作单类型失败:', error) | ||
| 278 | + } | ||
| 279 | + }, | ||
| 280 | + _chooseWorkStaff() { | ||
| 281 | + this.chooseStaffFlag = '1' | ||
| 282 | + this.$refs.selectStaff.open({ | ||
| 283 | + call: () => { | ||
| 284 | + } | ||
| 285 | + }) | ||
| 286 | + }, | ||
| 287 | + selectStaff(staff) { | ||
| 288 | + if(this.chooseStaffFlag === '1'){ | ||
| 289 | + this.addWorkInfo.staffs.push({ | ||
| 290 | + staffId: staff.userId, | ||
| 291 | + staffName: staff.userName | ||
| 292 | + }) | ||
| 293 | + }else{ | ||
| 294 | + this.addWorkInfo.copyStaffs.push({ | ||
| 295 | + staffId: staff.userId, | ||
| 296 | + staffName: staff.userName | ||
| 297 | + }) | ||
| 298 | + } | ||
| 299 | + }, | ||
| 300 | + _deleteWorkStaff(staff) { | ||
| 301 | + this.addWorkInfo.staffs = this.addWorkInfo.staffs.filter(item => item.staffId !== staff.staffId) | ||
| 302 | + }, | ||
| 303 | + _chooseCopyWorkStaff() { | ||
| 304 | + this.chooseStaffFlag = '2' | ||
| 305 | + this.$refs.selectStaff.open({ | ||
| 306 | + call: () => { | ||
| 307 | + } | ||
| 308 | + }) | ||
| 309 | + }, | ||
| 310 | + _deleteCopyWorkStaff(staff) { | ||
| 311 | + this.addWorkInfo.copyStaffs = this.addWorkInfo.copyStaffs.filter(item => item.staffId !== staff.staffId) | ||
| 312 | + }, | ||
| 313 | + addWorkContent() { | ||
| 314 | + this.addWorkInfo.contents.push({ | ||
| 315 | + id: getUuid(), | ||
| 316 | + content: '' | ||
| 317 | + }) | ||
| 318 | + }, | ||
| 319 | + deleteWorkContent(content) { | ||
| 320 | + this.addWorkInfo.contents = this.addWorkInfo.contents.filter(item => item.id !== content.id) | ||
| 321 | + }, | ||
| 322 | + handleWorkCycleChange(val) { | ||
| 323 | + if (val === '1001') { | ||
| 324 | + this.addWorkInfo.period = '' | ||
| 325 | + this.addWorkInfo.months = [] | ||
| 326 | + this.addWorkInfo.days = [] | ||
| 327 | + this.addWorkInfo.workdays = [] | ||
| 328 | + } | ||
| 329 | + }, | ||
| 330 | + notifyFile(data) { | ||
| 331 | + this.addWorkInfo.pathUrls.push(data.realFileName) | ||
| 332 | + }, | ||
| 333 | + goBack() { | ||
| 334 | + this.$router.go(-1) | ||
| 335 | + } | ||
| 336 | + } | ||
| 337 | +} | ||
| 338 | +</script> | ||
| 339 | + | ||
| 340 | +<style lang="scss" scoped> | ||
| 341 | +.add-work-container { | ||
| 342 | + padding: 20px; | ||
| 343 | + | ||
| 344 | + .staff-tags { | ||
| 345 | + display: flex; | ||
| 346 | + flex-wrap: wrap; | ||
| 347 | + align-items: center; | ||
| 348 | + | ||
| 349 | + .el-tag { | ||
| 350 | + margin-right: 10px; | ||
| 351 | + margin-bottom: 5px; | ||
| 352 | + } | ||
| 353 | + } | ||
| 354 | + | ||
| 355 | + .flex { | ||
| 356 | + display: flex; | ||
| 357 | + } | ||
| 358 | + | ||
| 359 | + .align-center { | ||
| 360 | + align-items: center; | ||
| 361 | + } | ||
| 362 | + | ||
| 363 | + .text-right { | ||
| 364 | + text-align: right; | ||
| 365 | + } | ||
| 366 | +} | ||
| 367 | +</style> | ||
| 0 | \ No newline at end of file | 368 | \ No newline at end of file |
src/views/oa/editWorkLang.js
0 → 100644
| 1 | +export const messages = { | ||
| 2 | + en: { | ||
| 3 | + editWork: { | ||
| 4 | + title: 'Edit Work Order', | ||
| 5 | + workName: 'Title', | ||
| 6 | + workNamePlaceholder: 'Required, please enter title', | ||
| 7 | + workType: 'Work Order Type', | ||
| 8 | + workTypePlaceholder: 'Required, please select work order type', | ||
| 9 | + processor: 'Processor', | ||
| 10 | + ccPerson: 'CC Person', | ||
| 11 | + choose: 'Choose', | ||
| 12 | + workSign: 'Work Order Sign', | ||
| 13 | + workSignPlaceholder: 'Required, please select work order sign', | ||
| 14 | + onceWork: 'One-time Work Order', | ||
| 15 | + cycleWork: 'Periodic Work Order', | ||
| 16 | + attachment: 'Attachment', | ||
| 17 | + startTime: 'Start Time', | ||
| 18 | + startTimePlaceholder: 'Required, please enter start time', | ||
| 19 | + endTime: 'End Time', | ||
| 20 | + endTimePlaceholder: 'Required, please enter end time', | ||
| 21 | + period: 'Period', | ||
| 22 | + periodPlaceholder: 'Required, please select task period', | ||
| 23 | + monthDay: 'Month/Day', | ||
| 24 | + byWeek: 'By Week', | ||
| 25 | + workHours: 'Work Hours', | ||
| 26 | + workHoursPlaceholder: 'Required, please enter hours', | ||
| 27 | + hoursComplete: 'hours to complete', | ||
| 28 | + month: 'Month', | ||
| 29 | + monthUnit: 'Month', | ||
| 30 | + day: 'Day', | ||
| 31 | + dayUnit: 'Day', | ||
| 32 | + week: 'Week', | ||
| 33 | + monday: 'Monday', | ||
| 34 | + tuesday: 'Tuesday', | ||
| 35 | + wednesday: 'Wednesday', | ||
| 36 | + thursday: 'Thursday', | ||
| 37 | + friday: 'Friday', | ||
| 38 | + saturday: 'Saturday', | ||
| 39 | + sunday: 'Sunday', | ||
| 40 | + content: 'Content', | ||
| 41 | + add: 'Add', | ||
| 42 | + delete: 'Delete' | ||
| 43 | + }, | ||
| 44 | + uploadFile: { | ||
| 45 | + upload: 'Upload Attachment', | ||
| 46 | + sizeLimit: 'File size cannot exceed 20MB', | ||
| 47 | + success: 'File uploaded successfully', | ||
| 48 | + failed: 'File upload failed' | ||
| 49 | + }, | ||
| 50 | + textarea: { | ||
| 51 | + placeholder: 'Required, please enter content', | ||
| 52 | + uploadFailed: 'Image upload failed' | ||
| 53 | + }, | ||
| 54 | + selectStaff: { | ||
| 55 | + title: 'Select Staff', | ||
| 56 | + orgInfo: 'Organization Information', | ||
| 57 | + staffInfo: 'Staff Information', | ||
| 58 | + submitter: 'Submitter', | ||
| 59 | + dynamicAssign: 'Dynamic Assign' | ||
| 60 | + } | ||
| 61 | + }, | ||
| 62 | + zh: { | ||
| 63 | + editWork: { | ||
| 64 | + title: '修改工作单', | ||
| 65 | + workName: '标题', | ||
| 66 | + workNamePlaceholder: '必填,请填写标题', | ||
| 67 | + workType: '工作单类型', | ||
| 68 | + workTypePlaceholder: '必填,请选择工作单类型', | ||
| 69 | + processor: '处理人', | ||
| 70 | + ccPerson: '抄送人', | ||
| 71 | + choose: '选择', | ||
| 72 | + workSign: '工作单标识', | ||
| 73 | + workSignPlaceholder: '必填,请选择工作单标识', | ||
| 74 | + onceWork: '一次性工单', | ||
| 75 | + cycleWork: '周期性工单', | ||
| 76 | + attachment: '附件', | ||
| 77 | + startTime: '开始时间', | ||
| 78 | + startTimePlaceholder: '必填,请填写开始时间', | ||
| 79 | + endTime: '结束时间', | ||
| 80 | + endTimePlaceholder: '必填,请填写结束时间', | ||
| 81 | + period: '周期', | ||
| 82 | + periodPlaceholder: '必填,请选择任务周期', | ||
| 83 | + monthDay: '月/天', | ||
| 84 | + byWeek: '按周', | ||
| 85 | + workHours: '工作单', | ||
| 86 | + workHoursPlaceholder: '必填,请输入小时数', | ||
| 87 | + hoursComplete: '小时内完成', | ||
| 88 | + month: '月', | ||
| 89 | + monthUnit: '月', | ||
| 90 | + day: '日', | ||
| 91 | + dayUnit: '日', | ||
| 92 | + week: '周', | ||
| 93 | + monday: '星期一', | ||
| 94 | + tuesday: '星期二', | ||
| 95 | + wednesday: '星期三', | ||
| 96 | + thursday: '星期四', | ||
| 97 | + friday: '星期五', | ||
| 98 | + saturday: '星期六', | ||
| 99 | + sunday: '星期日', | ||
| 100 | + content: '内容', | ||
| 101 | + add: '添加', | ||
| 102 | + delete: '删除' | ||
| 103 | + }, | ||
| 104 | + uploadFile: { | ||
| 105 | + upload: '上传附件', | ||
| 106 | + sizeLimit: '文件大小不能超过20MB', | ||
| 107 | + success: '文件上传成功', | ||
| 108 | + failed: '文件上传失败' | ||
| 109 | + }, | ||
| 110 | + textarea: { | ||
| 111 | + placeholder: '必填,请输入内容', | ||
| 112 | + uploadFailed: '图片上传失败' | ||
| 113 | + }, | ||
| 114 | + selectStaff: { | ||
| 115 | + title: '选择员工', | ||
| 116 | + orgInfo: '组织信息', | ||
| 117 | + staffInfo: '员工信息', | ||
| 118 | + submitter: '提交者', | ||
| 119 | + dynamicAssign: '动态指定' | ||
| 120 | + } | ||
| 121 | + } | ||
| 122 | +} | ||
| 0 | \ No newline at end of file | 123 | \ No newline at end of file |
src/views/oa/editWorkList.vue
0 → 100644
| 1 | +<template> | ||
| 2 | + <div class="edit-work-container"> | ||
| 3 | + <el-card class="box-card"> | ||
| 4 | + <div slot="header" class="clearfix"> | ||
| 5 | + <span>{{ $t('editWork.title') }}</span> | ||
| 6 | + </div> | ||
| 7 | + | ||
| 8 | + <el-form ref="form" :model="editWorkInfo" label-width="120px" label-position="right"> | ||
| 9 | + <el-row :gutter="20"> | ||
| 10 | + <el-col :span="12"> | ||
| 11 | + <el-form-item :label="$t('editWork.workName')" prop="workName"> | ||
| 12 | + <el-input v-model.trim="editWorkInfo.workName" :placeholder="$t('editWork.workNamePlaceholder')" | ||
| 13 | + maxlength="20" clearable /> | ||
| 14 | + </el-form-item> | ||
| 15 | + </el-col> | ||
| 16 | + <el-col :span="12"> | ||
| 17 | + <el-form-item :label="$t('editWork.workType')" prop="wtId"> | ||
| 18 | + <el-select v-model="editWorkInfo.wtId" :placeholder="$t('editWork.workTypePlaceholder')" style="width:100%" | ||
| 19 | + clearable> | ||
| 20 | + <el-option v-for="item in editWorkInfo.workTypes" :key="item.wtId" :label="item.typeName" | ||
| 21 | + :value="item.wtId" /> | ||
| 22 | + </el-select> | ||
| 23 | + </el-form-item> | ||
| 24 | + </el-col> | ||
| 25 | + </el-row> | ||
| 26 | + | ||
| 27 | + <el-row :gutter="20"> | ||
| 28 | + <el-col :span="12"> | ||
| 29 | + <el-form-item :label="$t('editWork.processor')"> | ||
| 30 | + <div class="staff-tags"> | ||
| 31 | + <el-tag v-for="(staff, index) in editWorkInfo.staffs" :key="index" closable | ||
| 32 | + @close="_deleteWorkStaff(staff)"> | ||
| 33 | + {{ staff.staffName }} | ||
| 34 | + </el-tag> | ||
| 35 | + <el-button type="text" @click="_chooseWorkStaff"> | ||
| 36 | + <i class="el-icon-search"></i>{{ $t('editWork.choose') }} | ||
| 37 | + </el-button> | ||
| 38 | + </div> | ||
| 39 | + </el-form-item> | ||
| 40 | + </el-col> | ||
| 41 | + <el-col :span="12"> | ||
| 42 | + <el-form-item :label="$t('editWork.ccPerson')"> | ||
| 43 | + <div class="staff-tags"> | ||
| 44 | + <el-tag v-for="(staff, index) in editWorkInfo.copyStaffs" :key="index" closable | ||
| 45 | + @close="_deleteCopyWorkStaff(staff)"> | ||
| 46 | + {{ staff.staffName }} | ||
| 47 | + </el-tag> | ||
| 48 | + <el-button type="text" @click="_chooseCopyWorkStaff"> | ||
| 49 | + <i class="el-icon-search"></i>{{ $t('editWork.choose') }} | ||
| 50 | + </el-button> | ||
| 51 | + </div> | ||
| 52 | + </el-form-item> | ||
| 53 | + </el-col> | ||
| 54 | + </el-row> | ||
| 55 | + | ||
| 56 | + <el-row :gutter="20"> | ||
| 57 | + <el-col :span="12"> | ||
| 58 | + <el-form-item :label="$t('editWork.workSign')" prop="workCycle"> | ||
| 59 | + <el-select v-model="editWorkInfo.workCycle" :placeholder="$t('editWork.workSignPlaceholder')" | ||
| 60 | + style="width:100%" @change="handleWorkCycleChange"> | ||
| 61 | + <el-option :label="$t('editWork.onceWork')" value="1001" /> | ||
| 62 | + <el-option :label="$t('editWork.cycleWork')" value="2002" /> | ||
| 63 | + </el-select> | ||
| 64 | + </el-form-item> | ||
| 65 | + </el-col> | ||
| 66 | + <el-col :span="12"> | ||
| 67 | + <el-form-item :label="$t('editWork.attachment')"> | ||
| 68 | + <upload-file ref="uploadFile" @notifyFile="notifyFile" :defaultFiles="editWorkInfo.pathUrls" /> | ||
| 69 | + </el-form-item> | ||
| 70 | + </el-col> | ||
| 71 | + </el-row> | ||
| 72 | + | ||
| 73 | + <el-row :gutter="20"> | ||
| 74 | + <el-col :span="12"> | ||
| 75 | + <el-form-item :label="$t('editWork.startTime')" prop="startTime"> | ||
| 76 | + <el-date-picker v-model="editWorkInfo.startTime" type="datetime" value-format="yyyy-MM-dd HH:mm:ss" | ||
| 77 | + :placeholder="$t('editWork.startTimePlaceholder')" style="width:100%" /> | ||
| 78 | + </el-form-item> | ||
| 79 | + </el-col> | ||
| 80 | + <el-col :span="12"> | ||
| 81 | + <el-form-item :label="$t('editWork.endTime')" prop="endTime"> | ||
| 82 | + <el-date-picker v-model="editWorkInfo.endTime" type="datetime" value-format="yyyy-MM-dd HH:mm:ss" | ||
| 83 | + :placeholder="$t('editWork.endTimePlaceholder')" style="width:100%" /> | ||
| 84 | + </el-form-item> | ||
| 85 | + </el-col> | ||
| 86 | + </el-row> | ||
| 87 | + | ||
| 88 | + <template v-if="editWorkInfo.workCycle === '2002'"> | ||
| 89 | + <el-row :gutter="20"> | ||
| 90 | + <el-col :span="12"> | ||
| 91 | + <el-form-item :label="$t('editWork.period')" prop="period"> | ||
| 92 | + <el-select v-model="editWorkInfo.period" :placeholder="$t('editWork.periodPlaceholder')" | ||
| 93 | + style="width:100%"> | ||
| 94 | + <el-option :label="$t('editWork.monthDay')" value="2020022" /> | ||
| 95 | + <el-option :label="$t('editWork.byWeek')" value="2020023" /> | ||
| 96 | + </el-select> | ||
| 97 | + </el-form-item> | ||
| 98 | + </el-col> | ||
| 99 | + <el-col :span="12"> | ||
| 100 | + <el-form-item :label="$t('editWork.workHours')"> | ||
| 101 | + <el-input v-model.trim="editWorkInfo.hours" :placeholder="$t('editWork.workHoursPlaceholder')"> | ||
| 102 | + <template slot="append">{{ $t('editWork.hoursComplete') }}</template> | ||
| 103 | + </el-input> | ||
| 104 | + </el-form-item> | ||
| 105 | + </el-col> | ||
| 106 | + </el-row> | ||
| 107 | + | ||
| 108 | + <template v-if="editWorkInfo.period === '2020022'"> | ||
| 109 | + <el-row :gutter="20"> | ||
| 110 | + <el-col :span="24"> | ||
| 111 | + <el-form-item :label="$t('editWork.month')"> | ||
| 112 | + <el-checkbox-group v-model="editWorkInfo.months"> | ||
| 113 | + <el-checkbox v-for="index in 12" :key="index" :label="index"> | ||
| 114 | + {{ index }}{{ $t('editWork.monthUnit') }} | ||
| 115 | + </el-checkbox> | ||
| 116 | + </el-checkbox-group> | ||
| 117 | + </el-form-item> | ||
| 118 | + </el-col> | ||
| 119 | + </el-row> | ||
| 120 | + | ||
| 121 | + <el-row :gutter="20"> | ||
| 122 | + <el-col :span="24"> | ||
| 123 | + <el-form-item :label="$t('editWork.day')"> | ||
| 124 | + <el-checkbox-group v-model="editWorkInfo.days"> | ||
| 125 | + <el-checkbox v-for="index in 31" :key="index" :label="index"> | ||
| 126 | + {{ index }}{{ $t('editWork.dayUnit') }} | ||
| 127 | + </el-checkbox> | ||
| 128 | + </el-checkbox-group> | ||
| 129 | + </el-form-item> | ||
| 130 | + </el-col> | ||
| 131 | + </el-row> | ||
| 132 | + </template> | ||
| 133 | + | ||
| 134 | + <template v-if="editWorkInfo.period === '2020023'"> | ||
| 135 | + <el-row :gutter="20"> | ||
| 136 | + <el-col :span="24"> | ||
| 137 | + <el-form-item :label="$t('editWork.week')"> | ||
| 138 | + <el-checkbox-group v-model="editWorkInfo.workdays"> | ||
| 139 | + <el-checkbox v-for="(day, index) in weekDays" :key="index" :label="index + 1"> | ||
| 140 | + {{ day }} | ||
| 141 | + </el-checkbox> | ||
| 142 | + </el-checkbox-group> | ||
| 143 | + </el-form-item> | ||
| 144 | + </el-col> | ||
| 145 | + </el-row> | ||
| 146 | + </template> | ||
| 147 | + </template> | ||
| 148 | + | ||
| 149 | + <el-row v-for="(item, index) in editWorkInfo.contents" :key="item.id" :gutter="20"> | ||
| 150 | + <el-col :span="18"> | ||
| 151 | + <el-form-item :label="`${$t('editWork.content')}${index + 1}`"> | ||
| 152 | + <el-input v-model="item.content" type="textarea" :rows="5" | ||
| 153 | + :placeholder="$t('editWork.contentPlaceholder')" /> | ||
| 154 | + </el-form-item> | ||
| 155 | + </el-col> | ||
| 156 | + <el-col :span="6" class="flex align-center"> | ||
| 157 | + <el-button v-if="index === 0" type="text" @click="addWorkContent"> | ||
| 158 | + {{ $t('editWork.add') }} | ||
| 159 | + </el-button> | ||
| 160 | + <el-button v-else type="text" @click="deleteWorkContent(item)"> | ||
| 161 | + {{ $t('editWork.delete') }} | ||
| 162 | + </el-button> | ||
| 163 | + </el-col> | ||
| 164 | + </el-row> | ||
| 165 | + | ||
| 166 | + <el-row> | ||
| 167 | + <el-col :span="24" class="text-right"> | ||
| 168 | + <el-button type="warning" @click="goBack"> | ||
| 169 | + <i class="el-icon-close"></i>{{ $t('common.back') }} | ||
| 170 | + </el-button> | ||
| 171 | + <el-button type="primary" @click="saveWorkPool"> | ||
| 172 | + <i class="el-icon-check"></i>{{ $t('common.submit') }} | ||
| 173 | + </el-button> | ||
| 174 | + </el-col> | ||
| 175 | + </el-row> | ||
| 176 | + </el-form> | ||
| 177 | + </el-card> | ||
| 178 | + | ||
| 179 | + <select-staff ref="selectStaff" @selectStaff="selectStaff" /> | ||
| 180 | + </div> | ||
| 181 | +</template> | ||
| 182 | + | ||
| 183 | +<script> | ||
| 184 | +import { updateWorkPool, listWorkType, queryStartWork, listWorkTask, listWorkCopy, listWorkCycle } from '@/api/oa/editWorkApi' | ||
| 185 | +import { getCommunityId } from '@/api/community/communityApi' | ||
| 186 | +import SelectStaff from '@/components/staff/SelectStaff' | ||
| 187 | +import UploadFile from '@/components/upload/uploadFile' | ||
| 188 | +import { getUuid } from '@/utils/commonUtil' | ||
| 189 | +import { dateFormat } from '@/utils/dateUtil' | ||
| 190 | + | ||
| 191 | +export default { | ||
| 192 | + name: 'EditWorkList', | ||
| 193 | + components: { | ||
| 194 | + SelectStaff, | ||
| 195 | + UploadFile | ||
| 196 | + }, | ||
| 197 | + data() { | ||
| 198 | + return { | ||
| 199 | + chooseStaffFlag: '1', | ||
| 200 | + editWorkInfo: { | ||
| 201 | + workId: '', | ||
| 202 | + workName: '', | ||
| 203 | + workTypes: [], | ||
| 204 | + wtId: '', | ||
| 205 | + workCycle: '1001', | ||
| 206 | + startTime: '', | ||
| 207 | + endTime: '', | ||
| 208 | + staffs: [], | ||
| 209 | + copyStaffs: [], | ||
| 210 | + pathUrls: [], | ||
| 211 | + contents: [], | ||
| 212 | + period: '', | ||
| 213 | + months: [], | ||
| 214 | + days: [], | ||
| 215 | + workdays: [], | ||
| 216 | + hours: '24', | ||
| 217 | + communityId: '' | ||
| 218 | + }, | ||
| 219 | + weekDays: [ | ||
| 220 | + this.$t('editWork.monday'), | ||
| 221 | + this.$t('editWork.tuesday'), | ||
| 222 | + this.$t('editWork.wednesday'), | ||
| 223 | + this.$t('editWork.thursday'), | ||
| 224 | + this.$t('editWork.friday'), | ||
| 225 | + this.$t('editWork.saturday'), | ||
| 226 | + this.$t('editWork.sunday') | ||
| 227 | + ] | ||
| 228 | + } | ||
| 229 | + }, | ||
| 230 | + created() { | ||
| 231 | + this.editWorkInfo.workId = this.$route.query.workId | ||
| 232 | + this.editWorkInfo.communityId = getCommunityId() | ||
| 233 | + this.loadData() | ||
| 234 | + }, | ||
| 235 | + methods: { | ||
| 236 | + async loadData() { | ||
| 237 | + try { | ||
| 238 | + await this._loadWorkPool() | ||
| 239 | + await this._loadTaskStaff() | ||
| 240 | + await this._loadWorkCopy() | ||
| 241 | + await this._listWorkTypes() | ||
| 242 | + await this._loadWorkCycle() | ||
| 243 | + } catch (error) { | ||
| 244 | + console.error('加载数据失败:', error) | ||
| 245 | + this.$message.error(this.$t('common.loadFailed')) | ||
| 246 | + } | ||
| 247 | + }, | ||
| 248 | + editWorkValidate() { | ||
| 249 | + return this.$refs.form.validate() | ||
| 250 | + }, | ||
| 251 | + async saveWorkPool() { | ||
| 252 | + try { | ||
| 253 | + const valid = await this.editWorkValidate() | ||
| 254 | + if (!valid) return | ||
| 255 | + | ||
| 256 | + const params = { | ||
| 257 | + ...this.editWorkInfo, | ||
| 258 | + // 处理月份和日期数组为字符串 | ||
| 259 | + months: this.editWorkInfo.months.join(','), | ||
| 260 | + days: this.editWorkInfo.days.join(','), | ||
| 261 | + workdays: this.editWorkInfo.workdays.join(',') | ||
| 262 | + } | ||
| 263 | + | ||
| 264 | + const res = await updateWorkPool(params) | ||
| 265 | + if (res.code === 0) { | ||
| 266 | + this.$message.success(this.$t('common.submitSuccess')) | ||
| 267 | + this.goBack() | ||
| 268 | + } else { | ||
| 269 | + this.$message.error(res.msg) | ||
| 270 | + } | ||
| 271 | + } catch (error) { | ||
| 272 | + console.error('保存工作单失败:', error) | ||
| 273 | + this.$message.error(this.$t('common.submitFailed')) | ||
| 274 | + } | ||
| 275 | + }, | ||
| 276 | + async _listWorkTypes() { | ||
| 277 | + try { | ||
| 278 | + const params = { | ||
| 279 | + page: 1, | ||
| 280 | + row: 100, | ||
| 281 | + communityId: this.editWorkInfo.communityId | ||
| 282 | + } | ||
| 283 | + const res = await listWorkType(params) | ||
| 284 | + this.editWorkInfo.workTypes = res.data | ||
| 285 | + } catch (error) { | ||
| 286 | + console.error('获取工作单类型失败:', error) | ||
| 287 | + } | ||
| 288 | + }, | ||
| 289 | + _chooseWorkStaff() { | ||
| 290 | + this.chooseStaffFlag = '1' | ||
| 291 | + this.$refs.selectStaff.open({ | ||
| 292 | + call: () => { | ||
| 293 | + } | ||
| 294 | + }) | ||
| 295 | + }, | ||
| 296 | + selectStaff(staff) { | ||
| 297 | + if (this.chooseStaffFlag === '1') { | ||
| 298 | + this.editWorkInfo.staffs.push({ | ||
| 299 | + staffId: staff.userId, | ||
| 300 | + staffName: staff.userName | ||
| 301 | + }) | ||
| 302 | + } else { | ||
| 303 | + this.editWorkInfo.copyStaffs.push({ | ||
| 304 | + staffId: staff.userId, | ||
| 305 | + staffName: staff.userName | ||
| 306 | + }) | ||
| 307 | + } | ||
| 308 | + }, | ||
| 309 | + _deleteWorkStaff(staff) { | ||
| 310 | + this.editWorkInfo.staffs = this.editWorkInfo.staffs.filter(item => item.staffId !== staff.staffId) | ||
| 311 | + }, | ||
| 312 | + _chooseCopyWorkStaff() { | ||
| 313 | + this.chooseStaffFlag = '2' | ||
| 314 | + this.$refs.selectStaff.open({ | ||
| 315 | + call: () => { | ||
| 316 | + } | ||
| 317 | + }) | ||
| 318 | + }, | ||
| 319 | + _deleteCopyWorkStaff(staff) { | ||
| 320 | + this.editWorkInfo.copyStaffs = this.editWorkInfo.copyStaffs.filter(item => item.staffId !== staff.staffId) | ||
| 321 | + }, | ||
| 322 | + async _loadWorkPool() { | ||
| 323 | + const params = { | ||
| 324 | + page: 1, | ||
| 325 | + row: 1, | ||
| 326 | + workId: this.editWorkInfo.workId | ||
| 327 | + } | ||
| 328 | + const { data } = await queryStartWork(params) | ||
| 329 | + if (data && data.length > 0) { | ||
| 330 | + Object.assign(this.editWorkInfo, data[0]) | ||
| 331 | + // 格式化日期 | ||
| 332 | + if (data[0].startTime) { | ||
| 333 | + this.editWorkInfo.startTime = dateFormat(new Date(data[0].startTime)) | ||
| 334 | + } | ||
| 335 | + if (data[0].endTime) { | ||
| 336 | + this.editWorkInfo.endTime = dateFormat(new Date(data[0].endTime)) | ||
| 337 | + } | ||
| 338 | + // 处理内容 | ||
| 339 | + this.editWorkInfo.contents = data[0].contents.map(c => ({ | ||
| 340 | + id: getUuid(), | ||
| 341 | + content: c.content | ||
| 342 | + })) || [{ | ||
| 343 | + id: getUuid(), | ||
| 344 | + content: '' | ||
| 345 | + }] | ||
| 346 | + } | ||
| 347 | + }, | ||
| 348 | + async _loadTaskStaff() { | ||
| 349 | + const params = { | ||
| 350 | + page: 1, | ||
| 351 | + row: 100, | ||
| 352 | + workId: this.editWorkInfo.workId | ||
| 353 | + } | ||
| 354 | + const { data } = await listWorkTask(params) | ||
| 355 | + this.editWorkInfo.staffs = data || [] | ||
| 356 | + }, | ||
| 357 | + async _loadWorkCopy() { | ||
| 358 | + const params = { | ||
| 359 | + page: 1, | ||
| 360 | + row: 100, | ||
| 361 | + workId: this.editWorkInfo.workId | ||
| 362 | + } | ||
| 363 | + const { data } = await listWorkCopy(params) | ||
| 364 | + this.editWorkInfo.copyStaffs = data || [] | ||
| 365 | + }, | ||
| 366 | + async _loadWorkCycle() { | ||
| 367 | + const params = { | ||
| 368 | + page: 1, | ||
| 369 | + row: 1, | ||
| 370 | + workId: this.editWorkInfo.workId | ||
| 371 | + } | ||
| 372 | + const { data } = await listWorkCycle(params) | ||
| 373 | + if (data && data.length > 0) { | ||
| 374 | + this.editWorkInfo.period = data[0].period | ||
| 375 | + this.editWorkInfo.workCycle = '2002' // 设置为周期工作 | ||
| 376 | + this.editWorkInfo.hours = data[0].hours || '24' | ||
| 377 | + | ||
| 378 | + // 处理月份、日期和工作日 | ||
| 379 | + if (data[0].periodMonth) { | ||
| 380 | + this.editWorkInfo.months = data[0].periodMonth.split(',').map(Number) | ||
| 381 | + } | ||
| 382 | + if (data[0].periodDay) { | ||
| 383 | + this.editWorkInfo.days = data[0].periodDay.split(',').map(Number) | ||
| 384 | + } | ||
| 385 | + if (data[0].workdays) { | ||
| 386 | + this.editWorkInfo.workdays = data[0].workdays.split(',').map(Number) | ||
| 387 | + } | ||
| 388 | + } | ||
| 389 | + }, | ||
| 390 | + addWorkContent() { | ||
| 391 | + this.editWorkInfo.contents.push({ | ||
| 392 | + id: getUuid(), | ||
| 393 | + content: '' | ||
| 394 | + }) | ||
| 395 | + }, | ||
| 396 | + deleteWorkContent(content) { | ||
| 397 | + this.editWorkInfo.contents = this.editWorkInfo.contents.filter(item => item.id !== content.id) | ||
| 398 | + }, | ||
| 399 | + handleWorkCycleChange(val) { | ||
| 400 | + if (val === '1001') { | ||
| 401 | + this.editWorkInfo.period = '' | ||
| 402 | + this.editWorkInfo.months = [] | ||
| 403 | + this.editWorkInfo.days = [] | ||
| 404 | + this.editWorkInfo.workdays = [] | ||
| 405 | + } | ||
| 406 | + }, | ||
| 407 | + notifyFile(data) { | ||
| 408 | + this.editWorkInfo.pathUrls.push(data.realFileName) | ||
| 409 | + }, | ||
| 410 | + goBack() { | ||
| 411 | + this.$router.go(-1) | ||
| 412 | + } | ||
| 413 | + } | ||
| 414 | +} | ||
| 415 | +</script> | ||
| 416 | + | ||
| 417 | +<style lang="scss" scoped> | ||
| 418 | +.edit-work-container { | ||
| 419 | + padding: 20px; | ||
| 420 | + | ||
| 421 | + .staff-tags { | ||
| 422 | + display: flex; | ||
| 423 | + flex-wrap: wrap; | ||
| 424 | + align-items: center; | ||
| 425 | + | ||
| 426 | + .el-tag { | ||
| 427 | + margin-right: 10px; | ||
| 428 | + margin-bottom: 5px; | ||
| 429 | + } | ||
| 430 | + } | ||
| 431 | + | ||
| 432 | + .flex { | ||
| 433 | + display: flex; | ||
| 434 | + } | ||
| 435 | + | ||
| 436 | + .align-center { | ||
| 437 | + align-items: center; | ||
| 438 | + } | ||
| 439 | + | ||
| 440 | + .text-right { | ||
| 441 | + text-align: right; | ||
| 442 | + } | ||
| 443 | + | ||
| 444 | + .el-checkbox-group { | ||
| 445 | + display: flex; | ||
| 446 | + flex-wrap: wrap; | ||
| 447 | + gap: 10px; | ||
| 448 | + } | ||
| 449 | +} | ||
| 450 | +</style> | ||
| 0 | \ No newline at end of file | 451 | \ No newline at end of file |
src/views/oa/startWorkLang.js
0 → 100644
| 1 | +export const messages = { | ||
| 2 | + en: { | ||
| 3 | + startWork: { | ||
| 4 | + state: { | ||
| 5 | + all: 'All', | ||
| 6 | + W: 'Pending', | ||
| 7 | + D: 'Processing', | ||
| 8 | + C: 'Completed' | ||
| 9 | + }, | ||
| 10 | + search: { | ||
| 11 | + title: 'Search Conditions', | ||
| 12 | + workName: 'Work Order Name', | ||
| 13 | + staffName: 'Handler', | ||
| 14 | + startTime: 'Start Time', | ||
| 15 | + endTime: 'End Time' | ||
| 16 | + }, | ||
| 17 | + list: { | ||
| 18 | + title: 'Work Order List', | ||
| 19 | + draft: 'Draft' | ||
| 20 | + }, | ||
| 21 | + table: { | ||
| 22 | + workId: 'ID', | ||
| 23 | + workName: 'Work Order Name', | ||
| 24 | + typeName: 'Type Name', | ||
| 25 | + workCycle: 'Cycle', | ||
| 26 | + startTime: 'Start Time', | ||
| 27 | + endTime: 'End Time', | ||
| 28 | + createUser: 'Creator', | ||
| 29 | + handler: 'Handler', | ||
| 30 | + ccUser: 'CC User', | ||
| 31 | + state: 'Status', | ||
| 32 | + createTime: 'Create Time' | ||
| 33 | + }, | ||
| 34 | + cycle: { | ||
| 35 | + once: 'One-time', | ||
| 36 | + periodic: 'Periodic' | ||
| 37 | + }, | ||
| 38 | + operation: { | ||
| 39 | + stop: 'Stop', | ||
| 40 | + start: 'Start' | ||
| 41 | + }, | ||
| 42 | + delete: { | ||
| 43 | + title: 'Confirm Operation', | ||
| 44 | + confirm: 'Are you sure to delete this work order?', | ||
| 45 | + success: 'Delete successfully', | ||
| 46 | + error: 'Delete failed' | ||
| 47 | + } | ||
| 48 | + }, | ||
| 49 | + }, | ||
| 50 | + zh: { | ||
| 51 | + startWork: { | ||
| 52 | + state: { | ||
| 53 | + all: '全部', | ||
| 54 | + W: '待处理', | ||
| 55 | + D: '处理中', | ||
| 56 | + C: '处理完成' | ||
| 57 | + }, | ||
| 58 | + search: { | ||
| 59 | + title: '查询条件', | ||
| 60 | + workName: '工单名称', | ||
| 61 | + staffName: '处理人', | ||
| 62 | + startTime: '开始时间', | ||
| 63 | + endTime: '结束时间' | ||
| 64 | + }, | ||
| 65 | + list: { | ||
| 66 | + title: '发起工作单', | ||
| 67 | + draft: '起草' | ||
| 68 | + }, | ||
| 69 | + table: { | ||
| 70 | + workId: '编号', | ||
| 71 | + workName: '工单名称', | ||
| 72 | + typeName: '类型名称', | ||
| 73 | + workCycle: '标识', | ||
| 74 | + startTime: '开始时间', | ||
| 75 | + endTime: '结束时间', | ||
| 76 | + createUser: '发起人', | ||
| 77 | + handler: '处理人', | ||
| 78 | + ccUser: '抄送人', | ||
| 79 | + state: '状态', | ||
| 80 | + createTime: '创建时间' | ||
| 81 | + }, | ||
| 82 | + cycle: { | ||
| 83 | + once: '一次性工单', | ||
| 84 | + periodic: '周期性工单' | ||
| 85 | + }, | ||
| 86 | + operation: { | ||
| 87 | + stop: '停止', | ||
| 88 | + start: '启用' | ||
| 89 | + }, | ||
| 90 | + delete: { | ||
| 91 | + title: '请确认您的操作', | ||
| 92 | + confirm: '确定删除工作单', | ||
| 93 | + success: '删除成功', | ||
| 94 | + error: '删除失败' | ||
| 95 | + } | ||
| 96 | + } | ||
| 97 | + } | ||
| 98 | +} | ||
| 0 | \ No newline at end of file | 99 | \ No newline at end of file |
src/views/oa/startWorkList.vue
0 → 100644
| 1 | +<template> | ||
| 2 | + <div class="start-work-container"> | ||
| 3 | + <el-row :gutter="20"> | ||
| 4 | + <el-col :span="2"> | ||
| 5 | + <div class="state-sidebar"> | ||
| 6 | + <ul class="state-list"> | ||
| 7 | + <li v-for="(item, index) in states" :key="index" class="state-item" | ||
| 8 | + :class="{ 'active-state': conditions.state === item.state }" @click="switchWorkState(item)"> | ||
| 9 | + {{ $t(`startWork.state.${item.state || 'all'}`) }} | ||
| 10 | + </li> | ||
| 11 | + </ul> | ||
| 12 | + </div> | ||
| 13 | + </el-col> | ||
| 14 | + <el-col :span="22"> | ||
| 15 | + <el-card class="search-card"> | ||
| 16 | + <div slot="header" class="flex justify-between"> | ||
| 17 | + <span>{{ $t('startWork.search.title') }}</span> | ||
| 18 | + </div> | ||
| 19 | + <el-form :inline="true" :model="conditions" class="search-form"> | ||
| 20 | + <el-form-item> | ||
| 21 | + <el-input v-model="conditions.workName" :placeholder="$t('startWork.search.workName')" clearable /> | ||
| 22 | + </el-form-item> | ||
| 23 | + <el-form-item> | ||
| 24 | + <el-input v-model="conditions.staffName" :placeholder="$t('startWork.search.staffName')" clearable /> | ||
| 25 | + </el-form-item> | ||
| 26 | + <el-form-item> | ||
| 27 | + <el-date-picker v-model="conditions.queryStartTime" type="datetime" | ||
| 28 | + :placeholder="$t('startWork.search.startTime')" value-format="yyyy-MM-dd HH:mm:ss" /> | ||
| 29 | + </el-form-item> | ||
| 30 | + <el-form-item> | ||
| 31 | + <el-date-picker v-model="conditions.queryEndTime" type="datetime" | ||
| 32 | + :placeholder="$t('startWork.search.endTime')" value-format="yyyy-MM-dd HH:mm:ss" | ||
| 33 | + :picker-options="endDateOptions" /> | ||
| 34 | + </el-form-item> | ||
| 35 | + <el-form-item> | ||
| 36 | + <el-button type="primary" @click="handleSearch"> | ||
| 37 | + {{ $t('common.search') }} | ||
| 38 | + </el-button> | ||
| 39 | + <el-button @click="handleReset"> | ||
| 40 | + {{ $t('common.reset') }} | ||
| 41 | + </el-button> | ||
| 42 | + </el-form-item> | ||
| 43 | + </el-form> | ||
| 44 | + </el-card> | ||
| 45 | + | ||
| 46 | + <el-card class="work-list-card"> | ||
| 47 | + <div slot="header" class="flex justify-between"> | ||
| 48 | + <span>{{ $t('startWork.list.title') }}</span> | ||
| 49 | + <el-button type="primary" size="small" style="float: right" @click="handleAdd"> | ||
| 50 | + <i class="el-icon-plus" /> | ||
| 51 | + {{ $t('startWork.list.draft') }} | ||
| 52 | + </el-button> | ||
| 53 | + </div> | ||
| 54 | + <el-table v-loading="loading" :data="works" border style="width: 100%"> | ||
| 55 | + <el-table-column prop="workId" :label="$t('startWork.table.workId')" align="center" /> | ||
| 56 | + <el-table-column prop="workName" :label="$t('startWork.table.workName')" align="center" /> | ||
| 57 | + <el-table-column prop="typeName" :label="$t('startWork.table.typeName')" align="center" /> | ||
| 58 | + <el-table-column :label="$t('startWork.table.workCycle')" align="center"> | ||
| 59 | + <template slot-scope="scope"> | ||
| 60 | + {{ scope.row.workCycle === '1001' ? $t('startWork.cycle.once') : $t('startWork.cycle.periodic') }} | ||
| 61 | + </template> | ||
| 62 | + </el-table-column> | ||
| 63 | + <el-table-column prop="startTime" :label="$t('startWork.table.startTime')" align="center" /> | ||
| 64 | + <el-table-column prop="endTime" :label="$t('startWork.table.endTime')" align="center" /> | ||
| 65 | + <el-table-column prop="createUserName" :label="$t('startWork.table.createUser')" align="center" /> | ||
| 66 | + <el-table-column prop="curStaffName" :label="$t('startWork.table.handler')" align="center"> | ||
| 67 | + <template slot-scope="scope"> | ||
| 68 | + {{ scope.row.curStaffName || '-' }} | ||
| 69 | + </template> | ||
| 70 | + </el-table-column> | ||
| 71 | + <el-table-column prop="curCopyName" :label="$t('startWork.table.ccUser')" align="center"> | ||
| 72 | + <template slot-scope="scope"> | ||
| 73 | + {{ scope.row.curCopyName || '-' }} | ||
| 74 | + </template> | ||
| 75 | + </el-table-column> | ||
| 76 | + <el-table-column prop="stateName" :label="$t('startWork.table.state')" align="center" /> | ||
| 77 | + <el-table-column prop="createTime" :label="$t('startWork.table.createTime')" align="center" /> | ||
| 78 | + <el-table-column :label="$t('common.operation')" align="center" width="300"> | ||
| 79 | + <template slot-scope="scope"> | ||
| 80 | + <el-button size="mini" @click="handleDetail(scope.row)"> | ||
| 81 | + {{ $t('common.detail') }} | ||
| 82 | + </el-button> | ||
| 83 | + <el-button v-if="scope.row.state === 'W'" size="mini" type="primary" @click="handleEdit(scope.row)"> | ||
| 84 | + {{ $t('common.edit') }} | ||
| 85 | + </el-button> | ||
| 86 | + <el-button size="mini" type="danger" @click="handleDelete(scope.row)"> | ||
| 87 | + {{ $t('common.delete') }} | ||
| 88 | + </el-button> | ||
| 89 | + <el-button v-if="scope.row.state !== 'S'" size="mini" type="warning" | ||
| 90 | + @click="handleUpdateState(scope.row, 'S')"> | ||
| 91 | + {{ $t('startWork.operation.stop') }} | ||
| 92 | + </el-button> | ||
| 93 | + <el-button v-if="scope.row.state === 'S'" size="mini" type="success" | ||
| 94 | + @click="handleUpdateState(scope.row, 'W')"> | ||
| 95 | + {{ $t('startWork.operation.start') }} | ||
| 96 | + </el-button> | ||
| 97 | + </template> | ||
| 98 | + </el-table-column> | ||
| 99 | + </el-table> | ||
| 100 | + <el-pagination :current-page="page.current" :page-sizes="[10, 20, 30, 50]" :page-size="page.size" | ||
| 101 | + :total="page.total" layout="total, sizes, prev, pager, next, jumper" @size-change="handleSizeChange" | ||
| 102 | + @current-change="handlePageChange" /> | ||
| 103 | + </el-card> | ||
| 104 | + </el-col> | ||
| 105 | + </el-row> | ||
| 106 | + | ||
| 107 | + <delete-work ref="deleteWork" @success="fetchData" /> | ||
| 108 | + </div> | ||
| 109 | +</template> | ||
| 110 | + | ||
| 111 | +<script> | ||
| 112 | +import { queryStartWork, updateWorkState } from '@/api/oa/startWorkApi' | ||
| 113 | +import DeleteWork from '@/components/oa/deleteWork' | ||
| 114 | +import { getCommunityId } from '@/api/community/communityApi' | ||
| 115 | + | ||
| 116 | +export default { | ||
| 117 | + name: 'StartWorkList', | ||
| 118 | + components: { | ||
| 119 | + DeleteWork | ||
| 120 | + }, | ||
| 121 | + data() { | ||
| 122 | + return { | ||
| 123 | + loading: false, | ||
| 124 | + communityId: '', | ||
| 125 | + states: [ | ||
| 126 | + { name: '全部', state: '' }, | ||
| 127 | + { name: '待处理', state: 'W' }, | ||
| 128 | + { name: '处理中', state: 'D' }, | ||
| 129 | + { name: '处理完成', state: 'C' } | ||
| 130 | + ], | ||
| 131 | + works: [], | ||
| 132 | + conditions: { | ||
| 133 | + state: '', | ||
| 134 | + workName: '', | ||
| 135 | + staffName: '', | ||
| 136 | + queryStartTime: '', | ||
| 137 | + queryEndTime: '' | ||
| 138 | + }, | ||
| 139 | + page: { | ||
| 140 | + current: 1, | ||
| 141 | + size: 10, | ||
| 142 | + total: 0 | ||
| 143 | + }, | ||
| 144 | + endDateOptions: { | ||
| 145 | + disabledDate: (time) => { | ||
| 146 | + if (this.conditions.queryStartTime) { | ||
| 147 | + return time.getTime() <= new Date(this.conditions.queryStartTime).getTime() | ||
| 148 | + } | ||
| 149 | + return false | ||
| 150 | + } | ||
| 151 | + } | ||
| 152 | + } | ||
| 153 | + }, | ||
| 154 | + created() { | ||
| 155 | + this.communityId = getCommunityId() | ||
| 156 | + this.fetchData() | ||
| 157 | + }, | ||
| 158 | + methods: { | ||
| 159 | + async fetchData() { | ||
| 160 | + this.loading = true | ||
| 161 | + try { | ||
| 162 | + const params = { | ||
| 163 | + ...this.conditions, | ||
| 164 | + page: this.page.current, | ||
| 165 | + row: this.page.size, | ||
| 166 | + communityId: this.communityId | ||
| 167 | + } | ||
| 168 | + const { data, total } = await queryStartWork(params) | ||
| 169 | + this.works = data | ||
| 170 | + this.page.total = total | ||
| 171 | + } catch (error) { | ||
| 172 | + console.error('获取工单列表失败:', error) | ||
| 173 | + } finally { | ||
| 174 | + this.loading = false | ||
| 175 | + } | ||
| 176 | + }, | ||
| 177 | + switchWorkState(item) { | ||
| 178 | + this.conditions.state = item.state | ||
| 179 | + this.page.current = 1 | ||
| 180 | + this.fetchData() | ||
| 181 | + }, | ||
| 182 | + handleSearch() { | ||
| 183 | + this.page.current = 1 | ||
| 184 | + this.fetchData() | ||
| 185 | + }, | ||
| 186 | + handleReset() { | ||
| 187 | + this.conditions = { | ||
| 188 | + state: '', | ||
| 189 | + workName: '', | ||
| 190 | + staffName: '', | ||
| 191 | + queryStartTime: '', | ||
| 192 | + queryEndTime: '' | ||
| 193 | + } | ||
| 194 | + this.page.current = 1 | ||
| 195 | + this.fetchData() | ||
| 196 | + }, | ||
| 197 | + handleAdd() { | ||
| 198 | + this.$router.push('/views/oa/addWork') | ||
| 199 | + }, | ||
| 200 | + handleEdit(row) { | ||
| 201 | + this.$router.push(`/views/oa/editWork?workId=${row.workId}`) | ||
| 202 | + }, | ||
| 203 | + handleDetail(row) { | ||
| 204 | + this.$router.push(`/oa/workDetail?workId=${row.workId}`) | ||
| 205 | + }, | ||
| 206 | + handleDelete(row) { | ||
| 207 | + this.$refs.deleteWork.open(row) | ||
| 208 | + }, | ||
| 209 | + async handleUpdateState(row, state) { | ||
| 210 | + try { | ||
| 211 | + await updateWorkState({ | ||
| 212 | + workId: row.workId, | ||
| 213 | + state, | ||
| 214 | + communityId: this.communityId | ||
| 215 | + }) | ||
| 216 | + this.$message.success(state === 'S' ? '停止成功' : '启用成功') | ||
| 217 | + this.fetchData() | ||
| 218 | + } catch (error) { | ||
| 219 | + console.error('更新状态失败:', error) | ||
| 220 | + } | ||
| 221 | + }, | ||
| 222 | + handleSizeChange(size) { | ||
| 223 | + this.page.size = size | ||
| 224 | + this.fetchData() | ||
| 225 | + }, | ||
| 226 | + handlePageChange(current) { | ||
| 227 | + this.page.current = current | ||
| 228 | + this.fetchData() | ||
| 229 | + } | ||
| 230 | + } | ||
| 231 | +} | ||
| 232 | +</script> | ||
| 233 | + | ||
| 234 | +<style lang="scss" scoped> | ||
| 235 | +.start-work-container { | ||
| 236 | + padding: 20px; | ||
| 237 | + | ||
| 238 | + .state-sidebar { | ||
| 239 | + background-color: #fff; | ||
| 240 | + border-radius: 4px; | ||
| 241 | + padding: 10px 0; | ||
| 242 | + height: 100%; | ||
| 243 | + | ||
| 244 | + .state-list { | ||
| 245 | + list-style: none; | ||
| 246 | + padding: 0; | ||
| 247 | + margin: 0; | ||
| 248 | + | ||
| 249 | + .state-item { | ||
| 250 | + padding: 10px 15px; | ||
| 251 | + cursor: pointer; | ||
| 252 | + text-align: center; | ||
| 253 | + transition: all 0.3s; | ||
| 254 | + | ||
| 255 | + &:hover { | ||
| 256 | + background-color: #f5f7fa; | ||
| 257 | + } | ||
| 258 | + | ||
| 259 | + &.active-state { | ||
| 260 | + background-color: #409eff; | ||
| 261 | + color: #fff; | ||
| 262 | + } | ||
| 263 | + } | ||
| 264 | + } | ||
| 265 | + } | ||
| 266 | + | ||
| 267 | + .search-card { | ||
| 268 | + margin-bottom: 20px; | ||
| 269 | + | ||
| 270 | + .search-form { | ||
| 271 | + .el-form-item { | ||
| 272 | + margin-bottom: 0; | ||
| 273 | + } | ||
| 274 | + } | ||
| 275 | + } | ||
| 276 | + | ||
| 277 | + .work-list-card { | ||
| 278 | + .el-table { | ||
| 279 | + margin-top: 10px; | ||
| 280 | + } | ||
| 281 | + | ||
| 282 | + .el-pagination { | ||
| 283 | + margin-top: 20px; | ||
| 284 | + text-align: right; | ||
| 285 | + } | ||
| 286 | + } | ||
| 287 | +} | ||
| 288 | +</style> | ||
| 0 | \ No newline at end of file | 289 | \ No newline at end of file |
src/views/oa/workTypeLang.js
0 → 100644
| 1 | +export const messages = { | ||
| 2 | + en: { | ||
| 3 | + workType: { | ||
| 4 | + search: { | ||
| 5 | + title: 'Search Conditions', | ||
| 6 | + typeName: 'Type Name' | ||
| 7 | + }, | ||
| 8 | + list: { | ||
| 9 | + title: 'Work Order Types' | ||
| 10 | + }, | ||
| 11 | + table: { | ||
| 12 | + typeName: 'Type Name', | ||
| 13 | + deduction: 'Deduction', | ||
| 14 | + smsWay: 'Notification Method', | ||
| 15 | + createTime: 'Create Time', | ||
| 16 | + remark: 'Remark' | ||
| 17 | + }, | ||
| 18 | + form: { | ||
| 19 | + typeName: 'Type Name', | ||
| 20 | + deduction: 'Deduction', | ||
| 21 | + smsWay: 'Notification Method', | ||
| 22 | + remark: 'Remark' | ||
| 23 | + }, | ||
| 24 | + placeholder: { | ||
| 25 | + typeName: 'Please enter type name', | ||
| 26 | + deduction: 'Please select deduction', | ||
| 27 | + smsWay: 'Please select notification method', | ||
| 28 | + remark: 'Optional, please enter remark' | ||
| 29 | + }, | ||
| 30 | + validate: { | ||
| 31 | + typeName: 'Type name is required', | ||
| 32 | + typeNameMax: 'Type name cannot exceed 200 characters', | ||
| 33 | + deduction: 'Deduction is required', | ||
| 34 | + smsWay: 'Notification method is required', | ||
| 35 | + wtId: 'ID is required' | ||
| 36 | + }, | ||
| 37 | + tip: { | ||
| 38 | + deduction: 'After selecting deduction, the copy recipient will deduct money according to the task completion!', | ||
| 39 | + wechat: 'Need to configure the official account in the system, the official account is a certified service account, and the employee has done employee certification', | ||
| 40 | + aliSms: 'Need to configure Alibaba Cloud SMS information in the system community configuration, the template is work order pending template and work order completion template' | ||
| 41 | + }, | ||
| 42 | + yes: 'Yes', | ||
| 43 | + no: 'No', | ||
| 44 | + wechat: 'WeChat', | ||
| 45 | + aliSms: 'Ali SMS', | ||
| 46 | + workLicense: 'Employee License', | ||
| 47 | + unknown: 'Unknown', | ||
| 48 | + add: { | ||
| 49 | + title: 'Add Work Order Type', | ||
| 50 | + success: 'Add success', | ||
| 51 | + error: 'Add failed' | ||
| 52 | + }, | ||
| 53 | + edit: { | ||
| 54 | + title: 'Edit Work Order Type', | ||
| 55 | + success: 'Edit success', | ||
| 56 | + error: 'Edit failed' | ||
| 57 | + }, | ||
| 58 | + delete: { | ||
| 59 | + title: 'Delete Confirmation', | ||
| 60 | + confirm: 'Are you sure to delete this work order type?', | ||
| 61 | + success: 'Delete success', | ||
| 62 | + error: 'Delete failed' | ||
| 63 | + }, | ||
| 64 | + fetchError: 'Failed to fetch work order types' | ||
| 65 | + } | ||
| 66 | + }, | ||
| 67 | + zh: { | ||
| 68 | + workType: { | ||
| 69 | + search: { | ||
| 70 | + title: '查询条件', | ||
| 71 | + typeName: '类型名称' | ||
| 72 | + }, | ||
| 73 | + list: { | ||
| 74 | + title: '工作单类型' | ||
| 75 | + }, | ||
| 76 | + table: { | ||
| 77 | + typeName: '类型名称', | ||
| 78 | + deduction: '扣款', | ||
| 79 | + smsWay: '通知方式', | ||
| 80 | + createTime: '创建时间', | ||
| 81 | + remark: '备注' | ||
| 82 | + }, | ||
| 83 | + form: { | ||
| 84 | + typeName: '类型名称', | ||
| 85 | + deduction: '扣款', | ||
| 86 | + smsWay: '通知方式', | ||
| 87 | + remark: '备注' | ||
| 88 | + }, | ||
| 89 | + placeholder: { | ||
| 90 | + typeName: '请输入类型名称', | ||
| 91 | + deduction: '请选择扣款', | ||
| 92 | + smsWay: '请选择通知方式', | ||
| 93 | + remark: '选填,请输入备注' | ||
| 94 | + }, | ||
| 95 | + validate: { | ||
| 96 | + typeName: '类型名称不能为空', | ||
| 97 | + typeNameMax: '类型名称不能超过200个字符', | ||
| 98 | + deduction: '扣款不能为空', | ||
| 99 | + smsWay: '通知方式不能为空', | ||
| 100 | + wtId: '编号不能为空' | ||
| 101 | + }, | ||
| 102 | + tip: { | ||
| 103 | + deduction: '选择扣款后,抄送人会根据任务完成情况,相应的扣款!', | ||
| 104 | + wechat: '需要在系统下公众号中配置公众号,公众号为认证过的服务号,并且员工做了员工认证', | ||
| 105 | + aliSms: '需要在系统下小区配置中配置阿里云短信信息,模版为工单待处理模版和工单完成模版' | ||
| 106 | + }, | ||
| 107 | + yes: '是', | ||
| 108 | + no: '否', | ||
| 109 | + wechat: '微信', | ||
| 110 | + aliSms: '阿里短信', | ||
| 111 | + workLicense: '员工工牌', | ||
| 112 | + unknown: '未知', | ||
| 113 | + add: { | ||
| 114 | + title: '添加工作单类型', | ||
| 115 | + success: '添加成功', | ||
| 116 | + error: '添加失败' | ||
| 117 | + }, | ||
| 118 | + edit: { | ||
| 119 | + title: '修改工作单类型', | ||
| 120 | + success: '修改成功', | ||
| 121 | + error: '修改失败' | ||
| 122 | + }, | ||
| 123 | + delete: { | ||
| 124 | + title: '删除确认', | ||
| 125 | + confirm: '确定删除此工作单类型吗?', | ||
| 126 | + success: '删除成功', | ||
| 127 | + error: '删除失败' | ||
| 128 | + }, | ||
| 129 | + fetchError: '获取工作单类型失败' | ||
| 130 | + } | ||
| 131 | + } | ||
| 132 | +} | ||
| 0 | \ No newline at end of file | 133 | \ No newline at end of file |
src/views/oa/workTypeList.vue
0 → 100644
| 1 | +<template> | ||
| 2 | + <div class="work-type-container"> | ||
| 3 | + <!-- 查询条件 --> | ||
| 4 | + <el-card class="search-wrapper"> | ||
| 5 | + <div slot="header" class="flex justify-between"> | ||
| 6 | + <span>{{ $t('workType.search.title') }}</span> | ||
| 7 | + </div> | ||
| 8 | + <el-row :gutter="20"> | ||
| 9 | + <el-col :span="6"> | ||
| 10 | + <el-input v-model.trim="searchForm.typeName" :placeholder="$t('workType.search.typeName')" clearable /> | ||
| 11 | + </el-col> | ||
| 12 | + <el-col :span="18" style="margin-top:5px;"> | ||
| 13 | + <el-button type="primary" @click="handleSearch"> | ||
| 14 | + <i class="el-icon-search"></i> | ||
| 15 | + {{ $t('common.search') }} | ||
| 16 | + </el-button> | ||
| 17 | + <el-button @click="handleReset"> | ||
| 18 | + <i class="el-icon-refresh"></i> | ||
| 19 | + {{ $t('common.reset') }} | ||
| 20 | + </el-button> | ||
| 21 | + </el-col> | ||
| 22 | + </el-row> | ||
| 23 | + </el-card> | ||
| 24 | + | ||
| 25 | + <!-- 工作单类型列表 --> | ||
| 26 | + <el-card class="list-wrapper"> | ||
| 27 | + <div slot="header" class="flex justify-between"> | ||
| 28 | + <span>{{ $t('workType.list.title') }}</span> | ||
| 29 | + <el-button type="primary" size="small" style="float:right;" @click="handleAdd"> | ||
| 30 | + <i class="el-icon-plus"></i> | ||
| 31 | + {{ $t('common.add') }} | ||
| 32 | + </el-button> | ||
| 33 | + </div> | ||
| 34 | + | ||
| 35 | + <el-table v-loading="loading" :data="tableData" border style="width:100%"> | ||
| 36 | + <el-table-column prop="typeName" :label="$t('workType.table.typeName')" align="center" /> | ||
| 37 | + <el-table-column prop="deduction" :label="$t('workType.table.deduction')" align="center"> | ||
| 38 | + <template slot-scope="scope"> | ||
| 39 | + {{ scope.row.deduction === 'Y' ? $t('workType.yes') : $t('workType.no') }} | ||
| 40 | + </template> | ||
| 41 | + </el-table-column> | ||
| 42 | + <el-table-column prop="smsWay" :label="$t('workType.table.smsWay')" align="center"> | ||
| 43 | + <template slot-scope="scope"> | ||
| 44 | + <span v-if="scope.row.smsWay === 'WECHAT'">{{ $t('workType.wechat') }}</span> | ||
| 45 | + <span v-else-if="scope.row.smsWay === 'ALI_SMS'">{{ $t('workType.aliSms') }}</span> | ||
| 46 | + <span v-else-if="scope.row.smsWay === 'WORK_LICENSE'">{{ $t('workType.workLicense') }}</span> | ||
| 47 | + <span v-else>{{ $t('workType.unknown') }}</span> | ||
| 48 | + </template> | ||
| 49 | + </el-table-column> | ||
| 50 | + <el-table-column prop="createTime" :label="$t('workType.table.createTime')" align="center" /> | ||
| 51 | + <el-table-column prop="remark" :label="$t('workType.table.remark')" align="center"> | ||
| 52 | + <template slot-scope="scope"> | ||
| 53 | + {{ scope.row.remark || '-' }} | ||
| 54 | + </template> | ||
| 55 | + </el-table-column> | ||
| 56 | + <el-table-column :label="$t('common.operation')" align="center" width="200"> | ||
| 57 | + <template slot-scope="scope"> | ||
| 58 | + <el-button size="mini" type="primary" @click="handleEdit(scope.row)"> | ||
| 59 | + {{ $t('common.edit') }} | ||
| 60 | + </el-button> | ||
| 61 | + <el-button size="mini" type="danger" @click="handleDelete(scope.row)"> | ||
| 62 | + {{ $t('common.delete') }} | ||
| 63 | + </el-button> | ||
| 64 | + </template> | ||
| 65 | + </el-table-column> | ||
| 66 | + </el-table> | ||
| 67 | + | ||
| 68 | + <el-pagination :current-page.sync="page.current" :page-sizes="[10, 20, 30, 50]" :page-size="page.size" | ||
| 69 | + :total="page.total" layout="total, sizes, prev, pager, next, jumper" @size-change="handleSizeChange" | ||
| 70 | + @current-change="handleCurrentChange" /> | ||
| 71 | + </el-card> | ||
| 72 | + | ||
| 73 | + <!-- 组件 --> | ||
| 74 | + <add-work-type ref="addWorkType" @success="handleSuccess" /> | ||
| 75 | + <edit-work-type ref="editWorkType" @success="handleSuccess" /> | ||
| 76 | + <delete-work-type ref="deleteWorkType" @success="handleSuccess" /> | ||
| 77 | + </div> | ||
| 78 | +</template> | ||
| 79 | + | ||
| 80 | +<script> | ||
| 81 | +import { listWorkType } from '@/api/oa/workTypeApi' | ||
| 82 | +import { getCommunityId } from '@/api/community/communityApi' | ||
| 83 | +import AddWorkType from '@/components/oa/addWorkType' | ||
| 84 | +import EditWorkType from '@/components/oa/editWorkType' | ||
| 85 | +import DeleteWorkType from '@/components/oa/deleteWorkType' | ||
| 86 | + | ||
| 87 | +export default { | ||
| 88 | + name: 'WorkTypeList', | ||
| 89 | + components: { | ||
| 90 | + AddWorkType, | ||
| 91 | + EditWorkType, | ||
| 92 | + DeleteWorkType | ||
| 93 | + }, | ||
| 94 | + data() { | ||
| 95 | + return { | ||
| 96 | + loading: false, | ||
| 97 | + searchForm: { | ||
| 98 | + typeName: '' | ||
| 99 | + }, | ||
| 100 | + tableData: [], | ||
| 101 | + page: { | ||
| 102 | + current: 1, | ||
| 103 | + size: 10, | ||
| 104 | + total: 0 | ||
| 105 | + }, | ||
| 106 | + communityId: '' | ||
| 107 | + } | ||
| 108 | + }, | ||
| 109 | + created() { | ||
| 110 | + this.communityId = getCommunityId() | ||
| 111 | + this.getList() | ||
| 112 | + }, | ||
| 113 | + methods: { | ||
| 114 | + async getList() { | ||
| 115 | + try { | ||
| 116 | + this.loading = true | ||
| 117 | + const params = { | ||
| 118 | + page: this.page.current, | ||
| 119 | + row: this.page.size, | ||
| 120 | + typeName: this.searchForm.typeName, | ||
| 121 | + communityId: this.communityId | ||
| 122 | + } | ||
| 123 | + const { data, total } = await listWorkType(params) | ||
| 124 | + this.tableData = data | ||
| 125 | + this.page.total = total | ||
| 126 | + } catch (error) { | ||
| 127 | + this.$message.error(this.$t('workType.fetchError')) | ||
| 128 | + } finally { | ||
| 129 | + this.loading = false | ||
| 130 | + } | ||
| 131 | + }, | ||
| 132 | + handleSearch() { | ||
| 133 | + this.page.current = 1 | ||
| 134 | + this.getList() | ||
| 135 | + }, | ||
| 136 | + handleReset() { | ||
| 137 | + this.searchForm = { | ||
| 138 | + typeName: '' | ||
| 139 | + } | ||
| 140 | + this.getList() | ||
| 141 | + }, | ||
| 142 | + handleAdd() { | ||
| 143 | + this.$refs.addWorkType.open() | ||
| 144 | + }, | ||
| 145 | + handleEdit(row) { | ||
| 146 | + this.$refs.editWorkType.open(row) | ||
| 147 | + }, | ||
| 148 | + handleDelete(row) { | ||
| 149 | + this.$refs.deleteWorkType.open(row) | ||
| 150 | + }, | ||
| 151 | + handleSuccess() { | ||
| 152 | + this.getList() | ||
| 153 | + }, | ||
| 154 | + handleSizeChange(val) { | ||
| 155 | + this.page.size = val | ||
| 156 | + this.getList() | ||
| 157 | + }, | ||
| 158 | + handleCurrentChange(val) { | ||
| 159 | + this.page.current = val | ||
| 160 | + this.getList() | ||
| 161 | + } | ||
| 162 | + } | ||
| 163 | +} | ||
| 164 | +</script> | ||
| 165 | + | ||
| 166 | +<style lang="scss" scoped> | ||
| 167 | +.work-type-container { | ||
| 168 | + padding: 20px; | ||
| 169 | + | ||
| 170 | + .search-wrapper { | ||
| 171 | + margin-bottom: 20px; | ||
| 172 | + } | ||
| 173 | + | ||
| 174 | + .list-wrapper { | ||
| 175 | + margin-bottom: 20px; | ||
| 176 | + } | ||
| 177 | + | ||
| 178 | + .el-pagination { | ||
| 179 | + margin-top: 20px; | ||
| 180 | + text-align: right; | ||
| 181 | + } | ||
| 182 | +} | ||
| 183 | +</style> | ||
| 0 | \ No newline at end of file | 184 | \ No newline at end of file |