edit1.vue 62 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886
  1. <template>
  2. <basic-container>
  3. <div class="flex flex-d-c h-100p">
  4. <div class="box-dashed flex jc-sb">
  5. <div class="flex">
  6. <div class="retain-box">
  7. <el-checkbox v-model="isRetain"></el-checkbox>
  8. <span>保留</span>
  9. <el-input-number
  10. v-model="retainNum"
  11. :step="1"
  12. :min="0" :max="5"
  13. :disabled="!isRetain"
  14. size="small"
  15. ></el-input-number>
  16. <span class="retain">位</span>
  17. </div>
  18. <div class="retain-box">
  19. <el-button size="mini" style="margin:10px;margin-top:16px;" @click="deviationRange.show = !deviationRange.show">允许偏差值范围</el-button>
  20. </div>
  21. <div>
  22. <el-menu
  23. :default-active="activeIndex"
  24. class="el-menu-demo"
  25. mode="horizontal"
  26. @select="handleSelect"
  27. >
  28. <el-submenu v-for="(value,key,index) in formulaList" :key="key" :index="key">
  29. <template slot="title">
  30. <span>{{key}}</span>
  31. </template>
  32. <el-menu-item v-for="(item2,index2) in value" :key="index2" :index="(index+1) +'-' + (index2+1)">{{item2.name}}</el-menu-item>
  33. </el-submenu>
  34. </el-menu>
  35. </div>
  36. </div>
  37. <div>
  38. <el-button size="small" @click="handwrit">手写模式</el-button>
  39. </div>
  40. </div>
  41. <div class="box-dashed">
  42. <div class="mg-b-20">函数公式.</div>
  43. <div class="edit-text">
  44. <span>
  45. <formula-item
  46. v-for="(item,index) in resultFormula" :key="index"
  47. :item="item" @click="obj => equationClick(obj,index,'resultFormula')"
  48. >
  49. </formula-item>
  50. </span>
  51. <span>=</span>
  52. <span v-for="(item,index) in processFormula" :key="index">
  53. <el-tooltip class="item" effect="light" placement="top-start" :disabled="item.type!=='Element'">
  54. <div slot="content">{{item.tableName }}</div>
  55. <formula-item
  56. :getname="getItemTableName(item)"
  57. :item="item" @click="obj => equationClick(obj,index,'processFormula')"
  58. >
  59. </formula-item>
  60. </el-tooltip>
  61. </span>
  62. </div>
  63. <div class="flex jc-sb">
  64. <div></div>
  65. <div><el-button type="info" size="small" @click="operationEdit">重置函数</el-button></div>
  66. </div>
  67. </div>
  68. <div v-show="operationVisible" class="operation-box flex1 flex flex-d-c ov-hidden">
  69. <div>选择参数设置</div>
  70. <div class="flex flex-d-c flex1 ov-hidden">
  71. <el-row :gutter="20" class="flex1 ov-hidden">
  72. <el-col :span="8" class="h-100p">
  73. <el-card shadow="never" v-loading="treeLoad" class="h-100p ov-auto">
  74. <div style="overflow: auto;flex:1;max-height:601px">
  75. <div class="flex">
  76. <el-input
  77. size="small"
  78. placeholder="输入关键字搜索"
  79. clearable
  80. @clear="clearfiltertext"
  81. v-model="filterText">
  82. </el-input>
  83. <el-button size="small" class="mg-l-10" @click="treeFilter">搜索</el-button>
  84. </div>
  85. <el-tree
  86. style="display: inline-block;min-width: 100%;"
  87. class="filter-tree"
  88. :data="treeData"
  89. :default-expanded-keys="defaultExpanded"
  90. @node-click="getNodeDetail"
  91. :props="defaultProps"
  92. :expand-on-click-node="false"
  93. highlight-current
  94. node-key="id"
  95. ref="tree"
  96. lazy
  97. :load="treeLoadNode"
  98. v-show="!allTreeShow"
  99. >
  100. </el-tree>
  101. <el-tree
  102. style="width: 100%"
  103. ref="treeall"
  104. v-loading="treeloading"
  105. :data="allTreeData"
  106. :props="defaultProps"
  107. @node-click="getNodeDetail"
  108. node-key="id"
  109. :expand-on-click-node="false"
  110. :filter-node-method="filterNode"
  111. v-show="allTreeShow"
  112. >
  113. </el-tree>
  114. </div>
  115. </el-card>
  116. </el-col>
  117. <el-col :span="16" class="h-100p flex flex-d-c ov-hidden">
  118. <div style="display:flex">
  119. <el-input placeholder="请输入你想搜索的元素字段" v-model="inputele" clearable @clear="clearinput" > </el-input>
  120. <el-button type="primary" icon="el-icon-search" size="small" @click="searchChange">搜索</el-button>
  121. </div>
  122. <div class="mg-t-10 no-mb-col flex1 ov-hidden" style="height: 360px; overflow-y: auto; max-height: 360px;">
  123. <el-scrollbar style="height: 100%">
  124. <el-row v-loading="eleListable">
  125. <el-col :span="6" v-for="item in eleList" :key="item.id">
  126. <div class="ele-box">
  127. <span v-if="item.k">{{item.name}}</span>
  128. <span v-else>{{item.eName}}</span>
  129. <!-- <span >{{item.title}}</span> -->
  130. <el-checkbox v-model="item.checked" @change="value => eleChang(value,item)"></el-checkbox>
  131. </div>
  132. </el-col>
  133. </el-row>
  134. </el-scrollbar>
  135. </div>
  136. <div class="flex jc-sb">
  137. <!-- <div>定位数据位置:</div> -->
  138. <div class="icon-box">
  139. <el-link :underline="false" icon="el-icon-delete" type="danger" @click="removeSelect"></el-link>
  140. <el-link :underline="false" type="primary" @click="addOperator('+')" icon="el-icon-circle-plus-outline"></el-link>
  141. <el-link :underline="false" type="primary" @click="addOperator('-')" icon="el-icon-remove-outline"></el-link>
  142. <el-link :underline="false" type="primary" @click="addOperator('*')" icon="el-icon-circle-close"></el-link>
  143. <el-link :underline="false" type="primary" @click="addOperator('%')">÷</el-link>
  144. </div>
  145. <div>
  146. <!-- <el-link :underline="false" type="primary" class="mg-r-20" @click="eleAddFormula">元素添加到公式</el-link> -->
  147. <el-link :underline="false" type="primary" class="mg-r-10" @click="addBrackets('(',false)">(</el-link>
  148. <el-link :underline="false" type="primary" class="mg-r-10" @click="addBrackets(')',true)">)</el-link>
  149. <!-- <el-link :underline="false" type="primary" class="mg-r-10" @click="addBrackets('[',false)">【</el-link>
  150. <el-link :underline="false" type="primary" class="mg-r-10" @click="addBrackets(']',true)">】</el-link> -->
  151. <el-link :underline="false" type="primary" @click="addText">输入值</el-link>
  152. </div>
  153. </div>
  154. <div class="border-grey sele-ele-box" >
  155. <draggable v-model="selectEleFormula">
  156. <formula-item
  157. v-for="(item,index) in selectEleFormula" :key="index"
  158. :item="item" @click="obj => eleFormulaClick(obj,index)"
  159. >
  160. </formula-item>
  161. </draggable>
  162. </div>
  163. </el-col>
  164. </el-row>
  165. <div class="text-align-c">
  166. <el-button size="small" @click="canceloperationVisible ">取消</el-button>
  167. <el-button size="small" @click="operationHandle" type="primary">保存</el-button>
  168. </div>
  169. </div>
  170. </div>
  171. <div v-show="!operationVisible && !showFunDetail && !deviationRange.show">
  172. <div class="box-dashed">
  173. <div class="mg-b-20">函数公式运算执行溯源</div>
  174. <div>
  175. <el-select
  176. v-model="projectId"
  177. @change="projectChange"
  178. placeholder="请选择项目"
  179. style="width: 380px"
  180. >
  181. <el-option
  182. v-for="item in projectList"
  183. :key="item.id"
  184. :label="item.projectName"
  185. :value="item.id"
  186. ></el-option>
  187. </el-select>
  188. <el-select v-model="contractId" placeholder="请选择合同段">
  189. <el-option
  190. v-for="item in contractList"
  191. :key="item.id"
  192. :label="item.contractName"
  193. :value="item.id"
  194. ></el-option>
  195. </el-select>
  196. <el-button type="info">查询</el-button>
  197. </div>
  198. </div>
  199. </div>
  200. <div v-if="!operationVisible && showFunDetail" class="flex1">
  201. <el-tabs v-model="actiFunIndex" closable @tab-remove="removeFun" :before-leave="funLeave">
  202. <el-tab-pane v-for="(item,index) in equationSelectEle.children" :key="index" :label="item.name" :name="index.toString()">
  203. <template v-if="!componentMap[item.name]">
  204. <formula-template ref="dynamiccomponent" :formulainfo="item" :curele="equationSelectEle" @sele-ele-handle="showChooseEle">
  205. </formula-template>
  206. </template>
  207. <template v-else>
  208. <div class="flex" >
  209. <div class=" flex-d-c" style="width:40%">
  210. <component ref="dynamiccomponent" v-bind:is="componentMap[item.name]" :formulainfo="item" :curele="equationSelectEle" :formulamap="formulaMap" @uncheck="unCheckEleComp" class="flex1"></component>
  211. <div class="flex1" v-show="item.showSelectEle" style="margin-top:10px;margin-bottom:30px">
  212. <div class="flex">
  213. <el-input
  214. size="small"
  215. placeholder="输入关键字搜索"
  216. clearable
  217. @clear="clearfiltertext"
  218. v-model="filterText">
  219. </el-input>
  220. <el-button size="small" class="mg-l-10" @click="treeFilter">搜索</el-button>
  221. </div>
  222. <el-scrollbar style="height: 520px">
  223. <el-tree
  224. class="filter-tree"
  225. :data="treeData"
  226. :default-expanded-keys="defaultExpanded"
  227. @node-click="getNodeDetailComp"
  228. :props="defaultProps"
  229. :expand-on-click-node="false"
  230. highlight-current
  231. node-key="id"
  232. ref="tree"
  233. lazy
  234. :load="treeLoadNode"
  235. v-show="!allTreeShow"
  236. >
  237. </el-tree>
  238. <el-tree
  239. style="width: 100%"
  240. ref="treeall"
  241. v-loading="treeloading"
  242. :data="allTreeData"
  243. :props="defaultProps"
  244. @node-click="getNodeDetailComp"
  245. node-key="id"
  246. :expand-on-click-node="false"
  247. :filter-node-method="filterNode"
  248. v-show="allTreeShow"
  249. >
  250. </el-tree>
  251. </el-scrollbar>
  252. </div>
  253. </div>
  254. <div v-show="item.showSelectEle" style="width:60%">
  255. <div style="display:flex">
  256. <el-input placeholder="请输入你想搜索的元素字段" v-model="inputelejudge" clearable @clear="clearinputjudge" > </el-input>
  257. <el-button type="primary" icon="el-icon-search" size="small" @click="searchChangejudge">搜索</el-button>
  258. </div>
  259. <div class="mg-t-10 mg-b-10 no-mb-col" style="width:100%">
  260. <el-scrollbar style="height:600px;">
  261. <el-row v-loading="eleListjudge">
  262. <el-col :span="6" v-for="item in eleListComp" :key="item.id">
  263. <div class="ele-box">
  264. <span v-if="item.k">{{item.name}}</span>
  265. <span v-else>{{item.eName}}</span>
  266. <el-checkbox v-model="item.checked" @change="value => setComponentEle(value,item,index)"></el-checkbox>
  267. </div>
  268. </el-col>
  269. </el-row>
  270. </el-scrollbar>
  271. </div>
  272. </div>
  273. </div>
  274. </template>
  275. </el-tab-pane>
  276. </el-tabs>
  277. </div>
  278. <!-- 允许偏差值范围 -->
  279. <div v-if="!operationVisible && !showFunDetail && deviationRange.show" class="flex1">
  280. <div class="flex">
  281. <div class=" flex-d-c" style="width:40%">
  282. <deviation-range ref="deviationrange" :formulainfo="deviationRange" :formulamap="formulaMap" @uncheck="unCheckEleComp" class="flex1"></deviation-range>
  283. <div class="flex1" v-show="deviationRange.showSelectEle" style="margin-top:10px;margin-bottom:30px">
  284. <div class="flex">
  285. <el-input
  286. size="small"
  287. placeholder="输入关键字搜索"
  288. clearable
  289. @clear="clearfiltertext"
  290. v-model="filterText">
  291. </el-input>
  292. <el-button size="small" class="mg-l-10" @click="treeFilter">搜索</el-button>
  293. </div>
  294. <el-scrollbar style="height: 520px">
  295. <el-tree
  296. class="filter-tree"
  297. :data="treeData"
  298. :default-expanded-keys="defaultExpanded"
  299. @node-click="getNodeDetailComp"
  300. :props="defaultProps"
  301. :expand-on-click-node="false"
  302. highlight-current
  303. node-key="id"
  304. ref="tree"
  305. lazy
  306. :load="treeLoadNode"
  307. v-show="!allTreeShow"
  308. >
  309. </el-tree>
  310. <el-tree
  311. style="width: 100%"
  312. ref="treeall"
  313. v-loading="treeloading"
  314. :data="allTreeData"
  315. :props="defaultProps"
  316. @node-click="getNodeDetailComp"
  317. node-key="id"
  318. :expand-on-click-node="false"
  319. :filter-node-method="filterNode"
  320. v-show="allTreeShow"
  321. >
  322. </el-tree>
  323. </el-scrollbar>
  324. </div>
  325. </div>
  326. <div v-show="deviationRange.showSelectEle" style="width:60%">
  327. <div style="display:flex">
  328. <el-input placeholder="请输入你想搜索的元素字段" v-model="inputelepian" clearable @clear="clearinputpian" > </el-input>
  329. <el-button type="primary" icon="el-icon-search" size="small" @click="searchChangepian">搜索</el-button>
  330. </div>
  331. <div class="mg-t-10 mg-b-10 no-mb-col" style="width:100%">
  332. <el-scrollbar style="height:520px;">
  333. <el-row v-loading="eleListComploading">
  334. <el-col :span="6" v-for="item in eleListComp" :key="item.id">
  335. <div class="ele-box">
  336. <span v-if="item.k">{{item.name}}</span>
  337. <span v-else>{{item.eName}}</span>
  338. <el-checkbox v-model="item.checked" @change="value => setDeviationRangeEle(value,item)"></el-checkbox>
  339. </div>
  340. </el-col>
  341. </el-row>
  342. </el-scrollbar>
  343. </div>
  344. </div>
  345. </div>
  346. </div>
  347. <div class="text-align-c" v-show="!operationVisible">
  348. <el-button type="warning" @click="$emit('hideDialog')">取消</el-button>
  349. <el-button type="primary" @click="saveFormula">保存</el-button>
  350. </div>
  351. </div>
  352. <el-dialog title="输入值" :visible.sync="inputVisible" width="300px" append-to-body :close-on-click-modal="false">
  353. <el-input v-model="inputText" placeholder="请输入内容"></el-input>
  354. <div class="text-align-c mg-t-10">
  355. <el-button size="small" @click="addTextHandle" type="primary">保存</el-button>
  356. <el-button size="small" @click="inputVisible = false">取消</el-button>
  357. </div>
  358. </el-dialog>
  359. <el-dialog title="选择元素" :visible.sync="chooseEleVisible" width="70%" append-to-body :close-on-click-modal="false">
  360. <div>
  361. <el-row :gutter="20">
  362. <el-col :span="8">
  363. <el-card shadow="never">
  364. <div class="flex">
  365. <el-input
  366. size="small"
  367. placeholder="输入关键字搜索表单"
  368. clearable
  369. @clear="clearfiltertext"
  370. v-model="filterText">
  371. </el-input>
  372. <el-button size="small" class="mg-l-10" @click="treeFilter">搜索</el-button>
  373. </div>
  374. <el-scrollbar style="height: 460px">
  375. <el-tree
  376. class="filter-tree"
  377. :data="treeData"
  378. :default-expanded-keys="defaultExpanded"
  379. @node-click="getNodeDetail"
  380. :props="defaultProps"
  381. :expand-on-click-node="false"
  382. highlight-current
  383. node-key="id"
  384. ref="tree"
  385. lazy
  386. :load="treeLoadNode"
  387. v-show="!allTreeShow"
  388. >
  389. </el-tree>
  390. <el-tree
  391. style="width: 100%"
  392. ref="treeall"
  393. v-loading="treeloading"
  394. :data="allTreeData"
  395. :props="defaultProps"
  396. @node-click="getNodeDetail"
  397. node-key="id"
  398. :expand-on-click-node="false"
  399. :filter-node-method="filterNode"
  400. v-show="allTreeShow"
  401. >
  402. </el-tree>
  403. </el-scrollbar>
  404. </el-card>
  405. </el-col>
  406. <el-col :span="16">
  407. <div style="display:flex">
  408. <el-input placeholder="请输入你想搜索的元素字段" v-model="inputele" clearable @clear="clearinput" > </el-input>
  409. <el-button type="primary" icon="el-icon-search" size="small" @click="searchChange">搜索</el-button>
  410. </div>
  411. <div class="mg-t-10 mg-b-10 no-mb-col">
  412. <el-scrollbar style="height: 460px;">
  413. <el-row >
  414. <el-col :span="6" v-for="item in eleList" :key="item.id">
  415. <div class="ele-box">
  416. <span v-if="item.k">{{item.name}}</span>
  417. <span v-else>{{item.eName}}</span>
  418. <el-checkbox v-model="item.checked" @change="value => eleCheckHandle(value,item)"></el-checkbox>
  419. </div>
  420. </el-col>
  421. </el-row>
  422. </el-scrollbar>
  423. </div>
  424. </el-col>
  425. </el-row>
  426. <div class="text-align-c">
  427. <el-button size="small" @click="chooseEleHandle" type="primary">保存</el-button>
  428. <el-button size="small" @click="chooseEleVisible = false">取消</el-button>
  429. </div>
  430. </div>
  431. </el-dialog>
  432. <el-dialog title="手写模式" :visible.sync="handwritVisible" width="900px" append-to-body :close-on-click-modal="false">
  433. <div class="font-c-warning">tips:手写模式不保证能转换成配置模式!!即使能转换也不保证正确!!!</div>
  434. <div class="mg-b-20 font-c-warning">无法在手写模式手写加入新的元素!新的节点参数!</div>
  435. <editor v-model="handwritText" @init="editorInit" lang="javascript" theme="github" width="100%" height="200"></editor>
  436. <!-- <el-input
  437. type="textarea"
  438. :autosize="{ minRows: 5,}"
  439. placeholder="请输入内容"
  440. v-model="handwritText">
  441. </el-input> -->
  442. <span slot="footer" class="dialog-footer">
  443. <el-button @click="handwritVisible = false">取 消</el-button>
  444. <el-button type="primary" @click="handwritTransform">转 换</el-button>
  445. </span>
  446. </el-dialog>
  447. </basic-container>
  448. </template>
  449. <script>
  450. import { getLazytree,selectFormElements,getAlltree,getNodeTabAndParam} from "@/api/manager/wbstree";
  451. import { getProjectList,findProjectTree } from "@/api/manager/projectinfo";
  452. import { findContractByProjectId } from "@/api/manager/contractinfo";
  453. import { getDetail as getEleDeatil } from "@/api/manager/wbsformelement";
  454. import { getTypeMap,saveFormula,formulaDetail,updateFormula } from "@/api/formula/formula";
  455. import { getNodeTabAndParam as wbsPrivateGetNodeTabAndParam} from "@/api/manager/wbsprivate";
  456. import {tabTypeLazyTreeAll} from "@/api/manager/wbsprivate";
  457. import {tabTypeLazyTree} from "@/api/manager/wbsprivate";
  458. import {getTableElments} from "@/api/manager/wbstree";
  459. import {mapGetters} from "vuex";
  460. import formulaItem from "./component/formulaItem"
  461. import formulaTemplate from "./component/formulaTemplate"
  462. import dateDeviation from "./component/funComponent/dateDeviation"
  463. import dateFormat from "./component/funComponent/dateFormat"
  464. import datasRepeat from "./component/funComponent/datasRepeat"
  465. import datasReme from "./component/funComponent/datasReme"
  466. import datasGetlist from "./component/funComponent/datasGetlist"
  467. import datasJoin from "./component/funComponent/datasJoin"
  468. import ifelse from "./component/funComponent/ifelse"
  469. import deviationRange from "./component/deviationRange/deviationRange"
  470. import {rangeToString} from "./component/deviationRange/rangeToString"
  471. import {formulaArrayToString} from "./formulaArrayToString"
  472. import {formulaStringToArray} from "./formulaStringToArray"
  473. import draggable from 'vuedraggable'
  474. import { log } from '@antv/g2plot/lib/utils';
  475. export default {
  476. components: {
  477. draggable,
  478. formulaItem,
  479. formulaTemplate,
  480. editor: require('vue2-ace-editor'),
  481. dateDeviation,
  482. dateFormat,
  483. datasRepeat,
  484. datasReme,
  485. datasGetlist,
  486. datasJoin,
  487. ifelse,
  488. deviationRange
  489. },
  490. props: {
  491. wbsid:{
  492. type:String,
  493. default:''
  494. },
  495. eleid:{
  496. type:String,
  497. default:''
  498. },
  499. globaltype:{
  500. type:Number,
  501. default:10
  502. },
  503. elementType:{
  504. type:Boolean,//公有还是私有
  505. },
  506. nodeid:{
  507. type:String,
  508. default:''
  509. },
  510. pid:{
  511. type:String,
  512. default:''
  513. },
  514. projectid:{
  515. type:String,
  516. default:''
  517. },
  518. fromcurNode:{
  519. type:Object,
  520. default:''
  521. },
  522. tableType:{
  523. type:Boolean,
  524. default:false
  525. }
  526. },
  527. data() {
  528. return {
  529. // wbsid: "", //从哪个wbs树过来的
  530. // eleid: "", //元素id
  531. // nodeid:'',//所在树节点id
  532. // pid:'',//项目id 私有树才有
  533. filterText:'',//树形控件搜索文字
  534. allTreeShow:'',//搜索树显示
  535. formulaid:'',
  536. treeloading:false,//搜索树加载效果
  537. allTreeData:[],//过滤树
  538. treeData:[],//树节点
  539. treeLoad:false,
  540. defaultExpanded:[],//默认展开节点
  541. isRetain: false, //是否保留小数
  542. retainNum: 2, //保留几位小数
  543. formulaList:{},
  544. formulaMap:{},
  545. activeIndex: "1-1", //当前选择的公式
  546. projectList: [], //项目备选列表
  547. projectId: "", //溯源的项目ID
  548. curProjiect: {}, //当前项目对象
  549. contractList: [], //合同段备选列表
  550. contractId: "", //合同段id
  551. operationVisible: false, //基础运算弹窗
  552. defaultProps: {
  553. children: "children",
  554. label: "title",
  555. isLeaf: function (data) {
  556. return !data.hasChildren;
  557. },
  558. },
  559. eleTableId:'',//选中的元素表id
  560. eleTableList:[],
  561. eleList:[],
  562. selectEleFormula:[],
  563. curSeleEleIndex:-1,//公式文字里面选中的元素索引
  564. inputVisible:false,//输入弹窗
  565. inputText:"",//输入值
  566. deleEleIndex:-1,//删除元素的位置,如果下次添加元素,先加到这个位置
  567. resultFormula:[],//=等号左边的数组
  568. processFormula:[],//=等号右边的数组
  569. rightDict:[],//等号右边元素的字典
  570. processType:'',//选中的元素在等号哪边
  571. processSelectIndex:0,//选中的索引
  572. actiFunIndex:0,//元素下挂载的计算式的索引
  573. chooseEleVisible:false,//选择元素弹窗
  574. argumenObj:{},
  575. symbolReg:/(\+|-|\*|\/)(.+)/,
  576. operatorReg : /^\+|-|\*|%/,//加减乘除
  577. startFCRegExp : /^FC\.([a-zA-Z]+)\(/,// 匹配开始的FC.xxx(
  578. componentMap:{
  579. '日期偏移':'date-deviation',
  580. '日期格式化':'date-format',
  581. // '去重':'datas-repeat',
  582. // '去空':'datas-reme',
  583. '下标取数':'datas-getlist',
  584. // '数组转字符串':"datas-join",
  585. '判断':'ifelse'
  586. },
  587. eleListComp:[],//方法下面元素列表
  588. eleTableListComp:[],//方法下面元素表列表
  589. eleTableIdComp:'',//方法下面元素表id
  590. handwritVisible:false,//手写弹框
  591. handwritText:'',//文本
  592. handwritEleMap:'',//元素map
  593. paramDataList:[],//节点参数数组
  594. deviationRange:{
  595. show:false,//显示
  596. showSelectEle:false,//显示选择元素
  597. datas:{
  598. symbol:'【min,max】',
  599. model:'1',
  600. arguments1:'',
  601. arguments2:'',
  602. },
  603. },//允许偏差值范围
  604. version:1,//版本号,以后可能会有不兼容旧公式的改动,留作以后可能用来判断
  605. curData:{},
  606. curNode:{},
  607. treeId:'',
  608. page: {
  609. size: 10,
  610. current: 1,
  611. total: 2
  612. },
  613. eleListable:false,
  614. eleListComploading:false,
  615. eleListjudge:false,
  616. input3:'',
  617. rootNodeData: [],
  618. nodeZero: null,
  619. resolveZero: null,
  620. loading: false,
  621. itemList:[],
  622. inputele:'',
  623. inputelepian:'',
  624. inputelejudge:'',
  625. };
  626. },
  627. computed: {
  628. ...mapGetters(["userInfo"]),
  629. // selectEleFormulaText:function(){
  630. // let text = '';
  631. // this.selectEleFormula.forEach((Element)=>{
  632. // text+=Element.name;
  633. // })
  634. // return text
  635. // }
  636. //等式中选中的元素
  637. equationSelectEle:function(){
  638. if(this.processType){
  639. return this[this.processType][this.processSelectIndex];
  640. }else{
  641. return null;
  642. }
  643. },
  644. //是否显示元素下挂载的计算式信息
  645. showFunDetail:function(){
  646. if(this.equationSelectEle && this.equationSelectEle.children && this.equationSelectEle.children.length>0){
  647. return true;
  648. }else{
  649. return false;
  650. }
  651. },
  652. },
  653. created() {
  654. // this.wbsid = this.$route.query.wbsid;
  655. // this.eleid = this.$route.query.eleid;
  656. // this.nodeid = this.$route.query.nodeid;
  657. this.pid = this.$route.query.pid;//项目id 私有树才有
  658. this.init();
  659. },
  660. methods: {
  661. async init() {
  662. this.getEleDeatil();
  663. this.getProjectList();
  664. // this.geTreeData();
  665. await this.getTypeMap();
  666. this.formulaStringToArray();
  667. },
  668. //#region 接口
  669. async tabTypeLazyTree (parentId, projectId,current,size,titleName) {//清表树
  670. const { data: res } = await tabTypeLazyTree({ parentId, projectId,current,size,titleName })
  671. if (res.code === 200) {
  672. return res.data;
  673. }
  674. },
  675. treeLoadNode(node, resolve){
  676. let parentId = 12345678910;
  677. if (node.level != 0) {
  678. parentId = node.data.id;
  679. }
  680. // 开启 “加载中” 动画
  681. if(node.level == 0) this.loading=true
  682. // if(this.globaltype===1&&!this.elementType){
  683. if(!this.elementType){
  684. tabTypeLazyTreeAll({parentId,current:1,size:1000,hasPartFormula:this.fromcurNode.hasPartFormula}).then(res => {
  685. // 请求接口,返回数据
  686. let data = res.data.data.records;
  687. this.loading=false
  688. resolve(data);
  689. this.$nextTick(() => {
  690. console.log(this.tableType,'tableType1111111111');
  691. // if(this.tableType){
  692. // let expandid=Number(this.tableType)-1
  693. // }else{
  694. // let expandid=Number(this.fromcurNode.parentId)-1
  695. // }
  696. console.log(this.fromcurNode,'this.fromcurNode');
  697. let expandid=this.tableType? Number(this.fromcurNode.tableType)-1:Number(this.fromcurNode.parentId)-1
  698. console.log(expandid,'expandid');
  699. node.childNodes[expandid].expand();
  700. let paramsId = this.fromcurNode.initTableId
  701. console.log(paramsId, "paramsId")
  702. let isArray = Array.isArray(this.$refs.tree)
  703. if (isArray) {
  704. // 根据 id 获取节点信息
  705. this.$refs.tree[0].setCurrentKey(paramsId);
  706. } else {
  707. this.$refs.tree.setCurrentKey(paramsId);
  708. }
  709. this.getNodeDetail(this.fromcurNode)
  710. this.getNodeDetailComp(this.fromcurNode)
  711. })
  712. })
  713. }
  714. // else if(this.globaltype===1&&this.elementType)
  715. else if(this.elementType)
  716. {
  717. tabTypeLazyTree({parentId,projectId:this.projectid,pcurrent:1,size:1000}).then(res => {
  718. // 请求接口,返回数据
  719. let data = res.data.data.records;
  720. this.loading=false
  721. resolve(data);
  722. this.$nextTick(() => {
  723. console.log(this.fromcurNode,'this.fromcurNode')
  724. let expandid=Number(this.fromcurNode.parentId)-1
  725. node.childNodes[expandid].expand();
  726. let paramsId = this.fromcurNode.id
  727. console.log(this.nodeid,'this.initTableId');
  728. // 根据 id 获取节点信息
  729. // let getNodeById = this.$refs.tree.getNode(paramsId);
  730. // if(getNodeById){
  731. // // 设置节点选中
  732. // this.$refs.tree.setCurrentKey(paramsId);
  733. // this.getNodeDetail(this.fromcurNode)
  734. // this.getNodeDetailComp(this.fromcurNode)
  735. // }
  736. let isArray = Array.isArray(this.$refs.tree)
  737. if (isArray) {
  738. // 根据 id 获取节点信息
  739. this.$refs.tree[0].setCurrentKey(paramsId);
  740. } else {
  741. this.$refs.tree.setCurrentKey(paramsId);
  742. }
  743. this.getNodeDetail(this.fromcurNode)
  744. this.getNodeDetailComp(this.fromcurNode)
  745. })
  746. })
  747. }
  748. },
  749. //搜索树
  750. treeFilter() {
  751. console.log('搜索');
  752. this.eleTableList=[];
  753. this.eleList=[];
  754. this.eleListComp=[];
  755. this.eleTableListComp =[];
  756. this.eleTableId='';
  757. this.eleTableIdComp=''
  758. if (this.filterText) {
  759. this.allTreeShow = true;
  760. this.allTreeData=[]
  761. if (!this.allTreeData.length) {
  762. this.treeloading = true;
  763. if(!this.elementType){
  764. let parentId=''
  765. if(this.curData.hasChildren){
  766. parentId=this.curData.id
  767. }else{
  768. // parentId=this.curData.parentId
  769. parentId=''
  770. }
  771. tabTypeLazyTreeAll({parentId:parentId,current:1,size:1000,titleName:this.filterText}).then((res) => {
  772. this.treeloading = false;
  773. this.allTreeData = res.data.data.records;
  774. this.$nextTick(() => {
  775. console.log("过滤");
  776. this.$refs.treeall.filter(this.filterText);
  777. });
  778. })
  779. }else if(this.elementType){
  780. let parentId=''
  781. if(this.curData.hasChildren){
  782. parentId=this.curData.id
  783. }else{
  784. // parentId=this.curData.parentId
  785. parentId=''
  786. }
  787. console.log(parentId,'parentId');
  788. tabTypeLazyTree({parentId:parentId,projectId:this.projectid,pcurrent:1,size:1000,titleName:this.filterText}).then((res) => {
  789. this.treeloading = false;
  790. this.allTreeData = res.data.data.records;
  791. });
  792. this.$nextTick(() => {
  793. console.log("过滤");
  794. this.$refs.treeall.filter(this.filterText);
  795. });
  796. }
  797. } else {
  798. this.$refs.treeall.filter(this.filterText);
  799. }
  800. } else {
  801. this.$message.warning('请先输入文字')
  802. this.allTreeShow = false;
  803. }
  804. },
  805. clearfiltertext(){
  806. this.allTreeShow=false;
  807. this.eleTableList=[];
  808. this.eleList=[];
  809. this.eleListComp=[];
  810. this.eleTableListComp =[];
  811. this.eleTableId='';
  812. this.eleTableIdComp=''
  813. },
  814. filterNode(value, data) {
  815. if (!value) return true;
  816. return data.title.indexOf(value) !== -1;
  817. },
  818. //获取项目列表
  819. getProjectList() {
  820. getProjectList(1, 999).then((res) => {
  821. this.projectList = res.data.data.records;
  822. });
  823. },
  824. //选择公式处理
  825. handleSelect(index,indexPath) {
  826. //console.log(index,'index')
  827. //console.log(indexPath,'indexPath')
  828. if(this.operationVisible){
  829. this.openerationSelect(index,indexPath)
  830. }else{
  831. this.equationSelect(index,indexPath)
  832. }
  833. },
  834. //在选择元素模式下点选计算式
  835. openerationSelect(index,indexPath){
  836. if(indexPath[0]!='基础运算'){
  837. this.$message({
  838. type: "warning",
  839. message: "当前只能使用基础运算"
  840. });
  841. return;
  842. }
  843. let formulaindex = Number(indexPath[1].split('-')[1])-1;
  844. this.eleAddFormulaHandle(this.formulaList[indexPath[0]][formulaindex]);
  845. },
  846. //溯源项目id切换
  847. projectChange(id) {
  848. for (let i = 0; i < this.projectList.length; i++) {
  849. if (id == this.projectList[i].id) {
  850. this.curProjiect = this.projectList[i];
  851. //根据项目id获取合同段列表
  852. findContractByProjectId(this.curProjiect.id).then((res) => {
  853. this.contractList = res.data.data;
  854. this.contractId = "";
  855. });
  856. return;
  857. }
  858. }
  859. },
  860. operationEdit(){
  861. this.selectEleFormula= JSON.parse(JSON.stringify(this.processFormula));
  862. this.operationVisible = true;
  863. },
  864. eleAddFormula(){
  865. for (let i = 0; i < this.eleList.length; i++) {
  866. if (this.eleList[i].checked) {
  867. this.eleAddFormulaHandle(this.eleList[i]);
  868. break;
  869. }
  870. }
  871. },
  872. eleChang(value,item){
  873. if(value){
  874. //简单语法判断
  875. if(this.itemList.length != 0 && this.deleEleIndex < 0){
  876. let lastEle = this.itemList[this.itemList.length-1];
  877. if(lastEle.type == 'Text'){
  878. this.$message({
  879. type: "warning",
  880. message: "元素无法连续出现在输入值后面"
  881. });
  882. item.checked = false;
  883. return;
  884. }
  885. if(lastEle.type == 'Brackets' && lastEle.name == ')'){
  886. this.$message({
  887. type: "warning",
  888. message: "元素无法连续出现在右括号后面"
  889. });
  890. item.checked = false;
  891. return;
  892. }
  893. }
  894. let lastEle = this.selectEleFormula[this.selectEleFormula.length-1];
  895. if(this.selectEleFormula.length == 0 || lastEle.type == 'Operator' || lastEle.type == 'Brackets' || lastEle.name == '('){ /* 存在运算符 */
  896. this.eleAddFormulaHandle(item);
  897. } else {
  898. this.itemList.push(item);
  899. }
  900. }else{
  901. let index = -1;
  902. for (let i = 0; i < this.itemList.length; i++) {
  903. if(this.itemList[i].id == item.id){
  904. index = i;
  905. break;
  906. }
  907. }
  908. if(index>-1){
  909. this.itemList.splice(index,1);
  910. }
  911. }
  912. },
  913. //快捷添加运算符号
  914. addOperator(operator){
  915. if( this.itemList.length>0){
  916. this.itemList.forEach(e => {
  917. let lastEle = this.selectEleFormula[this.selectEleFormula.length-1];
  918. if(this.selectEleFormula.length != 0 && lastEle.type != 'Operator' && lastEle.type != 'Brackets' && lastEle.name != '('){ /* 不存在运算符 */
  919. this.eleAddFormulaHandle(this.formulaMap[operator]);
  920. }
  921. this.eleAddFormulaHandle(e);
  922. })
  923. }else{
  924. if(this.curSeleEleIndex===-1 || this.curSeleEleIndex === this.selectEleFormula.length - 1){ /* 没选择值或者选择最后一个的时候直接添加符号 */
  925. this.eleAddFormulaHandle(this.formulaMap[operator]);
  926. }else{ /* 选择中间的值,如果下一个是符号这替换,反之则在指定的位置添加 */
  927. this.randomaddOperator(this.formulaMap[operator])
  928. }
  929. }
  930. this.itemList=[];
  931. },
  932. //随机插入运算符
  933. randomaddOperator(ele){
  934. //type 是true 表示在元素右边插入
  935. let item={
  936. type:'Operator',
  937. name:this.symbolReg.exec(ele.name)[1],
  938. selected:false,
  939. template:ele.template
  940. }
  941. let index = Number(this.curSeleEleIndex);
  942. let currentName = this.selectEleFormula[index]
  943. if (currentName.type === 'Operator') { /* 选择的符号的时候,直接替换 */
  944. this.selectEleFormula.splice(index,1, item)
  945. }
  946. else { /* 选择元素的时候,如果下一个是符号则替换,如果下一个是元素则添加 */
  947. let size = index + 1;
  948. let lastName = this.selectEleFormula[size]
  949. if (lastName.type === 'Operator') { /* 是符号,替换 */
  950. this.selectEleFormula.splice(size,1, item)
  951. }
  952. else { /* 是元素,添加 */
  953. this.selectEleFormula.splice(size,0, item)
  954. }
  955. }
  956. },
  957. //把元素加到公式里
  958. eleAddFormulaHandle(ele){
  959. if(ele.tableElementKey){
  960. //元素
  961. if(this.deleEleIndex > -1 && this.selectEleFormula.length-1 >= this.deleEleIndex){
  962. //删除元素的位置,如果下次添加元素,先加到这个位置
  963. this.selectEleFormula.splice(this.deleEleIndex,0,{
  964. type:'Element',
  965. name:ele.eName,
  966. id:ele.id,
  967. selected:false,
  968. tableElementKey:ele.tableElementKey,
  969. children:[],
  970. })
  971. this.deleEleIndex = -1;
  972. }else{
  973. this.selectEleFormula.push({
  974. type:'Element',
  975. name:ele.eName,
  976. id:ele.id,
  977. selected:false,
  978. tableElementKey:ele.tableElementKey,
  979. children:[],
  980. })
  981. this.deleEleIndex = -1;
  982. }
  983. }else if(ele.template && ele.example){
  984. //简单语法判断
  985. if(this.selectEleFormula.length == 0){
  986. this.$message({
  987. type: "warning",
  988. message: "公式开头不能是运算符号"
  989. });
  990. return;
  991. }else{
  992. let lastEle = this.selectEleFormula[this.selectEleFormula.length-1];
  993. if(lastEle.type == 'Operator'){
  994. this.$message({
  995. type: "warning",
  996. message: "运算符号无法连续出现在运算符号后面"
  997. });
  998. return;
  999. }
  1000. if(lastEle.type == 'Brackets' && lastEle.name == '('){
  1001. this.$message({
  1002. type: "warning",
  1003. message: "运算符号无法连续出现在左括号后面"
  1004. });
  1005. return;
  1006. }
  1007. }
  1008. //运算符号
  1009. this.selectEleFormula.push({
  1010. type:'Operator',
  1011. name:this.symbolReg.exec(ele.name)[1],
  1012. selected:false,
  1013. template:ele.template
  1014. })
  1015. }else if(ele.type == 'Brackets'){
  1016. //括号
  1017. this.selectEleFormula.splice(ele.selectIndex,0,{
  1018. type:'Brackets',
  1019. name:ele.name,
  1020. selected:false,
  1021. })
  1022. }else if(ele.type == 'Text'){
  1023. //输入值
  1024. this.selectEleFormula.push({
  1025. type:'Text',
  1026. name:ele.name,
  1027. selected:false,
  1028. })
  1029. }else if(ele.k){
  1030. //节点参数
  1031. this.selectEleFormula.push({
  1032. type:'ParamData',
  1033. name:ele.name,
  1034. selected:false,
  1035. id:ele.id,
  1036. v:ele.v,
  1037. k:ele.k,
  1038. children:[],
  1039. })
  1040. }
  1041. },
  1042. //添加括号
  1043. addBrackets(text,type){
  1044. //type 是true 表示在元素右边插入
  1045. if(this.curSeleEleIndex == Number(this.curSeleEleIndex)){
  1046. this.eleAddFormulaHandle({
  1047. type:'Brackets',
  1048. name:text,
  1049. selectIndex:type?Number(this.curSeleEleIndex)+1:this.curSeleEleIndex
  1050. })
  1051. //如果在左边插入index要增1
  1052. if(!type){
  1053. this.curSeleEleIndex = Number(this.curSeleEleIndex)+1;
  1054. }
  1055. }
  1056. },
  1057. addText(){
  1058. this.inputVisible = true;
  1059. },
  1060. //添加输入值
  1061. addTextHandle(){
  1062. //简单语法判断
  1063. if(this.selectEleFormula.length != 0){
  1064. let lastEle = this.selectEleFormula[this.selectEleFormula.length-1];
  1065. if(lastEle.type == 'Element'){
  1066. this.$message({
  1067. type: "warning",
  1068. message: "输入值无法连续出现在元素后面"
  1069. });
  1070. return;
  1071. }
  1072. if(lastEle.type == 'Text'){
  1073. this.$message({
  1074. type: "warning",
  1075. message: "输入值无法连续出现在输入值后面"
  1076. });
  1077. return;
  1078. }
  1079. if(lastEle.type == 'Brackets' && lastEle.name == ')'){
  1080. this.$message({
  1081. type: "warning",
  1082. message: "输入值无法连续出现在右括号后面"
  1083. });
  1084. return;
  1085. }
  1086. }
  1087. this.eleAddFormulaHandle({
  1088. type:'Text',
  1089. name:this.inputText
  1090. })
  1091. this.inputVisible = false;
  1092. },
  1093. //勾选元素
  1094. eleCheckHandle(checked,item){
  1095. if(checked){
  1096. this.eleList.forEach((ele)=>{
  1097. this.$set(ele,'checked',false);
  1098. //ele.checked = false;
  1099. })
  1100. item.checked = true;
  1101. }
  1102. },
  1103. //点选公式中的元素
  1104. eleFormulaClick({selected,item},index){
  1105. if(selected){
  1106. this.selectEleFormula.forEach((ele)=>{
  1107. ele.selected = false;
  1108. })
  1109. item.selected = true;
  1110. this.curSeleEleIndex = index;
  1111. }else{
  1112. this.curSeleEleIndex = -1;
  1113. }
  1114. },
  1115. //取消勾选
  1116. unCheckEleFormulac(eleId){
  1117. for (let i = 0; i < this.eleList.length; i++) {
  1118. if(this.eleList[i].id == eleId){
  1119. this.eleList[i].checked = false;
  1120. }
  1121. }
  1122. },
  1123. //删除点选公式中的元素
  1124. removeSelect(){
  1125. if(this.curSeleEleIndex > -1 && this.curSeleEleIndex <= this.selectEleFormula.length-1){
  1126. if(this.selectEleFormula[this.curSeleEleIndex].type == 'Element'){
  1127. //删除元素的位置,如果下次添加元素,先加到这个位置
  1128. this.deleEleIndex = this.curSeleEleIndex;
  1129. this.unCheckEleFormulac(this.selectEleFormula[this.curSeleEleIndex].id)
  1130. }
  1131. this.selectEleFormula.splice(this.curSeleEleIndex,1);
  1132. //this.curSeleEleIndex = -1;
  1133. }
  1134. },
  1135. //赋值给等号右边的数组
  1136. operationHandle(){
  1137. //检测左右括号数量是否相等
  1138. let lBracketNum = 0;
  1139. let rBracketNum = 0;
  1140. this.selectEleFormula.forEach((ele)=>{
  1141. if(ele.type == 'Brackets'){
  1142. if(ele.name == '('){
  1143. lBracketNum++;
  1144. }else if(ele.name == ')'){
  1145. rBracketNum++;
  1146. }
  1147. }
  1148. })
  1149. if(lBracketNum != rBracketNum){
  1150. this.$message({
  1151. type: "warning",
  1152. message: "左右括号数量不相等,请先检查是否正确"
  1153. });
  1154. return;
  1155. }
  1156. this.processFormula = JSON.parse(JSON.stringify(this.selectEleFormula));
  1157. this.operationVisible = false;
  1158. this.allTreeShow=false;
  1159. this.filterText=''
  1160. },
  1161. canceloperationVisible(){
  1162. this.operationVisible=false;
  1163. this.allTreeShow=false;
  1164. this.filterText=''
  1165. this.treeId=''
  1166. this.itemList=[];
  1167. this.eleList.forEach((ele)=>{
  1168. this.$set(ele,'checked',false);
  1169. //ele.checked = false;
  1170. })
  1171. console.log('取消');
  1172. },
  1173. //点选等式中的元素
  1174. equationClick({selected,item},index,arrName){
  1175. if(selected){
  1176. this.resultFormula.forEach((ele)=>{
  1177. ele.selected = false;
  1178. })
  1179. this.processFormula.forEach((ele)=>{
  1180. ele.selected = false;
  1181. })
  1182. this.processSelectIndex = index;
  1183. this.processType = arrName;
  1184. item.selected = true;
  1185. if(this.showFunDetail){
  1186. //切到第一个
  1187. this.actiFunIndex = '0';
  1188. }
  1189. }else{
  1190. this.processType = '';
  1191. }
  1192. },
  1193. //获取当前元素的表名
  1194. getItemTableName(item){
  1195. if(item.type==="Element"){
  1196. this.rightDict.forEach((ele)=>{
  1197. if(ele.ekey===item.tableElementKey){
  1198. item.tableName= ele.tableName
  1199. }
  1200. })
  1201. }
  1202. },
  1203. //在等式模式下点选计算式
  1204. equationSelect(index,indexPath){
  1205. if(!this.equationSelectEle ||(this.equationSelectEle && !(this.equationSelectEle.type == 'Element' || this.equationSelectEle.type == 'ParamData')) ){
  1206. this.$message({
  1207. type: "warning",
  1208. message: "请先选中元素"
  1209. });
  1210. return;
  1211. }
  1212. let formulaindex = Number(indexPath[1].split('-')[1])-1;
  1213. let expression = this.formulaList[indexPath[0]][formulaindex];
  1214. if(expression.type ==1){
  1215. return;
  1216. }
  1217. //alert(JSON.stringify(expression.template))
  1218. //debugger
  1219. let obj = Object.assign({}, expression);
  1220. //obj.template = JSON.parse(obj.template);
  1221. obj.arguments = new Array(obj.template.args.length);
  1222. let ele = {};
  1223. if(this.equationSelectEle.type == 'ParamData'){
  1224. ele = {
  1225. type:'ParamData',
  1226. name:this.equationSelectEle.name,
  1227. id:this.equationSelectEle.id,
  1228. selected:false,
  1229. v:this.equationSelectEle.v,
  1230. k:this.equationSelectEle.k,
  1231. }
  1232. }else{
  1233. ele = {
  1234. id:this.equationSelectEle.id,
  1235. name:this.equationSelectEle.name,
  1236. selected:false,
  1237. tableElementKey:this.equationSelectEle.tableElementKey,
  1238. type:"Element",
  1239. };
  1240. }
  1241. let tg=obj.template.args.findIndex(x=>x.m!=='常量');
  1242. obj.arguments[tg] = ele;
  1243. this.equationSelectEle.children.push(obj);
  1244. //跳转到最新的标签
  1245. this.actiFunIndex = (this.equationSelectEle.children.length-1).toString();
  1246. },
  1247. //选择元素
  1248. chooseEleHandle(){
  1249. for (let i = 0; i < this.eleList.length; i++) {
  1250. if (this.eleList[i].checked) {
  1251. let ele = this.eleList[i];
  1252. let obj = {};
  1253. if(ele.k){
  1254. obj = {
  1255. type:'ParamData',
  1256. name:ele.name,
  1257. id:ele.id,
  1258. selected:false,
  1259. v:ele.v,
  1260. k:ele.k,
  1261. children:[],
  1262. }
  1263. }else{
  1264. obj = {
  1265. type:'Element',
  1266. name:ele.eName,
  1267. id:ele.id,
  1268. selected:false,
  1269. tableElementKey:ele.tableElementKey,
  1270. children:[],
  1271. }
  1272. }
  1273. this.$set(this.argumenObj.arguments,this.argumenObj.index,obj);
  1274. this.chooseEleVisible = false;
  1275. break;
  1276. }
  1277. }
  1278. },
  1279. //显示选择元素弹窗
  1280. showChooseEle(argumenObj){
  1281. this.argumenObj = argumenObj;
  1282. this.chooseEleVisible = true;
  1283. // this.eleList=[];
  1284. // this.eleTableList=[];
  1285. this.eleTableId='';
  1286. this.allTreeShow=false;
  1287. this.filterText=''
  1288. this.eleList.forEach((ele)=>{
  1289. this.$set(ele,'checked',false);
  1290. //ele.checked = false;
  1291. })
  1292. // this.treeId=''
  1293. },
  1294. //移除挂载的函数
  1295. removeFun(name){
  1296. //console.log(name)
  1297. this.equationSelectEle.children.splice(Number(name), 1);
  1298. },
  1299. //切换公式tab标签
  1300. funLeave(activeName, oldActiveName){
  1301. if(oldActiveName){
  1302. let formula = this.equationSelectEle.children[Number(oldActiveName)];
  1303. if(formula){
  1304. return this.checkFormulaLegal(formula);
  1305. }
  1306. }
  1307. },
  1308. //检测公式合法
  1309. checkFormulaLegal(formula){
  1310. if(!formula.arguments){
  1311. return false;
  1312. }
  1313. //当前选中的元素
  1314. let curEle = this.equationSelectEle;
  1315. let isIn = false;
  1316. for (let i = 0; i < formula.arguments.length; i++) {
  1317. if(Array.isArray(formula.arguments[i])){
  1318. for(let j=0;j<formula.arguments[i].length;j++){
  1319. if(formula.arguments[i][j] && formula.arguments[i][j].id ==curEle.id){
  1320. isIn = true;
  1321. break;
  1322. }
  1323. }
  1324. if(isIn){
  1325. break;
  1326. }
  1327. }else if(formula.arguments[i] && formula.arguments[i].id ==curEle.id){
  1328. isIn = true;
  1329. break;
  1330. }
  1331. }
  1332. if(!isIn){
  1333. this.$message({
  1334. type: "warning",
  1335. message: "参数必须有一个值是当前元素"
  1336. });
  1337. return false;
  1338. }
  1339. return true;
  1340. },
  1341. //保存公式
  1342. saveFormula(){
  1343. console.log('保存1',this.pid);
  1344. let obj = formulaArrayToString(this.processFormula,this.resultFormula);
  1345. let deviationRangeText = rangeToString(this.deviationRange.datas,obj.eleMap);
  1346. obj.eleMap.deviationRangeJson = JSON.stringify(this.deviationRange.datas);
  1347. //console.log(obj.eleMap)
  1348. //return;
  1349. //特殊公式会有number
  1350. let number = '';
  1351. for (let i = 0; i < this.processFormula.length; i++) {
  1352. if(this.processFormula[i].children){
  1353. for (let j = 0; j < this.processFormula[i].children.length; j++) {
  1354. if(this.processFormula[i].children[j].number){
  1355. number = this.processFormula[i].children[j].number;
  1356. break;
  1357. }
  1358. }
  1359. }
  1360. if(number){
  1361. break;
  1362. }
  1363. }
  1364. if(number === ''){
  1365. for (let i = 0; i < this.resultFormula.length; i++) {
  1366. if(this.resultFormula[i].children){
  1367. for (let j = 0; j < this.resultFormula[i].children.length; j++) {
  1368. if(this.resultFormula[i].children[j].number){
  1369. number = this.resultFormula[i].children[j].number;
  1370. break;
  1371. }
  1372. }
  1373. }
  1374. if(number){
  1375. break;
  1376. }
  1377. }
  1378. }
  1379. //console.log(obj)
  1380. //console.log(text);
  1381. if(this.formulaid){
  1382. updateFormula({
  1383. id:this.formulaid,
  1384. formula:obj.text,
  1385. remark:'',
  1386. nodeId:this.nodeid,
  1387. elementId:this.eleid,
  1388. scale:this.isRetain?this.retainNum:'',
  1389. number:number,
  1390. map:JSON.stringify(obj.eleMap),
  1391. scope:this.globaltype,
  1392. // projectId:this.curProjiect.id||this.projectId,
  1393. projectId:this.curProjiect.id||this.pid,
  1394. dev:deviationRangeText
  1395. }).then(()=>{
  1396. this.formulaStringToArray();
  1397. this.$message({
  1398. type: "success",
  1399. message: "修改成功"
  1400. });
  1401. })
  1402. }else{
  1403. saveFormula({
  1404. formula:obj.text,
  1405. remark:'',
  1406. nodeId:this.nodeid,
  1407. elementId:this.eleid,
  1408. scale:this.isRetain?this.retainNum:'',
  1409. number:number,
  1410. map:JSON.stringify(obj.eleMap),
  1411. scope:this.globaltype,
  1412. // projectId:this.curProjiect.id||this.projectId,
  1413. projectId:this.curProjiect.id||this.pid,
  1414. dev:deviationRangeText,
  1415. ver:this.version
  1416. }).then((res)=>{
  1417. if(res.data.data){
  1418. this.formulaid = res.data.data;
  1419. }
  1420. this.formulaStringToArray();
  1421. this.$message({
  1422. type: "success",
  1423. message: "保存成功"
  1424. });
  1425. })
  1426. }
  1427. },
  1428. //把公式文本还原数组
  1429. async formulaStringToArray(){
  1430. let detail = (await formulaDetail({elementId:this.eleid,scope:this.globaltype,nodeId:this.nodeid,projectId:this.curProjiect.id||this.pid})).data.data;
  1431. console.log(detail);
  1432. if(detail&&detail.id){
  1433. //获取右边元素的字典
  1434. let dictMap=detail.dict
  1435. let dictArr=[]
  1436. //遍历:
  1437. for(let i in dictMap){
  1438. dictArr.push(dictMap[i])
  1439. }
  1440. this.rightDict=dictArr
  1441. this.formulaid = detail.id;
  1442. //let formula = formulaStringToArray('FC.sum(FC.repeat(E[测试测试_222]))+FC.ifelse(3<E[测试测试_333]&&E[测试测试_333]<10,E[测试测试_222]+E[测试测试_333],E[测试测试_333])',detail.map,this.formulaMap);
  1443. let formula = formulaStringToArray(detail.formula,detail.map,this.formulaMap);
  1444. this.processFormula = formula.processFormula;
  1445. formula.resultFormula[0].id = this.resultFormula[0].id;
  1446. formula.resultFormula[0].name = this.resultFormula[0].name;
  1447. formula.resultFormula[0].tableElementKey = this.resultFormula[0].tableElementKey;
  1448. this.resultFormula[0].children = formula.resultFormula[0].children;
  1449. //允许偏差值范围
  1450. let mapObj = JSON.parse(detail.map);
  1451. if(mapObj.deviationRangeJson){
  1452. this.deviationRange.datas = JSON.parse(mapObj.deviationRangeJson);
  1453. }
  1454. }
  1455. if(detail&&detail.scale > -1){
  1456. this.isRetain = true;
  1457. this.retainNum = detail.scale;
  1458. }
  1459. },
  1460. //设置动态组件里面的元素
  1461. setComponentEle(value,item,index){
  1462. if(value){
  1463. //console.log(this.$refs.dynamiccomponent[index])
  1464. this.$refs.dynamiccomponent[index].setELe(item);
  1465. }
  1466. },
  1467. //设置动态组件里面的元素
  1468. setDeviationRangeEle(value,item){
  1469. if(value){
  1470. //console.log(this.$refs.dynamiccomponent[index])
  1471. this.$refs.deviationrange.setELe(item);
  1472. }
  1473. },
  1474. async tabTypeLazyTreeAll ( parentId,current,size,titleName) {//清表树
  1475. console.log(parentId);
  1476. const { data: res } = await tabTypeLazyTreeAll({parentId,current,size,titleName} )
  1477. if (res.code === 200) {
  1478. return res.data
  1479. }
  1480. },
  1481. getNodeDetail(data,node){
  1482. console.log(data,node,'getNodeDetail');
  1483. this.curNode=node;
  1484. this.curData=data;
  1485. this.treeId=data.initTableId;
  1486. this.page.current=1;
  1487. this.page.currentPage=1;
  1488. this.input3=''
  1489. if(data.hasChildren===false||data.isLinkTable===2){
  1490. this.eleListable=true;
  1491. getTableElments(data.initTableId ).then((res)=>{
  1492. if(res.data.code==200){
  1493. this.eleList=res.data.data;
  1494. this.eleTableList =res.data.data;
  1495. this.eleListable=false;
  1496. }
  1497. })
  1498. }
  1499. else{
  1500. this.eleListable=true;
  1501. this.eleList=[]
  1502. this.page.total=0
  1503. setTimeout(() => {
  1504. this.eleListable=false
  1505. }, 1000);
  1506. }
  1507. },
  1508. getEleDeatil(){
  1509. getEleDeatil(this.eleid).then((res)=>{
  1510. let ele = res.data.data;
  1511. this.resultFormula = [{
  1512. type:'Element',
  1513. name:ele.eName,
  1514. id:ele.id,
  1515. selected:false,
  1516. tableElementKey:ele.tableElementKey,
  1517. children:[],
  1518. }]
  1519. })
  1520. },
  1521. searchChange(){
  1522. this.eleListable=true;
  1523. getTableElments( this.treeId,this.inputele ).then((res)=>{
  1524. this.eleList=res.data.data;
  1525. this.eleListable=false;
  1526. })
  1527. },
  1528. searchChangepian(){
  1529. this.eleListComploading=true;
  1530. getTableElments( this.treeId,this.inputelepian ).then((res)=>{
  1531. this.eleListComp=res.data.data;
  1532. this.eleListComploading=false;
  1533. })
  1534. },
  1535. searchChangejudge(){
  1536. this.eleListjudge=true;
  1537. getTableElments( this.treeId,this.inputelejudge ).then((res)=>{
  1538. this.eleListComp=res.data.data;
  1539. this.eleListjudge=false;
  1540. })
  1541. },
  1542. clearinput(){
  1543. this.eleListable=true;
  1544. getTableElments( this.treeId ).then((res)=>{
  1545. this.eleList=res.data.data;
  1546. this.eleListable=false;
  1547. })
  1548. },
  1549. clearinputpian(){
  1550. // eleListComp
  1551. this.eleListComploading=true;
  1552. getTableElments( this.treeId ).then((res)=>{
  1553. this.eleListComp=res.data.data;
  1554. this.eleListComploading=false
  1555. })
  1556. },
  1557. clearinputjudge(){
  1558. this.eleListjudge=true;
  1559. getTableElments( this.treeId ).then((res)=>{
  1560. this.eleListComp=res.data.data;
  1561. })
  1562. this.eleListjudge=false;
  1563. },
  1564. getNodeDetailComp(data,node) {
  1565. this.treeId=data.initTableId;
  1566. this.curNode=node;
  1567. this.curData=data;
  1568. this.input3=''
  1569. if(data.hasChildren===false){
  1570. getTableElments(data.initTableId ).then((res)=>{
  1571. if(res.data.code==200){
  1572. if(res.data.data.length){
  1573. this.eleListComp=res.data.data;
  1574. this.eleTableListComp =res.data.data;
  1575. console.log( this.eleTableListComp,' this.eleTableListComp');
  1576. this.eleTableIdComp = this.eleTableListComp[0].id;
  1577. }
  1578. }
  1579. })
  1580. }
  1581. else{
  1582. this.eleListComp=[]
  1583. this.page.total=0
  1584. }
  1585. },
  1586. //取消方法下面 元素勾选
  1587. unCheckEleComp(eleId){
  1588. //console.log(eleId)
  1589. for (let i = 0; i < this.eleListComp.length; i++) {
  1590. if(this.eleListComp[i].id == eleId){
  1591. this.eleListComp[i].checked = false;
  1592. }
  1593. }
  1594. },
  1595. //手写模式
  1596. handwrit(){
  1597. try {
  1598. let obj = formulaArrayToString(this.processFormula,this.resultFormula);
  1599. this.handwritText = obj.text;
  1600. this.handwritEleMap = JSON.stringify(obj.eleMap);
  1601. this.handwritVisible = true;
  1602. } catch (error) {
  1603. console.error(error)
  1604. this.$message({
  1605. type: "error",
  1606. message: "生成公式文本失败,"+error
  1607. });
  1608. }
  1609. },
  1610. //转成配置用的数组
  1611. handwritTransform(){
  1612. try {
  1613. let formula = formulaStringToArray(this.handwritText,this.handwritEleMap,this.formulaMap);
  1614. this.processFormula = formula.processFormula;
  1615. formula.resultFormula[0].id = this.resultFormula[0].id;
  1616. formula.resultFormula[0].name = this.resultFormula[0].name;
  1617. formula.resultFormula[0].tableElementKey = this.resultFormula[0].tableElementKey;
  1618. this.resultFormula[0].children = formula.resultFormula[0].children;
  1619. this.handwritVisible = false;
  1620. } catch (error) {
  1621. console.error(error)
  1622. this.$message({
  1623. type: "error",
  1624. message: "转成配置用的数组失败,"+error
  1625. });
  1626. }
  1627. },
  1628. editorInit: function (editor) {
  1629. console.log('editorInit')
  1630. require('brace/ext/searchbox') //添加搜索功能
  1631. require('brace/ext/language_tools') //language extension prerequsite...
  1632. require('brace/mode/javascript') //language
  1633. require('brace/theme/github')
  1634. require('brace/snippets/javascript') //snippet
  1635. editor.session.setUseWrapMode(true);//切换自动换行
  1636. editor.setHighlightActiveLine(false);//设置行高亮显示
  1637. editor.setShowPrintMargin(false);
  1638. editor.setOptions({
  1639. enableLiveAutocompletion:true,//语法提示和补全
  1640. showInvisibles:true,//显示隐藏,空格,回车等
  1641. fontSize:'16px'
  1642. })
  1643. },
  1644. getTypeMap(){
  1645. return new Promise((resolve)=>{
  1646. getTypeMap().then((res)=>{
  1647. //console.log(res)
  1648. this.formulaList = res.data.data;
  1649. //生成map,方便查找
  1650. for (let key in this.formulaList) {
  1651. if(typeof(this.formulaList[key]) == 'object'){
  1652. this.formulaList[key].forEach((formula)=>{
  1653. formula.template = JSON.parse(formula.template);
  1654. if(this.operatorReg.test(formula.template.ft)){
  1655. this.formulaMap[formula.template.ft] = formula;
  1656. }else if(this.startFCRegExp.test(formula.template.ft)){
  1657. let regRes = formula.template.ft.match(this.startFCRegExp);
  1658. this.formulaMap[regRes[0]] = formula;
  1659. }
  1660. })
  1661. }
  1662. }
  1663. }).finally(() => {
  1664. resolve();
  1665. })
  1666. })
  1667. }
  1668. },
  1669. };
  1670. </script>
  1671. <style scoped lang="scss">
  1672. .box-dashed {
  1673. border: 1px dashed #bbbbbb;
  1674. border-radius: 6px;
  1675. padding: 10px;
  1676. margin-bottom: 10px;
  1677. }
  1678. .retain-box {
  1679. border-right: 1px dashed #bbbbbb;
  1680. }
  1681. .retain {
  1682. line-height: 50px;
  1683. margin-right: 10px;
  1684. }
  1685. .edit-text {
  1686. font-size: 26px;
  1687. margin-left: 20px;
  1688. }
  1689. .el-menu--popup .el-menu-item.is-active {
  1690. background-color: #fff;
  1691. }
  1692. .ele-box{
  1693. //border: 1px solid #bbb;
  1694. //height: 26px;
  1695. display: flex;
  1696. justify-content: space-between;
  1697. align-items: center;
  1698. padding: 6px;
  1699. height: 100%;
  1700. box-sizing: border-box;
  1701. overflow: hidden;
  1702. }
  1703. .no-mb-col .el-col{
  1704. margin-bottom: 0px;
  1705. border: 1px solid #bbb;
  1706. height: 100px;
  1707. }
  1708. .sele-ele-box{
  1709. height: 160px;
  1710. padding: 20px;
  1711. overflow-y: auto;
  1712. // margin-top: 10px;
  1713. }
  1714. .icon-box .el-link{
  1715. font-size: 24px;
  1716. margin-right: 10px;
  1717. }
  1718. </style>
  1719. <style lang="scss">
  1720. .basic-container.h-basic-full {
  1721. height: calc(100% - 30px);
  1722. overflow: auto;
  1723. .el-card, .el-card .el-card__body {
  1724. height: 100%;
  1725. }
  1726. }
  1727. .el-select-dropdown{
  1728. max-width:600px ;
  1729. }
  1730. //.el-select-dropdown__item{
  1731. // display: inline-block;
  1732. //}
  1733. .el-select-dropdown__item span {
  1734. // min-width: 300px;
  1735. display: inline-block;
  1736. }
  1737. </style>