anji-crud.vue 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098
  1. <template>
  2. <div :class="[hasTreeFieldInQueryForm ? 'page-container' : 'app-container']">
  3. <div v-if="hasTreeFieldInQueryForm" class="left-container">
  4. <AnjiTree
  5. ref="queryFormTree"
  6. v-model.trim="queryParams[queryFormTreeField.field]"
  7. :is-open="queryFormTreeField.anjiTreeOption.isOpen"
  8. :enable-filter="queryFormTreeField.anjiTreeOption.enableFilter"
  9. :label-name="queryFormTreeField.label"
  10. :url="queryFormTreeField.anjiTreeOption.url"
  11. @node-click="handleTreeNodeCheck"
  12. />
  13. </div>
  14. <div class="right-container">
  15. <div class="top_part">
  16. <!-- 查询表单开始 -->
  17. <el-form
  18. v-if="queryFormTreeHide == false"
  19. ref="formSearch"
  20. :model="queryParams"
  21. label-width="100px"
  22. style="border-bottom: 1px solid #dbdde3; margin-bottom: 10px"
  23. >
  24. <div class="screenFlex">
  25. <div class="searchFormFlex">
  26. <el-row>
  27. <template v-for="(item, index) in queryFormFieldExcludeTree">
  28. <el-col
  29. v-if="index < 3 || queryParams.showMoreSearch"
  30. :key="item.field"
  31. :span="8"
  32. >
  33. <el-form-item
  34. :label="item.label"
  35. :rules="item.rules"
  36. :prop="item.field"
  37. >
  38. <!-- 输入框 -->
  39. <el-input
  40. v-if="
  41. item.inputType == 'input' ||
  42. item.inputType == 'input-number'
  43. "
  44. v-model.trim="queryParams[item.field]"
  45. :placeholder="item.placeholder || '请输入'"
  46. :clearable="item.clearable !== false"
  47. :disabled="item.disabled"
  48. @change="value => queryFormChange(item.field, value)"
  49. />
  50. <!-- 开关 -->
  51. <el-switch
  52. v-else-if="item.inputType == 'switch'"
  53. v-model.trim="queryParams[item.field]"
  54. :disabled="item.disabled"
  55. :active-value="item.switchOption.disableValue"
  56. :inactive-value="item.switchOption.enableValue"
  57. active-color="#5887fb"
  58. inactive-color="#ccc"
  59. @change="value => queryFormChange(item.field, value)"
  60. />
  61. <!-- 下拉框 -->
  62. <anji-select
  63. v-else-if="item.inputType == 'anji-select'"
  64. v-model.trim="queryParams[item.field]"
  65. :multiple="item.anjiSelectOption.multiple"
  66. :dict-code="item.anjiSelectOption.dictCode"
  67. :url="item.anjiSelectOption.url"
  68. :method="item.anjiSelectOption.method"
  69. :query-param="item.anjiSelectOption.queryParam"
  70. :option="item.anjiSelectOption.option"
  71. :label="item.anjiSelectOption.label"
  72. :disabled-options="
  73. item.anjiSelectOption.disabledOptions
  74. "
  75. :disabled="item.disabled"
  76. :merge-label="item.anjiSelectOption.mergeLabel"
  77. :local-options="item.anjiSelectOption.localOptions"
  78. @change="value => queryFormChange(item.field, value)"
  79. />
  80. <!-- 日期时间框 -->
  81. <el-date-picker
  82. v-else-if="item.inputType.indexOf('date') >= 0"
  83. v-model="queryParams[item.field]"
  84. style="width: 100%"
  85. :placeholder="item.placeholder || '请选择'"
  86. :type="item.inputType"
  87. :format="item.format"
  88. :value-format="item.valueFormat"
  89. :clearable="item.clearable !== false"
  90. @change="value => queryFormChange(item.field, value)"
  91. />
  92. <anji-cascader
  93. v-else-if="item.inputType == 'anji-cascader'"
  94. v-model.trim="queryParams[item.field]"
  95. :disabled="item.disabled"
  96. :single-display="item.anjiCascader.singleDisplay"
  97. :url="item.anjiCascader.url"
  98. @change="
  99. value => queryFormChange(item.field, value, null)
  100. "
  101. />
  102. <!-- 待扩展的表单类型,请自行扩展 -->
  103. <el-input
  104. v-else
  105. placeholder="组件不支持此类型表单请至组件内部自行扩展"
  106. disabled
  107. />
  108. </el-form-item>
  109. </el-col>
  110. </template>
  111. </el-row>
  112. </div>
  113. <div class="screenButtons">
  114. <el-button
  115. v-if="queryFormFieldExcludeTree.length > 3"
  116. class="button"
  117. size="mini"
  118. plain
  119. @click="handleToggleMoreSearch"
  120. >
  121. <i
  122. :class="
  123. queryParams.showMoreSearch
  124. ? 'el-icon-arrow-up'
  125. : 'el-icon-arrow-down'
  126. "
  127. />
  128. {{ queryParams.showMoreSearch == true ? "展开" : "收起" }}
  129. </el-button>
  130. <el-button
  131. class="button"
  132. size="mini"
  133. plain
  134. @click="handleResetForm()"
  135. >重置</el-button
  136. >
  137. <el-button
  138. class="button"
  139. size="mini"
  140. type="primary"
  141. @click="handleQueryForm('query')"
  142. >查询</el-button
  143. >
  144. </div>
  145. </div>
  146. </el-form>
  147. <!-- 查询表单结束 -->
  148. <!-- 批量操作 -->
  149. <div style="padding-bottom: 8px">
  150. <slot name="buttonLeftOnTable" :selection="checkRecords" />
  151. <el-button
  152. v-if="
  153. option.buttons.add.isShow == undefined
  154. ? true
  155. : option.buttons.add.isShow
  156. "
  157. v-permission="option.buttons.add.permission"
  158. class="button"
  159. plain
  160. icon="el-icon-plus"
  161. @click="handleOpenEditView('add')"
  162. >新增</el-button
  163. >
  164. <el-button
  165. v-if="
  166. option.buttons.delete.isShow == undefined
  167. ? true
  168. : option.buttons.delete.isShow
  169. "
  170. v-permission="option.buttons.delete.permission"
  171. class="button"
  172. plain
  173. :disabled="disableBatchDelete"
  174. type="danger"
  175. icon="el-icon-delete"
  176. @click="handleDeleteBatch()"
  177. >删除</el-button
  178. >
  179. <slot name="buttonRightOnTable" :selection="checkRecords" />
  180. </div>
  181. </div>
  182. <!-- 表格开始 -->
  183. <div class="main_part">
  184. <div class="page_main">
  185. <el-table
  186. ref="tables"
  187. class="elTable"
  188. align="center"
  189. :data="records"
  190. :row-class-name="tableRowClassName"
  191. border
  192. @selection-change="handleSelectionChange"
  193. @sort-change="handleSortChange"
  194. @row-dblclick="handleSelectionDblclick"
  195. @row-contextmenu="rowContextMenu"
  196. >
  197. <!--多选-->
  198. <el-table-column fixed type="selection" width="50" align="center" />
  199. <!--隐藏列-->
  200. <el-table-column v-if="tableExpandColumns.length > 0" type="expand">
  201. <template slot-scope="scope">
  202. <p
  203. v-for="item in tableExpandColumns"
  204. :key="item.field"
  205. class="table-expand-item"
  206. >
  207. <span class="titel"> {{ item.label }}: </span>
  208. <span>{{ scope.row[item.field] }}</span>
  209. </p>
  210. </template>
  211. </el-table-column>
  212. <!--序号-->
  213. <el-table-column label="序号" min-width="50" align="center">
  214. <template slot-scope="scope">
  215. {{
  216. queryParams.pageSize * (queryParams.pageNumber - 1) +
  217. scope.$index +
  218. 1
  219. }}
  220. </template>
  221. </el-table-column>
  222. <template v-for="(item, index) in option.columns">
  223. <el-table-column
  224. v-if="item.tableHide != true && item.columnType != 'expand'"
  225. :key="index"
  226. :prop="item.field"
  227. :label="fieldLabel(item)"
  228. :min-width="item.minWidth || 110"
  229. :sortable="item.sortable"
  230. :show-overflow-tooltip="true"
  231. align="center"
  232. >
  233. <template slot-scope="scope">
  234. <div v-if="item.columnType == 'imgPreview'">
  235. <!-- 图片缩略图-->
  236. <el-image
  237. style="width: 25%; height: 50%"
  238. fit="contain"
  239. :src="scope.row[item.field]"
  240. :preview-src-list="[scope.row[item.field]]"
  241. />
  242. </div>
  243. <div v-else>
  244. <span v-if="item.inputType == 'switch' && !item.colorStyle">
  245. <el-switch
  246. v-model.trim="scope.row[item.field]"
  247. :active-value="1"
  248. :inactive-value="0"
  249. active-color="#5887fb"
  250. inactive-color="#ccc"
  251. @change="switchChange(scope.row, item.switchOption)"
  252. />
  253. </span>
  254. <!-- 带单位 -->
  255. <span v-else-if="item.inputType == 'anji-input'">{{
  256. fieldValueByAnjiInput(scope.row[item.field], item)
  257. }}</span>
  258. <!--表格 a 合并 b上-->
  259. <span v-else-if="item.mergeColumn"
  260. >{{ scope.row[item.field] }}({{
  261. scope.row[item.mergeColumn]
  262. }})</span
  263. >
  264. <!-- 没有单位 -->
  265. <span
  266. v-else-if="item.colorStyle"
  267. :class="item.colorStyle[scope.row[item.editField]]"
  268. >{{ fieldValueByRowRenderer(scope.row, item) }}</span
  269. >
  270. <span v-else>{{
  271. fieldValueByRowRenderer(scope.row, item)
  272. }}</span>
  273. </div>
  274. </template>
  275. </el-table-column>
  276. </template>
  277. <!--操作栏-->
  278. <el-table-column
  279. align="center"
  280. fixed="right"
  281. label="操作"
  282. :width="
  283. option.buttons.customButton &&
  284. option.buttons.customButton.operationWidth
  285. ? option.buttons.customButton.operationWidth
  286. : 100
  287. "
  288. >
  289. <template slot-scope="scope">
  290. <slot name="rowButton" :msg="scope.row" />
  291. <el-button
  292. v-if="
  293. option.buttons.edit.isShow == undefined
  294. ? true
  295. : option.buttons.edit.isShow
  296. "
  297. type="text"
  298. size="small"
  299. @click="handleOpenEditView('edit', scope.row)"
  300. >编辑</el-button
  301. >
  302. <el-button
  303. v-if="
  304. hasCustomButtonInRowMore == false &&
  305. option.buttons.delete.isShow == undefined
  306. ? true
  307. : option.buttons.edit.isShow
  308. "
  309. type="text"
  310. size="small"
  311. @click="handleDeleteBatch(scope.row)"
  312. >删除</el-button
  313. >
  314. <el-dropdown v-if="hasCustomButtonInRowMore" trigger="click">
  315. <span class="el-dropdown-link"
  316. >更多<i class="el-icon-caret-bottom el-icon--right" />
  317. </span>
  318. <el-dropdown-menu slot="dropdown">
  319. <el-dropdown-item class="clearfix">
  320. <slot name="rowButtonInMore" :msg="scope.row" />
  321. <el-button
  322. v-if="
  323. option.buttons.delete.isShow == undefined
  324. ? true
  325. : option.buttons.edit.isShow
  326. "
  327. type="text"
  328. size="small"
  329. @click="handleDeleteBatch(scope.row)"
  330. >删除</el-button
  331. >
  332. </el-dropdown-item>
  333. </el-dropdown-menu>
  334. </el-dropdown>
  335. </template>
  336. </el-table-column>
  337. </el-table>
  338. <div class="page_bottom">
  339. <div class="pagination">
  340. <div>
  341. <slot name="tableSelectionBtn" :selection="checkRecords" />
  342. </div>
  343. <el-pagination
  344. v-show="total > 0"
  345. background
  346. :current-page.sync="queryParams.pageNumber"
  347. :page-sizes="$pageSizeAll"
  348. :page-size="queryParams.pageSize"
  349. layout="total, prev, pager, next, jumper, sizes"
  350. :total="total"
  351. @size-change="handleSizeChange"
  352. @current-change="handleCurrentChange"
  353. />
  354. </div>
  355. </div>
  356. </div>
  357. </div>
  358. <!-- 表格结束 -->
  359. <EditDialog
  360. ref="edit"
  361. :submit-detail-data="option.submitDetailData"
  362. :handle-detail-data="option.handleDetailData"
  363. :option="option"
  364. :model-type="editDialogModelType"
  365. :visible="editDialogOpen"
  366. :row-data="editDialogRowData"
  367. @closeEvent="editDialogClosedEvent"
  368. >
  369. <template v-slot:customCard>
  370. <slot name="cardInEditPage" />
  371. </template>
  372. <template slot="editBtn" slot-scope="scope">
  373. <slot name="editBtnPage" :rowData="scope" />
  374. </template>
  375. </EditDialog>
  376. </div>
  377. <slot name="pageSection" />
  378. <!-- 右键菜单 -->
  379. <anji-contextMenu
  380. :visible.sync="isShowRowContextMenu"
  381. :style-obj="contextMenuConfigStyle"
  382. >
  383. <div
  384. v-for="(item, index) in option.contextMenu"
  385. :key="index"
  386. class="contextMenu"
  387. >
  388. <el-button
  389. type="text"
  390. :disabled="item.disabled"
  391. class="contextMenuItem"
  392. @click="handleContextMenuItem(item)"
  393. >{{ item.label }}</el-button
  394. >
  395. </div>
  396. </anji-contextMenu>
  397. </div>
  398. </template>
  399. <script>
  400. import AnjiTree from "@/components/AnjiPlus/anji-tree.vue";
  401. import EditDialog from "./edit";
  402. import request from "@/utils/request";
  403. import anjiContextMenu from "@/components/AnjiPlus/anji-contextMenu";
  404. export default {
  405. components: {
  406. EditDialog,
  407. AnjiTree,
  408. anjiContextMenu
  409. },
  410. props: {
  411. option: {
  412. require: true,
  413. type: Object,
  414. default: () => {
  415. return {
  416. formHeight: this.$refs.formSearch.$el.offsetHeight,
  417. // 详情页中输入框左边文字宽度
  418. labelWidth: "120px",
  419. // 查询区隐藏
  420. queryFormHide: false,
  421. // 查询表单条件
  422. queryFormFields: [],
  423. // 按钮
  424. buttons: {
  425. query: {},
  426. edit: {},
  427. delete: {},
  428. add: {}
  429. },
  430. // 表格列
  431. columns: [],
  432. queryFormChange: (fileName, val) => {}
  433. };
  434. }
  435. }
  436. },
  437. data() {
  438. return {
  439. // 查询表单提交的值
  440. queryParams: {
  441. showMoreSearch: false, // 是否展开更多搜索条件
  442. pageNumber: 1,
  443. pageSize: 10,
  444. order: "",
  445. sort: ""
  446. },
  447. checkRecords: [], // 表格中当前选中的记录
  448. records: [], // 接口返回的记录列表
  449. total: 0, // 接口返回的总条数
  450. // 编辑详情弹框
  451. editDialogOpen: false, // 新建时主动打开编辑弹框
  452. editDialogRowData: {}, // 编辑时的主键
  453. editDialogModelType: "view", // 编辑 查看
  454. hasCustomButtonInRowMore: false, // 除了编辑删除外,还有自定义的行按钮
  455. isShowRowContextMenu: false,
  456. contextMenuConfigStyle: {},
  457. contextMenuRow: {}
  458. };
  459. },
  460. computed: {
  461. // 查询区隐藏
  462. queryFormTreeHide() {
  463. const flag =
  464. this.option.queryFormHide != null && this.option.queryFormHide == true;
  465. return flag;
  466. },
  467. // 左侧树形查询条件
  468. queryFormTreeField() {
  469. const treeField = this.option.queryFormFields.find(
  470. item => item["inputType"] == "anji-tree"
  471. );
  472. return treeField;
  473. },
  474. // 查询条件里是否有树形控件
  475. hasTreeFieldInQueryForm() {
  476. return this.isNotBlank(this.queryFormTreeField);
  477. },
  478. // 不包含树形控件的查询条件
  479. queryFormFieldExcludeTree() {
  480. let treeFields = this.option.queryFormFields.filter(
  481. item => item["inputType"] != "anji-tree"
  482. );
  483. return treeFields;
  484. },
  485. // 主键的列名
  486. primaryKeyFieldName() {
  487. let primaryKey = this.option.columns.find(
  488. item => item["primaryKey"] == true
  489. );
  490. if (primaryKey != null) {
  491. return primaryKey["field"];
  492. } else {
  493. return null;
  494. }
  495. },
  496. // 表格中可展开的列
  497. tableExpandColumns() {
  498. let expandColumns = this.option.columns.filter(
  499. item => item["columnType"] == "expand"
  500. );
  501. return expandColumns;
  502. },
  503. // 是否可以批量删除
  504. disableBatchDelete() {
  505. return this.checkRecords.length <= 0;
  506. }
  507. },
  508. created() {
  509. // 为查询框中所有input加上默认值
  510. this.option.queryFormFields.forEach(item => {
  511. // 动态添加属性
  512. this.$set(this.queryParams, item.field, item.defaultValue || null);
  513. });
  514. // 查询列表
  515. if (this.option.skipQuery || this.option.skipQuery == undefined) {
  516. this.handleQueryForm("query");
  517. }
  518. this.queryFormChange();
  519. },
  520. mounted() {
  521. if (this.$scopedSlots["rowButtonInMore"] != null) {
  522. this.hasCustomButtonInRowMore = true;
  523. } else {
  524. this.hasCustomButtonInRowMore = false;
  525. }
  526. console.log(`是否有自定义行按钮: ${this.hasCustomButtonInRowMore}`);
  527. },
  528. methods: {
  529. queryFormFieldSpan(item) {
  530. if (item.span != null) {
  531. return item.span;
  532. } else {
  533. return 6;
  534. }
  535. },
  536. // 切换更多搜索条件
  537. handleToggleMoreSearch() {
  538. this.queryParams.showMoreSearch = !this.queryParams.showMoreSearch;
  539. },
  540. // 列上排序切换
  541. handleSortChange(column) {
  542. // {column: {…}, prop: "orgCode", order: "ascending"}
  543. if (column == null || column.prop == null) {
  544. console.warn("排序字段名prop为空,无法排序");
  545. return;
  546. }
  547. let sort = column.prop; // 列表查询默认排序列
  548. let order = column.order == "ascending" ? "ASC" : "DESC";
  549. this.queryParams["sort"] = sort;
  550. this.queryParams["order"] = order;
  551. this.handleQueryForm("query");
  552. },
  553. // 查询按钮
  554. handleQueryForm(from) {
  555. // 如果是点查询按钮,把树的查询属性去掉
  556. if (from == "query") {
  557. if (this.hasTreeFieldInQueryForm) {
  558. delete this.queryParams[this.queryFormTreeField.field];
  559. }
  560. }
  561. // 如果是点树查询,把查询区里的属性去掉
  562. if (from == "tree") {
  563. if (this.hasTreeFieldInQueryForm) {
  564. let treeVal = this.queryParams[this.queryFormTreeField.field];
  565. this.queryParams = {
  566. pageNumber: 1,
  567. pageSize: 10
  568. };
  569. this.queryParams[this.queryFormTreeField.field] = treeVal;
  570. }
  571. }
  572. // 默认的排序
  573. if (
  574. this.isBlank(this.queryParams["order"]) &&
  575. this.isNotBlank(this.option.buttons.query.order)
  576. ) {
  577. this.queryParams["sort"] = this.option.buttons.query.sort;
  578. this.queryParams["order"] = this.option.buttons.query.order;
  579. }
  580. this.queryParams.pageNumber = 1;
  581. // 添加一些其他的查询参数
  582. if (this.option.buttons.query.params) {
  583. const params = this.option.buttons.query.params;
  584. for (const key in params) {
  585. this.queryParams[key] = params[key];
  586. }
  587. }
  588. this.handleQueryPageList();
  589. },
  590. // 外部追加参数进来
  591. handleAddQueryParams(k, v) {
  592. this.queryParams[k] = v;
  593. },
  594. // 列表查询
  595. async handleQueryPageList() {
  596. // 将特殊参数值urlcode处理
  597. let params = this.urlEncodeObject(this.queryParams, "order,sort");
  598. const { data, code } = await this.option.buttons.query.api(params);
  599. if (code != "200") return;
  600. this.records = data.records;
  601. this.total = data.total;
  602. },
  603. // 重置
  604. handleResetForm() {
  605. const showMoreSearch = this.queryParams.showMoreSearch;
  606. this.queryParams = {
  607. order: "",
  608. sort: "",
  609. pageNumber: 1,
  610. pageSize: 10,
  611. showMoreSearch
  612. };
  613. // 查询条件表单只读模式下不重置默认值
  614. const queryFormFieldsOption = this.option.queryFormFields;
  615. queryFormFieldsOption.forEach(el => {
  616. if (el.disabled) {
  617. this.queryParams[el.field] = el.defaultValue;
  618. }
  619. });
  620. },
  621. // 树形查询条件点击回调
  622. handleTreeNodeCheck() {
  623. this.handleQueryForm("tree");
  624. // 为新建页面的对应属性值,绑定上对应的默认值
  625. let treeFieldName = this.queryFormTreeField["field"];
  626. for (let i = 0; i < this.option.columns.length; i++) {
  627. let item = this.option.columns[i];
  628. if (
  629. item["editField"] == treeFieldName ||
  630. item["field"] == treeFieldName
  631. ) {
  632. this.$set(
  633. this.option.columns[i],
  634. "defaultValue",
  635. this.queryParams[treeFieldName]
  636. );
  637. break;
  638. }
  639. }
  640. },
  641. // 编辑和查看操作
  642. handleOpenEditView(modelType, row) {
  643. if (modelType == "view" || modelType == "edit") {
  644. this.editDialogRowData = row;
  645. }
  646. this.editDialogModelType = modelType;
  647. if (modelType == "add") {
  648. // 新增模式,不需要查询数据详情,直接打开
  649. this.editDialogOpen = true;
  650. }
  651. const obj = {
  652. type: modelType,
  653. value: row
  654. };
  655. this.$emit("handleCustomValue", obj);
  656. },
  657. // 弹框被关闭时的回调事件
  658. editDialogClosedEvent(value) {
  659. // 把列表页中弹框打开标记改成已关闭
  660. this.editDialogOpen = false;
  661. // 关闭弹出框时,如果有树,刷新下
  662. if (
  663. this.hasTreeFieldInQueryForm &&
  664. this.$refs.queryFormTree != null &&
  665. !value
  666. ) {
  667. this.$refs.queryFormTree.queryData();
  668. }
  669. this.$emit("handleCustomClose");
  670. this.handleQueryPageList();
  671. // 关闭时 清空表单的验证规则
  672. this.$refs.edit.$refs.mainForm.$refs.editForm.resetFields();
  673. },
  674. // 批量删除
  675. handleDeleteBatch(row) {
  676. let ids = [];
  677. if (row != null) {
  678. ids.push(row[this.primaryKeyFieldName]); // 删除指定的行
  679. } else {
  680. // 批量删除选中的行
  681. ids = this.checkRecords.map(item => item[this.primaryKeyFieldName]);
  682. }
  683. this.$confirm("删除确认", "确认要删除吗?", {
  684. type: "warning",
  685. confirmButtonClass: "delete_sure",
  686. cancelButtonClass: "el-button--danger is-plain"
  687. })
  688. .then(() => {
  689. this.option.buttons.delete.api(ids).then(res => {
  690. // {code: "200", message: "操作成功", data: true}
  691. this.checkRecords = [];
  692. // 关闭弹出框时,如果有树,刷新下
  693. if (
  694. this.hasTreeFieldInQueryForm &&
  695. this.$refs.queryFormTree != null
  696. ) {
  697. this.$refs.queryFormTree.queryData();
  698. }
  699. this.handleQueryPageList();
  700. });
  701. })
  702. .catch(e => {
  703. e;
  704. });
  705. },
  706. // 选择项改变时
  707. handleSelectionChange(val) {
  708. if (val.length > 0) {
  709. val.forEach(el => {
  710. this.records.forEach(ev => {
  711. if (el.id == ev.id) {
  712. ev.dblClickFlag = true;
  713. ev.bgColor = true;
  714. }
  715. });
  716. });
  717. } else {
  718. this.records.forEach(ev => {
  719. ev.dblClickFlag = false;
  720. ev.bgColor = false;
  721. });
  722. }
  723. this.isShowRowContextMenu = false;
  724. this.checkRecords = val;
  725. },
  726. // 双击
  727. handleSelectionDblclick(row) {
  728. row.dblClickFlag = !row.dblClickFlag;
  729. row.bgColor = row.dblClickFlag;
  730. this.$refs.tables.toggleRowSelection(row, row.dblClickFlag);
  731. },
  732. // 右键
  733. rowContextMenu(row, column, event) {
  734. event.preventDefault();
  735. this.option.contextMenu.forEach(el => {
  736. if (el.flag == "all") {
  737. el.disabled = !(this.checkRecords.length > 1);
  738. } else {
  739. el.disabled = this.checkRecords.length > 1;
  740. }
  741. });
  742. // 设置右键位置
  743. this.contextMenuConfigStyle = {
  744. left: event.clientX + "px",
  745. top: event.clientY + "px",
  746. display: "block"
  747. };
  748. // 获取当前右键行数据
  749. this.contextMenuRow = row;
  750. // 获取我们自定义的右键菜单
  751. this.isShowRowContextMenu = true;
  752. },
  753. handleContextMenuItem(item) {
  754. if (item.flag == "all") {
  755. item.click({ selection: this.checkRecords });
  756. } else {
  757. item.click({ msg: this.contextMenuRow });
  758. }
  759. },
  760. // 页码改变
  761. handleCurrentChange(pageNumber) {
  762. this.queryParams.pageNumber = pageNumber;
  763. this.handleQueryPageList();
  764. },
  765. // 每页size改变时
  766. handleSizeChange(val) {
  767. this.queryParams.pageNumber = 1;
  768. this.queryParams.pageSize = val;
  769. this.handleQueryPageList();
  770. },
  771. // 带单位的列,需要转换
  772. fieldLabel(columnConfig) {
  773. let objUnitText = "";
  774. const localStorageUnit = this.getSettingByName("unit_conversion");
  775. const objUnit = {};
  776. for (const key in localStorageUnit) {
  777. columnConfig.anjiInput &&
  778. key
  779. .toLowerCase()
  780. .indexOf(columnConfig.anjiInput.unit.toLowerCase()) != -1 &&
  781. (objUnit[key] = localStorageUnit[key]);
  782. }
  783. for (const key in objUnit) {
  784. key.toLowerCase().indexOf("text") != -1 && (objUnitText = objUnit[key]);
  785. }
  786. if (columnConfig == null) {
  787. return "";
  788. }
  789. if (
  790. columnConfig.inputType == "anji-input" &&
  791. columnConfig.anjiInput != null
  792. ) {
  793. return columnConfig.anjiInput["defaultUnit"] == undefined
  794. ? `${columnConfig.label}(${objUnitText})`
  795. : `${columnConfig.label}(${columnConfig.anjiInput["defaultUnit"]})`;
  796. } else {
  797. return columnConfig.label;
  798. }
  799. },
  800. // 带单位的输入框
  801. fieldValueByAnjiInput(value, columnConfig) {
  802. console.log(1);
  803. const localStorageUnit = this.getSettingByName("unit_conversion");
  804. let objUnitConversion = "";
  805. let objUnitKeepPoint = "";
  806. let objUnitConversionRadioGroup = [];
  807. const objUnit = {};
  808. for (const key in localStorageUnit) {
  809. columnConfig.anjiInput &&
  810. key
  811. .toLowerCase()
  812. .indexOf(columnConfig.anjiInput.unit.toLowerCase()) != -1 &&
  813. (objUnit[key] = localStorageUnit[key]);
  814. }
  815. for (const key in objUnit) {
  816. key.toLowerCase().indexOf("conversion") != -1 &&
  817. key.toLowerCase().indexOf("conversiontext") == -1 &&
  818. key.toLowerCase().indexOf("conversionradiogroup") == -1 &&
  819. (objUnitConversion = objUnit[key]);
  820. key.toLowerCase().indexOf("keeppoint") != -1 &&
  821. (objUnitKeepPoint = objUnit[key]);
  822. Array.isArray(objUnit[key]) &&
  823. (objUnitConversionRadioGroup = objUnit[key]);
  824. }
  825. if (columnConfig == null) {
  826. return value;
  827. }
  828. if (
  829. columnConfig.inputType == "anji-input" &&
  830. columnConfig.anjiInput != null
  831. ) {
  832. if (columnConfig.anjiInput["defaultUnit"] == undefined) {
  833. // 不存在
  834. return (value / objUnitConversion).toFixed(objUnitKeepPoint || 2);
  835. } else {
  836. const coversion = objUnitConversionRadioGroup.find(
  837. item => item.label == columnConfig.anjiInput["defaultUnit"]
  838. )["value"];
  839. return (value / coversion).toFixed(objUnitKeepPoint || 2);
  840. }
  841. } else {
  842. return value;
  843. }
  844. },
  845. // 带表格列格式化的值
  846. fieldValueByRowRenderer(row, columnConfig) {
  847. if (
  848. columnConfig == null ||
  849. typeof columnConfig.fieldTableRowRenderer != "function"
  850. ) {
  851. return row[columnConfig.field];
  852. } else {
  853. return columnConfig.fieldTableRowRenderer(row);
  854. }
  855. },
  856. // 暴露给外部crud页面,回传saveForm的值
  857. getMainEntity() {
  858. return this.$refs.edit.getSaveForm();
  859. },
  860. setMainEntity(object) {
  861. this.$refs.edit.setSaveForm(object);
  862. },
  863. async switchChange(val, api) {
  864. request({
  865. url: api.url,
  866. method: "put",
  867. headers: { noPrompt: false },
  868. data: [val.id]
  869. }).then(response => {
  870. this.handleQueryPageList();
  871. });
  872. },
  873. queryFormChange(fileName, fieldVal) {
  874. if (typeof this.option.queryFormChange == "function") {
  875. this.option.queryFormChange(this.queryParams, fileName, fieldVal);
  876. }
  877. },
  878. // 给表格某行改变颜色
  879. tableRowClassName({ row, rowIndex }) {
  880. if ((row.urgentFlag || row.tableRow) && !row.bgColor) {
  881. return "warning-row";
  882. } else if ((row.urgentFlag || row.tableRow) && row.bgColor) {
  883. return "warning-row bgColor";
  884. } else if ((!row.urgentFlag || !row.tableRow) && row.bgColor) {
  885. return "bgColor";
  886. }
  887. if ((rowIndex + 1) % 2 === 0) {
  888. return "success-row";
  889. }
  890. }
  891. }
  892. };
  893. </script>
  894. <style scoped lang="scss">
  895. .right-container {
  896. display: flex;
  897. flex: 1;
  898. flex-direction: column;
  899. .main_part {
  900. display: flex;
  901. flex-direction: column;
  902. flex: 1;
  903. background: #fff;
  904. border-radius: 4px;
  905. padding: 12px 20px 12px;
  906. margin-top: 4px;
  907. height: 100%;
  908. position: relative;
  909. }
  910. }
  911. /deep/.button {
  912. box-shadow: 0 0 6px 0 rgba(0, 0, 0, 0.08);
  913. border-radius: 6px;
  914. }
  915. /deep/.el-table th > .cell {
  916. text-align: center;
  917. }
  918. /deep/.el-table .cell {
  919. text-align: center;
  920. }
  921. /deep/.elTable {
  922. margin: 10px 0 50px;
  923. }
  924. .el-table {
  925. // 看这里!!!
  926. // 深度选择器,去除默认的padding
  927. /deep/ th {
  928. padding: 0;
  929. height: 36px;
  930. }
  931. /deep/ td {
  932. padding: 0;
  933. height: 36px;
  934. }
  935. }
  936. /deep/.el-table--striped .el-table__body tr.el-table__row--striped td {
  937. background: #f9fbfd;
  938. }
  939. .screenFlex {
  940. display: flex;
  941. }
  942. .searchFormFlex {
  943. flex: 1;
  944. }
  945. .screenButtons {
  946. padding-left: 20px;
  947. }
  948. .style-btn {
  949. pointer-events: none;
  950. }
  951. .page-container {
  952. height: 100%;
  953. position: relative;
  954. .left-container {
  955. width: 20%;
  956. position: absolute;
  957. top: 0;
  958. left: 0;
  959. background: #fff;
  960. border-radius: 4px 0px 0px 4px;
  961. padding: 20px 20px 0;
  962. overflow: hidden;
  963. overflow-y: auto;
  964. height: 100%;
  965. }
  966. .right-container {
  967. width: calc(80% - 5px);
  968. position: absolute;
  969. top: 0;
  970. right: 0;
  971. background: #fff;
  972. border-radius: 0px 4px 4px 0px;
  973. padding: 20px 20px 0;
  974. height: 100%;
  975. }
  976. }
  977. .el-table .cell,
  978. .el-table td div {
  979. overflow: hidden;
  980. text-overflow: ellipsis;
  981. }
  982. .el-dropdown {
  983. font-size: 12px;
  984. display: inline;
  985. color: #5887fb;
  986. cursor: pointer;
  987. }
  988. .el-dropdown-menu--mini .el-dropdown-menu__item {
  989. min-width: 80px;
  990. max-width: 110px;
  991. float: right;
  992. .el-button--text {
  993. float: right;
  994. }
  995. &:hover {
  996. background: none !important;
  997. }
  998. /deep/.el-button--text:hover,
  999. .el-button--text:focus {
  1000. color: #799ffc !important;
  1001. background-color: #ecf5ff !important;
  1002. border-color: transparent;
  1003. }
  1004. .el-button--mini {
  1005. float: right;
  1006. }
  1007. .el-button--text:hover,
  1008. .el-button--text:focus {
  1009. color: #799ffc;
  1010. border-color: transparent;
  1011. // background-color: transparent;
  1012. // background: red !important;
  1013. }
  1014. .el-button + .el-button {
  1015. margin-left: 0 !important;
  1016. float: right;
  1017. }
  1018. }
  1019. /deep/.el-pagination.is-background .btn-prev,
  1020. .el-pagination.is-background .btn-next,
  1021. .el-pagination.is-background .el-pager li {
  1022. margin: 0 5px;
  1023. border-radius: 2px;
  1024. background-color: #f4f4f5;
  1025. color: #606266;
  1026. min-width: 30px;
  1027. border-radius: 2px;
  1028. }
  1029. /deep/.el-pagination.is-background .el-pager li:not(.disabled).active {
  1030. background-color: #5887fb;
  1031. color: #ffffff;
  1032. border-radius: 4px;
  1033. }
  1034. .page_bottom {
  1035. width: 100%;
  1036. position: absolute;
  1037. bottom: 0;
  1038. }
  1039. .pagination {
  1040. display: flex;
  1041. flex-direction: row;
  1042. justify-content: space-between;
  1043. margin-bottom: 14px;
  1044. margin-right: 20px;
  1045. }
  1046. .el-table /deep/ .warning-row {
  1047. color: red !important;
  1048. }
  1049. .el-table /deep/ .bgColor {
  1050. background: #d9ecff;
  1051. }
  1052. /deep/.edit_button {
  1053. width: 22px;
  1054. height: 22px;
  1055. padding: 0;
  1056. margin: 0;
  1057. margin-right: 5px;
  1058. /deep/ i {
  1059. font-size: 30px;
  1060. }
  1061. }
  1062. .el-form-item--mini.el-form-item {
  1063. margin-bottom: 12px;
  1064. }
  1065. .el-table /deep/ .success-row {
  1066. background: #f9fbfd !important;
  1067. }
  1068. .contextMenu {
  1069. width: 100px;
  1070. .contextMenuItem {
  1071. width: 100%;
  1072. font-size: 12px;
  1073. line-height: 20px;
  1074. padding: 5px;
  1075. }
  1076. &:hover {
  1077. background: #f9fbfd;
  1078. }
  1079. }
  1080. </style>