form.vue 71 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033
  1. <template>
  2. <!-- 添加或修改项目信息对话框 -->
  3. <div class="el-drawer__wrapper">
  4. <el-drawer :title="title" v-model="visible" direction="rtl" size="100%">
  5. <div class="page-container form-container">
  6. <div class="form-btns-container">
  7. <span class="title-label"
  8. ><el-icon>
  9. <Document />
  10. </el-icon>
  11. 合同信息</span
  12. >
  13. <el-button
  14. v-if="form.verifyStatus == 0 && !editStatus"
  15. type="warning"
  16. size="small"
  17. icon="Edit"
  18. @click="editStatus = true"
  19. >修改</el-button
  20. >
  21. <el-button
  22. v-if="form.id && editStatus"
  23. type="info"
  24. size="small"
  25. icon="Close"
  26. @click="
  27. () => {
  28. editStatus = false;
  29. getForm();
  30. }
  31. "
  32. >取消编辑</el-button
  33. >
  34. <el-button
  35. v-if="form.id"
  36. type="success"
  37. size="small"
  38. icon="refresh"
  39. @click="getForm"
  40. >
  41. 刷新
  42. </el-button>
  43. <el-button
  44. v-show="form.id && !editStatus && form.verifyStatus == 0"
  45. v-hasPermi="['business:archive:order:verify']"
  46. type="primary"
  47. size="small"
  48. icon="check"
  49. @click="verifyHandler"
  50. >审核通过</el-button
  51. >
  52. <el-button
  53. v-show="form.id && !editStatus && form.verifyStatus == 0"
  54. v-hasPermi="['business:archive:order:verify']"
  55. type="danger"
  56. size="small"
  57. icon="back"
  58. @click="rejectHandler"
  59. >驳回</el-button
  60. >
  61. <el-button
  62. v-show="form.alterNumber > 0 && !editStatus"
  63. v-hasPermi="['business:archive:order:history']"
  64. type="info"
  65. size="small"
  66. icon="Notebook"
  67. @click="showHistoryList"
  68. >历史记录</el-button
  69. >
  70. <div class="screen-btn" @click="handleScreen">
  71. <template v-if="!isFullscreen">
  72. <i class="fa fa-window-maximize" aria-hidden="true" />
  73. <!-- <span>全屏</span> -->
  74. </template>
  75. <template v-else>
  76. <i class="fa fa-window-restore" aria-hidden="true" />
  77. <!-- <span>还原</span> -->
  78. </template>
  79. </div>
  80. <div class="close-btn" @click="cancel">
  81. <i class="fa fa-times" aria-hidden="true" />
  82. <!-- <span>关闭</span> -->
  83. </div>
  84. </div>
  85. <div
  86. class="Y-scrollbar"
  87. style="
  88. position: absolute;
  89. top: 32px;
  90. bottom: 0;
  91. width: 100%;
  92. overflow: auto;
  93. "
  94. ></div>
  95. <el-form
  96. ref="orderRef"
  97. class="master-container"
  98. size="small"
  99. :model="form"
  100. :rules="rules"
  101. label-width="100px"
  102. >
  103. <el-row :gutter="30">
  104. <el-col :span="6">
  105. <el-form-item label="合同编号" prop="contractNo">
  106. <el-input
  107. v-if="editStatus && type !== 'alterOrder'"
  108. v-model="form.contractNo"
  109. placeholder="请输入合同编号"
  110. width="100px"
  111. />
  112. <span v-else>{{ form.contractNo }}</span>
  113. </el-form-item>
  114. </el-col>
  115. <el-col :span="6">
  116. <el-form-item label="合同类型" prop="contractType">
  117. <el-radio-group
  118. v-if="editStatus && type !== 'alterOrder'"
  119. v-model="form.contractType"
  120. @change="contractTypeChangeHandler"
  121. >
  122. <el-radio :label="0">新签</el-radio>
  123. <el-radio :label="1">续签</el-radio>
  124. </el-radio-group>
  125. <span v-else>{{
  126. form.contractType === 0 ? "新签" : "续签"
  127. }}</span>
  128. </el-form-item>
  129. </el-col>
  130. <el-col :span="6">
  131. <el-form-item label="客户名称" prop="companyId">
  132. <template v-if="editStatus && type !== 'alterOrder'">
  133. <el-autocomplete
  134. :fetch-suggestions="querySearchCompanyAsync"
  135. :trigger-on-focus="true"
  136. v-model="form.companyName"
  137. placeholder="请输入客户名称"
  138. popper-class="my-autocomplete"
  139. clearable
  140. @select="handleSelectCompany"
  141. style="width: 100%"
  142. >
  143. <template #append>
  144. <el-button icon="Plus" @click="showAddCompanyDialog">
  145. </el-button>
  146. </template>
  147. <template #default="{ item }">
  148. <div
  149. style="
  150. display: flex;
  151. flex-direction: row;
  152. justify-content: space-between;
  153. "
  154. >
  155. <div class="name" style="font-size: 12px">
  156. {{ item.name }}
  157. </div>
  158. </div>
  159. </template>
  160. </el-autocomplete>
  161. <!-- <el-button @click="showAddCompanyDialog">
  162. <el-icon class="el-input__icon">
  163. <plus />
  164. </el-icon>
  165. </el-button> -->
  166. </template>
  167. <span v-else>{{ form.companyName }}</span>
  168. </el-form-item>
  169. </el-col>
  170. <el-col :span="6">
  171. <el-form-item label="签约日期" prop="formDate">
  172. <el-date-picker
  173. v-if="editStatus && type !== 'alterOrder'"
  174. clearable
  175. v-model="form.formDate"
  176. type="date"
  177. value-format="YYYY-MM-DD"
  178. placeholder="请选择签约日期"
  179. >
  180. </el-date-picker>
  181. <span v-else>{{ form.formDate }}</span>
  182. </el-form-item>
  183. </el-col>
  184. <el-col :span="6">
  185. <el-form-item label="签单人" prop="signerName">
  186. <el-autocomplete
  187. v-if="editStatus && type !== 'alterOrder'"
  188. :fetch-suggestions="querySearchAsync"
  189. :trigger-on-focus="true"
  190. style="width: 100%"
  191. v-model="form.signerName"
  192. placeholder="请输入签单人"
  193. popper-class="my-autocomplete"
  194. @select="handleSelectEmployee"
  195. >
  196. <template #default="{ item }">
  197. <div
  198. style="
  199. display: flex;
  200. flex-direction: row;
  201. justify-content: space-between;
  202. "
  203. >
  204. <div class="name" style="font-size: 12px">
  205. {{ item.nickName }}
  206. </div>
  207. <span
  208. class="code"
  209. style="font-size: 10px; color: darkgrey"
  210. >{{ item.userName }}</span
  211. >
  212. </div>
  213. </template>
  214. </el-autocomplete>
  215. <span v-else>{{ form.signerName }}</span>
  216. </el-form-item>
  217. </el-col>
  218. <el-col v-if="form.verifyStatus === 4" :span="6">
  219. <el-form-item label="驳回原因" prop="verifyRemark">
  220. <span>{{ form.verifyRemark }}</span>
  221. </el-form-item>
  222. </el-col>
  223. <el-col :span="8" style="width: 100%">
  224. <el-form-item
  225. label="来源"
  226. prop="sourceCategoryName"
  227. style="width: 100%"
  228. >
  229. <CustomerFormCom
  230. ref="CustomerFormComRef"
  231. :edit-status="editStatus && type !== 'alterOrder'"
  232. :form-data="form"
  233. :source-categories="sourceCategories"
  234. />
  235. </el-form-item>
  236. </el-col>
  237. <el-col :span="14">
  238. <el-form-item label="备注" prop="remark">
  239. <el-input
  240. v-if="editStatus"
  241. v-model="form.remark"
  242. show-word-limit
  243. maxlength="200"
  244. style="width: 100%; margin: 0; padding: 0"
  245. placeholder="请输入备注"
  246. type="textarea"
  247. :rows="2"
  248. />
  249. <span v-else>{{ form.remark }}</span>
  250. </el-form-item>
  251. </el-col>
  252. <br />
  253. <el-col :span="24">
  254. <el-tabs
  255. v-model="form.serviceType"
  256. size="small"
  257. class="demo-tabs"
  258. @tab-change="handleServiceTypeClick"
  259. >
  260. <el-tab-pane :disabled="!editStatus" label="循环服务" :name="1">
  261. <el-row>
  262. <el-col :span="24">
  263. <el-checkbox-group
  264. :disabled="!editStatus"
  265. v-model="loops"
  266. @change="(arg) => changeDetails('loop', arg)"
  267. >
  268. <el-checkbox
  269. v-for="(item, index) in loopTasks"
  270. :key="index"
  271. :label="item.id"
  272. >{{ item.name }}</el-checkbox
  273. >
  274. </el-checkbox-group>
  275. </el-col>
  276. <el-col :span="24">
  277. <el-row
  278. v-for="(item, index) in loopDetails"
  279. :key="index"
  280. style="
  281. border-radius: 5px;
  282. border-color: rgba(0, 0, 0, 20%);
  283. border-style: solid;
  284. border-width: 1px;
  285. margin-bottom: 10px;
  286. "
  287. >
  288. <el-col :span="5" style="padding-top: 18px">
  289. <el-form-item label="服务项目">
  290. {{ item.taskTypeName }}
  291. </el-form-item>
  292. </el-col>
  293. <el-col :span="5" style="padding-top: 18px">
  294. <el-form-item label="月单价">
  295. <el-input-number
  296. v-if="editStatus"
  297. v-model="item.price"
  298. :precision="2"
  299. :step="0.1"
  300. :min="0"
  301. :controls="false"
  302. @change="
  303. (arg) =>
  304. inputChangeHandler('loop', 'price', item, arg)
  305. "
  306. />
  307. <div v-else>{{ rowNum(item.price) }}</div>
  308. </el-form-item>
  309. </el-col>
  310. <el-col :span="5" style="padding-top: 18px">
  311. <el-form-item label="服务月数">
  312. <el-input-number
  313. v-if="editStatus"
  314. v-model="item.serviceNum"
  315. :step="1"
  316. step-strictly
  317. :min="0"
  318. :controls="false"
  319. @change="
  320. (arg) =>
  321. inputChangeHandler(
  322. 'loop',
  323. 'serviceNum',
  324. item,
  325. arg
  326. )
  327. "
  328. />
  329. <div v-else>{{ item.serviceNum }}</div>
  330. </el-form-item>
  331. </el-col>
  332. <el-col :span="5" style="padding-top: 18px">
  333. <el-form-item label="赠送月数">
  334. <el-input-number
  335. v-if="editStatus"
  336. v-model="item.freeNum"
  337. :step="1"
  338. step-strictly
  339. :min="0"
  340. :controls="false"
  341. @change="
  342. (arg) =>
  343. inputChangeHandler(
  344. 'loop',
  345. 'freeNum',
  346. item,
  347. arg
  348. )
  349. "
  350. />
  351. <div v-else>{{ item.freeNum }}</div>
  352. </el-form-item>
  353. </el-col>
  354. <el-col :span="4" style="padding-top: 18px">
  355. <el-form-item label="总金额">
  356. <div>{{ rowNum(item.amount) }}</div>
  357. </el-form-item>
  358. </el-col>
  359. </el-row>
  360. </el-col>
  361. <el-divider />
  362. </el-row>
  363. </el-tab-pane>
  364. <el-tab-pane
  365. :disabled="!editStatus || form.contractType === 1"
  366. label="代办服务"
  367. :name="2"
  368. >
  369. <el-checkbox-group
  370. :disabled="!editStatus"
  371. v-model="onces"
  372. @change="(arg) => changeDetails('once', arg)"
  373. >
  374. <el-checkbox
  375. v-for="(item, index) in onceTasks"
  376. :key="index"
  377. :label="item.id"
  378. >{{ item.name }}</el-checkbox
  379. >
  380. </el-checkbox-group>
  381. <el-col :span="24">
  382. <el-row
  383. v-for="(item, index) in onceDetails"
  384. :key="index"
  385. style="
  386. border-radius: 5px;
  387. border-color: rgba(0, 0, 0, 20%);
  388. border-style: solid;
  389. border-width: 1px;
  390. margin-bottom: 10px;
  391. "
  392. >
  393. <el-col :span="4" style="padding-top: 18px">
  394. <el-form-item label="服务项目">
  395. {{ item.taskTypeName }}
  396. </el-form-item>
  397. </el-col>
  398. <el-col
  399. v-if="item.payAddress === 1"
  400. :span="9"
  401. style="
  402. padding-top: 18px;
  403. padding-left: 35px;
  404. display: flex;
  405. flex-direction: column;
  406. margin-bottom: 18px;
  407. "
  408. >
  409. <el-radio-group
  410. v-if="editStatus"
  411. v-model="item.addressStyle"
  412. @change="changeProcesses(item)"
  413. >
  414. <el-radio :label="1" style="margin-bottom: 5px">
  415. <template #default>
  416. <div
  417. style="
  418. display: flex;
  419. flex-direction: row;
  420. width: 300px;
  421. justify-content: space-between;
  422. "
  423. >
  424. <div
  425. style="
  426. display: inline-block;
  427. height: 24px;
  428. line-height: 24px;
  429. margin-right: 10px;
  430. "
  431. >
  432. 自有地址
  433. </div>
  434. <div>
  435. <el-select
  436. :disabled="item.addressStyle === 2"
  437. v-model="item.provinceCode"
  438. placeholder="省份"
  439. style="width: 36%"
  440. @change="handleSelectProvince(item, index)"
  441. >
  442. <el-option
  443. v-for="item in provincesArr[index]"
  444. :key="item.code"
  445. :label="item.name"
  446. :value="item.code"
  447. />
  448. </el-select>
  449. <el-select
  450. :disabled="item.addressStyle === 2"
  451. v-model="item.cityCode"
  452. placeholder="城市"
  453. style="width: 37%"
  454. @change="handleSelectCity(item, index)"
  455. >
  456. <el-option
  457. v-for="item in citiesArr[index]"
  458. :key="item.code"
  459. :label="item.name"
  460. :value="item.code"
  461. />
  462. </el-select>
  463. <el-select
  464. :disabled="item.addressStyle === 2"
  465. v-model="item.districtCode"
  466. placeholder="行政区"
  467. style="width: 37%"
  468. @change="handleSelectDistrict(item, index)"
  469. >
  470. <el-option
  471. v-for="item in districtsArr[index]"
  472. :key="item.code"
  473. :label="item.name"
  474. :value="item.code"
  475. />
  476. </el-select>
  477. </div>
  478. </div>
  479. </template>
  480. </el-radio>
  481. <el-radio :label="2" style="margin-bottom: 5px">
  482. <template #default>
  483. <div
  484. style="
  485. display: flex;
  486. flex-direction: row;
  487. width: 325px;
  488. justify-content: space-between;
  489. "
  490. >
  491. <div
  492. style="
  493. display: inline-block;
  494. height: 24px;
  495. line-height: 24px;
  496. margin-right: 10px;
  497. "
  498. >
  499. 虚拟地址
  500. </div>
  501. <el-select
  502. :disabled="item.addressStyle !== 2"
  503. v-model="item.fictionAddressId"
  504. style="margin-right: 5px"
  505. >
  506. <el-option
  507. v-for="item in virtual_address"
  508. :key="item.value"
  509. :label="item.label"
  510. :value="item.id"
  511. ></el-option>
  512. </el-select>
  513. <div
  514. style="
  515. display: inline-block;
  516. height: 24px;
  517. line-height: 24px;
  518. "
  519. >
  520. 金额:
  521. </div>
  522. <el-input-number
  523. :disabled="item.addressStyle !== 2"
  524. v-if="editStatus"
  525. v-model="item.addressAmount"
  526. :precision="2"
  527. :step="0.01"
  528. step-strictly
  529. :controls="false"
  530. @change="
  531. (arg) =>
  532. inputChangeHandler(
  533. 'once',
  534. 'addressAmount',
  535. item,
  536. arg
  537. )
  538. "
  539. />
  540. </div>
  541. </template>
  542. </el-radio>
  543. </el-radio-group>
  544. <div
  545. v-else
  546. style="
  547. display: flex;
  548. flex-direction: row;
  549. width: 300px;
  550. justify-content: space-between;
  551. font-size: 12px;
  552. "
  553. >
  554. <div>
  555. {{
  556. item.addressStyle === 1
  557. ? "自有地址"
  558. : item.addressStyle === 2
  559. ? "虚拟地址"
  560. : ""
  561. }}
  562. </div>
  563. <div v-if="item.addressStyle === 1">
  564. 注册地区:{{ item.province }} - {{ item.city }} -
  565. {{ item.district }}
  566. </div>
  567. <div v-if="item.addressStyle === 2">
  568. {{ rowNum(item.fictionAddress) }}
  569. </div>
  570. <div v-if="item.addressStyle === 2">
  571. 金额:{{ rowNum(item.addressAmount) }}
  572. </div>
  573. </div>
  574. </el-col>
  575. <el-col
  576. v-if="item.payAddress === 0"
  577. :span="9"
  578. style="
  579. padding-top: 18px;
  580. display: flex;
  581. flex-direction: column;
  582. margin-bottom: 18px;
  583. "
  584. >
  585. <el-form-item
  586. v-if="item.taskTypeId === '6'"
  587. label="变更类型"
  588. >
  589. <el-select
  590. v-if="editStatus"
  591. v-model="item.alterType"
  592. style="width: 280px"
  593. >
  594. <el-option
  595. v-for="alter in alterTypes"
  596. :label="alter.label"
  597. :key="alter.value"
  598. :value="alter.value"
  599. >
  600. </el-option>
  601. </el-select>
  602. <div v-else>{{ item.alterType }}</div>
  603. </el-form-item>
  604. <div
  605. v-if="item.alterType === '跨区变更'"
  606. style="margin-left: 60px"
  607. >
  608. <el-radio-group
  609. v-if="editStatus"
  610. v-model="item.addressStyle"
  611. @change="changeProcesses(item)"
  612. >
  613. <el-radio :label="1" style="margin-bottom: 5px">
  614. <template #default>
  615. <div
  616. style="
  617. display: flex;
  618. flex-direction: row;
  619. width: 300px;
  620. justify-content: space-between;
  621. "
  622. >
  623. <div
  624. style="
  625. display: inline-block;
  626. height: 24px;
  627. line-height: 24px;
  628. margin-right: 10px;
  629. "
  630. >
  631. 自有地址
  632. </div>
  633. <div>
  634. <el-select
  635. :disabled="item.addressStyle === 2"
  636. v-model="item.provinceCode"
  637. placeholder="省份"
  638. style="width: 33.33%"
  639. @change="
  640. handleSelectProvince(item, index)
  641. "
  642. >
  643. <el-option
  644. v-for="item in provincesArr[index]"
  645. :key="item.code"
  646. :label="item.name"
  647. :value="item.code"
  648. />
  649. </el-select>
  650. <el-select
  651. :disabled="item.addressStyle === 2"
  652. v-model="item.cityCode"
  653. placeholder="城市"
  654. style="width: 33.33%"
  655. @change="handleSelectCity(item, index)"
  656. >
  657. <el-option
  658. v-for="item in citiesArr[index]"
  659. :key="item.code"
  660. :label="item.name"
  661. :value="item.code"
  662. />
  663. </el-select>
  664. <el-select
  665. :disabled="item.addressStyle === 2"
  666. v-model="item.districtCode"
  667. placeholder="行政区"
  668. style="width: 33.33%"
  669. @change="
  670. handleSelectDistrict(item, index)
  671. "
  672. >
  673. <el-option
  674. v-for="item in districtsArr[index]"
  675. :key="item.code"
  676. :label="item.name"
  677. :value="item.code"
  678. />
  679. </el-select>
  680. </div>
  681. </div>
  682. </template>
  683. </el-radio>
  684. <el-radio :label="2" style="margin-bottom: 5px">
  685. <template #default>
  686. <div
  687. style="
  688. display: flex;
  689. flex-direction: row;
  690. width: 300px;
  691. justify-content: space-between;
  692. "
  693. >
  694. <div
  695. style="
  696. display: inline-block;
  697. height: 24px;
  698. line-height: 24px;
  699. margin-right: 10px;
  700. "
  701. >
  702. 虚拟地址
  703. </div>
  704. <el-select
  705. :disabled="item.addressStyle !== 2"
  706. v-model="item.fictionAddressId"
  707. style="margin-right: 5px"
  708. >
  709. <el-option
  710. v-for="item in virtual_address"
  711. :key="item.value"
  712. :label="item.label"
  713. :value="item.id"
  714. ></el-option>
  715. </el-select>
  716. <div
  717. style="
  718. display: inline-block;
  719. height: 24px;
  720. line-height: 24px;
  721. "
  722. >
  723. 金额:
  724. </div>
  725. <el-input-number
  726. :disabled="item.addressStyle !== 2"
  727. v-if="editStatus"
  728. v-model="item.addressAmount"
  729. :precision="2"
  730. :step="0.01"
  731. step-strictly
  732. :controls="false"
  733. @change="
  734. (arg) =>
  735. inputChangeHandler(
  736. 'once',
  737. 'addressAmount',
  738. item,
  739. arg
  740. )
  741. "
  742. />
  743. </div>
  744. </template>
  745. </el-radio>
  746. </el-radio-group>
  747. <div
  748. v-else
  749. style="
  750. display: flex;
  751. flex-direction: row;
  752. width: 300px;
  753. justify-content: space-between;
  754. font-size: 12px;
  755. "
  756. >
  757. <div>
  758. {{
  759. item.addressStyle === 1
  760. ? "自有地址"
  761. : item.addressStyle === 2
  762. ? "虚拟地址"
  763. : ""
  764. }}
  765. </div>
  766. <div v-if="item.addressStyle === 1">
  767. 注册地区:{{ item.province }} - {{ item.city }} -
  768. {{ item.district }}
  769. </div>
  770. <div v-if="item.addressStyle === 2">
  771. {{ item.fictionAddress }}
  772. </div>
  773. <div v-if="item.addressStyle === 2">
  774. 金额:{{ rowNum(item.addressAmount) }}
  775. </div>
  776. </div>
  777. </div>
  778. <el-form-item v-else label="办理地区">
  779. <div
  780. v-if="editStatus"
  781. style="
  782. display: flex;
  783. flex-direction: row;
  784. width: 280px;
  785. justify-content: space-between;
  786. "
  787. >
  788. <el-select
  789. v-model="item.provinceCode"
  790. placeholder="省份"
  791. style="width: 33.33%"
  792. @click.stop="null"
  793. @change="handleSelectProvince(item, index)"
  794. >
  795. <el-option
  796. v-for="item in provincesArr[index]"
  797. :key="item.code"
  798. :label="item.name"
  799. :value="item.code"
  800. />
  801. </el-select>
  802. <el-select
  803. v-model="item.cityCode"
  804. placeholder="城市"
  805. style="width: 33.33%"
  806. @change="handleSelectCity(item, index)"
  807. @click.stop="null"
  808. >
  809. <el-option
  810. v-for="item in citiesArr[index]"
  811. :key="item.code"
  812. :label="item.name"
  813. :value="item.code"
  814. />
  815. </el-select>
  816. <el-select
  817. v-model="item.districtCode"
  818. placeholder="行政区"
  819. style="width: 33.33%"
  820. @change="handleSelectDistrict(item, index)"
  821. @click.stop="null"
  822. >
  823. <el-option
  824. v-for="item in districtsArr[index]"
  825. :key="item.code"
  826. :label="item.name"
  827. :value="item.code"
  828. />
  829. </el-select>
  830. </div>
  831. <div
  832. v-else
  833. style="
  834. display: flex;
  835. flex-direction: row;
  836. width: 300px;
  837. justify-content: space-between;
  838. "
  839. >
  840. {{ item.province }} - {{ item.city }} -
  841. {{ item.district }}
  842. </div>
  843. </el-form-item>
  844. </el-col>
  845. <el-col
  846. :span="7"
  847. style="padding-top: 18px; margin-bottom: 18px"
  848. >
  849. <el-checkbox-group
  850. :disabled="!editStatus"
  851. v-model="item.processes"
  852. @change="(arg) => changeProcesses(item, arg)"
  853. style="display: flex; flex-direction: column"
  854. >
  855. <el-checkbox
  856. v-for="(process, index) in item.defaultProcesses"
  857. :key="index"
  858. :label="process"
  859. >
  860. <template #default>
  861. <div
  862. style="
  863. display: flex;
  864. flex-direction: row;
  865. width: 300px;
  866. justify-content: space-between;
  867. "
  868. >
  869. <div
  870. style="
  871. display: inline-block;
  872. height: 24px;
  873. line-height: 24px;
  874. margin-right: 10px;
  875. width: 80px;
  876. "
  877. >
  878. {{ process.taskTypeDetailName }}
  879. </div>
  880. <div
  881. style="
  882. display: inline-block;
  883. height: 24px;
  884. line-height: 24px;
  885. "
  886. >
  887. 金额:
  888. </div>
  889. <el-input-number
  890. :disabled="
  891. checkedProcess(
  892. process.taskTypeDetailId,
  893. item
  894. )
  895. "
  896. size="small"
  897. v-if="editStatus"
  898. v-model="process.amount"
  899. :precision="2"
  900. :step="0.01"
  901. step-strictly
  902. :controls="false"
  903. style="width: 100px"
  904. @click.stop="null"
  905. @change="
  906. (arg) =>
  907. inputChangeHandler(
  908. 'process',
  909. 'amount',
  910. process,
  911. arg,
  912. item
  913. )
  914. "
  915. />
  916. <div
  917. v-else
  918. style="
  919. display: inline-block;
  920. height: 24px;
  921. line-height: 24px;
  922. width: 40px;
  923. text-align: right;
  924. "
  925. >
  926. {{ rowNum(process.amount) }}
  927. </div>
  928. </div>
  929. </template>
  930. <!-- {{ process.name }} -->
  931. </el-checkbox>
  932. </el-checkbox-group>
  933. </el-col>
  934. <el-col
  935. :span="3"
  936. style="
  937. padding-top: 18px;
  938. display: flex;
  939. flex-direction: column;
  940. margin-bottom: 18px;
  941. "
  942. >
  943. <div
  944. style="
  945. display: flex;
  946. flex-direction: row;
  947. font-size: 12px;
  948. "
  949. >
  950. <div
  951. style="
  952. display: inline-block;
  953. height: 24px;
  954. line-height: 24px;
  955. margin-left: 10px;
  956. "
  957. >
  958. 总金额:
  959. </div>
  960. <div
  961. style="
  962. display: inline-block;
  963. height: 24px;
  964. line-height: 24px;
  965. "
  966. >
  967. {{ rowNum(item.amount) }}
  968. </div>
  969. </div>
  970. </el-col>
  971. </el-row>
  972. </el-col>
  973. <el-divider />
  974. </el-tab-pane>
  975. </el-tabs>
  976. </el-col>
  977. <el-col :span="6">
  978. <el-form-item label="合计:" prop="remark">
  979. <span>{{ rowNum(form.amount) }}</span>
  980. </el-form-item>
  981. </el-col>
  982. <el-col :span="6">
  983. <el-form-item label="优惠金额:">
  984. <el-input-number
  985. v-if="editStatus"
  986. v-model="form.discountAmount"
  987. :precision="2"
  988. :step="0.1"
  989. :controls="false"
  990. @change="
  991. (arg) =>
  992. inputChangeHandler('default', 'discountAmount', form, arg)
  993. "
  994. />
  995. <div v-else>{{ rowNum(form.discountAmount) }}</div>
  996. </el-form-item>
  997. </el-col>
  998. <el-col :span="6">
  999. <el-form-item label="实收:">
  1000. <div>{{ rowNum(form.trueAmount) }}</div>
  1001. </el-form-item>
  1002. </el-col>
  1003. <br />
  1004. <el-col :span="24">
  1005. <div class="details-head" style="font-size: 12px">
  1006. <div class="title">
  1007. <i class="fa fa-th-list" aria-hidden="true" /> 合同附件
  1008. </div>
  1009. <div class="details-btns-container" style="display: flex">
  1010. <el-upload
  1011. v-if="editStatus && type != 'alterOrder'"
  1012. action="#"
  1013. :http-request="upload"
  1014. :with-credentials="true"
  1015. :show-file-list="false"
  1016. multiple
  1017. >
  1018. <el-button size="small" type="primary" icon="Upload"
  1019. >点击上传</el-button
  1020. >
  1021. </el-upload>
  1022. </div>
  1023. </div>
  1024. <div class="details-body" style="height: 200px">
  1025. <el-table
  1026. ref="filesTable"
  1027. :data="form.files"
  1028. size="small"
  1029. height="100%"
  1030. border
  1031. header-row-class-name="list-header-row"
  1032. >
  1033. <el-table-column
  1034. type="index"
  1035. label="序号"
  1036. width="47"
  1037. align="center"
  1038. />
  1039. <el-table-column
  1040. label="文件名"
  1041. prop="originalFileName"
  1042. align="center"
  1043. >
  1044. <template #default="scope">
  1045. <el-link
  1046. :href="`${baseUrl}${scope.row.fileUrl}`"
  1047. :underline="false"
  1048. target="_blank"
  1049. type="primary"
  1050. >
  1051. {{ scope.row.originalFileName }}
  1052. </el-link>
  1053. </template>
  1054. </el-table-column>
  1055. <el-table-column
  1056. v-if="editStatus && type !== 'alterOrder'"
  1057. label="操作"
  1058. width="70"
  1059. align="center"
  1060. >
  1061. <template #default="scope">
  1062. <el-button
  1063. link
  1064. size="small"
  1065. type="danger"
  1066. @click="handleDelFile(scope.$index)"
  1067. >删除</el-button
  1068. >
  1069. </template>
  1070. </el-table-column>
  1071. </el-table>
  1072. </div>
  1073. <br />
  1074. </el-col>
  1075. <el-col
  1076. v-if="editStatus"
  1077. :span="24"
  1078. style="
  1079. text-align: center;
  1080. display: flex;
  1081. flex-direction: row;
  1082. justify-content: center;
  1083. "
  1084. >
  1085. <el-button
  1086. size="small"
  1087. type="primary"
  1088. icon="Finished"
  1089. style="width: 160px"
  1090. @click="submitForm"
  1091. >保存</el-button
  1092. >
  1093. </el-col>
  1094. </el-row>
  1095. <br />
  1096. </el-form>
  1097. </div>
  1098. </el-drawer>
  1099. <el-dialog
  1100. title="驳回详情"
  1101. v-model="rejectOpen"
  1102. width="500px"
  1103. append-to-body
  1104. draggable
  1105. >
  1106. <el-form ref="dictRef" :model="form" label-width="100">
  1107. <el-form-item label="驳回原因" :prop="verifyRemark">
  1108. <el-input
  1109. v-model.trim="form.verifyRemark"
  1110. type="textarea"
  1111. :rows="3"
  1112. placeholder="请输入驳回原因"
  1113. maxlength="200"
  1114. show-word-limit
  1115. />
  1116. </el-form-item>
  1117. </el-form>
  1118. <template #footer>
  1119. <div class="dialog-footer">
  1120. <el-button
  1121. type="primary"
  1122. icon="Finished"
  1123. size="small"
  1124. @click="verifyUpload(4)"
  1125. >确 定</el-button
  1126. >
  1127. <el-button icon="close" size="small" @click="rejectCancel"
  1128. >取 消</el-button
  1129. >
  1130. </div>
  1131. </template>
  1132. </el-dialog>
  1133. <el-dialog
  1134. title="是否续签"
  1135. v-model="verifyOpen"
  1136. width="500px"
  1137. append-to-body
  1138. draggable
  1139. >
  1140. <el-form ref="dictRef" :model="verifyForm" label-width="300" size="small">
  1141. <el-form-item
  1142. v-for="item in redirectDetails"
  1143. :key="item.id"
  1144. :label="`${item.taskTypeName}上个任务结束月:${item.endMonth}是否重新开始`"
  1145. >
  1146. <el-checkbox v-model="item.redirect" />
  1147. </el-form-item>
  1148. </el-form>
  1149. <template #footer>
  1150. <div class="dialog-footer">
  1151. <el-button
  1152. type="primary"
  1153. icon="Finished"
  1154. size="small"
  1155. @click="redirectVerify()"
  1156. >确 定</el-button
  1157. >
  1158. <el-button icon="close" size="small" @click="verifyFormClose"
  1159. >取 消</el-button
  1160. >
  1161. </div>
  1162. </template>
  1163. </el-dialog>
  1164. <AddCompanyDialog ref="addCompanyDialogRef" />
  1165. <dialog-history-choice
  1166. ref="historyChoiceRef"
  1167. @choice="historyChoiceHandle"
  1168. />
  1169. </div>
  1170. </template>
  1171. <script setup>
  1172. import { uploadFile } from "@/api/tool/file";
  1173. import AddCompanyDialog from "../AddCompanyDialog";
  1174. import {
  1175. getOrder,
  1176. initTaskTypes,
  1177. addOrder,
  1178. updateOrder,
  1179. verifyOrder,
  1180. alterOrder,
  1181. dissolutionOrder,
  1182. verifyCheckOrder,
  1183. } from "@/api/business/crm/contract";
  1184. import { listSource } from "@/api/settings/source";
  1185. import { listCompany } from "@/api/business/crm/company";
  1186. import { listUser } from "@/api/system/user";
  1187. import CustomerFormCom from "@/components/CustomerFormCom";
  1188. import DialogHistoryChoice from "@/views/dialog/DialogHistoryChoice.vue";
  1189. import { formatDate, rowNum } from "@/utils/index";
  1190. import { ref } from "vue";
  1191. import useUserStore from "@/store/modules/user";
  1192. // import { it } from "element-plus/es/locale";
  1193. const { proxy } = getCurrentInstance();
  1194. const verifyOpen = ref(false);
  1195. const verifyForm = ref({});
  1196. const redirectDetails = ref([]);
  1197. const baseUrl = import.meta.env.VITE_APP_BASE_API;
  1198. const historyChoiceRef = ref(null);
  1199. const alterTypes = ref([
  1200. {
  1201. value: "普通变更",
  1202. label: "普通变更",
  1203. },
  1204. {
  1205. value: "股权变更",
  1206. label: "股权变更",
  1207. },
  1208. {
  1209. value: "减资",
  1210. label: "减资",
  1211. },
  1212. {
  1213. value: "跨区变更",
  1214. label: "跨区变更",
  1215. },
  1216. ]);
  1217. /** 父组件传参 */
  1218. const props = defineProps({
  1219. getList: {
  1220. type: Function,
  1221. default: () => {},
  1222. },
  1223. });
  1224. const { getList } = toRefs(props);
  1225. /** 字典数组区 */
  1226. const { virtual_address } = proxy.useDict("virtual_address");
  1227. /** 表单抽屉 页变量 */
  1228. const title = ref("");
  1229. const loading = ref(false);
  1230. const multiple = ref(true);
  1231. const visible = ref(false);
  1232. const editStatus = ref(false);
  1233. const loopTasks = ref([]);
  1234. const onceTasks = ref([]);
  1235. const sourceCategories = ref([]);
  1236. const loops = ref([]);
  1237. const onces = ref([]);
  1238. const type = ref("");
  1239. const addCompanyDialogRef = ref(null);
  1240. const rejectOpen = ref(false);
  1241. // 循环任务明细
  1242. const loopDetails = ref([]);
  1243. // 单次任务明细
  1244. const onceDetails = ref([]);
  1245. const detailEmpty = {
  1246. id: null,
  1247. taskTypeName: "",
  1248. taskTypeId: null,
  1249. serviceNum: undefined,
  1250. freeNum: undefined,
  1251. price: undefined,
  1252. amount: undefined,
  1253. addressStyle: undefined,
  1254. address: undefined,
  1255. fictionAddressId: undefined,
  1256. tenantId: undefined,
  1257. province: "",
  1258. city: "",
  1259. district: "",
  1260. addressStyle: 1,
  1261. provinceId: undefined,
  1262. processes: [],
  1263. defaultProcesses: [],
  1264. };
  1265. //地址数组
  1266. const provincesArr = ref([]);
  1267. const citiesArr = ref([]);
  1268. const districtsArr = ref([]);
  1269. const provinces = ref(proxy.region.getProvinces());
  1270. provinces.value.unshift({ code: "", name: "全部" });
  1271. const cities = ref([]);
  1272. const districts = ref([]);
  1273. const contractEmpty = {
  1274. serviceType: 1,
  1275. contractType: 0,
  1276. formDate: formatDate(new Date(), "yyyy-MM-dd"),
  1277. signerId: useUserStore().user.userId,
  1278. signerName: useUserStore().user.nickName,
  1279. files: [],
  1280. };
  1281. const isFullscreen = ref(false);
  1282. const webHost = import.meta.env.VITE_APP_BASE_API;
  1283. const data = reactive({
  1284. form: {},
  1285. rules: {
  1286. contractNo: [
  1287. { required: true, message: "合同编号不能为空", trigger: "blur" },
  1288. ],
  1289. companyId: [{ required: true, message: "请选择有效客户", trigger: "blur" }],
  1290. formDate: [
  1291. { required: true, message: "签约日期不能为空", trigger: "blur" },
  1292. ],
  1293. amount: [{ required: true, message: "签约金额不能为空", trigger: "blur" }],
  1294. signerName: [
  1295. { required: true, message: "签单人不能为空", trigger: "change" },
  1296. ],
  1297. contractType: [
  1298. { required: true, message: "合同类型不能为空", trigger: "change" },
  1299. ],
  1300. serviceType: [
  1301. { required: true, message: "任务类型不能为空", trigger: "change" },
  1302. ],
  1303. sourceCategoryName: [
  1304. { validator: sourceValidator, trigger: "change" },
  1305. { required: true, message: "客户来源不能为空", trigger: "change" },
  1306. ],
  1307. },
  1308. });
  1309. const { form, rules } = toRefs(data);
  1310. /*********************** 方法区 ****************************/
  1311. /** 打开抽屉 */
  1312. function open(id) {
  1313. reset();
  1314. visible.value = true;
  1315. // console.log(virtual_address.value)
  1316. if (id) {
  1317. Promise.all([initTaskTypes(), listSource(), getOrder(id)]).then((res) => {
  1318. loopTasks.value = res[0].data.loopTasks;
  1319. onceTasks.value = res[0].data.onceTasks;
  1320. sourceCategories.value = res[1].rows;
  1321. form.value = res[2].data;
  1322. type.value =
  1323. type.value == "" && form.value.status === 8 ? "alterOrder" : type.value;
  1324. parseDetail(form.value.details, form.value);
  1325. // console.log(onceDetails.value)
  1326. editStatus.value = false;
  1327. title.value = "修改订单信息";
  1328. initRegion();
  1329. });
  1330. // getOrder(id).then(response => {
  1331. // })
  1332. } else {
  1333. Promise.all([initTaskTypes(), listSource()]).then((res) => {
  1334. loopTasks.value = res[0].data.loopTasks;
  1335. onceTasks.value = res[0].data.onceTasks;
  1336. sourceCategories.value = res[1].rows;
  1337. });
  1338. editStatus.value = true;
  1339. title.value = "添加订单信息";
  1340. }
  1341. }
  1342. function openSimple(id, optionType) {
  1343. reset();
  1344. visible.value = true;
  1345. type.value = optionType || "";
  1346. if (id) {
  1347. Promise.all([initTaskTypes(), listSource(), getOrder(id)]).then((res) => {
  1348. loopTasks.value = res[0].data.loopTasks;
  1349. onceTasks.value = res[0].data.onceTasks;
  1350. sourceCategories.value = res[1].rows;
  1351. form.value = res[2].data;
  1352. parseDetail(form.value.details, form.value);
  1353. title.value = "合同变更信息";
  1354. if (type.value != "") {
  1355. editStatus.value = true;
  1356. } else {
  1357. editStatus.value = false;
  1358. }
  1359. });
  1360. } else {
  1361. Promise.all([initTaskTypes(), listSource()]).then((res) => {
  1362. loopTasks.value = res[0].data.loopTasks;
  1363. onceTasks.value = res[0].data.onceTasks;
  1364. sourceCategories.value = res[1].rows;
  1365. });
  1366. editStatus.value = true;
  1367. title.value = "添加订单信息";
  1368. }
  1369. }
  1370. /** 取消按钮 */
  1371. function cancel() {
  1372. visible.value = false;
  1373. reset();
  1374. }
  1375. /** 表单重置 */
  1376. function reset() {
  1377. form.value = JSON.parse(JSON.stringify(contractEmpty));
  1378. loops.value = [];
  1379. onces.value = [];
  1380. loopDetails.value = [];
  1381. onceDetails.value = [];
  1382. type.value = "";
  1383. // console.log(form)
  1384. proxy.resetForm("orderRef");
  1385. }
  1386. /** 全屏缩放 */
  1387. function handleScreen() {
  1388. const dom = document.querySelector(
  1389. ".list-container > .el-drawer__wrapper > .el-overlay"
  1390. );
  1391. isFullscreen.value = !isFullscreen.value;
  1392. dom.style.position = isFullscreen.value ? "fixed" : "absolute";
  1393. }
  1394. function sourceValidator(rule, value, callback) {
  1395. if (form.value.sourceCategoryName === "") {
  1396. callback(new Error("来源类型不能为空"));
  1397. return;
  1398. }
  1399. if (
  1400. form.value.referrerDataSource !== "" &&
  1401. form.value.referrerDataSource != null &&
  1402. form.value.sourceName === ""
  1403. ) {
  1404. callback(new Error("来源不能为空"));
  1405. return;
  1406. }
  1407. return callback();
  1408. }
  1409. /** 提交按钮 */
  1410. function submitForm() {
  1411. const query = { userId: form.value.signerId };
  1412. const users = [];
  1413. listUser(query).then((res) => {
  1414. users.value = res.rows;
  1415. console.log(form.value.signerId);
  1416. if (users.value.length == 1) {
  1417. if (
  1418. form.value.signerId == users.value[0].userId &&
  1419. form.value.signerName == users.value[0].nickName
  1420. ) {
  1421. } else {
  1422. proxy.$modal.msgError("请选择有效签单人");
  1423. return;
  1424. }
  1425. } else {
  1426. proxy.$modal.msgError("请选择有效签单人");
  1427. return;
  1428. }
  1429. const companyQuery = { id: form.value.companyId };
  1430. const companys = [];
  1431. listCompany(companyQuery).then((res) => {
  1432. companys.value = res.rows;
  1433. if (companys.value.length == 1) {
  1434. if (
  1435. form.value.companyId == companys.value[0].id &&
  1436. form.value.companyName == companys.value[0].name
  1437. ) {
  1438. } else {
  1439. proxy.$modal.msgError("请选择有效客户");
  1440. return;
  1441. }
  1442. } else {
  1443. proxy.$modal.msgError("请选择有效客户");
  1444. return;
  1445. }
  1446. proxy.$refs["orderRef"].validate((valid) => {
  1447. if (valid && detailValid() && amountValid()) {
  1448. const formValue = form.value;
  1449. formValue.details =
  1450. form.value.serviceType === 1
  1451. ? loopDetails.value
  1452. : onceDetails.value;
  1453. if (formValue.id != null) {
  1454. if (formValue.companyId !== null) {
  1455. if (type.value == "") {
  1456. updateOrder(formValue).then((response) => {
  1457. proxy.$modal.msgSuccess("修改成功");
  1458. visible.value = false;
  1459. getList.value();
  1460. });
  1461. } else if (type.value == "alterOrder") {
  1462. alterOrder(formValue).then((response) => {
  1463. proxy.$modal.msgSuccess("修改成功");
  1464. visible.value = false;
  1465. getList.value();
  1466. });
  1467. } else if (type.value == "dissolutionOrder") {
  1468. dissolutionOrder(formValue).then((response) => {
  1469. proxy.$modal.msgSuccess("修改成功");
  1470. visible.value = false;
  1471. getList.value();
  1472. });
  1473. } else {
  1474. proxy.$modal.msgError("请选择有效客户");
  1475. }
  1476. }
  1477. } else {
  1478. addOrder(formValue).then((response) => {
  1479. proxy.$modal.msgSuccess("新增成功");
  1480. visible.value = false;
  1481. getList.value();
  1482. });
  1483. }
  1484. }
  1485. });
  1486. });
  1487. });
  1488. }
  1489. function detailValid() {
  1490. if (form.value.serviceType === 1) {
  1491. // 循环服务
  1492. if (loopDetails.value.length === 0) {
  1493. proxy.$modal.msgError("请选择至少一条任务");
  1494. return false;
  1495. }
  1496. // loopDetails.forEach((item, index) => {
  1497. for (let i = 0; i < loopDetails.value.length; i++) {
  1498. let item = loopDetails.value[i];
  1499. if (
  1500. (item.freeNum ? Number(item.freeNum) : 0) +
  1501. (item.serviceNum ? Number(item.serviceNum) : 0) <=
  1502. 0
  1503. ) {
  1504. proxy.$modal.msgError(`${item.taskTypeName}服务月数不能为0`);
  1505. return false;
  1506. }
  1507. if (item.price == null || item.price === "") {
  1508. proxy.$modal.msgError(`${item.taskTypeName}请填写服务单价`);
  1509. return false;
  1510. }
  1511. }
  1512. } else if (form.value.serviceType === 2) {
  1513. // 代账服务
  1514. if (onceDetails.value.length === 0) {
  1515. proxy.$modal.msgError("请选择至少一条任务");
  1516. return false;
  1517. }
  1518. for (let i = 0; i < onceDetails.value.length; i++) {
  1519. let item = onceDetails.value[i];
  1520. if (item.payAddress === 1) {
  1521. if (item.addressStyle == null) {
  1522. proxy.$modal.msgError("请选择注册地址类型");
  1523. return false;
  1524. }
  1525. if (
  1526. item.addressStyle === 1 &&
  1527. (item.province == null || item.city == null || item.district == null)
  1528. ) {
  1529. proxy.$modal.msgError("请选择注册区域");
  1530. return false;
  1531. }
  1532. console.log(item);
  1533. if (item.addressStyle === 2 && item.fictionAddressId == null) {
  1534. proxy.$modal.msgError("请选择虚拟地址");
  1535. return false;
  1536. }
  1537. if (item.addressStyle === 2 && item.addressAmount == undefined) {
  1538. proxy.$modal.msgError("请填写虚拟地址金额");
  1539. return false;
  1540. }
  1541. }
  1542. if (
  1543. item.payAddress === 0 &&
  1544. (item.province == null || item.city == null || item.district == null)
  1545. ) {
  1546. proxy.$modal.msgError("请选择办理地区");
  1547. return false;
  1548. }
  1549. for (let j = 0; j < item.processes.length; j++) {
  1550. let process = item.processes[j];
  1551. if (process.amount == undefined) {
  1552. proxy.$modal.msgError(`${process.taskTypeDetailName}请填写金额`);
  1553. return false;
  1554. }
  1555. }
  1556. }
  1557. }
  1558. return true;
  1559. }
  1560. function amountValid() {
  1561. if (form.value.trueAmount < 0) {
  1562. proxy.$modal.msgError("实收金额不可小于0");
  1563. return false;
  1564. }
  1565. return true;
  1566. }
  1567. /** 查询表单信息 */
  1568. function getForm() {
  1569. proxy.$refs.orderRef.resetFields();
  1570. loading.value = true;
  1571. getOrder(form.value.id).then((response) => {
  1572. loading.value = false;
  1573. form.value = response.data;
  1574. type.value =
  1575. type.value == "" && form.value.status === 8 ? "alterOrder" : type.value;
  1576. });
  1577. }
  1578. function handleServiceTypeClick(tab) {
  1579. computedService();
  1580. }
  1581. function changeDetails(type, arg) {
  1582. switch (type) {
  1583. case "loop":
  1584. arg.forEach((e) => {
  1585. const taskType = loopTasks.value.find((v) => v.id == e);
  1586. if (loopDetails.value.findIndex((v) => v.taskTypeId == e) < 0) {
  1587. const newDetail = JSON.parse(JSON.stringify(detailEmpty));
  1588. newDetail.taskTypeId = e;
  1589. newDetail.taskTypeName = taskType.name;
  1590. loopDetails.value.push(newDetail);
  1591. }
  1592. });
  1593. loopDetails.value = loopDetails.value.filter(
  1594. (v) => arg.findIndex((e) => e == v.taskTypeId) > -1
  1595. );
  1596. break;
  1597. case "once":
  1598. arg.forEach((e) => {
  1599. const taskType = onceTasks.value.find((v) => v.id == e);
  1600. if (onceDetails.value.findIndex((v) => v.taskTypeId == e) < 0) {
  1601. const newDetail = JSON.parse(JSON.stringify(detailEmpty));
  1602. newDetail.taskTypeId = e;
  1603. newDetail.taskTypeName = taskType.name;
  1604. newDetail.payAddress = taskType.payAddress;
  1605. (newDetail.alterType = e === "6" ? "普通变更" : ""),
  1606. (newDetail.defaultProcesses = taskType.processes.map((v) => ({
  1607. taskTypeId: e,
  1608. taskTypeDetailId: v.id,
  1609. taskTypeDetailName: v.name,
  1610. fictionAddressId: null,
  1611. fictionAddress: "",
  1612. addressStyle: 0,
  1613. checked: false,
  1614. amount: undefined,
  1615. })));
  1616. newDetail.processes = [];
  1617. onceDetails.value.push(newDetail);
  1618. }
  1619. });
  1620. onceDetails.value = onceDetails.value.filter(
  1621. (v) => arg.findIndex((e) => e == v.taskTypeId) > -1
  1622. );
  1623. let provincesLength = provincesArr.value.length;
  1624. if (onceDetails.value.length > provincesLength) {
  1625. for (let i = 0; i < onceDetails.value.length - provincesLength; i++) {
  1626. provincesArr.value.push(provinces.value);
  1627. citiesArr.value.push(cities.value);
  1628. districtsArr.value.push(districts.value);
  1629. }
  1630. } else if (onceDetails.value.length < provincesLength) {
  1631. for (let i = 0; i < provincesLength - onceDetails.value.length; i++) {
  1632. provincesArr.value.length--;
  1633. citiesArr.value.length--;
  1634. districtsArr.value.length--;
  1635. }
  1636. }
  1637. break;
  1638. default:
  1639. break;
  1640. }
  1641. }
  1642. function inputChangeHandler(type, field, item, value, parent) {
  1643. let amount = 0;
  1644. switch (type) {
  1645. case "loop":
  1646. switch (field) {
  1647. case "price":
  1648. amount =
  1649. (item.serviceNum ? Number(item.serviceNum) : 0) *
  1650. (value ? Number(value) : 0);
  1651. item.amount = amount;
  1652. break;
  1653. case "serviceNum":
  1654. amount =
  1655. (item.price ? Number(item.price) : 0) * (value ? Number(value) : 0);
  1656. item.amount = amount;
  1657. break;
  1658. case "freeNum":
  1659. amount =
  1660. (item.price ? Number(item.price) : 0) *
  1661. (item.serviceNum ? Number(item.serviceNum) : 0);
  1662. item.amount = amount;
  1663. break;
  1664. }
  1665. break;
  1666. case "once":
  1667. computedItem(item);
  1668. break;
  1669. case "process":
  1670. computedItem(parent);
  1671. break;
  1672. default:
  1673. break;
  1674. }
  1675. computedService();
  1676. }
  1677. function computedItem(parent) {
  1678. let amount = 0;
  1679. amount +=
  1680. parent.payAddress === 1 && parent.addressStyle === 2 && parent.addressAmount
  1681. ? Number(parent.addressAmount)
  1682. : 0;
  1683. amount +=
  1684. parent.taskTypeId === "6" &&
  1685. parent.alterType === "跨区变更" &&
  1686. parent.addressStyle === 2 &&
  1687. parent.addressAmount
  1688. ? Number(parent.addressAmount)
  1689. : 0;
  1690. parent.processes.forEach((l) => {
  1691. amount += l.amount ? Number(l.amount) : 0;
  1692. });
  1693. parent.amount = amount;
  1694. }
  1695. function computedService() {
  1696. let amount = 0;
  1697. switch (form.value.serviceType) {
  1698. case 1:
  1699. loopDetails.value.forEach((l) => {
  1700. amount += l.amount;
  1701. });
  1702. amount = amount >= 0 ? amount : 0;
  1703. break;
  1704. case 2:
  1705. onceDetails.value.forEach((l) => {
  1706. amount +=
  1707. l.payAddress === 1 && l.addressStyle === 2 && l.addressAmount
  1708. ? Number(l.addressAmount)
  1709. : 0;
  1710. l.processes.forEach((v) => {
  1711. amount += v.amount ? Number(v.amount) : 0;
  1712. });
  1713. });
  1714. break;
  1715. }
  1716. form.value.amount = amount;
  1717. form.value.trueAmount =
  1718. amount -
  1719. (form.value.discountAmount ? Number(form.value.discountAmount) : 0);
  1720. }
  1721. /** 输入框输出建议 */
  1722. function querySearchAsync(queryString, cb) {
  1723. const query = { keyword: queryString };
  1724. listUser(query).then((res) => {
  1725. cb(res.rows);
  1726. });
  1727. }
  1728. function querySearchCompanyAsync(queryString, cb) {
  1729. const query =
  1730. queryString.length > 0
  1731. ? {
  1732. keyword: queryString,
  1733. pageSize: 50,
  1734. pageNum: 1,
  1735. orderByColumn: "create_time",
  1736. }
  1737. : { pageSize: 50, pageNum: 1, orderByColumn: "create_time" };
  1738. listCompany(query).then((res) => {
  1739. cb(res.rows);
  1740. });
  1741. }
  1742. function handleSelectEmployee(item) {
  1743. form.value.signerName = item.nickName;
  1744. form.value.signerId = item.userId;
  1745. }
  1746. function handleSelectCompany(item) {
  1747. form.value.companyName = item.name;
  1748. form.value.companyId = item.id;
  1749. }
  1750. function handleSelectProvince(item, index) {
  1751. const _provinceCode = item.provinceCode;
  1752. const _province = provincesArr.value[index].find((i) => {
  1753. return i.code === _provinceCode;
  1754. });
  1755. item.province = _province.name;
  1756. citiesArr.value[index] = proxy.region.getCities(_provinceCode);
  1757. if (citiesArr.value[index].length === 0) {
  1758. // 清空城市数据
  1759. item.cityCode = "";
  1760. item.city = "";
  1761. cities.value = [{ code: "", name: "全部" }];
  1762. // 清空行政区数据
  1763. item.districtCode = "";
  1764. item.district = "";
  1765. districts.value = [{ code: "", name: "全部" }];
  1766. } else {
  1767. citiesArr.value[index].unshift({ code: "", name: "全部" });
  1768. item.cityCode = citiesArr.value[index][0].code;
  1769. item.city = citiesArr.value[index][0].name;
  1770. handleSelectCity(item, index);
  1771. }
  1772. }
  1773. function handleSelectCity(item, index) {
  1774. const _cityCode = item.cityCode;
  1775. const _city = citiesArr.value[index].find((i) => {
  1776. return i.code === _cityCode;
  1777. });
  1778. item.city = _city.name;
  1779. districtsArr.value[index] = proxy.region.getDistricts(_cityCode);
  1780. if (districtsArr.value[index].length === 0) {
  1781. // 清空行政区数据
  1782. item.districtCode = "";
  1783. item.district = "";
  1784. districtsArr.value[index] = [{ code: "", name: "全部" }];
  1785. } else {
  1786. districtsArr.value[index].unshift({ code: "", name: "全部" });
  1787. item.districtCode = districtsArr.value[index][0].code;
  1788. item.district = districtsArr.value[index][0].name;
  1789. }
  1790. }
  1791. function handleSelectDistrict(item, index) {
  1792. const _districtCode = item.districtCode;
  1793. const _district = districtsArr.value[index].find((i) => {
  1794. return i.code === _districtCode;
  1795. });
  1796. item.district = _district.name;
  1797. }
  1798. function getProcess(item) {
  1799. const typeItem = onceTasks.value.find((i) => i.id === item.taskTypeId);
  1800. return typeItem.processes;
  1801. }
  1802. function checkedProcess(processId, item) {
  1803. const processes = item.processes;
  1804. return processes.findIndex((v) => v.taskTypeDetailId == processId) < 0;
  1805. }
  1806. function changeProcesses(item) {
  1807. computedItem(item);
  1808. computedService();
  1809. }
  1810. function parseDetail(details, form) {
  1811. loops.value = [];
  1812. onces.value = [];
  1813. loopDetails.value = [];
  1814. onceDetails.value = [];
  1815. switch (form.serviceType) {
  1816. case 1:
  1817. // 循环任务
  1818. details.forEach((i) => {
  1819. loops.value.push(i.taskTypeId);
  1820. loopDetails.value.push(i);
  1821. });
  1822. break;
  1823. case 2:
  1824. // 代办任务
  1825. details.forEach((i) => {
  1826. onces.value.push(i.taskTypeId);
  1827. const taskType = onceTasks.value.find((j) => j.id === i.taskTypeId);
  1828. onceDetails.value.push({
  1829. ...i,
  1830. defaultProcesses: parseProcess(i, taskType.processes),
  1831. });
  1832. onceDetails.value.forEach((j) => {
  1833. j.processes = j.defaultProcesses.filter((v) => v.checked);
  1834. });
  1835. });
  1836. break;
  1837. default:
  1838. break;
  1839. }
  1840. }
  1841. function parseProcess(item, processes) {
  1842. return processes.map((l) => {
  1843. // console.log(item.processes.find((i) => i.taskTypeDetailId === l.id));
  1844. if (item.processes.findIndex((i) => i.taskTypeDetailId === l.id) < 0) {
  1845. return {
  1846. taskTypeId: item.taskTypeId,
  1847. taskTypeDetailId: l.id,
  1848. taskTypeDetailName: l.name,
  1849. checked: false,
  1850. amount: undefined,
  1851. };
  1852. } else {
  1853. return {
  1854. ...item.processes.find((i) => i.taskTypeDetailId === l.id),
  1855. checked: true,
  1856. };
  1857. }
  1858. });
  1859. }
  1860. function verifyHandler() {
  1861. proxy.$modal
  1862. .confirm("是否确认审核?")
  1863. .then((_) => {
  1864. verifyCheckOrder(form.value).then((res) => {
  1865. if (res.data == null) {
  1866. verifyUpload(1);
  1867. } else {
  1868. verifyOpen.value = true;
  1869. redirectDetails.value = res.data;
  1870. }
  1871. });
  1872. })
  1873. .catch((_) => {
  1874. proxy.$modal.msg("取消审核");
  1875. });
  1876. }
  1877. function verifyFormClose() {
  1878. redirectDetails.value = [];
  1879. verifyForm.value = {};
  1880. verifyOpen.value = false;
  1881. }
  1882. function redirectVerify() {
  1883. redirectDetails.value.forEach((l) => {
  1884. const index = form.value.details.findIndex((v) => v.id === l.id);
  1885. form.value.details[index].redirect = l.redirect;
  1886. });
  1887. verifyUpload(1);
  1888. verifyFormClose();
  1889. }
  1890. function rejectHandler() {
  1891. rejectOpen.value = true;
  1892. }
  1893. function rejectCancel() {
  1894. rejectOpen.value = false;
  1895. }
  1896. function rejectSubmitHandler() {
  1897. if (form.value.verifyRemark === "" || form.value.verifyRemark == null) {
  1898. proxy.$modal.msgError("请填写驳回原因");
  1899. return;
  1900. }
  1901. }
  1902. function verifyUpload(status) {
  1903. const formValue = proxy.deepClone(form.value);
  1904. formValue.verifyStatus = status;
  1905. formValue.status = status;
  1906. verifyOrder(formValue).then((res) => {
  1907. getForm();
  1908. getList.value();
  1909. rejectCancel();
  1910. proxy.$modal.msgSuccess("保存成功");
  1911. });
  1912. }
  1913. /** 文件上传 */
  1914. function upload(param) {
  1915. const formData = new FormData();
  1916. formData.append("file", param.file);
  1917. uploadFile(formData).then((res) => {
  1918. if (res.code === 200) {
  1919. const file = {};
  1920. file.fileName = res.newFileName;
  1921. file.url = res.url;
  1922. file.originalFileName = res.originalFilename;
  1923. file.fileUrl = res.fileName;
  1924. form.value.files.push(file);
  1925. }
  1926. });
  1927. }
  1928. function handleDelFile(index) {
  1929. form.value.files.splice(index, 1);
  1930. }
  1931. function initRegion() {
  1932. console.log("initRegion开始", form.value);
  1933. for (let i = 0; i < form.value.details.length; i++) {
  1934. cities.value = proxy.region.getCities(form.value.details[i].provinceCode);
  1935. cities.value.unshift({ code: "", name: "全部" });
  1936. districts.value = proxy.region.getDistricts(form.value.details[i].cityCode);
  1937. districts.value.unshift({ code: "", name: "全部" });
  1938. console.log("市", cities.value);
  1939. provincesArr.value.push(provinces.value);
  1940. citiesArr.value.push(cities.value);
  1941. districtsArr.value.push(districts.value);
  1942. }
  1943. }
  1944. function showAddCompanyDialog() {
  1945. addCompanyDialogRef.value.open();
  1946. }
  1947. function contractTypeChangeHandler() {
  1948. if (form.value.contractType === 1) {
  1949. form.value.serviceType = 1;
  1950. }
  1951. }
  1952. function showHistoryList() {
  1953. historyChoiceRef.value.open(
  1954. form.value.fromId === "0" ? form.value.id : form.value.fromId
  1955. );
  1956. }
  1957. function historyChoiceHandle(row) {
  1958. open(row.id);
  1959. }
  1960. /** 暴露给父组件的方法 */
  1961. defineExpose({
  1962. open,
  1963. openSimple,
  1964. });
  1965. </script>
  1966. <style scoped>
  1967. .my-autocomplete .el-input-group__append {
  1968. padding: 0 10px !important;
  1969. }
  1970. </style>