123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521 |
- <!--
- * @Descripttion: 增删改查列表查询页-表格行编辑组件
- * @Author: Devli
- * @Date: 2021-7-17 10:42:24
- * @Last Modified by: qianlishi
- * @Last Modified time: 2021-12-13 11:04:24
- !-->
- <template>
- <div
- v-if="option['hide'] == null || option['hide'] == false"
- class="anji-card"
- >
- <div class="card-head">{{ option.title }}</div>
- <div class="card-body">
- <el-form ref="form" :model="form">
- <!-- 表格开始 -->
- <el-table
- :data="formRecordsUndelete"
- border
- :row-class-name="tableRowClassAdapter"
- @selection-change="handleSelectionChange"
- @row-click="handleTableRowClick"
- >
- <el-table-column label="序号" min-width="50" align="center">
- <template slot-scope="scope">
- {{ scope.$index + 1 }}
- </template>
- </el-table-column>
- <template v-for="item in option.columns">
- <el-table-column
- v-if="
- fieldIsHide(item.tableHide) != true &&
- item.columnType != 'expand'
- "
- :key="item.field"
- :label="item.label"
- :min-width="item.minWidth || 110"
- align="center"
- >
- <template slot-scope="scope">
- <el-form-item
- :prop="'records.' + scope.$index + '.' + item.field"
- :rules="item.rules"
- >
- <!-- 输入框 -->
- <el-input
- v-if="item.inputType == 'input'"
- v-model="scope.row[item.field]"
- size="small"
- :placeholder="item.placeholder || '请输入'"
- :clearable="item.clearable !== false"
- :disabled="
- saveButtonStatus[scope.$index] == 'inShow' ||
- item.disabled
- "
- @change="
- value => tableRowChange(scope.$index, item.field, value)
- "
- />
- <!-- 开关 -->
- <el-switch
- v-else-if="item.inputType == 'switch'"
- v-model="scope.row[item.field]"
- :disabled="
- saveButtonStatus[scope.$index] == 'inShow' ||
- item.disabled
- "
- :active-value="item.switchOption.disableValue"
- :inactive-value="item.switchOption.enableValue"
- @change="
- value => tableRowChange(scope.$index, item.field, value)
- "
- active-color="#5887fb"
- inactive-color="#ccc"
- >
- </el-switch>
- <el-input
- v-else-if="item.inputType == 'input-number'"
- v-model="scope.row[item.field]"
- size="small"
- :min="item.inputNumberOption.min"
- :max="item.inputNumberOption.max"
- :placeholder="item.placeholder || '请输入'"
- :clearable="item.clearable !== false"
- :disabled="
- saveButtonStatus[scope.$index] == 'inShow' ||
- item.disabled
- "
- @change="
- value => tableRowChange(scope.$index, item.field, value)
- "
- />
- <!-- 自定义input -->
- <anji-input
- v-else-if="item.inputType == 'anji-input'"
- v-model.trim="scope.row[item.field]"
- :default-value="item.defaultValue"
- :unit="item.anjiInput.unit"
- :conversion="item.anjiInput.conversion"
- :placeholder="item.placeholder || '请输入'"
- :clearable="item.clearable !== false"
- :disabled="
- saveButtonStatus[scope.$index] == 'inShow' ||
- item.disabled
- "
- @change="
- value => tableRowChange(scope.$index, item.field, value)
- "
- />
- <!-- 下拉框 -->
- <anji-select
- v-else-if="item.inputType == 'anji-select'"
- v-model.trim="scope.row[item.field]"
- :multiple="item.anjiSelectOption.multiple"
- :default-value="item.defaultValue"
- :dict-code="item.anjiSelectOption.dictCode"
- :url="item.anjiSelectOption.url"
- :method="item.anjiSelectOption.method"
- :query-param="item.anjiSelectOption.queryParam"
- :option="item.anjiSelectOption.option"
- :label="item.anjiSelectOption.label"
- :disabled-options="item.anjiSelectOption.disabledOptions"
- :disabled="
- saveButtonStatus[scope.$index] == 'inShow' ||
- item.disabled
- "
- @change="
- (value, option) =>
- tableRowChange(scope.$index, item.field, value, option)
- "
- />
- <!-- 日期时间框 -->
- <el-date-picker
- v-else-if="item.inputType.indexOf('date') >= 0"
- v-model="scope.row[item.field]"
- style="width: 100%"
- :placeholder="item.placeholder || '请选择'"
- :type="item.inputType"
- :clearable="item.clearable !== false"
- :disabled="
- saveButtonStatus[scope.$index] == 'inShow' ||
- item.disabled
- "
- @change="
- value => tableRowChange(scope.$index, item.field, value)
- "
- />
- <!-- 待扩展的表单类型,请自行扩展 -->
- <el-input
- v-else
- placeholder="组件不支持此类型表单请至组件内部自行扩展"
- disabled
- />
- </el-form-item>
- </template>
- </el-table-column>
- </template>
- <el-table-column fixed="right" label="操作" width="100">
- <template slot-scope="scope">
- <el-button
- type="text"
- size="small"
- @click="handleAddOrUpdate(scope.row, scope.$index)"
- >{{ getRowEditButton(scope.$index) }}</el-button
- >
- <el-button
- type="text"
- size="small"
- @click="handleDelete(scope.row, scope.$index)"
- >删除</el-button
- >
- </template>
- </el-table-column>
- </el-table>
- <!-- 表格结束 -->
- </el-form>
- <button
- v-if="modelType != 'view'"
- class="table-add-row-button"
- @click="handleAdd"
- >
- <i class="el-icon-plus" />
- <span>新增</span>
- </button>
- </div>
- </div>
- </template>
- <script>
- const ROW_DELETE_FLAG = "deletedFlag";
- export default {
- components: {},
- props: {
- modelType: String, // add view edit
- option: {
- // 界面渲染相关配置json
- type: [Object],
- default: () => {
- return {
- title: "", // 页面标题
- labelWidth: "",
- queryFormFields: [], // 查询表单条件
- buttons: {
- // 按钮
- query: {},
- edit: {},
- delete: {},
- add: {}
- },
- columns: [] // 表格列
- };
- }
- },
- relateData: {
- // 关联的主记录
- type: [Object],
- default: () => {
- return {};
- }
- },
- value: {
- type: [Array],
- default: () => {
- return [];
- }
- },
- valueNew: {
- type: [Array],
- default: () => {
- return [];
- }
- }
- },
- data() {
- return {
- checkRecords: [], // 表格中当前选中的记录
- form: {
- records: [], // 接口返回的记录列表
- total: 0 // 接口返回的总条数
- },
- saveButtonStatus: [], // 维护表格中每行编辑按钮的状态 inShow inEditing inAdding
- rowIdList: []
- };
- },
- computed: {
- // 主键的列名
- primaryKeyFieldName() {
- let primaryKey = this.option.columns.find(
- item => item["primaryKey"] == true
- );
- if (primaryKey != null) {
- return primaryKey["field"];
- } else {
- return null;
- console.warn(
- "在columns中查找primaryKey=true失败,会导致查询详情和删除失败"
- );
- }
- },
- // 指定当前实体关联主表的关联字段,孙子关联表,没有该属性
- joinColumn() {
- let columnName = this.option.joinColumn;
- if (this.isBlank(columnName)) {
- console.warn(
- "在columns中查找关联字段失败,会导致查询详情和删除失败,孙子关联表忽略该错误"
- );
- columnName = "";
- }
- return columnName;
- },
- // 未删除的记录
- formRecordsUndelete() {
- if (this.form.records == null) {
- return [];
- }
- return this.form.records.filter(
- item => item[ROW_DELETE_FLAG] == null || item[ROW_DELETE_FLAG] == false
- );
- }
- },
- watch: {},
- created() {
- // 主表 relateData 的关联字段 joinColumn 变动时,触发查询子表的查询,孙子关联儿子的无效
- if (this.isNotBlank(this.joinColumn)) {
- this.$watch(
- function() {
- return this.relateData[this.joinColumn];
- },
- function(newVal, oldVal) {
- // 如果是关联字段发生更新,触发查询
- if (this.isNotBlank(newVal)) {
- this.handleQueryPageList(newVal);
- } else {
- // 如果关联字段为空,清空本表格的数据,如果是父组件(弹出框)关闭时,设置this.relateData = {默认值}时触发
- this.checkRecords = [];
- this.form.records = [];
- this.form.total = 0;
- this.saveButtonStatus = [];
- }
- }
- );
- }
- },
- mounted() {
- // 首次打开时,根据主表关联字段查询子表,加载表格数据
- if (
- this.isNotBlank(this.relateData) &&
- this.isNotBlank(this.relateData[this.joinColumn])
- ) {
- this.handleQueryPageList();
- }
- },
- methods: {
- // 该行是否显示 true/false/ 'hideOnAdd hideOnView hideOnEdit'
- fieldIsHide(tableHide) {
- if (typeof tableHide == "boolean") {
- return tableHide;
- }
- if (typeof tableHide == "string") {
- if (this.modelType == "add") {
- return tableHide.indexOf("hideOnAdd") >= 0;
- }
- if (this.modelType == "view") {
- return tableHide.indexOf("hideOnView") >= 0;
- }
- if (this.modelType == "edit") {
- return tableHide.indexOf("hideOnEdit") >= 0;
- }
- }
- return false;
- },
- // 获取行的提交按钮文字
- getRowEditButton(index) {
- if (this.saveButtonStatus[index] == "inEditing") {
- return "btn_savetemp";
- } else if (this.saveButtonStatus[index] == "inAdding") {
- return "btn_savetemp";
- } else if (this.saveButtonStatus[index] == "inShow") {
- return "btn_edit";
- } else {
- return "not_permission";
- }
- },
- // 表格行渲染前前置处理
- tableRowClassAdapter({ row, rowIndex }) {
- row.index = rowIndex;
- },
- // 查询
- async handleQueryPageList(joinColumnValue) {
- if (this.isBlank(joinColumnValue)) {
- joinColumnValue = this.relateData[this.joinColumn];
- }
- let params = {};
- params[this.joinColumn] = joinColumnValue;
- this.queryPageList(params);
- },
- // 暴露给外部直接调用带参数
- async queryPageList(params) {
- // 默认的排序
- if (this.isNotBlank(this.option.buttons.query.order)) {
- params["sort"] = this.option.buttons.query.sort;
- params["order"] = this.option.buttons.query.order;
- }
- const { data, code } = await this.option.buttons.query.api(params);
- if (code != "200") return;
- this.form.records = data.records;
- this.form.total = data.total;
- this.$emit("input", this.form.records);
- for (let i = 0; i < this.form.total; i++) {
- this.saveButtonStatus.push("inShow");
- }
- },
- // 选择项改变时
- handleSelectionChange(val) {
- this.checkRecords = val;
- },
- // 表格选中某一行时
- handleTableRowClick(row, column, event) {
- // 行点击后,回调option中的tableRowClick事件
- if (typeof this.option.tableRowClick == "function") {
- this.option.tableRowClick(
- this.form.records,
- row,
- row.index,
- this.relateData
- );
- }
- },
- // 行数据更新时回调
- tableRowChange(rowIndex, fieldName, fieldVal, fieldExtend) {
- // 通知外面的组件
- this.$emit("input", this.form.records);
- // 表单变动后,回调option中的tableRowChange事件
- if (typeof this.option.tableChange == "function") {
- this.option.tableChange(
- this.form.records,
- rowIndex,
- fieldName,
- fieldVal,
- fieldExtend,
- this.relateData
- );
- }
- },
- // 新增
- handleAdd() {
- this.saveButtonStatus.push("inAdding");
- this.form.records.push({});
- },
- // 父节点Change,子节点表格更新
- handleUpdata() {
- this.saveButtonStatus = [];
- this.form.records = [];
- },
- // 提交和修改
- handleAddOrUpdate(row, index) {
- // 编辑状态下点击保存提交
- if (
- this.saveButtonStatus[index] == "inEditing" ||
- this.saveButtonStatus[index] == "inAdding"
- ) {
- this.handleSaveTemp(row, index);
- } else {
- this.$set(this.saveButtonStatus, index, "inEditing");
- }
- },
- // 校验表单
- validate(callback) {
- this.$refs["form"].validate(async (valid, obj) => {
- if (callback != null) {
- callback(valid);
- }
- });
- },
- // 暂存
- async handleSaveTemp(row, index) {
- this.$refs["form"].validate(valid => {
- if (valid) {
- if (this.isBlank(row[this.primaryKeyFieldName])) {
- // 补全关联属性
- if (typeof this.option.beforeInsert == "function") {
- this.option.beforeInsert(this.relateData, row);
- }
- } else {
- // 补全关联属性
- if (typeof this.option.beforeUpdate == "function") {
- this.option.beforeUpdate(this.relateData, row);
- }
- }
- // 将行按钮的文字改成编辑
- this.$set(this.saveButtonStatus, index, "inShow");
- // 通知外面的组件
- this.$emit("input", this.form.records);
- }
- });
- },
- // 删除
- handleDelete(row, index) {
- this.saveButtonStatus.splice(index, 1); // 清空状态
- // 界面上临时新增出来的一行,还没有提交到数据库,可以直接删除
- if (this.saveButtonStatus[index] == "inAdding") {
- this.form.records.splice(index, 1);
- this.saveButtonStatus.splice(index, 1);
- this.$emit("input", this.form.records);
- return;
- }
- // if (this.isBlank(row) || this.isBlank(row[this.primaryKeyFieldName])) {
- // return
- // }
- // 将对应的行标识成删除
- // 找出该行在原始记录中的index
- let realIndex = this.form.records.findIndex(
- item => item[this.primaryKeyFieldName] == row[this.primaryKeyFieldName]
- );
- row[ROW_DELETE_FLAG] = true;
- this.$set(this.form.records, realIndex, row);
- this.$emit("input", this.form.records);
- }
- }
- };
- </script>
- <style scoped lang="scss">
- .table-add-row-button {
- width: 100%;
- margin-top: 0px;
- margin-bottom: 0px;
- border-color: #d9d9d9;
- border-style: dashed;
- line-height: 1.499;
- position: relative;
- display: inline-block;
- font-weight: 400;
- white-space: nowrap;
- text-align: center;
- background-image: none;
- border: 1px solid transparent;
- box-shadow: 0 2px 0 rgba(0, 0, 0, 0.015);
- cursor: pointer;
- transition: all 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);
- -webkit-user-select: none;
- -ms-user-select: none;
- user-select: none;
- -ms-touch-action: manipulation;
- touch-action: manipulation;
- height: 32px;
- padding: 0 15px;
- font-size: 14px;
- border-radius: 4px;
- color: rgba(0, 0, 0, 0.65);
- background-color: #fff;
- border-color: #d9d9d9;
- }
- </style>
|