Commit caba9d96517fe37f776708586b1fa9fb13bdb229

Authored by wuxw
1 parent eb48bd86

oa 中除了 工作办理没有测试其他测试完成

src/components/oa/addWorkType.vue
1 <template> 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"> 2 + <el-dialog :title="$t('workType.add.title')" :visible.sync="visible" width="50%" @close="handleClose">
  3 + <el-form ref="form" :model="formData" :rules="rules" label-width="120px" class="text-left">
9 <el-form-item :label="$t('workType.form.typeName')" prop="typeName"> 4 <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 - /> 5 + <el-input v-model.trim="formData.typeName" :placeholder="$t('workType.placeholder.typeName')" />
14 </el-form-item> 6 </el-form-item>
15 - 7 +
16 <el-form-item :label="$t('workType.form.deduction')" prop="deduction"> 8 <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 - /> 9 + <el-select v-model="formData.deduction" :placeholder="$t('workType.placeholder.deduction')" style="width:100%">
  10 + <el-option v-for="item in deductionOptions" :key="item.value" :label="item.label" :value="item.value" />
28 </el-select> 11 </el-select>
29 <div class="el-form-item__tip" v-if="formData.deduction === 'Y'"> 12 <div class="el-form-item__tip" v-if="formData.deduction === 'Y'">
30 {{ $t('workType.tip.deduction') }} 13 {{ $t('workType.tip.deduction') }}
@@ -32,17 +15,8 @@ @@ -32,17 +15,8 @@
32 </el-form-item> 15 </el-form-item>
33 16
34 <el-form-item :label="$t('workType.form.smsWay')" prop="smsWay"> 17 <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 - /> 18 + <el-select v-model="formData.smsWay" :placeholder="$t('workType.placeholder.smsWay')" style="width:100%">
  19 + <el-option v-for="item in smsWayOptions" :key="item.value" :label="item.label" :value="item.value" />
46 </el-select> 20 </el-select>
47 <div class="el-form-item__tip" v-if="formData.smsWay === 'WECHAT'"> 21 <div class="el-form-item__tip" v-if="formData.smsWay === 'WECHAT'">
48 {{ $t('workType.tip.wechat') }} 22 {{ $t('workType.tip.wechat') }}
@@ -53,14 +27,8 @@ @@ -53,14 +27,8 @@
53 </el-form-item> 27 </el-form-item>
54 28
55 <el-form-item :label="$t('workType.form.remark')"> 29 <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 - /> 30 + <el-input v-model.trim="formData.remark" type="textarea" :rows="3"
  31 + :placeholder="$t('workType.placeholder.remark')" maxlength="500" show-word-limit />
64 </el-form-item> 32 </el-form-item>
65 </el-form> 33 </el-form>
66 34
src/components/oa/editWorkType.vue
1 <template> 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"> 2 + <el-dialog :title="$t('workType.edit.title')" :visible.sync="visible" width="50%" @close="handleClose">
  3 + <el-form ref="form" :model="formData" :rules="rules" label-width="120px" class="text-left">
9 <el-form-item :label="$t('workType.form.typeName')" prop="typeName"> 4 <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 - /> 5 + <el-input v-model.trim="formData.typeName" :placeholder="$t('workType.placeholder.typeName')" />
14 </el-form-item> 6 </el-form-item>
15 - 7 +
16 <el-form-item :label="$t('workType.form.deduction')" prop="deduction"> 8 <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 - /> 9 + <el-select v-model="formData.deduction" :placeholder="$t('workType.placeholder.deduction')" style="width:100%">
  10 + <el-option v-for="item in deductionOptions" :key="item.value" :label="item.label" :value="item.value" />
28 </el-select> 11 </el-select>
29 <div class="el-form-item__tip" v-if="formData.deduction === 'Y'"> 12 <div class="el-form-item__tip" v-if="formData.deduction === 'Y'">
30 {{ $t('workType.tip.deduction') }} 13 {{ $t('workType.tip.deduction') }}
@@ -32,29 +15,14 @@ @@ -32,29 +15,14 @@
32 </el-form-item> 15 </el-form-item>
33 16
34 <el-form-item :label="$t('workType.form.smsWay')" prop="smsWay"> 17 <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 - /> 18 + <el-select v-model="formData.smsWay" :placeholder="$t('workType.placeholder.smsWay')" style="width:100%">
  19 + <el-option v-for="item in smsWayOptions" :key="item.value" :label="item.label" :value="item.value" />
46 </el-select> 20 </el-select>
47 </el-form-item> 21 </el-form-item>
48 22
49 <el-form-item :label="$t('workType.form.remark')"> 23 <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 - /> 24 + <el-input v-model.trim="formData.remark" type="textarea" :rows="3"
  25 + :placeholder="$t('workType.placeholder.remark')" maxlength="500" show-word-limit />
58 </el-form-item> 26 </el-form-item>
59 </el-form> 27 </el-form>
60 28
src/components/oa/newOaWorkflowFinish.vue
@@ -4,7 +4,7 @@ @@ -4,7 +4,7 @@
4 <div slot="header" class="flex justify-between"> 4 <div slot="header" class="flex justify-between">
5 <span>{{ $t('newOaWorkflowFinish.searchTitle') }}</span> 5 <span>{{ $t('newOaWorkflowFinish.searchTitle') }}</span>
6 </div> 6 </div>
7 - <el-form :inline="true" :model="conditions" class="search-form"> 7 + <el-form :inline="true" :model="conditions" class="search-form text-left">
8 <el-form-item> 8 <el-form-item>
9 <el-input v-model="conditions.createUserName" :placeholder="$t('newOaWorkflowFinish.enterApplicant')" 9 <el-input v-model="conditions.createUserName" :placeholder="$t('newOaWorkflowFinish.enterApplicant')"
10 clearable /> 10 clearable />
src/components/oa/newOaWorkflowForm.vue
1 <template> 1 <template>
2 <div class="new-oa-workflow-form"> 2 <div class="new-oa-workflow-form">
3 <el-card class="form-card"> 3 <el-card class="form-card">
4 - <div class="form-container" id="form-container"> 4 + <el-form ref="form" :model="formData" label-width="120px" label-position="right" class="text-left">
  5 + <div v-for="(item, index) in components" :key="index">
  6 + <!-- 标题 -->
  7 + <el-divider v-if="item.type == 'text'" content-position="left">
  8 + <span class="form-title">{{ item.text }}</span>
  9 + </el-divider>
5 10
6 - <div class="upload-wrapper">  
7 - <upload-file ref="uploadFile" :call-back-listener="callBackListener" :call-back-function="callBackFunction" /> 11 + <!-- 文本框 -->
  12 + <el-form-item v-if="item.type == 'textfield'" :label="item.label" :prop="item.key"
  13 + :rules="getValidationRules(item)">
  14 + <el-input v-model="item.value" :placeholder="item.description" clearable>
  15 + </el-input>
  16 + </el-form-item>
  17 +
  18 + <!-- 数字框 -->
  19 + <el-form-item v-if="item.type == 'number'" :label="item.label" :prop="item.key"
  20 + :rules="getValidationRules(item)">
  21 + <el-input-number v-model="item.value" :placeholder="item.description" :min="0" style="width: 100%">
  22 + </el-input-number>
  23 + </el-form-item>
  24 +
  25 + <!-- 文本域 -->
  26 + <el-form-item v-if="item.type == 'textarea'" :label="item.label" :prop="item.key"
  27 + :rules="getValidationRules(item)">
  28 + <el-input v-model="item.value" type="textarea" :rows="4" :placeholder="item.description">
  29 + </el-input>
  30 + </el-form-item>
  31 +
  32 + <!-- 日期选择 -->
  33 + <el-form-item v-if="item.type == 'textdate'" :label="item.label" :prop="item.key"
  34 + :rules="getValidationRules(item)">
  35 + <el-date-picker v-model="item.value" type="date" :placeholder="item.description" format="yyyy-MM-dd"
  36 + value-format="yyyy-MM-dd" style="width: 100%">
  37 + </el-date-picker>
  38 + </el-form-item>
  39 +
  40 + <!-- 时间选择 -->
  41 + <el-form-item v-if="item.type == 'textdatetime'" :label="item.label" :prop="item.key"
  42 + :rules="getValidationRules(item)">
  43 + <el-time-picker v-model="item.value" :placeholder="item.description" format="HH:mm"
  44 + value-format="HH:mm" style="width: 100%">
  45 + </el-time-picker>
  46 + </el-form-item>
  47 +
  48 + <!-- 单选框 -->
  49 + <el-form-item v-if="item.type == 'radio'" :label="item.label" :prop="item.key"
  50 + :rules="getValidationRules(item)">
  51 + <el-radio-group v-model="item.value">
  52 + <el-radio v-for="(option, optionIndex) in item.values" :key="optionIndex" :label="option.value">
  53 + {{ option.label }}
  54 + </el-radio>
  55 + </el-radio-group>
  56 + </el-form-item>
  57 +
  58 + <!-- 下拉选择 -->
  59 + <el-form-item v-if="item.type == 'select'" :label="item.label" :prop="item.key"
  60 + :rules="getValidationRules(item)">
  61 + <el-select v-model="item.value" :placeholder="item.description" style="width: 100%" clearable>
  62 + <el-option v-for="(option, optionIndex) in item.values" :key="optionIndex" :label="option.label"
  63 + :value="option.value">
  64 + </el-option>
  65 + </el-select>
  66 + </el-form-item>
  67 +
  68 + <!-- 复选框 -->
  69 + <el-form-item v-if="item.type == 'checkbox'" :label="item.label" :prop="item.key"
  70 + :rules="getValidationRules(item)">
  71 + <el-checkbox-group v-model="item.value">
  72 + <el-checkbox v-for="(option, optionIndex) in item.values" :key="optionIndex" :label="option.value">
  73 + {{ option.label }}
  74 + </el-checkbox>
  75 + </el-checkbox-group>
  76 + </el-form-item>
  77 +
  78 + <!-- 文件上传 -->
  79 + <el-form-item v-if="item.type == 'button' && item.action == 'submit'" :label="$t('common.file')">
  80 + <div class="upload-section">
  81 + <upload-file ref="uploadFile" @notify="handleFileUpload" />
  82 + </div>
  83 + </el-form-item>
  84 +
  85 + <!-- 提交按钮 -->
  86 + <el-form-item v-if="item.type == 'button' && item.action == 'submit'" class="text-right">
  87 + <el-button type="primary" @click="_doSubmit" :loading="submitLoading">
  88 + <i class="el-icon-check"></i>
  89 + {{ item.label }}
  90 + </el-button>
  91 + </el-form-item>
  92 +
  93 + <!-- 重置按钮 -->
  94 + <el-form-item v-if="item.type == 'button' && item.action == 'reset'" class="text-right">
  95 + <el-button @click="_doReset">
  96 + <i class="el-icon-refresh"></i>
  97 + {{ item.label }}
  98 + </el-button>
  99 + </el-form-item>
8 </div> 100 </div>
9 - </div>  
10 101
  102 + </el-form>
11 </el-card> 103 </el-card>
12 </div> 104 </div>
13 </template> 105 </template>
@@ -15,7 +107,6 @@ @@ -15,7 +107,6 @@
15 <script> 107 <script>
16 import UploadFile from '@/components/upload/uploadFile' 108 import UploadFile from '@/components/upload/uploadFile'
17 import { queryOaWorkflowForm, saveOaWorkflowFormData } from '@/api/oa/newOaWorkflowApi' 109 import { queryOaWorkflowForm, saveOaWorkflowFormData } from '@/api/oa/newOaWorkflowApi'
18 -//import { Formio } from 'formiojs'  
19 110
20 export default { 111 export default {
21 name: 'NewOaWorkflowForm', 112 name: 'NewOaWorkflowForm',
@@ -24,20 +115,26 @@ export default { @@ -24,20 +115,26 @@ export default {
24 data() { 115 data() {
25 return { 116 return {
26 formJson: {}, 117 formJson: {},
  118 + components: [],
  119 + formData: {},
27 fileName: '', 120 fileName: '',
28 realFileName: '', 121 realFileName: '',
29 callBackListener: 'newOaWorkflowForm', 122 callBackListener: 'newOaWorkflowForm',
30 callBackFunction: 'fileName', 123 callBackFunction: 'fileName',
31 - formViewer: null 124 + submitLoading: false,
  125 + showUploadComponent: false
32 } 126 }
33 }, 127 },
  128 +
34 mounted() { 129 mounted() {
35 }, 130 },
  131 +
36 methods: { 132 methods: {
37 open(params) { 133 open(params) {
38 this.flowId = params.flowId 134 this.flowId = params.flowId
39 this.listOaWorkflowForm() 135 this.listOaWorkflowForm()
40 }, 136 },
  137 +
41 async listOaWorkflowForm() { 138 async listOaWorkflowForm() {
42 try { 139 try {
43 const res = await queryOaWorkflowForm({ 140 const res = await queryOaWorkflowForm({
@@ -50,60 +147,109 @@ export default { @@ -50,60 +147,109 @@ export default {
50 this.initForm() 147 this.initForm()
51 } catch (error) { 148 } catch (error) {
52 console.error('获取表单配置失败:', error) 149 console.error('获取表单配置失败:', error)
  150 + this.$message.error('获取表单配置失败')
53 } 151 }
54 }, 152 },
  153 +
55 initForm() { 154 initForm() {
56 - const container = document.getElementById('form-container') 155 + this.components = this.formJson.components
  156 + this.formData = {}
57 157
58 - const form = window.FormViewer.createForm({  
59 - container,  
60 - schema: this.formJson  
61 - });  
62 - console.log(form);  
63 - form.then((_from) => {  
64 - _from.on('submit', (event) => {  
65 - this.submitFormData(event.data, event.errors);  
66 - })  
67 - }).then((_from) => {  
68 - console.log(_from);  
69 - let node = document.querySelector('.fjs-form .uploadFile');  
70 - const submitBtn = document.querySelector('.fjs-form .fjs-form-field-button');  
71 - submitBtn.parentNode.insertBefore(node, submitBtn);  
72 - }); 158 + this.components.forEach(item => {
  159 + if (item.type !== 'button' && item.type !== 'text') {
  160 + // 初始化表单数据
  161 + if (item.type === 'checkbox') {
  162 + this.formData[item.key] = []
  163 + } else if (item.type === 'radio' || item.type === 'select') {
  164 + this.formData[item.key] = item.values && item.values.length > 0 ? item.values[0].value : ''
  165 + } else {
  166 + this.formData[item.key] = ''
  167 + }
  168 + }
  169 + })
73 }, 170 },
74 - async submitFormData(data, errors) {  
75 - if (Object.keys(errors).length !== 0) return  
76 -  
77 - const formData = {  
78 - ...data,  
79 - flowId: this.flowId,  
80 - fileName: this.fileName,  
81 - realFileName: this.realFileName 171 +
  172 + getValidationRules(item) {
  173 + const rules = []
  174 + if (item.validate && item.validate.required) {
  175 + rules.push({
  176 + required: true,
  177 + message: `${item.label}不能为空`,
  178 + trigger: 'blur'
  179 + })
82 } 180 }
  181 + return rules
  182 + },
83 183
  184 + async _doSubmit() {
84 try { 185 try {
85 - const res = await saveOaWorkflowFormData(formData) 186 + // 表单验证
  187 + await this.$refs.form.validate()
  188 +
  189 + this.submitLoading = true
  190 +
  191 + const _data = {
  192 + fileName: this.fileName,
  193 + realFileName: this.realFileName,
  194 + flowId: this.flowId,
  195 + ...this.formData
  196 + }
  197 +
  198 + const res = await saveOaWorkflowFormData(_data)
86 if (res.code === 0) { 199 if (res.code === 0) {
87 this.$message.success(this.$t('common.submitSuccess')) 200 this.$message.success(this.$t('common.submitSuccess'))
88 this.resetForm() 201 this.resetForm()
89 this.$emit('switch-tab', 'newOaWorkflowPool') 202 this.$emit('switch-tab', 'newOaWorkflowPool')
90 } else { 203 } else {
91 - this.$message.error(res.msg) 204 + this.$message.error(res.msg || this.$t('common.submitFailed'))
92 } 205 }
93 } catch (error) { 206 } catch (error) {
  207 + if (error.message) {
  208 + // 表单验证错误
  209 + return
  210 + }
94 console.error('提交表单失败:', error) 211 console.error('提交表单失败:', error)
95 this.$message.error(this.$t('common.submitFailed')) 212 this.$message.error(this.$t('common.submitFailed'))
  213 + } finally {
  214 + this.submitLoading = false
96 } 215 }
97 }, 216 },
  217 +
  218 + _doReset() {
  219 + let _that = this;
  220 + _that.components.forEach(item => {
  221 + item.value = "";
  222 + if (item.type == 'textdate' || item.type == 'textdatetime') {
  223 + item.value = "请选择";
  224 + }
  225 +
  226 + if (item.type == "radio" || item.type == "select") {
  227 + item.valueIndex = 0;
  228 + }
  229 + });
  230 + this.$forceUpdate();
  231 + },
  232 +
  233 + _doUploadFile() {
  234 + this.showUploadComponent = true
  235 + this.$nextTick(() => {
  236 + this.$refs.uploadFile.open()
  237 + })
  238 + },
  239 +
98 resetForm() { 240 resetForm() {
99 - if (this.formViewer) {  
100 - this.formViewer.destroy() 241 + this.$refs.form.resetFields()
  242 + if (this.$refs.uploadFile) {
  243 + this.$refs.uploadFile.clear()
101 } 244 }
102 - this.$refs.uploadFile.clear()  
103 this.fileName = '' 245 this.fileName = ''
104 this.realFileName = '' 246 this.realFileName = ''
105 this.formJson = {} 247 this.formJson = {}
  248 + this.components = []
  249 + this.formData = {}
  250 + this.showUploadComponent = false
106 }, 251 },
  252 +
107 handleFileUpload(fileInfo) { 253 handleFileUpload(fileInfo) {
108 this.fileName = fileInfo.fileName 254 this.fileName = fileInfo.fileName
109 this.realFileName = fileInfo.realFileName 255 this.realFileName = fileInfo.realFileName
@@ -112,103 +258,28 @@ export default { @@ -112,103 +258,28 @@ export default {
112 } 258 }
113 </script> 259 </script>
114 260
115 -<style lang="scss"> 261 +<style lang="scss" scoped>
116 .new-oa-workflow-form { 262 .new-oa-workflow-form {
117 .form-card { 263 .form-card {
118 - padding: 20px;  
119 - border-radius: 4px;  
120 - border: 1px solid #ebeef5;  
121 - background-color: #fff;  
122 - box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);  
123 -  
124 - .form-container {  
125 -  
126 - .upload-wrapper {  
127 - margin-bottom: 20px;  
128 - padding: 20px;  
129 - background-color: #fafafa;  
130 - border: 1px solid #e4e7ed;  
131 - border-radius: 4px;  
132 - } 264 + .form-title {
  265 + font-size: 16px;
  266 + font-weight: 600;
  267 + color: #303133;
133 } 268 }
134 - }  
135 -}  
136 -  
137 -// 全局Formio样式覆盖(不使用scoped)  
138 -  
139 -// Formio Element UI 风格样式  
140 -.formio-form {  
141 - font-family: 'Helvetica Neue', Helvetica, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', '微软雅黑', Arial, sans-serif !important;  
142 -  
143 - .form-group {  
144 - margin-bottom: 22px !important;  
145 - text-align: left !important;  
146 - }  
147 -  
148 - .form-control {  
149 - border: 1px solid #dcdfe6 !important;  
150 - border-radius: 4px !important;  
151 - padding: 0 15px !important;  
152 - height: 40px !important;  
153 - line-height: 40px !important;  
154 - font-size: 14px !important;  
155 - background: #fff !important;  
156 - color: #606266 !important;  
157 - box-sizing: border-box !important;  
158 - width: 100% !important;  
159 - transition: border-color 0.2s cubic-bezier(0.645, 0.045, 0.355, 1) !important;  
160 - }  
161 -  
162 - .form-control:focus {  
163 - border-color: #409eff !important;  
164 - outline: none !important;  
165 - }  
166 -  
167 - .form-control:disabled {  
168 - background: #f5f7fa !important;  
169 - color: #c0c4cc !important;  
170 - }  
171 -  
172 - .col-form-label {  
173 - font-weight: 500 !important;  
174 - color: #606266 !important;  
175 - font-size: 14px !important;  
176 - margin-bottom: 8px !important;  
177 - }  
178 -  
179 - .formio-errors {  
180 - color: #f56c6c !important;  
181 - font-size: 12px !important;  
182 - margin-top: 4px !important;  
183 - }  
184 269
185 - button.btn {  
186 - background-color: #409eff !important;  
187 - border: 1px solid #409eff !important;  
188 - border-radius: 4px !important;  
189 - padding: 12px 20px !important;  
190 - font-size: 14px !important;  
191 - font-weight: 500 !important;  
192 - color: #fff !important;  
193 - cursor: pointer !important;  
194 - transition: all 0.3s cubic-bezier(0.645, 0.045, 0.355, 1) !important;  
195 - }  
196 -  
197 - button.btn:hover {  
198 - background-color: #66b1ff !important;  
199 - border-color: #66b1ff !important;  
200 - } 270 + .upload-section {
  271 + .file-info {
  272 + margin-bottom: 10px;
  273 + }
  274 + }
201 275
202 - button.btn:active {  
203 - background-color: #3a8ee6 !important;  
204 - border-color: #3a8ee6 !important;  
205 - } 276 + .el-form-item {
  277 + margin-bottom: 22px;
  278 + }
206 279
207 - button.btn:disabled {  
208 - background-color: #c0c4cc !important;  
209 - border-color: #c0c4cc !important;  
210 - color: #fff !important;  
211 - cursor: not-allowed !important; 280 + .el-divider {
  281 + margin: 24px 0;
  282 + }
212 } 283 }
213 } 284 }
214 </style> 285 </style>
215 \ No newline at end of file 286 \ No newline at end of file
src/components/oa/newOaWorkflowUndo.vue
@@ -4,7 +4,7 @@ @@ -4,7 +4,7 @@
4 <div slot="header" class="flex justify-between"> 4 <div slot="header" class="flex justify-between">
5 <span>{{ $t('newOaWorkflowUndo.searchTitle') }}</span> 5 <span>{{ $t('newOaWorkflowUndo.searchTitle') }}</span>
6 </div> 6 </div>
7 - <el-form :inline="true" :model="conditions" class="search-form"> 7 + <el-form :inline="true" :model="conditions" class="search-form text-left">
8 <el-form-item> 8 <el-form-item>
9 <el-input v-model="conditions.createUserName" :placeholder="$t('newOaWorkflowUndo.enterApplicant')" 9 <el-input v-model="conditions.createUserName" :placeholder="$t('newOaWorkflowUndo.enterApplicant')"
10 clearable /> 10 clearable />
src/i18n/commonLang.js
@@ -58,6 +58,7 @@ export const messages = { @@ -58,6 +58,7 @@ export const messages = {
58 submitSuccess:'Submit successfully', 58 submitSuccess:'Submit successfully',
59 saveSuccess:'successfully', 59 saveSuccess:'successfully',
60 noData:'No Data', 60 noData:'No Data',
  61 + file:'File'
61 } 62 }
62 }, 63 },
63 zh: { 64 zh: {
@@ -119,6 +120,7 @@ export const messages = { @@ -119,6 +120,7 @@ export const messages = {
119 submitSuccess:'提交成功', 120 submitSuccess:'提交成功',
120 saveSuccess:'成功', 121 saveSuccess:'成功',
121 noData:'暂无数据', 122 noData:'暂无数据',
  123 + file:'附件'
122 } 124 }
123 } 125 }
124 } 126 }
125 \ No newline at end of file 127 \ No newline at end of file
src/router/index.js
@@ -63,8 +63,8 @@ const routes = [ @@ -63,8 +63,8 @@ const routes = [
63 63
64 64
65 { 65 {
66 - path: '/views/staff/staffDetailList',  
67 - name: '/views/staff/staffDetailList', 66 + path: '/views/staff/staffDetail',
  67 + name: '/views/staff/staffDetail',
68 component: () => import('@/views/staff/staffDetailList.vue') 68 component: () => import('@/views/staff/staffDetailList.vue')
69 }, 69 },
70 70
src/views/oa/addAttendanceClassesStaffList.vue
1 <template> 1 <template>
2 <div class="add-attendance-classes-staff-container"> 2 <div class="add-attendance-classes-staff-container">
3 <el-card> 3 <el-card>
4 - <div slot="header" class="clearfix"> 4 + <div slot="header" class="flex justify-between">
5 <span>{{ $t('addAttendanceClassesStaff.title') }}</span> 5 <span>{{ $t('addAttendanceClassesStaff.title') }}</span>
6 <el-button type="primary" size="small" class="float-right" @click="handleGoBack"> 6 <el-button type="primary" size="small" class="float-right" @click="handleGoBack">
7 <i class="el-icon-close"></i> 7 <i class="el-icon-close"></i>
src/views/oa/addWorkList.vue
1 <template> 1 <template>
2 <div class="add-work-container"> 2 <div class="add-work-container">
3 <el-card class="box-card"> 3 <el-card class="box-card">
4 - <div slot="header" class="clearfix"> 4 + <div slot="header" class="flex justify-between">
5 <span>{{ $t('addWork.title') }}</span> 5 <span>{{ $t('addWork.title') }}</span>
6 </div> 6 </div>
7 7
8 - <el-form ref="form" :model="addWorkInfo" label-width="120px" label-position="right"> 8 + <el-form ref="form" :model="addWorkInfo" label-width="120px" label-position="right" class="text-left">
9 <el-row :gutter="20"> 9 <el-row :gutter="20">
10 <el-col :span="12"> 10 <el-col :span="12">
11 <el-form-item :label="$t('addWork.workName')" prop="workName"> 11 <el-form-item :label="$t('addWork.workName')" prop="workName">
@@ -235,10 +235,10 @@ export default { @@ -235,10 +235,10 @@ export default {
235 methods: { 235 methods: {
236 initDateTime() { 236 initDateTime() {
237 const now = new Date() 237 const now = new Date()
238 - this.addWorkInfo.startTime = dateFormat(now) 238 + this.addWorkInfo.startTime = dateFormat(now)+' 00:00:00'
239 const tomorrow = new Date(now) 239 const tomorrow = new Date(now)
240 tomorrow.setDate(tomorrow.getDate() + 1) 240 tomorrow.setDate(tomorrow.getDate() + 1)
241 - this.addWorkInfo.endTime = dateFormat(tomorrow) 241 + this.addWorkInfo.endTime = dateFormat(tomorrow)+' 23:59:59'
242 }, 242 },
243 addWorkValidate() { 243 addWorkValidate() {
244 return this.$refs.form.validate() 244 return this.$refs.form.validate()
src/views/oa/newOaWorkflowDetailList.vue
@@ -93,7 +93,7 @@ @@ -93,7 +93,7 @@
93 <span>{{ $t('newOaWorkflowDetail.workflowHandle') }}</span> 93 <span>{{ $t('newOaWorkflowDetail.workflowHandle') }}</span>
94 </div> 94 </div>
95 95
96 - <el-form label-width="120px"> 96 + <el-form label-width="120px" class="text-left">
97 <el-form-item :label="$t('newOaWorkflowDetail.action')"> 97 <el-form-item :label="$t('newOaWorkflowDetail.action')">
98 <el-select v-model="newOaWorkflowDetailInfo.audit.auditCode" style="width:100%" 98 <el-select v-model="newOaWorkflowDetailInfo.audit.auditCode" style="width:100%"
99 :placeholder="$t('newOaWorkflowDetail.selectAction')"> 99 :placeholder="$t('newOaWorkflowDetail.selectAction')">
@@ -109,7 +109,7 @@ @@ -109,7 +109,7 @@
109 </el-select> 109 </el-select>
110 </el-form-item> 110 </el-form-item>
111 111
112 - <el-form-item :label="$t('newOaWorkflowDetail.workflowDescription')"> 112 + <el-form-item :label="$t('newOaWorkflowDetail.workflowDescription')" class="margin-top">
113 <el-input type="textarea" :rows="3" :placeholder="$t('newOaWorkflowDetail.descriptionRequired')" 113 <el-input type="textarea" :rows="3" :placeholder="$t('newOaWorkflowDetail.descriptionRequired')"
114 v-model="newOaWorkflowDetailInfo.audit.auditMessage" /> 114 v-model="newOaWorkflowDetailInfo.audit.auditMessage" />
115 </el-form-item> 115 </el-form-item>
@@ -117,7 +117,7 @@ @@ -117,7 +117,7 @@
117 <!-- 办理时 判断是否指定 委托人 如果指定了 则不显示 --> 117 <!-- 办理时 判断是否指定 委托人 如果指定了 则不显示 -->
118 <el-form-item 118 <el-form-item
119 v-if="newOaWorkflowDetailInfo.audit.auditCode == '1100' && newOaWorkflowDetailInfo.nextAudit.assignee == '-2'" 119 v-if="newOaWorkflowDetailInfo.audit.auditCode == '1100' && newOaWorkflowDetailInfo.nextAudit.assignee == '-2'"
120 - :label="$t('newOaWorkflowDetail.nextHandler')"> 120 + :label="$t('newOaWorkflowDetail.nextHandler')" class="margin-top">
121 <el-input v-model="newOaWorkflowDetailInfo.audit.staffName" 121 <el-input v-model="newOaWorkflowDetailInfo.audit.staffName"
122 :placeholder="$t('newOaWorkflowDetail.selectNextHandler')" disabled style="width:80%" /> 122 :placeholder="$t('newOaWorkflowDetail.selectNextHandler')" disabled style="width:80%" />
123 <el-button type="primary" @click="chooseStaff" style="margin-left:10px"> 123 <el-button type="primary" @click="chooseStaff" style="margin-left:10px">
@@ -127,7 +127,7 @@ @@ -127,7 +127,7 @@
127 127
128 <!-- 转单时 必须指定 委托人 --> 128 <!-- 转单时 必须指定 委托人 -->
129 <el-form-item v-if="newOaWorkflowDetailInfo.audit.auditCode == '1300'" 129 <el-form-item v-if="newOaWorkflowDetailInfo.audit.auditCode == '1300'"
130 - :label="$t('newOaWorkflowDetail.nextHandler')"> 130 + :label="$t('newOaWorkflowDetail.nextHandler')" class="margin-top">
131 <el-input v-model="newOaWorkflowDetailInfo.audit.staffName" 131 <el-input v-model="newOaWorkflowDetailInfo.audit.staffName"
132 :placeholder="$t('newOaWorkflowDetail.selectNextHandler')" disabled style="width:80%" /> 132 :placeholder="$t('newOaWorkflowDetail.selectNextHandler')" disabled style="width:80%" />
133 <el-button type="primary" @click="chooseStaff" style="margin-left:10px"> 133 <el-button type="primary" @click="chooseStaff" style="margin-left:10px">
@@ -158,13 +158,14 @@ @@ -158,13 +158,14 @@
158 </el-col> 158 </el-col>
159 </el-row> 159 </el-row>
160 160
161 - <select-staff ref="selectStaff" /> 161 + <select-staff ref="selectStaff" @selectStaff="handleSelectStaff"/>
162 </div> 162 </div>
163 </template> 163 </template>
164 164
165 <script> 165 <script>
166 import { getCommunityId } from '@/api/community/communityApi' 166 import { getCommunityId } from '@/api/community/communityApi'
167 -import { queryOaWorkflowForm, queryOaWorkflowFormData, queryOaWorkflowUser, getNextTask, auditOaWorkflow, listRunWorkflowImage } from '@/api/oa/newOaWorkflowDetailApi' 167 +import { queryOaWorkflowForm, queryOaWorkflowFormData, queryOaWorkflowUser,
  168 + getNextTask, auditOaWorkflow, listRunWorkflowImage } from '@/api/oa/newOaWorkflowDetailApi'
168 import SelectStaff from '@/components/staff/SelectStaff' 169 import SelectStaff from '@/components/staff/SelectStaff'
169 170
170 export default { 171 export default {
@@ -253,7 +254,7 @@ export default { @@ -253,7 +254,7 @@ export default {
253 row: 10 254 row: 10
254 } 255 }
255 const response = await queryOaWorkflowUser(params) 256 const response = await queryOaWorkflowUser(params)
256 - if (response.code !== '0') return 257 + if (response.code !== 0) return
257 this.newOaWorkflowDetailInfo.comments = response.data 258 this.newOaWorkflowDetailInfo.comments = response.data
258 } catch (error) { 259 } catch (error) {
259 console.error('请求失败:', error) 260 console.error('请求失败:', error)
@@ -265,6 +266,10 @@ export default { @@ -265,6 +266,10 @@ export default {
265 chooseStaff() { 266 chooseStaff() {
266 this.$refs.selectStaff.open(this.newOaWorkflowDetailInfo.audit) 267 this.$refs.selectStaff.open(this.newOaWorkflowDetailInfo.audit)
267 }, 268 },
  269 + handleSelectStaff(staff) {
  270 + this.newOaWorkflowDetailInfo.audit.staffId = staff.userId
  271 + this.newOaWorkflowDetailInfo.audit.staffName = staff.userName
  272 + },
268 async _auditSubmit() { 273 async _auditSubmit() {
269 const audit = this.newOaWorkflowDetailInfo.audit 274 const audit = this.newOaWorkflowDetailInfo.audit
270 audit.flowId = this.newOaWorkflowDetailInfo.flowId 275 audit.flowId = this.newOaWorkflowDetailInfo.flowId
@@ -336,7 +341,7 @@ export default { @@ -336,7 +341,7 @@ export default {
336 businessKey: this.newOaWorkflowDetailInfo.id 341 businessKey: this.newOaWorkflowDetailInfo.id
337 } 342 }
338 const response = await listRunWorkflowImage(params) 343 const response = await listRunWorkflowImage(params)
339 - if (response.code !== '0') return 344 + if (response.code !== 0) return
340 this.newOaWorkflowDetailInfo.imgData = 'data:image/png;base64,' + response.data 345 this.newOaWorkflowDetailInfo.imgData = 'data:image/png;base64,' + response.data
341 } catch (error) { 346 } catch (error) {
342 console.error('请求失败:', error) 347 console.error('请求失败:', error)
src/views/oa/newOaWorkflowDoingList.vue
@@ -83,26 +83,26 @@ export default { @@ -83,26 +83,26 @@ export default {
83 ownerSettledApplyCount: 0 83 ownerSettledApplyCount: 0
84 }, 84 },
85 pendingItems: [ 85 pendingItems: [
86 - { key: 'repairPending', url: '/#/pages/property/repairDispatchManage', count: 0 },  
87 - { key: 'complaintPending', url: '/#/pages/complaint/uodoComplaints', count: 0 },  
88 - { key: 'purchasePending', url: '/#/pages/admin/myAuditOrders', count: 0 },  
89 - { key: 'collectionPending', url: '/#/pages/admin/myItemOutAuditOrders', count: 0 },  
90 - { key: 'contractApplyPending', url: '/#/pages/admin/contractApplyAuditOrders', count: 0 },  
91 - { key: 'contractChangePending', url: '/#/pages/admin/contractChangeAuditOrders', count: 0 },  
92 - { key: 'allocationPending', url: '/#/pages/admin/allocationStorehouseAuditOrders', count: 0 },  
93 - { key: 'itemReleasePending', url: '/#/pages/property/itemReleaseUndo', count: 0 },  
94 - { key: 'visitPending', url: '/#/pages/property/visitUndo', count: 0 } 86 + { key: 'repairPending', url: '/pages/property/repairDispatchManage', count: 0 },
  87 + { key: 'complaintPending', url: '/pages/complaint/uodoComplaints', count: 0 },
  88 + { key: 'purchasePending', url: '/pages/admin/myAuditOrders', count: 0 },
  89 + { key: 'collectionPending', url: '/pages/admin/myItemOutAuditOrders', count: 0 },
  90 + { key: 'contractApplyPending', url: '/pages/admin/contractApplyAuditOrders', count: 0 },
  91 + { key: 'contractChangePending', url: '/pages/admin/contractChangeAuditOrders', count: 0 },
  92 + { key: 'allocationPending', url: '/pages/admin/allocationStorehouseAuditOrders', count: 0 },
  93 + { key: 'itemReleasePending', url: '/pages/property/itemReleaseUndo', count: 0 },
  94 + { key: 'visitPending', url: '/pages/property/visitUndo', count: 0 }
95 ], 95 ],
96 completedItems: [ 96 completedItems: [
97 - { key: 'repairCompleted', url: '/#/pages/property/myRepairDispatchManage' },  
98 - { key: 'complaintCompleted', url: '/#/pages/complaint/doHistoryComplaints' },  
99 - { key: 'purchaseCompleted', url: '/#/pages/admin/myAuditHistoryOrders' },  
100 - { key: 'collectionCompleted', url: '/#/pages/admin/myItemOutAuditHistoryOrders' },  
101 - { key: 'contractApplyCompleted', url: '/#/pages/admin/contractApplyAuditHistoryOrders' },  
102 - { key: 'contractChangeCompleted', url: '/#/pages/admin/contractChangeAuditHistoryOrders' },  
103 - { key: 'allocationCompleted', url: '/#/pages/admin/allocationStorehouseHistoryAuditOrders' },  
104 - { key: 'itemReleaseCompleted', url: '/#/pages/property/itemReleaseFinish' },  
105 - { key: 'visitCompleted', url: '/#/pages/property/visitFinish' } 97 + { key: 'repairCompleted', url: '/pages/property/myRepairDispatchManage' },
  98 + { key: 'complaintCompleted', url: '/pages/complaint/doHistoryComplaints' },
  99 + { key: 'purchaseCompleted', url: '/pages/admin/myAuditHistoryOrders' },
  100 + { key: 'collectionCompleted', url: '/pages/admin/myItemOutAuditHistoryOrders' },
  101 + { key: 'contractApplyCompleted', url: '/pages/admin/contractApplyAuditHistoryOrders' },
  102 + { key: 'contractChangeCompleted', url: '/pages/admin/contractChangeAuditHistoryOrders' },
  103 + { key: 'allocationCompleted', url: '/pages/admin/allocationStorehouseHistoryAuditOrders' },
  104 + { key: 'itemReleaseCompleted', url: '/pages/property/itemReleaseFinish' },
  105 + { key: 'visitCompleted', url: '/pages/property/visitFinish' }
106 ], 106 ],
107 communityId: '' 107 communityId: ''
108 } 108 }
src/views/oa/newOaWorkflowFormEditList.vue
@@ -4,50 +4,97 @@ @@ -4,50 +4,97 @@
4 <div slot="header" class="flex justify-between"> 4 <div slot="header" class="flex justify-between">
5 <span>{{ $t('newOaWorkflowFormEdit.title') }}</span> 5 <span>{{ $t('newOaWorkflowFormEdit.title') }}</span>
6 </div> 6 </div>
7 - <el-form> 7 + <el-form ref="form" :model="formData" class="text-left" label-width="120px">
8 <el-row :gutter="20"> 8 <el-row :gutter="20">
9 <el-col :span="24"> 9 <el-col :span="24">
10 <div v-for="(item, index) in newOaWorkflowFormEditInfo.components" :key="index"> 10 <div v-for="(item, index) in newOaWorkflowFormEditInfo.components" :key="index">
  11 + <!-- 文本框 -->
11 <el-form-item v-if="item.type === 'textfield'" :label="item.label" 12 <el-form-item v-if="item.type === 'textfield'" :label="item.label"
12 - :prop="'components.' + index + '.value'"  
13 - :rules="[{ required: item.validate && item.validate.required, message: $t('newOaWorkflowFormEdit.requiredMessage') }]">  
14 - <el-input v-model="item.value" :placeholder="item.description" clearable /> 13 + :prop="item.key"
  14 + :rules="getValidationRules(item)">
  15 + <el-input v-model="formData[item.key]" :placeholder="item.description" clearable />
15 </el-form-item> 16 </el-form-item>
16 17
17 - <el-form-item v-if="item.type === 'number'" :label="item.label" :prop="'components.' + index + '.value'">  
18 - <el-input-number v-model="item.value" :placeholder="item.description" controls-position="right" /> 18 + <!-- 数字框 -->
  19 + <el-form-item v-if="item.type === 'number'" :label="item.label"
  20 + :prop="item.key"
  21 + :rules="getValidationRules(item)">
  22 + <el-input-number v-model="formData[item.key]" :placeholder="item.description"
  23 + controls-position="right" style="width: 100%" />
19 </el-form-item> 24 </el-form-item>
20 25
  26 + <!-- 文本域 -->
21 <el-form-item v-if="item.type === 'textarea'" :label="item.label" 27 <el-form-item v-if="item.type === 'textarea'" :label="item.label"
22 - :prop="'components.' + index + '.value'">  
23 - <el-input v-model="item.value" type="textarea" :placeholder="item.description" :rows="4" /> 28 + :prop="item.key"
  29 + :rules="getValidationRules(item)">
  30 + <el-input v-model="formData[item.key]" type="textarea" :placeholder="item.description"
  31 + :rows="4" />
24 </el-form-item> 32 </el-form-item>
25 33
  34 + <!-- 日期选择 -->
26 <el-form-item v-if="item.type === 'textdate'" :label="item.label" 35 <el-form-item v-if="item.type === 'textdate'" :label="item.label"
27 - :prop="'components.' + index + '.value'">  
28 - <el-date-picker v-model="item.value" type="date" :placeholder="item.description"  
29 - value-format="yyyy-MM-dd" /> 36 + :prop="item.key"
  37 + :rules="getValidationRules(item)">
  38 + <el-date-picker v-model="formData[item.key]" type="date" :placeholder="item.description"
  39 + value-format="yyyy-MM-dd" style="width: 100%" />
30 </el-form-item> 40 </el-form-item>
31 41
  42 + <!-- 日期时间选择 -->
32 <el-form-item v-if="item.type === 'textdatetime'" :label="item.label" 43 <el-form-item v-if="item.type === 'textdatetime'" :label="item.label"
33 - :prop="'components.' + index + '.value'">  
34 - <el-date-picker v-model="item.value" type="datetime" :placeholder="item.description"  
35 - value-format="yyyy-MM-dd HH:mm:ss" /> 44 + :prop="item.key"
  45 + :rules="getValidationRules(item)">
  46 + <el-date-picker v-model="formData[item.key]" type="datetime" :placeholder="item.description"
  47 + value-format="yyyy-MM-dd HH:mm:ss" style="width: 100%" />
36 </el-form-item> 48 </el-form-item>
37 49
  50 + <!-- 单选框 -->
  51 + <el-form-item v-if="item.type === 'radio'" :label="item.label"
  52 + :prop="item.key"
  53 + :rules="getValidationRules(item)">
  54 + <el-radio-group v-model="formData[item.key]">
  55 + <el-radio v-for="(option, optionIndex) in item.values" :key="optionIndex"
  56 + :label="option.value">
  57 + {{ option.label }}
  58 + </el-radio>
  59 + </el-radio-group>
  60 + </el-form-item>
  61 +
  62 + <!-- 下拉选择 -->
  63 + <el-form-item v-if="item.type === 'select'" :label="item.label"
  64 + :prop="item.key"
  65 + :rules="getValidationRules(item)">
  66 + <el-select v-model="formData[item.key]" :placeholder="item.description"
  67 + style="width: 100%" clearable>
  68 + <el-option v-for="(option, optionIndex) in item.values" :key="optionIndex"
  69 + :label="option.label" :value="option.value">
  70 + </el-option>
  71 + </el-select>
  72 + </el-form-item>
  73 +
  74 + <!-- 复选框 - 修复数组类型问题 -->
38 <el-form-item v-if="item.type === 'checkbox'" :label="item.label" 75 <el-form-item v-if="item.type === 'checkbox'" :label="item.label"
39 - :prop="'components.' + index + '.value'">  
40 - <el-checkbox-group v-model="item.value">  
41 - <el-checkbox :label="item.value">{{ item.label }}</el-checkbox> 76 + :prop="item.key"
  77 + :rules="getValidationRules(item)">
  78 + <el-checkbox-group v-model="formData[item.key]">
  79 + <el-checkbox v-for="(option, optionIndex) in item.values" :key="optionIndex"
  80 + :label="option.value">
  81 + {{ option.label }}
  82 + </el-checkbox>
42 </el-checkbox-group> 83 </el-checkbox-group>
43 </el-form-item> 84 </el-form-item>
44 </div> 85 </div>
45 86
46 - <upload-file ref="uploadFile" :call-back-listener="'newOaWorkflowFormEdit'"  
47 - :call-back-function="'fileName'" /> 87 + <!-- 文件上传 -->
  88 + <el-form-item :label="$t('common.file')">
  89 + <div class="file-info" v-if="newOaWorkflowFormEditInfo.fileName">
  90 + <el-tag type="info">{{ newOaWorkflowFormEditInfo.fileName }}</el-tag>
  91 + </div>
  92 + <upload-file ref="uploadFile" @notify="handleFileUpload" />
  93 + </el-form-item>
48 94
  95 + <!-- 按钮区域 -->
49 <div class="form-footer"> 96 <div class="form-footer">
50 - <el-button type="primary" @click="_submitFormData"> 97 + <el-button type="primary" @click="_submitFormData" :loading="submitLoading">
51 <i class="el-icon-check"></i> 98 <i class="el-icon-check"></i>
52 {{ $t('newOaWorkflowFormEdit.submit') }} 99 {{ $t('newOaWorkflowFormEdit.submit') }}
53 </el-button> 100 </el-button>
@@ -64,7 +111,7 @@ @@ -64,7 +111,7 @@
64 111
65 <script> 112 <script>
66 import { queryOaWorkflowForm, queryOaWorkflowFormData, updateOaWorkflowFormData } from '@/api/oa/newOaWorkflowFormEditApi' 113 import { queryOaWorkflowForm, queryOaWorkflowFormData, updateOaWorkflowFormData } from '@/api/oa/newOaWorkflowFormEditApi'
67 -import UploadFile from '@/components/oa/uploadFile' 114 +import UploadFile from '@/components/upload/uploadFile'
68 115
69 export default { 116 export default {
70 name: 'NewOaWorkflowFormEditList', 117 name: 'NewOaWorkflowFormEditList',
@@ -81,7 +128,9 @@ export default { @@ -81,7 +128,9 @@ export default {
81 id: '', 128 id: '',
82 fileName: '', 129 fileName: '',
83 realFileName: '' 130 realFileName: ''
84 - } 131 + },
  132 + formData: {}, // 新增:用于表单数据绑定
  133 + submitLoading: false
85 } 134 }
86 }, 135 },
87 created() { 136 created() {
@@ -102,11 +151,34 @@ export default { @@ -102,11 +151,34 @@ export default {
102 const formData = JSON.parse(data[0].formJson) 151 const formData = JSON.parse(data[0].formJson)
103 this.newOaWorkflowFormEditInfo.formJson = formData 152 this.newOaWorkflowFormEditInfo.formJson = formData
104 this.newOaWorkflowFormEditInfo.components = formData.components 153 this.newOaWorkflowFormEditInfo.components = formData.components
  154 +
  155 + // 初始化表单数据
  156 + this.initFormData()
  157 +
105 this._listOaWorkflowDetails() 158 this._listOaWorkflowDetails()
106 } catch (error) { 159 } catch (error) {
107 console.error('获取表单数据失败:', error) 160 console.error('获取表单数据失败:', error)
  161 + this.$message.error('获取表单数据失败')
108 } 162 }
109 }, 163 },
  164 +
  165 + initFormData() {
  166 + // 初始化表单数据对象
  167 + this.formData = {}
  168 + this.newOaWorkflowFormEditInfo.components.forEach(item => {
  169 + if (item.type !== 'button' && item.type !== 'text') {
  170 + if (item.type === 'checkbox') {
  171 + // 确保复选框的值是数组类型
  172 + this.$set(this.formData, item.key, [])
  173 + } else if (item.type === 'radio' || item.type === 'select') {
  174 + this.$set(this.formData, item.key, item.values && item.values.length > 0 ? item.values[0].value : '')
  175 + } else {
  176 + this.$set(this.formData, item.key, '')
  177 + }
  178 + }
  179 + })
  180 + },
  181 +
110 async _listOaWorkflowDetails() { 182 async _listOaWorkflowDetails() {
111 try { 183 try {
112 const params = { 184 const params = {
@@ -119,39 +191,80 @@ export default { @@ -119,39 +191,80 @@ export default {
119 const { data } = await queryOaWorkflowFormData(params) 191 const { data } = await queryOaWorkflowFormData(params)
120 const detailData = data[0] 192 const detailData = data[0]
121 193
  194 + // 更新表单数据
122 this.newOaWorkflowFormEditInfo.components.forEach(item => { 195 this.newOaWorkflowFormEditInfo.components.forEach(item => {
123 - item.value = detailData[item.key] 196 + if (item.type !== 'button' && item.type !== 'text') {
  197 + const value = detailData[item.key]
  198 + if (value !== undefined && value !== null) {
  199 + if (item.type === 'checkbox') {
  200 + // 确保复选框数据是数组类型
  201 + if (Array.isArray(value)) {
  202 + this.$set(this.formData, item.key, value)
  203 + } else if (typeof value === 'string' && value) {
  204 + // 如果是字符串,转换为数组
  205 + this.$set(this.formData, item.key, [value])
  206 + } else {
  207 + this.$set(this.formData, item.key, [])
  208 + }
  209 + } else {
  210 + this.$set(this.formData, item.key, value)
  211 + }
  212 + }
  213 + }
124 }) 214 })
125 215
126 - if (detailData.files) { 216 + // 处理文件数据
  217 + if (detailData.files && detailData.files.length > 0) {
127 this.newOaWorkflowFormEditInfo.fileName = detailData.files[0].fileName 218 this.newOaWorkflowFormEditInfo.fileName = detailData.files[0].fileName
128 this.newOaWorkflowFormEditInfo.realFileName = detailData.files[0].realFileName 219 this.newOaWorkflowFormEditInfo.realFileName = detailData.files[0].realFileName
129 - this.$refs.uploadFile.notifyVedio(detailData.files[0].fileName) 220 + this.$nextTick(() => {
  221 + if (this.$refs.uploadFile) {
  222 + this.$refs.uploadFile.notifyVedio(detailData.files[0].fileName)
  223 + }
  224 + })
130 } 225 }
131 } catch (error) { 226 } catch (error) {
132 console.error('获取表单详情失败:', error) 227 console.error('获取表单详情失败:', error)
  228 + this.$message.error('获取表单详情失败')
133 } 229 }
134 }, 230 },
  231 +
  232 + getValidationRules(item) {
  233 + const rules = []
  234 + if (item.validate && item.validate.required) {
  235 + rules.push({
  236 + required: true,
  237 + message: `${item.label}不能为空`,
  238 + trigger: 'blur'
  239 + })
  240 + }
  241 + return rules
  242 + },
  243 +
135 async _submitFormData() { 244 async _submitFormData() {
136 try { 245 try {
137 - const components = this.newOaWorkflowFormEditInfo.components 246 + // 表单验证
  247 + await this.$refs.form.validate()
  248 +
  249 + this.submitLoading = true
  250 +
138 const formData = { 251 const formData = {
139 id: this.newOaWorkflowFormEditInfo.id, 252 id: this.newOaWorkflowFormEditInfo.id,
140 flowId: this.newOaWorkflowFormEditInfo.flowId, 253 flowId: this.newOaWorkflowFormEditInfo.flowId,
141 fileName: this.newOaWorkflowFormEditInfo.fileName, 254 fileName: this.newOaWorkflowFormEditInfo.fileName,
142 - realFileName: this.newOaWorkflowFormEditInfo.realFileName 255 + realFileName: this.newOaWorkflowFormEditInfo.realFileName,
  256 +
143 } 257 }
144 258
145 - components.forEach(item => {  
146 - if (item.validate && item.validate.required && !item.value) {  
147 - this.$message.error(item.label + this.$t('newOaWorkflowFormEdit.requiredMessage'))  
148 - throw new Error(item.label + this.$t('newOaWorkflowFormEdit.requiredMessage'))  
149 - }  
150 - 259 + // 收集表单数据
  260 + this.newOaWorkflowFormEditInfo.components.forEach(item => {
151 if (item.type !== 'button' && item.type !== 'text') { 261 if (item.type !== 'button' && item.type !== 'text') {
152 - formData[item.key] = item.value 262 + formData[item.key] = this.formData[item.key]
153 if (item.type === 'checkbox') { 263 if (item.type === 'checkbox') {
154 - formData[item.key] = item.value.length > 0 ? item.value[0] : '' 264 + // 复选框提交时取第一个值或空字符串
  265 + formData[item.key] = this.formData[item.key] && this.formData[item.key].length > 0
  266 + ? this.formData[item.key][0]
  267 + : ''
155 } 268 }
156 } 269 }
157 }) 270 })
@@ -161,15 +274,27 @@ export default { @@ -161,15 +274,27 @@ export default {
161 this.$message.success(this.$t('newOaWorkflowFormEdit.submitSuccess')) 274 this.$message.success(this.$t('newOaWorkflowFormEdit.submitSuccess'))
162 this.closeEditInfo() 275 this.closeEditInfo()
163 } else { 276 } else {
164 - this.$message.error(res.msg) 277 + this.$message.error(res.msg || this.$t('newOaWorkflowFormEdit.submitError'))
165 } 278 }
166 } catch (error) { 279 } catch (error) {
  280 + if (error.message) {
  281 + // 表单验证错误
  282 + return
  283 + }
167 console.error('提交表单失败:', error) 284 console.error('提交表单失败:', error)
168 this.$message.error(this.$t('newOaWorkflowFormEdit.submitError')) 285 this.$message.error(this.$t('newOaWorkflowFormEdit.submitError'))
  286 + } finally {
  287 + this.submitLoading = false
169 } 288 }
170 }, 289 },
  290 +
171 closeEditInfo() { 291 closeEditInfo() {
172 this.$router.go(-1) 292 this.$router.go(-1)
  293 + },
  294 +
  295 + handleFileUpload(data) {
  296 + this.newOaWorkflowFormEditInfo.fileName = data.fileName
  297 + this.newOaWorkflowFormEditInfo.realFileName = data.realFileName
173 } 298 }
174 } 299 }
175 } 300 }
@@ -191,5 +316,9 @@ export default { @@ -191,5 +316,9 @@ export default {
191 .el-form-item { 316 .el-form-item {
192 margin-bottom: 22px; 317 margin-bottom: 22px;
193 } 318 }
  319 +
  320 + .file-info {
  321 + margin-bottom: 10px;
  322 + }
194 } 323 }
195 </style> 324 </style>
196 \ No newline at end of file 325 \ No newline at end of file
src/views/oa/newOaWorkflowList.vue
@@ -23,7 +23,7 @@ @@ -23,7 +23,7 @@
23 <el-col :span="20"> 23 <el-col :span="20">
24 <div class="content-wrapper"> 24 <div class="content-wrapper">
25 <new-oa-workflow-pool v-show="activeTab === 'newOaWorkflowPool'" ref="newOaWorkflowPool" /> 25 <new-oa-workflow-pool v-show="activeTab === 'newOaWorkflowPool'" ref="newOaWorkflowPool" />
26 - <new-oa-workflow-form v-if="activeTab === 'newOaWorkflowForm'" ref="newOaWorkflowForm" /> 26 + <new-oa-workflow-form v-if="activeTab === 'newOaWorkflowForm'" ref="newOaWorkflowForm" @switch-tab="switchTab"/>
27 <new-oa-workflow-undo v-show="activeTab === 'newOaWorkflowUndo'" ref="newOaWorkflowUndo" /> 27 <new-oa-workflow-undo v-show="activeTab === 'newOaWorkflowUndo'" ref="newOaWorkflowUndo" />
28 <new-oa-workflow-finish v-show="activeTab === 'newOaWorkflowFinish'" ref="newOaWorkflowFinish" /> 28 <new-oa-workflow-finish v-show="activeTab === 'newOaWorkflowFinish'" ref="newOaWorkflowFinish" />
29 </div> 29 </div>
src/views/oa/startWorkList.vue
1 <template> 1 <template>
2 <div class="start-work-container"> 2 <div class="start-work-container">
3 <el-row :gutter="20"> 3 <el-row :gutter="20">
4 - <el-col :span="2"> 4 + <el-col :span="3">
5 <div class="state-sidebar"> 5 <div class="state-sidebar">
6 <ul class="state-list"> 6 <ul class="state-list">
7 <li v-for="(item, index) in states" :key="index" class="state-item" 7 <li v-for="(item, index) in states" :key="index" class="state-item"
@@ -11,12 +11,12 @@ @@ -11,12 +11,12 @@
11 </ul> 11 </ul>
12 </div> 12 </div>
13 </el-col> 13 </el-col>
14 - <el-col :span="22"> 14 + <el-col :span="21">
15 <el-card class="search-card"> 15 <el-card class="search-card">
16 <div slot="header" class="flex justify-between"> 16 <div slot="header" class="flex justify-between">
17 <span>{{ $t('startWork.search.title') }}</span> 17 <span>{{ $t('startWork.search.title') }}</span>
18 </div> 18 </div>
19 - <el-form :inline="true" :model="conditions" class="search-form"> 19 + <el-form :inline="true" :model="conditions" class="search-form text-left">
20 <el-form-item> 20 <el-form-item>
21 <el-input v-model="conditions.workName" :placeholder="$t('startWork.search.workName')" clearable /> 21 <el-input v-model="conditions.workName" :placeholder="$t('startWork.search.workName')" clearable />
22 </el-form-item> 22 </el-form-item>
src/views/oa/workTypeList.vue
@@ -9,7 +9,7 @@ @@ -9,7 +9,7 @@
9 <el-col :span="6"> 9 <el-col :span="6">
10 <el-input v-model.trim="searchForm.typeName" :placeholder="$t('workType.search.typeName')" clearable /> 10 <el-input v-model.trim="searchForm.typeName" :placeholder="$t('workType.search.typeName')" clearable />
11 </el-col> 11 </el-col>
12 - <el-col :span="18" style="margin-top:5px;"> 12 + <el-col :span="6" >
13 <el-button type="primary" @click="handleSearch"> 13 <el-button type="primary" @click="handleSearch">
14 <i class="el-icon-search"></i> 14 <i class="el-icon-search"></i>
15 {{ $t('common.search') }} 15 {{ $t('common.search') }}
src/views/org/orgList.vue
@@ -122,7 +122,7 @@ export default { @@ -122,7 +122,7 @@ export default {
122 this.$refs.deleteOrgRelStaff.open(staff); 122 this.$refs.deleteOrgRelStaff.open(staff);
123 }, 123 },
124 toStaffDetail(staff) { 124 toStaffDetail(staff) {
125 - this.$router.push(`/views/staff/staffDetailList?staffId=${staff.userId}`) 125 + this.$router.push(`/views/staff/staffDetail?staffId=${staff.userId}`)
126 126
127 }, 127 },
128 handlePageChange(page) { 128 handlePageChange(page) {
src/views/resource/addItemOutList.vue
@@ -69,35 +69,43 @@ @@ -69,35 +69,43 @@
69 <table class="custom-table"> 69 <table class="custom-table">
70 <thead> 70 <thead>
71 <tr> 71 <tr>
72 - <th style="text-align: center; padding: 12px 8px; border: 1px solid #ebeef5; background-color: #fafafa;"> 72 + <th
  73 + style="text-align: center; padding: 12px 8px; border: 1px solid #ebeef5; background-color: #fafafa;">
73 {{ $t('addItemOut.itemType') }} 74 {{ $t('addItemOut.itemType') }}
74 </th> 75 </th>
75 - <th style="text-align: center; padding: 12px 8px; border: 1px solid #ebeef5; background-color: #fafafa;"> 76 + <th
  77 + style="text-align: center; padding: 12px 8px; border: 1px solid #ebeef5; background-color: #fafafa;">
76 {{ $t('addItemOut.itemName') }} 78 {{ $t('addItemOut.itemName') }}
77 </th> 79 </th>
78 - <th style="text-align: center; padding: 12px 8px; border: 1px solid #ebeef5; background-color: #fafafa;"> 80 + <th
  81 + style="text-align: center; padding: 12px 8px; border: 1px solid #ebeef5; background-color: #fafafa;">
79 {{ $t('addItemOut.itemSpec') }} 82 {{ $t('addItemOut.itemSpec') }}
80 </th> 83 </th>
81 - <th style="text-align: center; padding: 12px 8px; border: 1px solid #ebeef5; background-color: #fafafa;"> 84 + <th
  85 + style="text-align: center; padding: 12px 8px; border: 1px solid #ebeef5; background-color: #fafafa;">
82 {{ $t('addItemOut.price') }} 86 {{ $t('addItemOut.price') }}
83 </th> 87 </th>
84 - <th style="text-align: center; padding: 12px 8px; border: 1px solid #ebeef5; background-color: #fafafa;"> 88 + <th
  89 + style="text-align: center; padding: 12px 8px; border: 1px solid #ebeef5; background-color: #fafafa;">
85 {{ $t('addItemOut.stock') }} 90 {{ $t('addItemOut.stock') }}
86 </th> 91 </th>
87 - <th style="text-align: center; padding: 12px 8px; border: 1px solid #ebeef5; background-color: #fafafa;"> 92 + <th
  93 + style="text-align: center; padding: 12px 8px; border: 1px solid #ebeef5; background-color: #fafafa;">
88 {{ $t('addItemOut.applyQuantity') }} 94 {{ $t('addItemOut.applyQuantity') }}
89 </th> 95 </th>
90 - <th style="text-align: center; padding: 12px 8px; border: 1px solid #ebeef5; background-color: #fafafa;"> 96 + <th
  97 + style="text-align: center; padding: 12px 8px; border: 1px solid #ebeef5; background-color: #fafafa;">
91 {{ $t('addItemOut.remark') }} 98 {{ $t('addItemOut.remark') }}
92 </th> 99 </th>
93 - <th style="text-align: center; padding: 12px 8px; border: 1px solid #ebeef5; background-color: #fafafa;"> 100 + <th
  101 + style="text-align: center; padding: 12px 8px; border: 1px solid #ebeef5; background-color: #fafafa;">
94 {{ $t('addItemOut.operation') }} 102 {{ $t('addItemOut.operation') }}
95 </th> 103 </th>
96 </tr> 104 </tr>
97 </thead> 105 </thead>
98 <tbody> 106 <tbody>
99 - <tr v-for="(item, index) in addItemOutInfo.resourceStores" :key="index"  
100 - style="border-bottom: 1px solid #ebeef5;"> 107 + <tr v-for="(item, index) in addItemOutInfo.resourceStores" :key="index"
  108 + style="border-bottom: 1px solid #ebeef5;">
101 <td style="text-align: center; padding: 12px 8px; border: 1px solid #ebeef5;"> 109 <td style="text-align: center; padding: 12px 8px; border: 1px solid #ebeef5;">
102 {{ item.parentRstName || '-' }} > {{ item.rstName || '-' }} 110 {{ item.parentRstName || '-' }} > {{ item.rstName || '-' }}
103 </td> 111 </td>
@@ -159,8 +167,8 @@ @@ -159,8 +167,8 @@
159 <el-form-item :label="$t('addItemOut.approver')"> 167 <el-form-item :label="$t('addItemOut.approver')">
160 <el-row :gutter="20"> 168 <el-row :gutter="20">
161 <el-col :span="18"> 169 <el-col :span="18">
162 - <el-input :placeholder="$t('addItemOut.approverPlaceholder')" v-model="addItemOutInfo.audit.staffName"  
163 - disabled></el-input> 170 + <el-input :placeholder="$t('addItemOut.approverPlaceholder')"
  171 + v-model="addItemOutInfo.audit.staffName" disabled></el-input>
164 </el-col> 172 </el-col>
165 <el-col :span="6"> 173 <el-col :span="6">
166 <el-button type="primary" @click="chooseStaff"> 174 <el-button type="primary" @click="chooseStaff">
src/views/staff/staffList.vue
@@ -230,7 +230,7 @@ export default { @@ -230,7 +230,7 @@ export default {
230 this.resetPwdVisible = true 230 this.resetPwdVisible = true
231 }, 231 },
232 openStaffDetail(staff) { 232 openStaffDetail(staff) {
233 - this.$router.push(`/views/staff/staffDetailList?staffId=${staff.userId}`) 233 + this.$router.push(`/views/staff/staffDetail?staffId=${staff.userId}`)
234 }, 234 },
235 handleSuccess() { 235 handleSuccess() {
236 this.loadData(this.page.current, this.page.size) 236 this.loadData(this.page.current, this.page.size)