buildIncident.vue 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510
  1. <template>
  2. <view class="buildIncident">
  3. <scroll-view scroll-y class="body">
  4. <view class="form_item">
  5. <view class="title select"><text class="required newicon newicon-bitian"></text>院区:</view>
  6. <uni-data-select class="value" v-model="incidentData.branch" :localdata="dataInfo.branchList" :clear="false" placeholder="请选择院区" :class="{formRed: isSubmit && !incidentData.branch}" @change="changeBranch"></uni-data-select>
  7. </view>
  8. <view class="form_item">
  9. <view class="title"><text class="required newicon newicon-bitian"></text>报修科室:</view>
  10. <view class="value category" @click="selectDepartment">
  11. <text class="categoryName ellipsis-multiline">{{incidentData.department ? incidentData.department.dept : ''}}</text>
  12. <text class="newicon newicon-weibiaoti2010104"></text>
  13. </view>
  14. </view>
  15. <view class="form_item">
  16. <view class="title select"><text class="required newicon newicon-bitian transparent"></text>报修人:</view>
  17. <uni-data-select readonly class="value" v-model="incidentData.requester" :localdata="dataInfo.requesterList" placeholder="请选择报修人"></uni-data-select>
  18. </view>
  19. <view class="form_item">
  20. <view class="title select"><text class="required newicon newicon-bitian transparent"></text>联系人:</view>
  21. <uni-easyinput class="value" v-model="incidentData.contacts" placeholder="请输入联系人" />
  22. </view>
  23. <view class="form_item">
  24. <view class="title select"><text class="required newicon newicon-bitian"></text>联系电话:</view>
  25. <uni-easyinput class="value" v-model="incidentData.contactsInformation" placeholder="请输入联系电话" :class="{formRed: isSubmit && !incidentData.contactsInformation.trim()}" />
  26. </view>
  27. <view class="form_item">
  28. <view class="title"><text class="required newicon newicon-bitian transparent"></text>楼栋楼层:</view>
  29. <view class="value category" @click="selectAreaPlace">
  30. <text class="categoryName ellipsis-multiline">{{incidentData.place ? incidentData.place.area.area + ' ' + incidentData.place.place : ''}}</text>
  31. <text class="newicon newicon-weibiaoti2010104"></text>
  32. </view>
  33. </view>
  34. <view class="form_item">
  35. <view class="title select"><text class="required newicon newicon-bitian transparent"></text>详细地址:</view>
  36. <uni-easyinput class="value" v-model="incidentData.houseNumber" placeholder="请输入详细地址" />
  37. </view>
  38. <view class="form_item">
  39. <view class="title"><text class="required newicon newicon-bitian"></text>故障现象:</view>
  40. <view class="value category" @click="selectCategory">
  41. <text class="categoryName ellipsis-multiline">{{incidentData.category ? incidentData.category.mutiCategory : ''}}</text>
  42. <text class="newicon newicon-weibiaoti2010104"></text>
  43. </view>
  44. </view>
  45. <view class="form_item">
  46. <view class="title select"><text class="required newicon newicon-bitian"></text>故障来源:</view>
  47. <uni-data-select readonly class="value" v-model="incidentData.source" :localdata="dataInfo.sourceList" placeholder="请选择故障来源" :class="{formRed: isSubmit && !incidentData.source}"></uni-data-select>
  48. </view>
  49. <view class="form_item">
  50. <view class="title select"><text class="required newicon newicon-bitian"></text>优先级:</view>
  51. <uni-data-select placement="top" readonly class="value" v-model="incidentData.priority" :localdata="dataInfo.priorityList" placeholder="请选择优先级" :class="{formRed: isSubmit && !incidentData.priority}"></uni-data-select>
  52. </view>
  53. <view class="form_item column">
  54. <view class="title select"><text class="required newicon newicon-bitian"></text>故障描述:</view>
  55. <uni-easyinput class="value" type="textarea" v-model="incidentData.description" placeholder="请输入故障描述" :class="{formRed: isSubmit && !incidentData.description.trim()}" />
  56. </view>
  57. <view class="form_item_column">
  58. <view class="form_item">
  59. <view class="title"><text class="required newicon newicon-bitian transparent"></text>报修图片:</view>
  60. <view class="value">
  61. <uni-file-picker ref="handlerImgRef" v-model="incidentData.repairImgList" limit="3" @success="handlerImgSuccess" @fail="handlerImgFail" @select="handlerImgSelect" @delete="handlerImgDelete"></uni-file-picker>
  62. </view>
  63. </view>
  64. <view class="form_item">
  65. <view class="title transparent"><text class="required newicon newicon-bitian transparent"></text>报修图片:</view>
  66. <view class="value">
  67. <text class="imgTips ellipsis">(支持JPG/PNG格式图片,单张大小10M以内)</text>
  68. </view>
  69. </view>
  70. </view>
  71. </scroll-view>
  72. <view class="foot_common_btns">
  73. <button @click="goBack" type="default" class="cancelButton btn">返回</button>
  74. <button @click="submit" type="default" class="primaryButton btn">下一步</button>
  75. </view>
  76. </view>
  77. </template>
  78. <script setup>
  79. import { ref, reactive } from 'vue'
  80. import { onLoad } from '@dcloudio/uni-app'
  81. import { api_user, api_branch, api_getDictionary, api_incidentTask } from "@/http/api.js"
  82. import { defaultColor } from '@/static/js/theme.js'
  83. import { useSetTitle } from '@/share/useSetTitle.js'
  84. import { useGoBack } from '@/share/useGoBack.js'
  85. import { useLoginUserStore } from '@/stores/loginUser'
  86. import { useIncidentBuildStore } from '@/stores/incidentBuild'
  87. import { useHandlerStore } from '@/stores/handler'
  88. import { useUploadFile } from '@/share/useUploadFile.js'
  89. useSetTitle();
  90. const loginUserStore = useLoginUserStore();
  91. const incidentBuildStore = useIncidentBuildStore();
  92. const handlerStore = useHandlerStore();
  93. const { uploadFile } = useUploadFile();
  94. const { goBack } = useGoBack();
  95. // 主题颜色
  96. const primaryColor = ref(defaultColor)
  97. // 工单对象
  98. const incidentData = reactive({
  99. "deleteFlag": 0,
  100. "duty": undefined,
  101. "department": undefined,
  102. "contactsInformation": '',
  103. "contacts": '',
  104. "branch": undefined,
  105. "area": undefined,
  106. "place": undefined,
  107. "houseNumber": '',
  108. "category": undefined,
  109. "priority": undefined,
  110. "source": undefined,
  111. "title": '',
  112. "description": '',
  113. "repairType": undefined,
  114. "requester":undefined,
  115. "acceptUser": loginUserStore.loginUser.user,
  116. repairImgList: [],//报修图片列表
  117. })
  118. // 报修图片
  119. const handlerImgRef = ref(null)
  120. // 数据
  121. const dataInfo = reactive({
  122. branchList: [], //院区列表
  123. requesterList: [], //报修人列表
  124. sourceList: [], //故障来源列表
  125. priorityList: [], //优先级列表
  126. })
  127. // 是否提交
  128. const isSubmit = ref(false)
  129. // 上传报修图片成功
  130. function handlerImgSuccess(e){
  131. incidentData.repairImgList.forEach(v => {
  132. v.url = v.path;
  133. })
  134. console.log(incidentData.repairImgList);
  135. }
  136. // 上传报修图片失败
  137. function handlerImgFail(e){
  138. incidentData.repairImgList.forEach(v => {
  139. v.url = v.path;
  140. })
  141. console.log(incidentData.repairImgList);
  142. }
  143. // 选择上传图片
  144. function handlerImgSelect(e){
  145. incidentData.repairImgList = incidentData.repairImgList.concat(e.tempFiles);
  146. console.log(incidentData.repairImgList);
  147. }
  148. // 删除上传图片
  149. function handlerImgDelete(e){
  150. incidentData.repairImgList = incidentData.repairImgList.filter(v => e.tempFile.uuid != v.uuid);
  151. console.log(incidentData.repairImgList);
  152. }
  153. // 选择故障现象
  154. function selectCategory(){
  155. incidentBuildStore.setIncidentBuildData(incidentData, 'buildIncident');
  156. uni.navigateTo({
  157. url: `/pages/categoryOne/categoryOne`
  158. })
  159. }
  160. // 选择楼栋楼层
  161. function selectAreaPlace(){
  162. incidentBuildStore.setIncidentBuildData(incidentData, 'buildIncident', 'area');
  163. uni.navigateTo({
  164. url: `/pages/searchArea/searchArea`
  165. })
  166. }
  167. // 跳转到搜索报修科室
  168. function selectDepartment(){
  169. incidentBuildStore.setIncidentBuildData(incidentData, 'buildIncident', 'department');
  170. uni.navigateTo({
  171. url: `/pages/searchDept/searchDept`
  172. })
  173. }
  174. // 获取院区列表
  175. function getBranchs(){
  176. uni.showLoading({
  177. title: "加载中",
  178. mask: true,
  179. });
  180. let postData = {
  181. "idx": 0,
  182. "sum": 9999,
  183. };
  184. api_branch(postData).then(res => {
  185. uni.hideLoading();
  186. if(res.status == 200){
  187. res.list = res.list || [];
  188. dataInfo.branchList = res.list.map(v => ({
  189. text: v.hosName,
  190. value: v.id,
  191. }));
  192. if(!incidentBuildStore.incidentBuild.data){
  193. if(loginUserStore.loginUser.user.duty){
  194. // 当前的所属责任科室
  195. incidentData.branch = loginUserStore.loginUser.user.duty.branch;
  196. }else if(loginUserStore.loginUser.user.branch){
  197. // 当前的所属院区
  198. incidentData.branch = loginUserStore.loginUser.user.branch.id;
  199. }
  200. }
  201. }else{
  202. uni.showToast({
  203. icon: 'none',
  204. title: res.msg || '请求数据失败!'
  205. });
  206. }
  207. })
  208. }
  209. // 获取报修人列表
  210. function getRequesters(){
  211. uni.showLoading({
  212. title: "加载中",
  213. mask: true,
  214. });
  215. let postData = {
  216. "idx": 0,
  217. "sum": 9999,
  218. "user": {
  219. "simple": true,
  220. "engineer": undefined,
  221. }
  222. };
  223. api_user(postData).then(res => {
  224. uni.hideLoading();
  225. if(res.status == 200){
  226. res.list = res.list || [];
  227. dataInfo.requesterList = res.list.map(v => ({
  228. text: v.name,
  229. value: v.id,
  230. }));
  231. }else{
  232. uni.showToast({
  233. icon: 'none',
  234. title: res.msg || '请求数据失败!'
  235. });
  236. }
  237. })
  238. }
  239. // 获取故障来源列表
  240. function getSources(){
  241. uni.showLoading({
  242. title: "加载中",
  243. mask: true,
  244. });
  245. let postData = {
  246. "key": 'incident_source',
  247. "type": "list",
  248. };
  249. api_getDictionary(postData).then(res => {
  250. uni.hideLoading();
  251. res = res || [];
  252. dataInfo.sourceList = res.map(v => ({
  253. text: v.name,
  254. value: v.id,
  255. key: v.value,
  256. }));
  257. let discover = dataInfo.sourceList.find(v => v.key === 'discover');
  258. if(discover){
  259. incidentData.source = discover.value;
  260. }
  261. })
  262. }
  263. // 获取优先级列表
  264. function getPrioritys(){
  265. uni.showLoading({
  266. title: "加载中",
  267. mask: true,
  268. });
  269. let postData = {
  270. "key": 'incident_priority',
  271. "type": "list",
  272. };
  273. api_getDictionary(postData).then(res => {
  274. uni.hideLoading();
  275. res = res || [];
  276. dataInfo.priorityList = res.map(v => ({
  277. text: v.name,
  278. value: v.id,
  279. }));
  280. })
  281. }
  282. // 选择院区
  283. function changeBranch(){
  284. incidentData.department = undefined;
  285. incidentData.contactsInformation = '';
  286. incidentData.place = undefined;
  287. incidentData.houseNumber = undefined;
  288. }
  289. // 处理提交事件
  290. function handlerOrder(){
  291. let postData = {
  292. incident: dataInfo.incidentData,
  293. }
  294. postData.incident.handleDescription = dataInfo.handleDescription;
  295. postData.incident.handleCategory = {id: dataInfo.handleCategory};
  296. postData.incident.closecode = {id: dataInfo.closecode};
  297. postData.incident.category = dataInfo.category;
  298. postData.incident.synergetic = dataInfo.synergetic;
  299. return api_incidentTask('accept', postData);
  300. }
  301. // 报修图片
  302. function handlerOrderImg(imgObj){
  303. return uploadFile(imgObj, 'incident', dataInfo.incidentId)
  304. }
  305. // 提交
  306. function submit(){
  307. isSubmit.value = true;
  308. console.log(dataInfo);
  309. if(!incidentData.branch){
  310. uni.showToast({
  311. icon: 'none',
  312. title: '请选择院区'
  313. });
  314. return;
  315. }
  316. if(!incidentData.department){
  317. uni.showToast({
  318. icon: 'none',
  319. title: '请选择报修科室'
  320. });
  321. return;
  322. }
  323. if(!incidentData.contactsInformation.trim()){
  324. uni.showToast({
  325. icon: 'none',
  326. title: '请填写联系电话'
  327. });
  328. return;
  329. }
  330. if(!incidentData.category){
  331. uni.showToast({
  332. icon: 'none',
  333. title: '请选择故障现象'
  334. });
  335. return;
  336. }
  337. if(!incidentData.source){
  338. uni.showToast({
  339. icon: 'none',
  340. title: '请选择故障来源'
  341. });
  342. return;
  343. }
  344. if(!incidentData.priority){
  345. uni.showToast({
  346. icon: 'none',
  347. title: '请选择优先级'
  348. });
  349. return;
  350. }
  351. if(!incidentData.description.trim()){
  352. uni.showToast({
  353. icon: 'none',
  354. title: '请填写故障描述'
  355. });
  356. return;
  357. }
  358. console.log(incidentData);
  359. // 处理责任科室
  360. if(incidentData.category.branchType == 1){
  361. // 分院区
  362. if(incidentData.branch){
  363. let dutyConfig = incidentData.category.branchUserGroups.find(v=>v.branchId == incidentData.branch);
  364. if(dutyConfig && dutyConfig.dutyId && dutyConfig.dutyName){
  365. incidentData.duty = {id:dutyConfig.dutyId,dept:dutyConfig.dutyName};
  366. }else{
  367. incidentData.duty = undefined;
  368. }
  369. }else{
  370. incidentData.duty = undefined;
  371. }
  372. }else{
  373. // 不分院区
  374. incidentData.duty = incidentData.category.dutyDepartment;
  375. }
  376. incidentData.title = incidentData.category.category;
  377. incidentBuildStore.setIncidentBuildData(incidentData, 'buildIncident');
  378. uni.navigateTo({
  379. url: '/pages/assign/assign'
  380. })
  381. }
  382. onLoad((option) => {
  383. handlerStore.clearHandlerData();
  384. if(incidentBuildStore.incidentBuild.data){
  385. Object.assign(incidentData, incidentBuildStore.incidentBuild.data);
  386. // 修改报修科室,则回显楼栋,楼层,详细地址,联系电话
  387. if(incidentBuildStore.incidentBuild.sign === 'department'){
  388. incidentData.place = incidentData.department.place || undefined;
  389. incidentData.houseNumber = incidentData.department.address || '';
  390. incidentData.contactsInformation = incidentData.department.phone ? incidentData.department.phone.split(',')[0] : '';
  391. }
  392. }
  393. getBranchs();
  394. getRequesters();
  395. getSources();
  396. getPrioritys();
  397. })
  398. </script>
  399. <style lang="scss" scoped>
  400. .buildIncident{
  401. height: 100%;
  402. display: flex;
  403. flex-direction: column;
  404. justify-content: space-between;
  405. .body{
  406. padding: 0 24rpx;
  407. box-sizing: border-box;
  408. flex: 1;
  409. min-height: 0;
  410. .form_item{
  411. display: flex;
  412. align-items: center;
  413. padding-top: 24rpx;
  414. min-height: 86rpx;
  415. &.column{
  416. height: auto;
  417. flex-direction: column;
  418. align-items: flex-start;
  419. .title{
  420. margin-right: 0;
  421. }
  422. .value{
  423. margin-top: 10rpx;
  424. padding-left: 20rpx;
  425. box-sizing: border-box;
  426. }
  427. .tips{
  428. padding: 24rpx;
  429. text-align: center;
  430. font-size: 22rpx;
  431. color: #909399;
  432. width: 100%;
  433. box-sizing: border-box;
  434. }
  435. }
  436. .title{
  437. font-size: 26rpx;
  438. display: flex;
  439. align-items: center;
  440. margin-right: 12rpx;
  441. flex-shrink: 0;
  442. &.select{
  443. width: calc(5em + 20rpx);
  444. }
  445. }
  446. .value{
  447. width: 100%;
  448. &.category{
  449. width: 100%;
  450. display: flex;
  451. justify-content: space-between;
  452. align-items: center;
  453. .categoryName{
  454. font-size: 26rpx;
  455. color: #555;
  456. flex: 1;
  457. }
  458. .newicon-weibiaoti2010104{
  459. color: $uni-primary;
  460. margin-left: 24rpx;
  461. }
  462. }
  463. .imgTips{
  464. color: #909399;
  465. font-size: 22rpx;
  466. }
  467. }
  468. }
  469. }
  470. }
  471. </style>