综合办公系统
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

declare.vue 11KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398
  1. <template>
  2. <view class="form-container">
  3. <!-- 表单标题 -->
  4. <view class="form-title">
  5. <text class="title-text">工作填报</text>
  6. <view class="title-line"></view>
  7. </view>
  8. <!-- 表单内容 -->
  9. <uni-forms ref="form" :modelValue="formData" :rules="rules" label-position="top" label-width="150"
  10. class="custom-form">
  11. <!-- 当前节点 -->
  12. <uni-forms-item label="当前节点" class="form-item">
  13. <uni-tag :inverted="true" type="primary" :text="taskName"></uni-tag>
  14. </uni-forms-item>
  15. <!-- 流程发起人 -->
  16. <uni-forms-item label="填报人" class="form-item">
  17. <uni-tag :inverted="true" type="primary" :text="startUserName"></uni-tag>
  18. </uni-forms-item>
  19. <!-- 填报日期 -->
  20. <uni-forms-item label="填报日期" class="form-item">
  21. <text>{{formData.submitTime}}</text>
  22. </uni-forms-item>
  23. <!-- 是否零星项目 -->
  24. <uni-forms-item label="是否零星项目" required class="form-item" name="isScattered">
  25. <uni-data-checkbox v-model="isScattered" :localdata="isScatteredOptions"></uni-data-checkbox>
  26. </uni-forms-item>
  27. <!-- 选择项目 -->
  28. <uni-forms-item label="选择项目" required class="form-item" v-if="!isScattered" name="projectId">
  29. <!-- <ProjectPicker v-model="formData.projectId" placeholder="请选择项目" :labelKey="'projectName'"
  30. :valueKey="'projectId'" @change="handleProjectChange"
  31. :customStyle="{ borderColor: '#e5e5e5', borderRadius: '8px' }" v-if="taskName == '工作填报'" /> -->
  32. <!-- <ProjectInfo :project="projectObj" v-else></ProjectInfo> -->
  33. <u-button type="primary" @click="openProject = true" v-if="taskName == '工作填报'">选择项目</u-button>
  34. <ProjectPicker :visible.sync="openProject" :selected.sync="selectedProject" @confirm="handleConfirm" />
  35. <ProjectInfo :project="projectObj"></ProjectInfo>
  36. </uni-forms-item>
  37. <!-- 工作类别 -->
  38. <uni-forms-item label="工作类别" required class="form-item" name="workType">
  39. <uni-data-select :disabled="taskName != '工作填报'" :clear="taskName == '工作填报'" v-model="formData.workType"
  40. :localdata="workTypeColumns" @change="bindWorkTypeChange"></uni-data-select>
  41. </uni-forms-item>
  42. <!-- 工作细项 -->
  43. <uni-forms-item label="工作细项" required class="form-item" name="workItem">
  44. <picker @change="bindWorkItemChange" :value="formData.workItem" :range="workItemList"
  45. :disabled="taskName != '工作填报'">
  46. <view class="uni-input">
  47. <uni-easyinput type="text" :disabled="taskName != '工作填报'" v-model="formData.workItem"
  48. @click="showType = true" placeholder="请选择" :styles="inputStyle" />
  49. </view>
  50. </picker>
  51. </uni-forms-item>
  52. <!-- 具体内容 -->
  53. <uni-forms-item label="具体内容" required class="form-item" name="workContent">
  54. <uni-easyinput :disabled="taskName != '工作填报'" type="textarea" v-model="formData.workContent"
  55. placeholder="请输入具体工作内容" :styles="textareaStyle" />
  56. </uni-forms-item>
  57. <!-- 工天 -->
  58. <uni-forms-item label="工天" required class="form-item" name="workLoad">
  59. <uni-easyinput :disabled="taskName != '工作填报'" type="number" v-model="formData.workLoad" placeholder="请输入所需工天"
  60. :styles="inputStyle">
  61. <text slot="right" class="unit">天</text>
  62. </uni-easyinput>
  63. </uni-forms-item>
  64. <uni-forms-item label="系数" required class="form-item" name="coefficient" v-if="taskName != '工作填报'">
  65. <uni-easyinput type="number" v-model="formData.coefficient" placeholder="请输入系数" :styles="inputStyle"
  66. @input="countMoney">
  67. </uni-easyinput>
  68. </uni-forms-item>
  69. <uni-forms-item label="工天单价" class="form-item" v-if="taskName != '工作填报'">
  70. <u-tag :text="formData.price+'/人天'" type="success" plain></u-tag>
  71. </uni-forms-item>
  72. <uni-forms-item label="预估绩效" class="form-item" v-if="taskName != '工作填报'">
  73. <u-tag :text="'¥'+money" type="primary" plain></u-tag>
  74. </uni-forms-item>
  75. <!-- 提交按钮 -->
  76. <button class="save-btn" @click="save">保存</button>
  77. <button class="submit-btn margin-top-xs" type="primary" @click="submitForm">提交</button>
  78. </uni-forms>
  79. </view>
  80. </template>
  81. <script>
  82. import ProjectPicker from '@/pages/components/ProjectPicker.vue';
  83. import ProjectInfo from '@/pages/components/ProjectInfo.vue';
  84. import {
  85. listPrice,
  86. getWorkTypeList,
  87. getWorkItemList
  88. } from '@/api/oa/price/price'
  89. import {
  90. listProject,
  91. submitProject,
  92. modifyProject,
  93. delProject
  94. } from "@/api/oa/project/project";
  95. import {
  96. listDeclare,
  97. getDeclare,
  98. addDeclare,
  99. updateDeclare
  100. } from '@/api/oa/declare/declare';
  101. import {
  102. parseTime
  103. } from "@/utils/common.js"
  104. export default {
  105. components: {
  106. ProjectPicker,
  107. ProjectInfo
  108. },
  109. props: {
  110. taskForm: Object,
  111. taskName: String, // 当前节点
  112. startUserName: String, // 流程发起人
  113. },
  114. created() {
  115. this.getProjectList();
  116. this.initForm();
  117. if (this.taskName != '工作填报') {
  118. this.isScatteredOptions.map(item => item.disable = true)
  119. }
  120. },
  121. data() {
  122. return {
  123. openProject: false,
  124. selectedProject: null,
  125. isScattered: 0,
  126. formData: {
  127. userId: null,
  128. projectId: '',
  129. workType: '',
  130. workItem: '',
  131. workContent: '',
  132. workLoad: '',
  133. price: 216,
  134. submitTime: ''
  135. },
  136. money: '',
  137. rules: {
  138. isScattered: {
  139. rules: [{
  140. required: true,
  141. errorMessage: '必填项',
  142. }, ]
  143. },
  144. projectId: {
  145. rules: [{
  146. required: true,
  147. errorMessage: '请选择项目',
  148. }, ]
  149. },
  150. workType: {
  151. rules: [{
  152. required: true,
  153. errorMessage: '请选择工作类别',
  154. }, ]
  155. },
  156. workItem: {
  157. rules: [{
  158. required: true,
  159. errorMessage: '请选择工作细项',
  160. }, ]
  161. },
  162. workContent: {
  163. rules: [{
  164. required: true,
  165. errorMessage: '请输入具体内容',
  166. }, ]
  167. },
  168. workLoad: {
  169. rules: [{
  170. required: true,
  171. errorMessage: '请输入工作量',
  172. }, ]
  173. },
  174. },
  175. projectObj: {},
  176. isScatteredOptions: [{
  177. text: '否',
  178. value: 0,
  179. disable: false
  180. }, {
  181. text: '是',
  182. value: 1,
  183. disable: false
  184. }],
  185. projects: [],
  186. projectIndex: -1,
  187. inputStyle: {
  188. borderColor: '#e5e5e5',
  189. borderRadius: '8px'
  190. },
  191. textareaStyle: {
  192. borderColor: '#e5e5e5',
  193. borderRadius: '8px',
  194. height: '100px'
  195. },
  196. showType: false,
  197. workTypeColumns: [{
  198. text: '外业',
  199. value: '外业',
  200. },
  201. {
  202. text: '内业',
  203. value: '内业'
  204. }
  205. ],
  206. workItemList: [],
  207. hasForm: false,
  208. };
  209. },
  210. methods: {
  211. handleConfirm(project) {
  212. console.log('选中的项目:', project);
  213. this.selectedProject = project;
  214. this.projectObj = project;
  215. },
  216. initForm() {
  217. getDeclare(this.taskForm.formId).then(res => {
  218. if (res.data) {
  219. this.hasForm = true;
  220. this.formData = res.data;
  221. console.log(res.data)
  222. if (res.data.projectId) {
  223. this.isScattered = 0;
  224. } else {
  225. this.isScattered = 1;
  226. }
  227. res.data.project.projectLeader = res.data.projectLeader
  228. this.projectObj = res.data.project;
  229. this.selectedProject = res.data.project;
  230. this.bindWorkTypeChange(this.formData.workType);
  231. this.countMoney();
  232. } else {
  233. this.hasForm = false;
  234. }
  235. if (this.taskName == '工作填报') {
  236. this.formData.submitTime = parseTime(new Date(), "{y}-{m}-{d}");
  237. this.formData.userId = this.$store.getters.userId;
  238. console.log(this.$store.getters)
  239. }
  240. })
  241. },
  242. bindProjectChange(e) {
  243. this.projectIndex = e.detail.value;
  244. this.formData.project = this.projects[this.projectIndex];
  245. },
  246. bindWorkTypeChange(e) {
  247. listPrice({
  248. workType: e,
  249. pageNum: 1,
  250. pageSize: 9999
  251. }).then(res => {
  252. if (res.code == 200) {
  253. let data = res.rows;
  254. let list = [];
  255. for (let d of data) {
  256. list.push(d.workItem)
  257. }
  258. if (e == '内业') {
  259. list.push('其他')
  260. }
  261. this.workItemList = [...new Set(list)];
  262. }
  263. })
  264. },
  265. bindWorkItemChange(e) {
  266. this.formData.workItem = this.workItemList[e.detail.value];
  267. console.log(this.formData.workItem);
  268. },
  269. handleRadioChange(e) {
  270. this.formData.isScattered = e.detail.value;
  271. },
  272. handleProjectChange(row) {
  273. console.log(row)
  274. },
  275. getProjectList() {
  276. listProject({
  277. pageNum: 1,
  278. pageSize: 10
  279. }).then(res => {
  280. this.projects = res.rows
  281. })
  282. },
  283. countMoney() {
  284. let result = parseFloat(this.formData.price * this.formData.workLoad * this.formData.coefficient)
  285. console.log(result)
  286. this.money = result.toFixed(2)
  287. },
  288. async save() {
  289. if (!this.isScattered) {
  290. this.formData.projectId = this.projectObj.projectId;
  291. } else {
  292. this.formData.projectId = ''
  293. }
  294. if (this.hasForm) {
  295. let updateRes = await updateDeclare(this.formData);
  296. } else {
  297. this.formData.formId = this.taskForm.formId;
  298. let addRes = await addDeclare(this.formData);
  299. if (addRes.code == 200) {
  300. this.hasForm = true;
  301. } else {
  302. this.hasForm = false;
  303. }
  304. }
  305. uni.showToast({
  306. title: '保存成功',
  307. icon: 'success'
  308. });
  309. },
  310. submitForm() {
  311. this.$refs.form.validate().then(res => {
  312. console.log('表单数据信息:', res);
  313. uni.showToast({
  314. title: '提交成功',
  315. icon: 'success'
  316. });
  317. }).catch(err => {
  318. console.log('表单错误信息:', err);
  319. })
  320. }
  321. }
  322. };
  323. </script>
  324. <style lang="scss" scoped>
  325. .form-container {
  326. padding: 20px;
  327. background-color: #f8f8f8;
  328. }
  329. .form-title {
  330. margin-bottom: 15px;
  331. text-align: center;
  332. .title-text {
  333. font-size: 20px;
  334. font-weight: bold;
  335. color: #333;
  336. }
  337. .title-line {
  338. width: 50px;
  339. height: 2px;
  340. background-color: #007AFF;
  341. margin: 8px auto;
  342. }
  343. }
  344. .custom-form {
  345. background-color: #fff;
  346. padding: 15px;
  347. border-radius: 12px;
  348. box-shadow: 0 2px 12px rgba(0, 0, 0, 0.05);
  349. }
  350. .form-item {
  351. margin-bottom: 20px;
  352. /deep/ .uni-forms-item__label {
  353. font-weight: 500;
  354. color: #666;
  355. padding-bottom: 8px;
  356. }
  357. }
  358. .picker {
  359. width: 100%;
  360. padding: 10px;
  361. border: 1px solid #e5e5e5;
  362. border-radius: 8px;
  363. display: flex;
  364. align-items: center;
  365. justify-content: space-between;
  366. color: #333;
  367. }
  368. .radio-label {
  369. margin-right: 25px;
  370. display: inline-flex;
  371. align-items: center;
  372. }
  373. .unit {
  374. color: #999;
  375. padding: 0 10px;
  376. }
  377. </style>