<template>
  <div>
    <div class="i-layout-page-header">
      <PageHeader :title="$route.meta.title" :content="$route.meta.description" hidden-breadcrumb />
    </div>
    <Card :bordered="false" dis-hover class="ivu-mt">
      <view-table ref="table" view-code="User" @create="$refs.form.open()" :create-enable="allow('create')">
        <template #command="{ row }">
          <Button
            v-if="allow('role')"
            size="small"
            :title="$t('Front_Btn_Role')"
            type="info"
            custom-icon="fa fa-users"
            @click="$refs.userRoleTable.open({ userID: row.id })"
          ></Button>
          <Button
            v-if="allow('edit') || allow('resetPassword')"
            size="small"
            :title="$t('Front_Btn_Edit')"
            type="primary"
            custom-icon="fa fa-edit"
            @click="$refs.form.open(row)"
          ></Button>
          <Button
            v-if="allow('dataPermission')"
            size="small"
            :title="$t('Front_Btn_Data_Permission')"
            type="primary"
            custom-icon="fa fa-sitemap"
            @click="openDataPermission(row)"
          ></Button>
          <Button v-if="allow('remove')" size="small" :title="$t('Front_Btn_Remove')" type="warning" custom-icon="fa fa-trash-alt" @click="$refs.table.remove(row)"></Button>
        </template>
      </view-table>
    </Card>
    <modal-form ref="form" view-code="UserEdit" @on-after-save="$refs.table.loadData()">
      <template #footer>
        <Button v-if="allow('create') || allow('edit')" type="primary" custom-icon="fa fa-save" @click="$refs.form.onSave()">{{ $t('Front_Btn_Save') }}</Button>
        <Button v-if="allow('resetPassword')" type="primary" custom-icon="fa fa-user-lock" @click="resetPassword">{{ $t('Front_Btn_Reset_Password') }}</Button>
      </template>
    </modal-form>
    <modal-table ref="userRoleTable" view-code="UserRole" @edit="({ row }) => editUserRole(row)">
      <template #filterCommand>
        <Button size="small" type="primary" custom-icon="fa fa-plus" @click="addUserRole()">{{ $t('Front_Btn_Add') }}</Button>
      </template>
    </modal-table>
    <modal-form ref="userRoleForm" view-code="UserRoleEdit" @on-after-save="$refs.userRoleTable.loadData()" @on-change="userRoleChange">
      <template #bottom>
        <view-table ref="userRoleDataTable" view-code="UserRoleDataEdit" :static="true">
          <template #column="{ row, code }">
            <template v-if="row.controlType === 'TextInput'">
              <Input
                type="text"
                size="small"
                v-model="row.propertyValue"
                @on-change="
                  () => {
                    row.propertyDisplayValue = row.propertyValue;
                  }
                "
              />
            </template>
            <template v-else-if="row.controlType === 'NumberInput'">
              <Input
                type="number"
                size="small"
                number
                v-model="row.propertyValue"
                @on-change="
                  () => {
                    row.propertyDisplayValue = row.propertyValue;
                  }
                "
              />
            </template>
            <template v-else-if="row.controlType === 'Select'">
              <Select size="small" v-model="row.propertyValue" :clearable="true" :transfer="true" @on-change="selected => selectChange(selected, row)">
                <Option v-for="item in row._dataSource" :key="item.id" :value="item.id">{{ item.name }}</Option>
              </Select>
            </template>
            <template v-else-if="row.controlType === 'MultiSelect'">
              <Select
                size="small"
                :model-value="row.propertyValue == null ? null : JSON.parse(row.propertyValue)"
                @update:model-value="
                  $event => {
                    row.propertyValue = $event.length == 0 ? null : JSON.stringify($event);
                  }
                "
                :multiple="true"
                clearable
                :transfer="true"
                @on-change="selected => multiSelectChange(selected, row)"
              >
                <Option v-for="item in row._dataSource" :key="item.id" :value="item.id">{{ item.name }}</Option>
              </Select>
            </template>
            <template v-else-if="row.controlType === 'DialogSelect'">
              <dialog-select
                v-model="row.propertyValue"
                size="small"
                :source="row.source"
                :source-data-code="row.sourceDataCode"
                :source-display-code="row.sourceDisplayCode"
                :param="getParam(row)"
                @on-change="selected => dialogSelectChange(selected, row)"
              ></dialog-select>
            </template>
            <template v-else-if="row.controlType === 'MultiDialogSelect'">
              <dialog-select
                v-model="row.propertyValue"
                size="small"
                :multi="true"
                :source="row.source"
                :source-data-code="row.sourceDataCode"
                :source-display-code="row.sourceDisplayCode"
                :param="getParam(row)"
                @on-change="(selected, displaySelected) => multiDialogSelectChange(selected, displaySelected, row)"
              ></dialog-select>
            </template>
            <template v-else-if="row.controlType === 'Check'">
              <Checkbox :model-value="!!parseData(row, code)" @update:model-value="$event => setData(row, code, $event)" />
            </template>
          </template>
        </view-table>
      </template>
      <template #footer>
        <Button type="primary" custom-icon="fa fa-save" @click="userRoleSave">{{ $t('Front_Btn_Save') }}</Button>
      </template>
    </modal-form>
    <modal-form ref="dataPermissionForm" view-code="DataPermission">
      <template #footer>
        <Button type="primary" custom-icon="fa fa-save" @click="saveDataPermission">{{ $t('Front_Btn_Save') }}</Button>
      </template>
    </modal-form>
  </div>
</template>
<script>
  import mixinPage from '../../mixins/page';
  import modelApi from '../../api/model';
  import userApi from '../../api/user';
  import customModelApi from '../../api/customModel';

  export default {
    name: 'system-user',
    mixins: [mixinPage],
    components: {},
    data() {
      return {
        user: null,
        userID: null,
        factories: []
      };
    },
    computed: {},
    created() {},
    methods: {
      // 给角色添加用户
      async addUserRole() {
        this.$refs.userRoleForm.columns.find(item => item.code == 'roleID').isReadonly = false;

        this.$refs.userRoleDataTable.loadData([]);
        this.$refs.userRoleForm.openDefault(this.$refs.userRoleTable.param);
      },
      // 用户角色编辑
      async editUserRole(row) {
        this.$refs.userRoleForm.columns.find(item => item.code == 'roleID').isReadonly = true;

        this.initUserRoleData(row.userID, row.roleID);
        this.$refs.userRoleForm.open(row);
      },
      // 加载数据源
      async initDataSource() {
        for (let i = 0; i < this.roleProperties.length; i++) {
          let item = this.roleProperties[i];
          if (!!(item.source || '').trim()) {
            if (item.controlType === 'Select' || item.controlType === 'MultiSelect') {
              item._dataSource = [];
              let param = this.getParam(item);

              // 选择框、单选框组
              if (param != null) {
                await this.fillDataSource(item, param);
              }
            }
          }
        }
      },
      // 填充数据源
      async fillDataSource(data, param) {
        // 参数完整，查询数据
        let res;
        if (data.isSourceCustom) {
          res = await customModelApi.query(data.source, param, [data.sourceDataCode, data.sourceDisplayCode]);
        } else {
          res = await modelApi.query(data.source, param, [data.sourceDataCode, data.sourceDisplayCode]);
        }
        res.data.forEach(item => {
          data._dataSource.push({
            id: !(data.sourceDataCode || '').trim() ? item.id : this.parseData(item, data.sourceDataCode),
            name: this.parseData(item, data.sourceDisplayCode)
          });
        });
      },
      // 获取参数
      getParam(data) {
        let param = {};

        if (!!(data.param || '').trim()) {
          // 有参数
          param = JSON.parse(data.param);

          // 填充参数
          for (let key in param) {
            // 常量
            let index = param[key].search(/^\[.*?\]$/);
            if (index === 0) {
              param[key] = param[key].substring(1, param[key].length - 1);
              continue;
            }

            // 变量
            let paramData = this.parseData(data, param[key]);

            if (paramData != null) {
              param[key] = paramData;
              continue;
            }

            // 参数不完整
            return null;
          }
        }

        return param;
      },
      // 用户角色保存
      async userRoleSave() {
        let isOK = await this.$refs.userRoleForm.validate();

        if (!isOK) {
          this.error('Front_Msg_Form_Validate_Fail');
        } else {
          this.confirm('Front_Msg_Sure_To_Save', async () => {
            let userRole = this.$refs.userRoleForm.getFullData();

            if (!userRole) {
              // 表格验证失败
              return;
            }

            let userRoleDatas = this.$refs.userRoleDataTable.data;

            let data = {
              userRole,
              userRoleDatas
            };

            if (!userRole.id) {
              await modelApi.add('UserRole', data);
            } else {
              await modelApi.update('UserRole', data);
            }

            this.success('Front_Msg_Success', () => {
              this.$refs.userRoleDataTable.loadData([]);
              this.$refs.userRoleTable.loadData();
              this.$refs.userRoleForm.close();
            });
          });
        }
      },
      // 角色变化
      async userRoleChange(sender) {
        if (sender && sender.code == 'roleID') {
          let roleID = this.$refs.userRoleForm.data.roleID;
          let userID = this.$refs.userRoleForm.data.userID;

          this.initUserRoleData(userID, roleID);
        }
      },
      // 初始化用户角色数据
      async initUserRoleData(userID, roleID) {
        let res = await modelApi.query('RoleProperty', { roleID });
        let roleProperties = res.data;

        let userRoleDatas = [];

        if (this.$refs.userRoleForm.data.id) {
          res = await modelApi.query('UserRoleData', { userID: userID, roleID: roleID });
          userRoleDatas = res.data;
        }

        this.roleProperties = roleProperties.map(roleProperty => {
          let userRoleData = userRoleDatas.find(item => item.propertyCode == roleProperty.propertyCode);

          return {
            ...roleProperty,
            propertyValue: userRoleData == null ? null : userRoleData.propertyValue
          };
        });
        await this.initDataSource();

        this.$refs.userRoleDataTable.loadData(this.roleProperties);
      },
      // 重置密码
      async resetPassword() {
        this.confirm('Front_Msg_Sure_To_Reset_Password', async () => {
          await userApi.resetPassword(this.$refs.form.data.id);
          this.success('Front_Msg_Reset_Password_Success');
        });
      },
      // 打开数据权限
      openDataPermission(row) {
        let data = {};
        if (!!(row.dataPermission || '').trim()) {
          data = JSON.parse(row.dataPermission);
        }

        this.user = row;
        this.$refs.dataPermissionForm.open(data);
      },
      // 数据权限保存
      saveDataPermission() {
        let data = this.$refs.dataPermissionForm.data;
        for (let key in data) {
          if (typeof data[key] == 'object') {
            delete data[key];
          }
        }

        this.user.dataPermission = JSON.stringify(data);

        this.confirm('Front_Msg_Sure_To_Save', async () => {
          await modelApi.update('User', this.user);
          this.success('Front_Msg_Success');
          this.$refs.dataPermissionForm.close();
        });
      },
      selectChange(selected, row) {
        console.log('selectChange', selected, row);

        if (selected) {
          row.propertyDisplayValue = row._dataSource.find(item => item.id == selected).name;
        } else {
          row.propertyDisplayValue = null;
        }
      },
      multiSelectChange(selected, row) {
        let displayValue = [];

        selected.forEach(item => {
          displayValue.push(row._dataSource.find(i => i.id == item).name);
        });

        row.propertyDisplayValue = displayValue.join(',');
      },
      dialogSelectChange(selected, row) {
        if (selected) {
          row.propertyDisplayValue = selected.name;
        } else {
          row.propertyDisplayValue = null;
        }
      },
      multiDialogSelectChange(selected, displaySelected, row) {
        row.propertyDisplayValue = displaySelected;
      }
    }
  };
</script>
