edit1.vue 59 KB

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