buildIncident.vue 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509
  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. "engineer": undefined,
  220. }
  221. };
  222. api_user(postData).then(res => {
  223. uni.hideLoading();
  224. if(res.status == 200){
  225. res.list = res.list || [];
  226. dataInfo.requesterList = res.list.map(v => ({
  227. text: v.name,
  228. value: v.id,
  229. }));
  230. }else{
  231. uni.showToast({
  232. icon: 'none',
  233. title: res.msg || '请求数据失败!'
  234. });
  235. }
  236. })
  237. }
  238. // 获取故障来源列表
  239. function getSources(){
  240. uni.showLoading({
  241. title: "加载中",
  242. mask: true,
  243. });
  244. let postData = {
  245. "key": 'incident_source',
  246. "type": "list",
  247. };
  248. api_getDictionary(postData).then(res => {
  249. uni.hideLoading();
  250. res = res || [];
  251. dataInfo.sourceList = res.map(v => ({
  252. text: v.name,
  253. value: v.id,
  254. key: v.value,
  255. }));
  256. let discover = dataInfo.sourceList.find(v => v.key === 'discover');
  257. if(discover){
  258. incidentData.source = discover.value;
  259. }
  260. })
  261. }
  262. // 获取优先级列表
  263. function getPrioritys(){
  264. uni.showLoading({
  265. title: "加载中",
  266. mask: true,
  267. });
  268. let postData = {
  269. "key": 'incident_priority',
  270. "type": "list",
  271. };
  272. api_getDictionary(postData).then(res => {
  273. uni.hideLoading();
  274. res = res || [];
  275. dataInfo.priorityList = res.map(v => ({
  276. text: v.name,
  277. value: v.id,
  278. }));
  279. })
  280. }
  281. // 选择院区
  282. function changeBranch(){
  283. incidentData.department = undefined;
  284. incidentData.contactsInformation = '';
  285. incidentData.place = undefined;
  286. incidentData.houseNumber = undefined;
  287. }
  288. // 处理提交事件
  289. function handlerOrder(){
  290. let postData = {
  291. incident: dataInfo.incidentData,
  292. }
  293. postData.incident.handleDescription = dataInfo.handleDescription;
  294. postData.incident.handleCategory = {id: dataInfo.handleCategory};
  295. postData.incident.closecode = {id: dataInfo.closecode};
  296. postData.incident.category = dataInfo.category;
  297. postData.incident.synergetic = dataInfo.synergetic;
  298. return api_incidentTask('accept', postData);
  299. }
  300. // 报修图片
  301. function handlerOrderImg(imgObj){
  302. return uploadFile(imgObj, 'incident', dataInfo.incidentId)
  303. }
  304. // 提交
  305. function submit(){
  306. isSubmit.value = true;
  307. console.log(dataInfo);
  308. if(!incidentData.branch){
  309. uni.showToast({
  310. icon: 'none',
  311. title: '请选择院区'
  312. });
  313. return;
  314. }
  315. if(!incidentData.department){
  316. uni.showToast({
  317. icon: 'none',
  318. title: '请选择报修科室'
  319. });
  320. return;
  321. }
  322. if(!incidentData.contactsInformation.trim()){
  323. uni.showToast({
  324. icon: 'none',
  325. title: '请填写联系电话'
  326. });
  327. return;
  328. }
  329. if(!incidentData.category){
  330. uni.showToast({
  331. icon: 'none',
  332. title: '请选择故障现象'
  333. });
  334. return;
  335. }
  336. if(!incidentData.source){
  337. uni.showToast({
  338. icon: 'none',
  339. title: '请选择故障来源'
  340. });
  341. return;
  342. }
  343. if(!incidentData.priority){
  344. uni.showToast({
  345. icon: 'none',
  346. title: '请选择优先级'
  347. });
  348. return;
  349. }
  350. if(!incidentData.description.trim()){
  351. uni.showToast({
  352. icon: 'none',
  353. title: '请填写故障描述'
  354. });
  355. return;
  356. }
  357. console.log(incidentData);
  358. // 处理责任科室
  359. if(incidentData.category.branchType == 1){
  360. // 分院区
  361. if(incidentData.branch){
  362. let dutyConfig = incidentData.category.branchUserGroups.find(v=>v.branchId == incidentData.branch);
  363. if(dutyConfig && dutyConfig.dutyId && dutyConfig.dutyName){
  364. incidentData.duty = {id:dutyConfig.dutyId,dept:dutyConfig.dutyName};
  365. }else{
  366. incidentData.duty = undefined;
  367. }
  368. }else{
  369. incidentData.duty = undefined;
  370. }
  371. }else{
  372. // 不分院区
  373. incidentData.duty = incidentData.category.dutyDepartment;
  374. }
  375. incidentData.title = incidentData.category.category;
  376. incidentBuildStore.setIncidentBuildData(incidentData, 'buildIncident');
  377. uni.navigateTo({
  378. url: '/pages/assign/assign'
  379. })
  380. }
  381. onLoad((option) => {
  382. handlerStore.clearHandlerData();
  383. if(incidentBuildStore.incidentBuild.data){
  384. Object.assign(incidentData, incidentBuildStore.incidentBuild.data);
  385. // 修改报修科室,则回显楼栋,楼层,详细地址,联系电话
  386. if(incidentBuildStore.incidentBuild.sign === 'department'){
  387. incidentData.place = incidentData.department.place || undefined;
  388. incidentData.houseNumber = incidentData.department.address || '';
  389. incidentData.contactsInformation = incidentData.department.phone ? incidentData.department.phone.split(',')[0] : '';
  390. }
  391. }
  392. getBranchs();
  393. getRequesters();
  394. getSources();
  395. getPrioritys();
  396. })
  397. </script>
  398. <style lang="scss" scoped>
  399. .buildIncident{
  400. height: 100%;
  401. display: flex;
  402. flex-direction: column;
  403. justify-content: space-between;
  404. .body{
  405. padding: 0 24rpx;
  406. box-sizing: border-box;
  407. flex: 1;
  408. min-height: 0;
  409. .form_item{
  410. display: flex;
  411. align-items: center;
  412. padding-top: 24rpx;
  413. min-height: 86rpx;
  414. &.column{
  415. height: auto;
  416. flex-direction: column;
  417. align-items: flex-start;
  418. .title{
  419. margin-right: 0;
  420. }
  421. .value{
  422. margin-top: 10rpx;
  423. padding-left: 20rpx;
  424. box-sizing: border-box;
  425. }
  426. .tips{
  427. padding: 24rpx;
  428. text-align: center;
  429. font-size: 22rpx;
  430. color: #909399;
  431. width: 100%;
  432. box-sizing: border-box;
  433. }
  434. }
  435. .title{
  436. font-size: 26rpx;
  437. display: flex;
  438. align-items: center;
  439. margin-right: 12rpx;
  440. flex-shrink: 0;
  441. &.select{
  442. width: calc(5em + 20rpx);
  443. }
  444. }
  445. .value{
  446. width: 100%;
  447. &.category{
  448. width: 100%;
  449. display: flex;
  450. justify-content: space-between;
  451. align-items: center;
  452. .categoryName{
  453. font-size: 26rpx;
  454. color: #555;
  455. flex: 1;
  456. }
  457. .newicon-weibiaoti2010104{
  458. color: $uni-primary;
  459. margin-left: 24rpx;
  460. }
  461. }
  462. .imgTips{
  463. color: #909399;
  464. font-size: 22rpx;
  465. }
  466. }
  467. }
  468. }
  469. }
  470. </style>