edit1.vue 62 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887
  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\d]+)\(/,// 匹配开始的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. debugger
  1176. if(selected){
  1177. this.resultFormula.forEach((ele)=>{
  1178. ele.selected = false;
  1179. })
  1180. this.processFormula.forEach((ele)=>{
  1181. ele.selected = false;
  1182. })
  1183. this.processSelectIndex = index;
  1184. this.processType = arrName;
  1185. item.selected = true;
  1186. if(this.showFunDetail){
  1187. //切到第一个
  1188. this.actiFunIndex = '0';
  1189. }
  1190. }else{
  1191. this.processType = '';
  1192. }
  1193. },
  1194. //获取当前元素的表名
  1195. getItemTableName(item){
  1196. if(item.type==="Element"){
  1197. this.rightDict.forEach((ele)=>{
  1198. if(ele.ekey===item.tableElementKey){
  1199. item.tableName= ele.tableName
  1200. }
  1201. })
  1202. }
  1203. },
  1204. //在等式模式下点选计算式
  1205. equationSelect(index,indexPath){
  1206. debugger
  1207. if(!this.equationSelectEle ||(this.equationSelectEle && !(this.equationSelectEle.type == 'Element' || this.equationSelectEle.type == 'ParamData')) ){
  1208. this.$message({
  1209. type: "warning",
  1210. message: "请先选中元素"
  1211. });
  1212. return;
  1213. }
  1214. let formulaindex = Number(indexPath[1].split('-')[1])-1;
  1215. let expression = this.formulaList[indexPath[0]][formulaindex];
  1216. if(expression.type ==1){
  1217. return;
  1218. }
  1219. //alert(JSON.stringify(expression.template))
  1220. //debugger
  1221. let obj = Object.assign({}, expression);
  1222. //obj.template = JSON.parse(obj.template);
  1223. obj.arguments = new Array(obj.template.args.length);
  1224. let ele = {};
  1225. if(this.equationSelectEle.type == 'ParamData'){
  1226. ele = {
  1227. type:'ParamData',
  1228. name:this.equationSelectEle.name,
  1229. id:this.equationSelectEle.id,
  1230. selected:false,
  1231. v:this.equationSelectEle.v,
  1232. k:this.equationSelectEle.k,
  1233. }
  1234. }else{
  1235. ele = {
  1236. id:this.equationSelectEle.id,
  1237. name:this.equationSelectEle.name,
  1238. selected:false,
  1239. tableElementKey:this.equationSelectEle.tableElementKey,
  1240. type:"Element",
  1241. };
  1242. }
  1243. let tg=obj.template.args.findIndex(x=>x.m!=='常量');
  1244. obj.arguments[tg] = ele;
  1245. this.equationSelectEle.children.push(obj);
  1246. //跳转到最新的标签
  1247. this.actiFunIndex = (this.equationSelectEle.children.length-1).toString();
  1248. },
  1249. //选择元素
  1250. chooseEleHandle(){
  1251. for (let i = 0; i < this.eleList.length; i++) {
  1252. if (this.eleList[i].checked) {
  1253. let ele = this.eleList[i];
  1254. let obj = {};
  1255. if(ele.k){
  1256. obj = {
  1257. type:'ParamData',
  1258. name:ele.name,
  1259. id:ele.id,
  1260. selected:false,
  1261. v:ele.v,
  1262. k:ele.k,
  1263. children:[],
  1264. }
  1265. }else{
  1266. obj = {
  1267. type:'Element',
  1268. name:ele.eName,
  1269. id:ele.id,
  1270. selected:false,
  1271. tableElementKey:ele.tableElementKey,
  1272. children:[],
  1273. }
  1274. }
  1275. this.$set(this.argumenObj.arguments,this.argumenObj.index,obj);
  1276. this.chooseEleVisible = false;
  1277. break;
  1278. }
  1279. }
  1280. },
  1281. //显示选择元素弹窗
  1282. showChooseEle(argumenObj){
  1283. this.argumenObj = argumenObj;
  1284. this.chooseEleVisible = true;
  1285. // this.eleList=[];
  1286. // this.eleTableList=[];
  1287. this.eleTableId='';
  1288. this.allTreeShow=false;
  1289. this.filterText=''
  1290. this.eleList.forEach((ele)=>{
  1291. this.$set(ele,'checked',false);
  1292. //ele.checked = false;
  1293. })
  1294. // this.treeId=''
  1295. },
  1296. //移除挂载的函数
  1297. removeFun(name){
  1298. //console.log(name)
  1299. this.equationSelectEle.children.splice(Number(name), 1);
  1300. },
  1301. //切换公式tab标签
  1302. funLeave(activeName, oldActiveName){
  1303. if(oldActiveName){
  1304. let formula = this.equationSelectEle.children[Number(oldActiveName)];
  1305. if(formula){
  1306. return this.checkFormulaLegal(formula);
  1307. }
  1308. }
  1309. },
  1310. //检测公式合法
  1311. checkFormulaLegal(formula){
  1312. if(!formula.arguments){
  1313. return false;
  1314. }
  1315. //当前选中的元素
  1316. let curEle = this.equationSelectEle;
  1317. let isIn = false;
  1318. for (let i = 0; i < formula.arguments.length; i++) {
  1319. if(Array.isArray(formula.arguments[i])){
  1320. for(let j=0;j<formula.arguments[i].length;j++){
  1321. if(formula.arguments[i][j] && formula.arguments[i][j].id ==curEle.id){
  1322. isIn = true;
  1323. break;
  1324. }
  1325. }
  1326. if(isIn){
  1327. break;
  1328. }
  1329. }else if(formula.arguments[i] && formula.arguments[i].id ==curEle.id){
  1330. isIn = true;
  1331. break;
  1332. }
  1333. }
  1334. if(!isIn){
  1335. this.$message({
  1336. type: "warning",
  1337. message: "参数必须有一个值是当前元素"
  1338. });
  1339. return false;
  1340. }
  1341. return true;
  1342. },
  1343. //保存公式
  1344. saveFormula(){
  1345. console.log('保存1',this.pid);
  1346. let obj = formulaArrayToString(this.processFormula,this.resultFormula);
  1347. let deviationRangeText = rangeToString(this.deviationRange.datas,obj.eleMap);
  1348. obj.eleMap.deviationRangeJson = JSON.stringify(this.deviationRange.datas);
  1349. //console.log(obj.eleMap)
  1350. //return;
  1351. //特殊公式会有number
  1352. let number = '';
  1353. for (let i = 0; i < this.processFormula.length; i++) {
  1354. if(this.processFormula[i].children){
  1355. for (let j = 0; j < this.processFormula[i].children.length; j++) {
  1356. if(this.processFormula[i].children[j].number){
  1357. number = this.processFormula[i].children[j].number;
  1358. break;
  1359. }
  1360. }
  1361. }
  1362. if(number){
  1363. break;
  1364. }
  1365. }
  1366. if(number === ''){
  1367. for (let i = 0; i < this.resultFormula.length; i++) {
  1368. if(this.resultFormula[i].children){
  1369. for (let j = 0; j < this.resultFormula[i].children.length; j++) {
  1370. if(this.resultFormula[i].children[j].number){
  1371. number = this.resultFormula[i].children[j].number;
  1372. break;
  1373. }
  1374. }
  1375. }
  1376. if(number){
  1377. break;
  1378. }
  1379. }
  1380. }
  1381. //console.log(obj)
  1382. //console.log(text);
  1383. if(this.formulaid){
  1384. updateFormula({
  1385. id:this.formulaid,
  1386. formula:obj.text,
  1387. remark:'',
  1388. nodeId:this.nodeid,
  1389. elementId:this.eleid,
  1390. scale:this.isRetain?this.retainNum:'',
  1391. number:number,
  1392. map:JSON.stringify(obj.eleMap),
  1393. scope:this.globaltype,
  1394. // projectId:this.curProjiect.id||this.projectId,
  1395. projectId:this.curProjiect.id||this.pid,
  1396. dev:deviationRangeText
  1397. }).then(()=>{
  1398. this.formulaStringToArray();
  1399. this.$message({
  1400. type: "success",
  1401. message: "修改成功"
  1402. });
  1403. })
  1404. }else{
  1405. saveFormula({
  1406. formula:obj.text,
  1407. remark:'',
  1408. nodeId:this.nodeid,
  1409. elementId:this.eleid,
  1410. scale:this.isRetain?this.retainNum:'',
  1411. number:number,
  1412. map:JSON.stringify(obj.eleMap),
  1413. scope:this.globaltype,
  1414. // projectId:this.curProjiect.id||this.projectId,
  1415. projectId:this.curProjiect.id||this.pid,
  1416. dev:deviationRangeText,
  1417. ver:this.version
  1418. }).then((res)=>{
  1419. if(res.data.data){
  1420. this.formulaid = res.data.data;
  1421. }
  1422. this.formulaStringToArray();
  1423. this.$message({
  1424. type: "success",
  1425. message: "保存成功"
  1426. });
  1427. })
  1428. }
  1429. },
  1430. //把公式文本还原数组
  1431. async formulaStringToArray(){
  1432. let detail = (await formulaDetail({elementId:this.eleid,scope:this.globaltype,nodeId:this.nodeid,projectId:this.curProjiect.id||this.pid})).data.data;
  1433. console.log(detail);
  1434. if(detail&&detail.id){
  1435. //获取右边元素的字典
  1436. let dictMap=detail.dict
  1437. let dictArr=[]
  1438. //遍历:
  1439. for(let i in dictMap){
  1440. dictArr.push(dictMap[i])
  1441. }
  1442. this.rightDict=dictArr
  1443. this.formulaid = detail.id;
  1444. //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);
  1445. let formula = formulaStringToArray(detail.formula,detail.map,this.formulaMap);
  1446. this.processFormula = formula.processFormula;
  1447. formula.resultFormula[0].id = this.resultFormula[0].id;
  1448. formula.resultFormula[0].name = this.resultFormula[0].name;
  1449. formula.resultFormula[0].tableElementKey = this.resultFormula[0].tableElementKey;
  1450. this.resultFormula[0].children = formula.resultFormula[0].children;
  1451. //允许偏差值范围
  1452. let mapObj = JSON.parse(detail.map);
  1453. if(mapObj.deviationRangeJson){
  1454. this.deviationRange.datas = JSON.parse(mapObj.deviationRangeJson);
  1455. }
  1456. }
  1457. if(detail&&detail.scale > -1){
  1458. this.isRetain = true;
  1459. this.retainNum = detail.scale;
  1460. }
  1461. },
  1462. //设置动态组件里面的元素
  1463. setComponentEle(value,item,index){
  1464. if(value){
  1465. //console.log(this.$refs.dynamiccomponent[index])
  1466. this.$refs.dynamiccomponent[index].setELe(item);
  1467. }
  1468. },
  1469. //设置动态组件里面的元素
  1470. setDeviationRangeEle(value,item){
  1471. if(value){
  1472. //console.log(this.$refs.dynamiccomponent[index])
  1473. this.$refs.deviationrange.setELe(item);
  1474. }
  1475. },
  1476. async tabTypeLazyTreeAll ( parentId,current,size,titleName) {//清表树
  1477. console.log(parentId);
  1478. const { data: res } = await tabTypeLazyTreeAll({parentId,current,size,titleName} )
  1479. if (res.code === 200) {
  1480. return res.data
  1481. }
  1482. },
  1483. getNodeDetail(data,node){
  1484. console.log(data,node,'getNodeDetail');
  1485. this.curNode=node;
  1486. this.curData=data;
  1487. this.treeId=data.initTableId;
  1488. this.page.current=1;
  1489. this.page.currentPage=1;
  1490. this.input3=''
  1491. if(data.hasChildren===false||data.isLinkTable===2){
  1492. this.eleListable=true;
  1493. getTableElments(data.initTableId ).then((res)=>{
  1494. if(res.data.code==200){
  1495. this.eleList=res.data.data;
  1496. this.eleTableList =res.data.data;
  1497. this.eleListable=false;
  1498. }
  1499. })
  1500. }
  1501. else{
  1502. this.eleListable=true;
  1503. this.eleList=[]
  1504. this.page.total=0
  1505. setTimeout(() => {
  1506. this.eleListable=false
  1507. }, 1000);
  1508. }
  1509. },
  1510. getEleDeatil(){
  1511. getEleDeatil(this.eleid).then((res)=>{
  1512. let ele = res.data.data;
  1513. this.resultFormula = [{
  1514. type:'Element',
  1515. name:ele.eName,
  1516. id:ele.id,
  1517. selected:false,
  1518. tableElementKey:ele.tableElementKey,
  1519. children:[],
  1520. }]
  1521. })
  1522. },
  1523. searchChange(){
  1524. this.eleListable=true;
  1525. getTableElments( this.treeId,this.inputele ).then((res)=>{
  1526. this.eleList=res.data.data;
  1527. this.eleListable=false;
  1528. })
  1529. },
  1530. searchChangepian(){
  1531. this.eleListComploading=true;
  1532. getTableElments( this.treeId,this.inputelepian ).then((res)=>{
  1533. this.eleListComp=res.data.data;
  1534. this.eleListComploading=false;
  1535. })
  1536. },
  1537. searchChangejudge(){
  1538. this.eleListjudge=true;
  1539. getTableElments( this.treeId,this.inputelejudge ).then((res)=>{
  1540. this.eleListComp=res.data.data;
  1541. this.eleListjudge=false;
  1542. })
  1543. },
  1544. clearinput(){
  1545. this.eleListable=true;
  1546. getTableElments( this.treeId ).then((res)=>{
  1547. this.eleList=res.data.data;
  1548. this.eleListable=false;
  1549. })
  1550. },
  1551. clearinputpian(){
  1552. // eleListComp
  1553. this.eleListComploading=true;
  1554. getTableElments( this.treeId ).then((res)=>{
  1555. this.eleListComp=res.data.data;
  1556. this.eleListComploading=false
  1557. })
  1558. },
  1559. clearinputjudge(){
  1560. this.eleListjudge=true;
  1561. getTableElments( this.treeId ).then((res)=>{
  1562. this.eleListComp=res.data.data;
  1563. })
  1564. this.eleListjudge=false;
  1565. },
  1566. getNodeDetailComp(data,node) {
  1567. this.treeId=data.initTableId;
  1568. this.curNode=node;
  1569. this.curData=data;
  1570. this.input3=''
  1571. if(data.hasChildren===false){
  1572. getTableElments(data.initTableId ).then((res)=>{
  1573. if(res.data.code==200){
  1574. if(res.data.data.length){
  1575. this.eleListComp=res.data.data;
  1576. this.eleTableListComp =res.data.data;
  1577. console.log( this.eleTableListComp,' this.eleTableListComp');
  1578. this.eleTableIdComp = this.eleTableListComp[0].id;
  1579. }
  1580. }
  1581. })
  1582. }
  1583. else{
  1584. this.eleListComp=[]
  1585. this.page.total=0
  1586. }
  1587. },
  1588. //取消方法下面 元素勾选
  1589. unCheckEleComp(eleId){
  1590. //console.log(eleId)
  1591. for (let i = 0; i < this.eleListComp.length; i++) {
  1592. if(this.eleListComp[i].id == eleId){
  1593. this.eleListComp[i].checked = false;
  1594. }
  1595. }
  1596. },
  1597. //手写模式
  1598. handwrit(){
  1599. try {
  1600. let obj = formulaArrayToString(this.processFormula,this.resultFormula);
  1601. this.handwritText = obj.text;
  1602. this.handwritEleMap = JSON.stringify(obj.eleMap);
  1603. this.handwritVisible = true;
  1604. } catch (error) {
  1605. console.error(error)
  1606. this.$message({
  1607. type: "error",
  1608. message: "生成公式文本失败,"+error
  1609. });
  1610. }
  1611. },
  1612. //转成配置用的数组
  1613. handwritTransform(){
  1614. try {
  1615. let formula = formulaStringToArray(this.handwritText,this.handwritEleMap,this.formulaMap);
  1616. this.processFormula = formula.processFormula;
  1617. formula.resultFormula[0].id = this.resultFormula[0].id;
  1618. formula.resultFormula[0].name = this.resultFormula[0].name;
  1619. formula.resultFormula[0].tableElementKey = this.resultFormula[0].tableElementKey;
  1620. this.resultFormula[0].children = formula.resultFormula[0].children;
  1621. this.handwritVisible = false;
  1622. } catch (error) {
  1623. console.error(error)
  1624. this.$message({
  1625. type: "error",
  1626. message: "转成配置用的数组失败,"+error
  1627. });
  1628. }
  1629. },
  1630. editorInit: function (editor) {
  1631. console.log('editorInit')
  1632. require('brace/ext/searchbox') //添加搜索功能
  1633. require('brace/ext/language_tools') //language extension prerequsite...
  1634. require('brace/mode/javascript') //language
  1635. require('brace/theme/github')
  1636. require('brace/snippets/javascript') //snippet
  1637. editor.session.setUseWrapMode(true);//切换自动换行
  1638. editor.setHighlightActiveLine(false);//设置行高亮显示
  1639. editor.setShowPrintMargin(false);
  1640. editor.setOptions({
  1641. enableLiveAutocompletion:true,//语法提示和补全
  1642. showInvisibles:true,//显示隐藏,空格,回车等
  1643. fontSize:'16px'
  1644. })
  1645. },
  1646. getTypeMap(){
  1647. return new Promise((resolve)=>{
  1648. getTypeMap().then((res)=>{
  1649. //console.log(res)
  1650. this.formulaList = res.data.data;
  1651. //生成map,方便查找
  1652. for (let key in this.formulaList) {
  1653. if(typeof(this.formulaList[key]) == 'object'){
  1654. this.formulaList[key].forEach((formula)=>{
  1655. formula.template = JSON.parse(formula.template);
  1656. if(this.operatorReg.test(formula.template.ft)){
  1657. this.formulaMap[formula.template.ft] = formula;
  1658. }else if(this.startFCRegExp.test(formula.template.ft)){
  1659. let regRes = formula.template.ft.match(this.startFCRegExp);
  1660. this.formulaMap[regRes[0]] = formula;
  1661. }
  1662. })
  1663. }
  1664. }
  1665. }).finally(() => {
  1666. resolve();
  1667. })
  1668. })
  1669. }
  1670. },
  1671. };
  1672. </script>
  1673. <style scoped lang="scss">
  1674. .box-dashed {
  1675. border: 1px dashed #bbbbbb;
  1676. border-radius: 6px;
  1677. padding: 10px;
  1678. margin-bottom: 10px;
  1679. }
  1680. .retain-box {
  1681. border-right: 1px dashed #bbbbbb;
  1682. }
  1683. .retain {
  1684. line-height: 50px;
  1685. margin-right: 10px;
  1686. }
  1687. .edit-text {
  1688. font-size: 26px;
  1689. margin-left: 20px;
  1690. }
  1691. .el-menu--popup .el-menu-item.is-active {
  1692. background-color: #fff;
  1693. }
  1694. .ele-box{
  1695. //border: 1px solid #bbb;
  1696. //height: 26px;
  1697. display: flex;
  1698. justify-content: space-between;
  1699. align-items: center;
  1700. padding: 6px;
  1701. height: 100%;
  1702. box-sizing: border-box;
  1703. overflow: hidden;
  1704. }
  1705. .no-mb-col .el-col{
  1706. margin-bottom: 0px;
  1707. border: 1px solid #bbb;
  1708. height: 100px;
  1709. }
  1710. .sele-ele-box{
  1711. height: 160px;
  1712. padding: 20px;
  1713. overflow-y: auto;
  1714. // margin-top: 10px;
  1715. }
  1716. .icon-box .el-link{
  1717. font-size: 24px;
  1718. margin-right: 10px;
  1719. }
  1720. </style>
  1721. <style lang="scss">
  1722. .basic-container.h-basic-full {
  1723. height: calc(100% - 30px);
  1724. overflow: auto;
  1725. .el-card, .el-card .el-card__body {
  1726. height: 100%;
  1727. }
  1728. }
  1729. .el-select-dropdown{
  1730. max-width:600px ;
  1731. }
  1732. //.el-select-dropdown__item{
  1733. // display: inline-block;
  1734. //}
  1735. .el-select-dropdown__item span {
  1736. // min-width: 300px;
  1737. display: inline-block;
  1738. }
  1739. </style>