index.vue 42 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227
  1. <template>
  2. <div class="query-index" >
  3. <div v-if="showOverlay" style="position: fixed;top: 0;left: 0;width: 100vw;height: 100vh;background-color: rgba(0, 0, 0, 0.5);z-index: 999; "></div>
  4. <div class="query-index-tree" v-if="showTree" data-v-step="1"
  5. :style="showOverlay&&curStepVal==1?'z-index:1000;background:white;':''">
  6. <div class="query-index-tree-search">
  7. <a-tabs v-model:activeKey="activeTab" @change="tabChange" style="width:97%;">
  8. <a-tab-pane key="1" tab="组织架构目录" >
  9. </a-tab-pane>
  10. <a-tab-pane key="2" tab="地质单元目录" forceRender="true">
  11. </a-tab-pane>
  12. </a-tabs>
  13. <DoubleLeftOutlined @click="changeTree()"/>
  14. </div>
  15. <div style="margin-top: -15px">
  16. <a-input-search
  17. v-model:value="subjectTrees.searchStr"
  18. placeholder="查找目录..." allow-clear
  19. @search="searchTree"
  20. />
  21. </div>
  22. <div class="query-index-tree-box">
  23. <a-tree
  24. ref="treeRef"
  25. :show-line="true" blockNode="true"
  26. :tree-data="subjectTrees.data"
  27. v-model:expandedKeys="subjectTrees.expandedKeys"
  28. v-model:selectedKeys="subjectTrees.selectedKeys"
  29. :replace-fields="replaceFields"
  30. :autoExpandParent="subjectTrees.autoExpandParent"
  31. @expand="treeOnExpand" @select="treeOnSelect">
  32. <template #switcherIcon="{ switcherCls }">
  33. <caret-down-outlined style="font-size:20px;" :class="switcherCls"/>
  34. </template>
  35. <template #title="{ label,value,children }">
  36. <span v-if="label!=null&&label.indexOf(subjectTrees.searchStr) > -1">
  37. {{ label.substr(0, label.indexOf(subjectTrees.searchStr)) }}
  38. <span style="color: #f50">{{ subjectTrees.searchStr }}</span>
  39. {{ label.substr(label.indexOf(subjectTrees.searchStr) + subjectTrees.searchStr.length) }}
  40. </span>
  41. <span v-else>{{ label }}</span>
  42. </template>
  43. </a-tree>
  44. </div>
  45. </div>
  46. <div class="query-index-close" v-else>
  47. <DoubleRightOutlined @click="showTree=true;colspan=8;"/>
  48. </div>
  49. <v-tour name="wellInfoTour" style="z-index: 1000;" :steps="steps" :options="myOptions" :callbacks="myCallbacks"></v-tour>
  50. <div class="query-index-content" >
  51. <div class="query-index-form" >
  52. <a-form ref="formRef" name="fromQuery"
  53. class="ant-advanced-search-form"
  54. :label-col="labelCol"
  55. :model="formState">
  56. <a-row :gutter="24" class="query-index-row" >
  57. <a-col :span="6">
  58. <a-form-item name="well_common_name" label="井名:">
  59. <a-input id="wellName" v-model:value="formState.well_common_name"/>
  60. </a-form-item>
  61. </a-col>
  62. <a-col :span="6">
  63. <a-form-item name="well_type" label="井型:">
  64. <a-tree-select
  65. v-model:value="formState.well_type"
  66. show-search
  67. allow-clear
  68. tree-line
  69. :tree-data="wellTypeTree"
  70. tree-node-filter-prop="label">
  71. </a-tree-select>
  72. </a-form-item>
  73. </a-col>
  74. <a-col :span="6">
  75. <a-form-item name="well_type" label="井别:">
  76. <a-tree-select
  77. v-model:value="formState.well_purpose"
  78. show-search
  79. allow-clear
  80. tree-line
  81. :tree-data="wellPurposeTree"
  82. tree-node-filter-prop="label">
  83. </a-tree-select>
  84. </a-form-item>
  85. </a-col>
  86. <a-col :span="6" :style="showOverlay && curStepVal==2?'z-index:1000;background:white;display:inline-block;width:150px;height:32px;position:relative;':'display:inline-block;width:450px;height:32px;'">
  87. <MenuOutlined @click="changeQuery(true)" v-if="!showQuery" data-v-step="2" />
  88. <LineOutlined @click="changeQuery(false)" v-else/>
  89. <a-button type="primary" html-type="submit" @click="onQuery" style="margin-left: 10px;">查询</a-button>
  90. <a-button html-type="submit"
  91. @click="() => {resetFields();formState.ref_date=new Date(); onQuery()}"
  92. style="margin-left: 10px;">重置
  93. </a-button>
  94. <QuestionCircleOutlined title="查看帮助" @click="showHelp"
  95. :style="{fontSize: '20px',display:'contents',cursor:'pointer'}"/>
  96. </a-col>
  97. </a-row>
  98. <a-row :gutter="24" class="query-index-row" v-if="showQuery">
  99. <a-col :span="18">
  100. <a-form-item name="well_id" label="组织机构:">
  101. <a-tree-select
  102. v-model:value="formState.orgList"
  103. show-search
  104. allow-clear
  105. multiple
  106. tree-line
  107. :tree-data="filterOrgTree(subjectTrees.organizationTree)"
  108. tree-node-filter-prop="label"
  109. @change="onOrgTreeChange"
  110. >
  111. </a-tree-select>
  112. </a-form-item>
  113. </a-col>
  114. </a-row>
  115. <a-row :gutter="24" class="query-index-row" v-if="showQuery">
  116. <a-col :span="18">
  117. <a-form-item name="spud_date_begin" label="地质单元:">
  118. <a-tree-select
  119. v-model:value="formState.unitList"
  120. show-search
  121. allow-clear
  122. multiple
  123. tree-line
  124. :tree-data="filterUnitTree(subjectTrees.constructUnitTree)"
  125. tree-node-filter-prop="label" @change="onUnitTreeChange">
  126. </a-tree-select>
  127. </a-form-item>
  128. </a-col>
  129. </a-row>
  130. <a-row :gutter="24" class="query-index-row" v-if="showQuery">
  131. <a-col :span="6">
  132. <a-form-item name="spud_date_begin" label="开钻日期:">
  133. <a-range-picker :key="formState.ref_date" format="YYYY-MM-DD" :placeholder="['开始日期', '结束日期']"
  134. @change="(d)=>{onRangeChange(d,'spud_date_begin','spud_date_end')}"/>
  135. </a-form-item>
  136. </a-col>
  137. <a-col :span="6">
  138. <a-form-item name="completion_date_begin" label="完井日期:">
  139. <a-range-picker :key="formState.ref_date" format="YYYY-MM-DD" :placeholder="['开始日期', '结束日期']"
  140. @change="(d)=>{onRangeChange(d,'completion_date_begin','completion_date_end')}"/>
  141. </a-form-item>
  142. </a-col>
  143. <a-col :span="6">
  144. <a-form-item name="oil_prod_begin_date_begin" label="投产日期:">
  145. <a-range-picker :key="formState.ref_date" format="YYYY-MM-DD" :placeholder="['开始日期', '结束日期']"
  146. @change="(d)=>{onRangeChange(d,'oil_prod_begin_date_begin','oil_prod_begin_date_end')}"/>
  147. </a-form-item>
  148. </a-col>
  149. </a-row>
  150. <a-row class="edit-operation" style="width:450px;float:right;" data-v-step="3">
  151. <a-col :span="24" :style="showOverlay && curStepVal==3?'text-align: right;z-index:1000;background:white;':'text-align: right;'">
  152. <a-checkbox-group v-model:value="showColumnType" @change="onCheckboxChange">
  153. <a-row>
  154. <a-col :span="8">
  155. <a-checkbox value="oil">显示产油</a-checkbox>
  156. </a-col>
  157. <a-col :span="8">
  158. <a-checkbox value="gas">显示产气</a-checkbox>
  159. </a-col>
  160. <a-col :span="8">
  161. <a-checkbox value="water">显示产水</a-checkbox>
  162. </a-col>
  163. </a-row>
  164. </a-checkbox-group>
  165. <a-radio-group v-model:value="viewModel" style="text-align: left">
  166. <a-radio-button value="list">
  167. <UnorderedListOutlined/>
  168. 列表
  169. </a-radio-button>
  170. <a-radio-button value="card">
  171. <TableOutlined/>
  172. 卡片
  173. </a-radio-button>
  174. </a-radio-group>
  175. </a-col>
  176. </a-row>
  177. </a-form>
  178. </div>
  179. <div :style="showOverlay&&curStepVal==4?'flex-grow: 1;overflow: auto;height:auto;z-index:999;background:white;':'flex-grow: 1;overflow: auto;height:auto;'">
  180. <a-spin :spinning="loading">
  181. <div class="query-index-table" data-v-step="4" v-if="viewModel=='list'" >
  182. <a-table :columns="filterColumns" :data-source="data" :scroll="{ x:'100%', y: '100%' }"
  183. :row-key="record=>record.tempId" :pagination="false" @resizeColumn="handleResizeColumn"
  184. bordered>
  185. <template #bodyCell="{ column,record }">
  186. <template v-if="column.dataIndex === 'oil'">
  187. <div style="height:25px">
  188. <ChartCell :timeType="('month')" :dataType="('oil')" :wellId="record.well_id"></ChartCell>
  189. </div>
  190. </template>
  191. <template v-if="column.dataIndex === 'gas'">
  192. <div style="height:25px">
  193. <ChartCell :timeType="('month')" :dataType="('gas')" :wellId="record.well_id"></ChartCell>
  194. </div>
  195. </template>
  196. <template v-if="column.dataIndex === 'water'">
  197. <div style="height:25px">
  198. <ChartCell :timeType="('month')" :dataType="('vol')" :wellId="record.well_id"></ChartCell>
  199. </div>
  200. </template>
  201. <template v-if="column.key === 'well_common_name'">
  202. <a-button type="link" size="small" @click="detail(record.well_id)">{{
  203. record.well_common_name
  204. }}
  205. </a-button>
  206. </template>
  207. <template v-if="column.key === 'operation'">
  208. <a-button type="link" size="small" @click="showDoc(record.well_id)">相关文档</a-button>
  209. </template>
  210. </template>
  211. </a-table>
  212. </div>
  213. <div class="query-index-table" v-else >
  214. <a-row :gutter="[24,8]">
  215. <a-col :span="colspan" v-for="item in data">
  216. <a-card :title="'井名:'+item.well_common_name" class="ant-card-index" bodyStyle="padding: 10px;">
  217. <template #extra>
  218. <a-button type="link" @click="detail(item.well_id)">查看详情</a-button>
  219. <a-button type="link" @click="showDoc(item.well_id)">相关文档</a-button>
  220. </template>
  221. <table class="well-card-table">
  222. <tr>
  223. <th>井型:</th>
  224. <td>{{ item.well_type }}</td>
  225. <th>状态:</th>
  226. <td name="current_state_name">{{ item.current_state_name }}</td>
  227. </tr>
  228. <tr>
  229. <th>开钻日期:</th>
  230. <td name="spud_date">{{ item.spud_date }}</td>
  231. <th>含水率:</th>
  232. <td name="water_cut">
  233. <span style="padding:2px 10px;" :class="getTdColor(item.water_cut)">{{
  234. item.water_cut
  235. }}</span>
  236. </td>
  237. </tr>
  238. <tr>
  239. <th>开始采油日期:</th>
  240. <td name="oil_prod_begin_date">{{ item.oil_prod_begin_date }}</td>
  241. <th>最近采油日期:</th>
  242. <td name="oil_prod_recent_date">{{ item.oil_prod_recent_date }}</td>
  243. </tr>
  244. <tr v-if="showColumnType.includes('oil')">
  245. <th>最近月产油量:</th>
  246. <td name="oil_prod_mon">
  247. {{ item.oil_prod_mon == null ? "" : (numberToCurrencyNo(item.oil_prod_mon) + "t") }}
  248. </td>
  249. <td colspan="2" rowspan="2">
  250. <div style="height:25px">
  251. <ChartCell :timeType="('month')" :dataType="('oil')" :wellId="item.well_id"
  252. :lineColor="('#E63038')"></ChartCell>
  253. </div>
  254. </td>
  255. </tr>
  256. <tr v-if="showColumnType.includes('oil')">
  257. <th>累产油量:</th>
  258. <td name="oil_prod_year">
  259. {{ item.oil_prod_year == null ? "" : (numberToCurrencyNo(item.oil_prod_year) + "t") }}
  260. </td>
  261. </tr>
  262. <tr v-if="showColumnType.includes('gas')">
  263. <th>最近月产气量:</th>
  264. <td name="gas_prod_mon">
  265. {{ item.gas_prod_mon == null ? "" : (numberToCurrencyNo(item.gas_prod_mon) + "m³") }}
  266. </td>
  267. <td colspan="2" rowspan="2">
  268. <div style="height:25px">
  269. <ChartCell :timeType="('month')" :dataType="('gas')" :wellId="item.well_id"></ChartCell>
  270. </div>
  271. </td>
  272. </tr>
  273. <tr v-if="showColumnType.includes('gas')">
  274. <th>累产气量:</th>
  275. <td name="gas_prod_year">
  276. {{ item.gas_prod_year == null ? "" : (numberToCurrencyNo(item.gas_prod_year) + "m³") }}
  277. </td>
  278. </tr>
  279. <tr v-if="showColumnType.includes('water')">
  280. <th>最近注水量:</th>
  281. <td name="water_prod_mon">
  282. {{ item.water_prod_mon == null ? "" : (numberToCurrencyNo(item.water_prod_mon) + "t") }}
  283. </td>
  284. <td colspan="2" rowspan="2">
  285. <div style="height:25px">
  286. <ChartCell :timeType="('month')" :dataType="('vol')" :wellId="item.well_id"></ChartCell>
  287. </div>
  288. </td>
  289. </tr>
  290. <tr v-if="showColumnType.includes('water')">
  291. <th>累注水量:</th>
  292. <td name="water_prod_year">
  293. {{ item.water_prod_year == null ? "" : (numberToCurrencyNo(item.water_prod_year) + "10kt") }}
  294. </td>
  295. </tr>
  296. </table>
  297. </a-card>
  298. </a-col>
  299. </a-row>
  300. </div>
  301. <a-pagination :page-size-options="pagination.pageSizeOptions" show-size-changer
  302. :total="pagination.total" style="float: right;margin-top: 10px;"
  303. :current="pagination.current" :pageSize="pagination.pageSize"
  304. :show-total="total => `共 ${total} 条`"
  305. @change="(current)=>handleTableChange({ current: current,pageSize: pagination.pageSize })"
  306. @showSizeChange="(current,pageSize)=>handleTableChange({ current: current,pageSize: pageSize })"/>
  307. </a-spin>
  308. </div>
  309. <div :style="showOverlay&&curStepVal==5?'flex-grow: 1;overflow: auto;z-index:999;background:white;':'flex-grow: 1;overflow: auto;'" style="width:100%;height: 500px;" >
  310. <ChartMap ref="chartMapRef" :isSearch="(true)" data-v-step="5"></ChartMap>
  311. </div>
  312. </div>
  313. <a-modal v-model:visible="isShowDoc" title="相关文档" width="800px" :footer="null" @onCancel="isShowDoc=false">
  314. <a-input-search
  315. v-model:value="fileOptions.docKey"
  316. placeholder="查找文档" allow-clear
  317. />
  318. <div class="files-type">
  319. <a-checkable-tag color="processing"
  320. :checked="fileOptions.selectBusinessType.length==0||fileOptions.selectBusinessType.length==fileOptions.businessType.length"
  321. @change="() => fileOptions.selectBusinessType=[]">全部
  322. </a-checkable-tag>
  323. <template v-for="tag in fileOptions.businessType">
  324. <a-checkable-tag color="processing"
  325. :checked="fileOptions.selectBusinessType.includes(tag)"
  326. @change="checked => onBusTypeChange(checked,tag)">{{ tag }}
  327. </a-checkable-tag>
  328. </template>
  329. </div>
  330. <div style="max-height:300px;overflow-y:scroll;margin-top:10px;">
  331. <a-list item-layout="horizontal" :data-source="docList">
  332. <template #renderItem="{ item }">
  333. <a-list-item v-if="(item.file_name.indexOf(fileOptions.docKey)>-1||fileOptions.docKey=='')
  334. &&(fileOptions.selectBusinessType.length==0||fileOptions.selectBusinessType.includes(item.file_business_type))">
  335. <template #actions>
  336. <PlusOutlined v-if="!item.isApply" @click="onAddCart(item)" title="加入购物车"
  337. :style="{fontSize: '16px', color: '#08c'}"/>
  338. <a-button type="link" @click="downFile(item)" v-if="item.isDown" danger>下载</a-button>
  339. <filePreview :fileName="item.file_name" :filePath="item.storage_path"></filePreview>
  340. </template>
  341. <a-list-item-meta
  342. :description="item.file_business_type">
  343. <template #title>
  344. {{ item.file_name }}
  345. </template>
  346. <template #avatar>
  347. <img src="~@/assets/images/file.png"/>
  348. </template>
  349. </a-list-item-meta>
  350. </a-list-item>
  351. </template>
  352. </a-list>
  353. </div>
  354. </a-modal>
  355. </div>
  356. </template>
  357. <script lang="ts">
  358. import {ref, defineComponent, computed, watch, reactive, getCurrentInstance} from 'vue';
  359. import type {FormInstance} from 'ant-design-vue';
  360. import {useRoute} from 'vue-router';
  361. import {get, postData} from "@/api/common";
  362. import {getPaginationTotalTitle} from "@/utils/common";
  363. import {message} from 'ant-design-vue';
  364. import type {TableProps} from "ant-design-vue";
  365. import {useTabsViewStore} from "@/store/modules/tabsView";
  366. import ChartCell from '@/components/basic/chart/chart-cell.vue'
  367. import ChartMap from '@/components/basic/chart/chart-map.vue'
  368. import {download} from "@/utils/downloadFile";
  369. import {columns, filterColumns, formState, getTdColor} from './table';
  370. import filePreview from '@/components/basic/file-preview/index.vue';
  371. import {numberToCurrencyNo} from "@/utils/common";
  372. export default defineComponent({
  373. name: 'wellinfoindex',
  374. components: {ChartCell, ChartMap, filePreview},
  375. setup() {
  376. const curTour = ref({});
  377. const route = useRoute();
  378. const expand = ref(false);
  379. const formRef = ref<FormInstance>();
  380. const loading = ref(false);
  381. const showQuery = ref(false);
  382. const selectedRowKeys = ref([]);
  383. const activeTab = ref("1");
  384. const colspan = ref(8);
  385. const showTree = ref(true);
  386. const isShowDoc = ref(false);
  387. const showColumnType = ref(['oil', 'gas', 'water']);
  388. const data = ref([]);
  389. const viewModel = ref("list");
  390. const tabsViewStore = useTabsViewStore();
  391. const docKey = ref('');
  392. const docList = ref<any>([]);
  393. const wellTypeList = ref([{label: "直井", value: "直井"}, {label: "定向井", value: "定向井"}, {label: "分支井", value: "分支井"}]);
  394. const wellPurposeList = ref([{label: "探井", value: "探井"}, {label: "开发井", value: "开发井"}, {label: "水井", value: "水井"}]);
  395. const chartMapRef = ref();
  396. const steps = reactive([
  397. {
  398. target:'[data-v-step="1"]',
  399. header:{
  400. title:'<div class="leftTriangle" style="position:absolute;right:28.5em;top:1.5em;"></div>' +
  401. '<div class="tipsTitle">引导1/5:</div>'
  402. },
  403. content:'<div class="tipsContent">可以切换目录查询</div>',
  404. params:{
  405. placement:'right'
  406. }
  407. },{
  408. target:'[data-v-step="2"]',
  409. header:{
  410. title:'<div class="rightTriangle" style="position:absolute;left:23.5em;top:1em;"></div>' +
  411. '<div class="tipsTitle" style="position:relative;left:-4.7em;">引导2/5:</div>',
  412. },
  413. content:'<div class="tipsContent" style="position:relative;left:-5em;">点击"☰"按钮展开更多查询</div>',
  414. params:{
  415. placement:'left'
  416. }
  417. },{
  418. target:'[data-v-step="3"]',
  419. header:{
  420. title:'<div class="rightTriangle" style="position:absolute;left:28.5em;top:1.5em;"></div>' +
  421. '<div class="tipsTitle">引导3/5:</div>',
  422. },
  423. content:'<div class="tipsContent">切换不同视图,也可勾选需要显示的列</div>',
  424. params:{
  425. placement:'left'
  426. }
  427. },{
  428. target:'[data-v-step="4"]',
  429. header:{
  430. title:'<div class="topTriangle" style="position:absolute;top:-2.5em;left:13em;"></div>' +
  431. '<div class="tipsTitle">引导4/5:</div>'
  432. },
  433. content:'<div class="tipsContent" >可移动表格数据列的顺序</div>',
  434. params:{
  435. placement:'bottom'
  436. }
  437. },{
  438. target:'[data-v-step="5"]',
  439. header:{
  440. title:'<div class="topTriangle" style="position:absolute;top:-2.5em;left:13em;"></div>' +
  441. '<div class="tipsTitle">引导5/5:</div>'
  442. },
  443. content:'<div class="tipsContent">地图显示当前列表的井所在位置</div>',
  444. params:{
  445. placement:'bottom'
  446. }
  447. }
  448. ]);
  449. const myOptions = reactive({
  450. dialogVisible:false,
  451. useKeyboardNavigation:false,
  452. labels:{
  453. buttonSkip:' 跳过引导 ',
  454. buttonPrevious:' 上一步 ',
  455. buttonNext:'下一步 ',
  456. buttonStop:' 明白了 '
  457. }
  458. });
  459. const showOverlay = ref(false);
  460. const curStepVal = ref(1);
  461. const myCallbacks = ref({
  462. onStart(){
  463. loadStyle();
  464. },
  465. onPreviousStep(){
  466. curStepVal.value -= 1;
  467. loadStyle();
  468. },
  469. onNextStep(){
  470. curStepVal.value += 1;
  471. loadStyle();
  472. },
  473. onStop:async function(){
  474. showOverlay.value = false;
  475. curStepVal.value = 1;
  476. const $input = document.getElementById('wellName');
  477. $input?.focus();
  478. }
  479. });
  480. function loadStyle(){
  481. setTimeout(()=>{
  482. const $divs = document.getElementsByClassName("v-step__buttons");
  483. for(let i=0;i < $divs.length;i++) {
  484. const div = $divs[i];
  485. if(curStepVal.value ==2){
  486. div.setAttribute("style","background-color:#4c8dff;color:white;height:3em;width:100%;" +
  487. "position: relative;top:-.2em;left:-5em;padding-top:0.4em;border-radius:0 0 10px 10px;");
  488. }else{
  489. div.setAttribute("style","background-color:#4c8dff;color:white;height:3em;width:100%;" +
  490. "position: relative;top:-0.2em;padding-top:0.4em;border-radius:0 0 10px 10px;");
  491. }
  492. }
  493. const $buttons = document.getElementsByClassName("v-step__button");
  494. for(let i=0;i < $buttons.length;i++) {
  495. const button = $buttons[i];
  496. button.setAttribute("style","border:1px solid white;margin:0 10px 0 10px;" +
  497. "padding:0 4px 0 4px;border-radius:5px;");
  498. }
  499. },10);
  500. }
  501. function changeTree(){
  502. if(showOverlay.value){
  503. message.warn('请退出引导状态再进行操作!');
  504. return false;
  505. }
  506. showTree.value = false;
  507. colspan.value = 6;
  508. }
  509. function changeQuery(curVal:boolean){
  510. if(showOverlay.value){
  511. message.warn('请退出引导状态再进行操作!');
  512. return false;
  513. }
  514. showQuery.value = curVal;
  515. }
  516. const replaceFields = {
  517. children: 'children',
  518. title: 'label',
  519. key: 'value',
  520. };
  521. const fileOptions = reactive({
  522. docKey: '',
  523. businessType: [] as any[],
  524. selectBusinessType: [] as any[]
  525. })
  526. const wellPurposeTree = ref([]);
  527. get('wellInfo/getWellPurposeTree', {}).then(data => {
  528. wellPurposeTree.value = data;
  529. });
  530. const wellTypeTree = ref([]);
  531. get('wellInfo/getWellTypeTree', {}).then(data => {
  532. wellTypeTree.value = data;
  533. });
  534. function onBusTypeChange(checked, it) {
  535. if (checked) {
  536. fileOptions.selectBusinessType.push(it);
  537. } else {
  538. fileOptions.selectBusinessType.splice(fileOptions.selectBusinessType.indexOf(it), 1);
  539. }
  540. console.log(checked, it);
  541. }
  542. const downFile = (record: any) => {
  543. download(record.storage_path, record.file_name);
  544. };
  545. const resetFields = function () {
  546. let keys: string[] = Object.keys(formState);
  547. keys.forEach(key => {
  548. if (typeof (formState[key]) == "string") {
  549. formState[key] = '';
  550. } else if (typeof (formState[key]) == "object") {
  551. formState[key] = [];
  552. }
  553. })
  554. }
  555. filterColumns.value = [...columns];
  556. function showColumnTypeChange() {
  557. const filterValue = columns.filter((item: any) => {
  558. if (!showColumnType.value.includes("oil")) {
  559. if (["oil_prod_mon", "oil_prod_year", "oil"].includes(item.dataIndex)) {
  560. return false
  561. }
  562. }
  563. if (!showColumnType.value.includes("gas")) {
  564. if (["gas_prod_mon", "gas_prod_year", "gas"].includes(item.dataIndex)) {
  565. return false
  566. }
  567. }
  568. if (!showColumnType.value.includes("water")) {
  569. if (["water_prod_mon", "water_prod_year", "water"].includes(item.dataIndex)) {
  570. return false
  571. }
  572. }
  573. return true
  574. })
  575. //拖拽后在显示隐藏列则需要按拖拽后的列排序
  576. const sortedArray = filterValue.sort((a, b) => {
  577. const indexA = filterColumns.value.findIndex(f => f.key == a.key);
  578. const indexB = filterColumns.value.findIndex(f => f.key == b.key);
  579. return (indexA == -1 || indexB == -1) ? 1 : indexA - indexB;
  580. });
  581. filterColumns.value = [...sortedArray];
  582. setSettingColumns();
  583. }
  584. function getSettingColumns() {
  585. let userColumnsJson = localStorage.getItem('userColumns');
  586. let userShowColumnsType = localStorage.getItem('userShowColumnsType');
  587. if (userColumnsJson != undefined) {
  588. let array = new Array();
  589. let userColumns = JSON.parse(userColumnsJson);
  590. userColumns.forEach(it => {
  591. array.push(columns.find(c => c.key == it.key));
  592. })
  593. filterColumns.value = array;
  594. }
  595. if (userShowColumnsType != undefined) {
  596. showColumnType.value = JSON.parse(userShowColumnsType);
  597. }
  598. }
  599. function setSettingColumns() {
  600. localStorage.setItem("userShowColumnsType", JSON.stringify(showColumnType.value));
  601. localStorage.setItem("userColumns", JSON.stringify(filterColumns.value));
  602. }
  603. const preCheckValues = ref(Object.assign(showColumnType.value));
  604. const onCheckboxChange = (checkValues: []) => {
  605. showColumnTypeChange();
  606. setTimeout(() => {
  607. let tbody = document.getElementsByClassName("ant-table-body")[0];
  608. if (tbody) {
  609. tbody.scrollLeft = preCheckValues.value.length > checkValues.length ? 0 : tbody.scrollWidth;
  610. }
  611. preCheckValues.value = checkValues;
  612. }, 300)
  613. }
  614. const onSelectChange = (keys: any) => {
  615. selectedRowKeys.value = keys;
  616. };
  617. const pagination = computed(() => ({
  618. total: formState.total,
  619. current: formState.page,
  620. pageSize: formState.rows,
  621. showSizeChanger: true,
  622. pageSizeOptions: viewModel.value == "list" ? ['10', '20', '30', '40', '50'] : ['12', '24', '36', '48', '60'],
  623. showTotal: total => getPaginationTotalTitle(total)
  624. }));
  625. watch(() => viewModel.value,
  626. () => {
  627. pagination.value.current = 1;
  628. formState.page = 1;
  629. if (viewModel.value == "list") {
  630. formState.rows = 10;
  631. pagination.value.pageSize = 10;
  632. } else {
  633. formState.rows = 12;
  634. pagination.value.pageSize = 12;
  635. }
  636. loadData();
  637. });
  638. const loadData = async function () {
  639. loading.value = true;
  640. const result: any = await postData('wellInfo/getList', formState);
  641. data.value = result.list;
  642. formState.total = result.total;
  643. loading.value = false;
  644. }
  645. const handleTableChange: TableProps['onChange'] = (
  646. pag: { pageSize: number; current: number },
  647. ) => {
  648. formState.page = pag.current;
  649. formState.rows = pag.pageSize;
  650. loadData();
  651. };
  652. const onRangeChange = (dateString, begin, end) => {
  653. formState[begin] = dateString ? dateString[0].format("YYYY-MM-DD") : '';
  654. formState[end] = dateString ? dateString[1].format("YYYY-MM-DD") : '';
  655. };
  656. const tabChange = (key) => {
  657. console.log("tabChange", key);
  658. formState.org_id_a1 = '';
  659. formState.project_id = '';
  660. formState.orgList = [];
  661. formState.unitList = [];
  662. if (key == "2") {
  663. subjectTrees.value.data = Object.assign(subjectTrees.value.constructUnitTree);
  664. } else {
  665. subjectTrees.value.data = Object.assign(subjectTrees.value.organizationTree);
  666. }
  667. data.value=[];
  668. getSubjectTree();
  669. }
  670. const detail = (well_id) => {
  671. tabsViewStore.addTabByPath('/wellinfo/detail', {id: well_id});
  672. }
  673. const onQuery = () => {
  674. loadData();
  675. chartMapRef.value.getDatas(formState);
  676. }
  677. const treeRef = ref();
  678. const subjectTrees = ref({
  679. data: [],
  680. organizationTree: [],
  681. constructUnitTree: [],
  682. expandedKeys: [''],
  683. selectedKeys: [''],
  684. autoExpandParent: true,
  685. searchStr: ''
  686. });
  687. const getSubjectData = async function () {
  688. get('wellInfo/getOrganizationTree', {tabName: subjectTrees.value.searchStr}).then(data => {
  689. subjectTrees.value.organizationTree = data;
  690. subjectTrees.value.data = Object.assign(data);
  691. getSubjectTree();
  692. });
  693. get('wellInfo/getConstructUnitTree', {tabName: subjectTrees.value.searchStr}).then(data => {
  694. subjectTrees.value.constructUnitTree = data;
  695. });
  696. }
  697. const getSubjectTree = async function () {
  698. //计算第一个展开节点
  699. subjectTrees.value.expandedKeys = [];
  700. if (subjectTrees.value.data && subjectTrees.value.data.length > 0) {
  701. subjectTrees.value.expandedKeys.push((subjectTrees.value.data[0] as any).value + "");
  702. }
  703. generateList(subjectTrees.value.data);
  704. }
  705. getSubjectData();
  706. const searchTree = () => {
  707. if (subjectTrees.value.searchStr == "") {
  708. return;
  709. }
  710. const expanded = dataList
  711. .map((item: any) => {
  712. if (item.label != null && item.label.indexOf(subjectTrees.value.searchStr) > -1) {
  713. return getParentKey(item.value as string, subjectTrees.value.data);
  714. }
  715. return null;
  716. })
  717. .filter((item, i, self) => item && self.indexOf(item) === i);
  718. if (expanded.length == 0) {
  719. message.warning('没有查询到相关目录');
  720. }
  721. subjectTrees.value.expandedKeys = expanded as string[];
  722. subjectTrees.value.autoExpandParent = true;
  723. // (treeRef.value as any).scrollTo({key:expanded[0]});
  724. }
  725. const dataList: any[] = [];
  726. const generateList = (data: any[]) => {
  727. for (let i = 0; i < data.length; i++) {
  728. const node = data[i];
  729. const label = node.label;
  730. dataList.push({value: node.value, label: label as string});
  731. if (node.children) {
  732. generateList(node.children);
  733. }
  734. }
  735. };
  736. const getParentKey = (key: string, tree: any[]): string | number | undefined => {
  737. let parentKey;
  738. for (let i = 0; i < tree.length; i++) {
  739. const node = tree[i];
  740. if (node.children) {
  741. if (node.children.some(item => item.value === key)) {
  742. parentKey = node.value;
  743. } else if (getParentKey(key, node.children)) {
  744. parentKey = getParentKey(key, node.children);
  745. }
  746. }
  747. }
  748. return parentKey;
  749. };
  750. const treeOnExpand = function (keys: string[]) {
  751. subjectTrees.value.expandedKeys = keys;
  752. subjectTrees.value.autoExpandParent = false;
  753. }
  754. const treeOnSelect = function (selected, selectedNodes, node) {
  755. console.log(selected, selectedNodes, node);
  756. if (selectedNodes.node.parent != undefined || activeTab.value == "1") {
  757. if (activeTab.value == "1") {
  758. formState.org_id_a1 = selected.length > 0 ? selectedNodes.node.key : '';
  759. formState.orgList = selected.length > 0 ? [formState.org_id_a1] : [];
  760. onOrgTreeChange();
  761. } else {
  762. formState.project_id = selected.length > 0 ? selectedNodes.node.key : '';
  763. formState.unitList = selected.length > 0 ? [formState.project_id] : [];
  764. onUnitTreeChange();
  765. }
  766. loadData();
  767. }
  768. }
  769. const orgUnitList: any = ref([]);
  770. const unitOrgList: any = ref([]);
  771. let filterTreeData: any[] = [];
  772. //组织机构和地质单元联动,选择组织机构只显示该组织机构的地质单元
  773. function filterOrgTree(treeData: any[]) {
  774. if (formState.unitList.length == 0) {
  775. return treeData;
  776. }
  777. filterTreeData = [];
  778. treeData.forEach(node => {
  779. if (unitOrgList.value.indexOf(node.value) > -1) {
  780. filterTreeData.push(node);
  781. return;
  782. }
  783. eachOrgTreeNode(node.children);
  784. })
  785. return filterTreeData;
  786. }
  787. function eachOrgTreeNode(treeData: any[]) {
  788. if (treeData == undefined) {
  789. return;
  790. }
  791. treeData.forEach(node => {
  792. if (unitOrgList.value.indexOf(node.value) > -1) {
  793. filterTreeData.push(node);
  794. return;
  795. }
  796. eachOrgTreeNode(node.children);
  797. })
  798. }
  799. function onOrgTreeChange() {
  800. postData('wellInfo/getOrgProjectList', {orgList: formState.orgList}).then((data: any[]) => {
  801. orgUnitList.value = data.map(x => x.project_id);
  802. })
  803. }
  804. function onUnitTreeChange() {
  805. postData('wellInfo/getOrgProjectList', {unitList: formState.unitList}).then((data: any[]) => {
  806. unitOrgList.value = data.map(x => x.org_id);
  807. })
  808. }
  809. function filterUnitTree(treeData: any[]) {
  810. if (formState.orgList.length == 0) {
  811. return treeData;
  812. }
  813. filterTreeData = [];
  814. treeData.forEach(node => {
  815. if (orgUnitList.value.indexOf(node.value) > -1) {
  816. filterTreeData.push(node);
  817. return;
  818. }
  819. eachUnitTreeNode(node.children);
  820. })
  821. return filterTreeData;
  822. }
  823. function eachUnitTreeNode(treeData: any[]) {
  824. if (treeData == undefined) {
  825. return;
  826. }
  827. treeData.forEach(node => {
  828. if (orgUnitList.value.indexOf(node.value) > -1) {
  829. filterTreeData.push(node);
  830. return;
  831. }
  832. eachUnitTreeNode(node.children);
  833. })
  834. }
  835. const showDoc = (id) => {
  836. get('wellInfo/getWellDocumentList', {wellId: id}).then((data: any[]) => {
  837. let applyFileList = getStoreFiles();
  838. data.forEach(it => {
  839. if (!it.isApply) {
  840. it.isApply = applyFileList.filter(file => file.well_common_name == it.well_common_name && file.file_name == it.file_name).length > 0;
  841. }
  842. })
  843. docList.value = data;
  844. isShowDoc.value = true;
  845. fileOptions.businessType = docList.value.map(x => x.file_business_type);
  846. fileOptions.businessType = Array.from(new Set(fileOptions.businessType));
  847. })
  848. };
  849. const onAddCart = (file) => {
  850. let applyFileList = getStoreFiles();
  851. applyFileList.push({
  852. well_common_name: file.well_common_name,
  853. file_name: file.file_name,
  854. storage_path: file.storage_path
  855. });
  856. localStorage.setItem("applyFileList", JSON.stringify(applyFileList));
  857. file.isApply = true;
  858. message.info('成功加入购物车');
  859. }
  860. const getStoreFiles = () => {
  861. let applyFileList = new Array();
  862. let storeList = localStorage.getItem("applyFileList");
  863. if (storeList != null) {
  864. applyFileList = JSON.parse(storeList);
  865. }
  866. return applyFileList;
  867. }
  868. const labelCol = {style: {width: '100px'}};
  869. const showHelp = () => {
  870. if (curTour.value && curTour.value['wellInfoTour'] ) {
  871. (curTour.value['wellInfoTour'] as any).start();
  872. loadStyle();
  873. showOverlay.value = true;
  874. }
  875. }
  876. return {
  877. route,
  878. selectedRowKeys,
  879. loading,
  880. activeTab,
  881. showTree,
  882. onSelectChange,
  883. data,
  884. expand,
  885. onQuery,
  886. loadData,
  887. onRangeChange,
  888. chartMapRef,
  889. showQuery,
  890. wellTypeList,
  891. wellPurposeList,
  892. replaceFields,
  893. formRef,
  894. viewModel,
  895. handleTableChange,
  896. detail,
  897. formState,
  898. isShowDoc,
  899. showDoc,
  900. docKey,
  901. docList,
  902. resetFields,
  903. showColumnType,
  904. filterColumns,
  905. filterUnitTree,
  906. filterOrgTree,
  907. labelCol,
  908. getTdColor,
  909. downFile,
  910. tabChange,
  911. onCheckboxChange,
  912. treeRef,
  913. colspan,
  914. treeOnExpand,
  915. subjectTrees,
  916. fileOptions,
  917. onBusTypeChange,
  918. onOrgTreeChange,
  919. onUnitTreeChange,
  920. getSubjectTree,
  921. searchTree,
  922. treeOnSelect,
  923. pagination,
  924. getSettingColumns,
  925. wellPurposeTree,
  926. wellTypeTree,
  927. numberToCurrencyNo,
  928. onAddCart,
  929. handleResizeColumn: (w, col) => {
  930. col.width = w;
  931. },
  932. curStepVal,steps,myOptions,curTour,showOverlay,myCallbacks,loadStyle,changeTree,changeQuery,showHelp
  933. };
  934. },
  935. mounted(){
  936. this.curTour = getCurrentInstance()?.appContext.config.globalProperties.$tours;
  937. console.log("tour2",this.curTour);
  938. if(this.curTour && this.curTour['wellInfoTour']){
  939. const localData = localStorage.getItem('wellInfoTourShow');
  940. const curTour = localData?JSON.parse(localData):null;
  941. if(curTour==null||!curTour.ifShowed){
  942. this.showOverlay = true;
  943. (this.curTour['wellInfoTour'] as any).start();
  944. const curLocalData = JSON.stringify({ifShowed:true});
  945. localStorage.setItem('wellInfoTourShow',curLocalData);
  946. }
  947. }
  948. },
  949. beforeMount() {
  950. this.loadStyle();
  951. },
  952. created() {
  953. this.getSettingColumns();
  954. //this.loadData();
  955. },
  956. activated() {
  957. }
  958. });
  959. </script>
  960. <style lang="less">
  961. .tipsTitle{
  962. color: white;
  963. background: #4c8dff;
  964. font-size: 15px;
  965. border-radius:10px 10px 0 0;
  966. padding:5px 20px 0 10px;
  967. font-weight:bolder;
  968. display: inline-block;
  969. width:400px;
  970. }
  971. .tipsContent{
  972. color: white;
  973. background: #4c8dff;
  974. font-size: 14px;
  975. padding-left: 20px;
  976. }
  977. .leftTriangle{
  978. height: 0;
  979. border-top: 12px solid transparent;
  980. border-bottom: 15px solid transparent;
  981. border-left: 15px solid transparent;
  982. border-right: 12px solid #4c8dff;
  983. }
  984. .rightTriangle{
  985. height: 0;
  986. border-top: 12px solid transparent;
  987. border-bottom: 15px solid transparent;
  988. border-left: 15px solid #4c8dff;
  989. border-right: 12px solid transparent;
  990. }
  991. .topTriangle{
  992. height: 0;
  993. border-top: 18px solid transparent;
  994. border-bottom: 18px solid #4c8dff;
  995. border-left: 15px solid transparent;
  996. border-right: 15px solid transparent;
  997. }
  998. .bottomTriangle{
  999. height: 0;
  1000. border-top: 18px solid #4c8dff;
  1001. border-bottom: 18px solid transparent;
  1002. border-left: 15px solid transparent;
  1003. border-right: 15px solid transparent;
  1004. }
  1005. .query-index {
  1006. display: flex;
  1007. flex-direction: row;
  1008. height: 100%;
  1009. background-color: white;
  1010. overflow: hidden;
  1011. position: relative;
  1012. }
  1013. .apply-cart {
  1014. position: fixed;
  1015. right: 10px;
  1016. bottom: 80px;
  1017. width: 55px;
  1018. z-index: 99;
  1019. cursor: pointer;
  1020. }
  1021. .query-index-tree {
  1022. min-width: 260px;
  1023. max-width: 360px;
  1024. border-right: 2px solid #f2f2f2;
  1025. margin-right: 5px;
  1026. }
  1027. .query-index-close {
  1028. width: 15px;
  1029. padding-top: 10px;
  1030. padding-left: 10px;
  1031. }
  1032. .query-index-content {
  1033. flex-grow: 1;
  1034. display: flex;
  1035. flex-direction: column;
  1036. width: 80%;
  1037. }
  1038. .query-index-row {
  1039. height: 34px;
  1040. }
  1041. .query-index-form {
  1042. padding: 15px 10px 10px 15px;
  1043. }
  1044. .query-index-table {
  1045. flex-grow: 1;
  1046. display: flex;
  1047. .ant-row {
  1048. width: 100%;
  1049. }
  1050. }
  1051. .query-index-tabs {
  1052. margin-left: 10px;
  1053. margin-right: 10px;
  1054. height: 100%;
  1055. flex: 1;
  1056. }
  1057. .tabs-view-content {
  1058. padding: 0px;
  1059. }
  1060. .query-index-tree-item {
  1061. white-space: nowrap; /*强制span不换行*/
  1062. display: inline-block; /*将span当做块级元素对待*/
  1063. text-overflow: ellipsis; /*超出部分以点号代替*/
  1064. }
  1065. .query-index-tree-search {
  1066. padding: 5px;
  1067. border-bottom: 2px solid #f2f2f2;
  1068. display: flex;
  1069. align-items: center;
  1070. }
  1071. .query-index-tree-box {
  1072. padding: 5px;
  1073. padding-top: 10px;
  1074. overflow-y: scroll;
  1075. height: 100%;
  1076. }
  1077. .col-text {
  1078. padding-right: 0px !important;
  1079. text-align: right;
  1080. font-weight: bold;
  1081. }
  1082. .col-content {
  1083. width: 200px;
  1084. overflow: hidden;
  1085. text-overflow: ellipsis;
  1086. white-space: nowrap;
  1087. }
  1088. .ant-card-body {
  1089. padding: 10px;
  1090. }
  1091. .well-card-table {
  1092. width: 100%;
  1093. th {
  1094. width: 25%;
  1095. text-align: left;
  1096. font-size: 12px;
  1097. }
  1098. td {
  1099. width: 25%;
  1100. text-align: left;
  1101. font-size: 12px;
  1102. }
  1103. }
  1104. .ant-card-index {
  1105. .ant-card-head-title {
  1106. font-weight: bold;
  1107. color: #1f37dd;
  1108. }
  1109. .ant-card-head {
  1110. padding: 0px 10px;
  1111. height: 35px;
  1112. background-color: #F9FCFF;
  1113. }
  1114. .ant-card-head-wrapper {
  1115. height: 35px;
  1116. margin-top: 5px;
  1117. }
  1118. }
  1119. .ant-card-index:hover {
  1120. box-shadow: 3px 2px 10px #999;
  1121. opacity: 0.8;
  1122. }
  1123. .color_level1, .ant-table-tbody > tr > td.color_level1:hover {
  1124. }
  1125. .color_level2, .ant-table-tbody > tr > td.color_level2:hover {
  1126. background-color: #EAF4FF !important;
  1127. }
  1128. .color_level3, .ant-table-tbody > tr > td.color_level3:hover {
  1129. background-color: #D5EAFF !important;
  1130. }
  1131. .color_level4, .ant-table-tbody > tr > td.color_level4:hover {
  1132. background-color: #B7DBFF !important;
  1133. }
  1134. .files-type {
  1135. margin-top: 10px;
  1136. span {
  1137. color: #8e9ae1;
  1138. border: 1px solid #c6ccf0;
  1139. padding: 3px 5px;
  1140. margin-bottom: 5px;
  1141. }
  1142. .ant-tag-checkable-checked, .ant-tag-checkable-checked:active {
  1143. background-color: #8e9ae1;
  1144. color: #ffffff;
  1145. }
  1146. }
  1147. </style>