<template>
  <div class="setting">
    <a-tabs tab-position="left" size="large" :tab-bar-style="objStr">
      <a-tab-pane key="1" :tab="$t('SYSTEM_PARAMETERS')">
        <MomTable
          ref="MomTable"
          row-key="id"
          :row-selection="rowSelection"
          :columns="tableColumns"
          :data-source="tableData"
          :query-param="queryForm"
          :query-param-item="queryFormItem"
          :total="total"
          :page.sync="page"
          :show-enable-flag="hasAuth('SYSTEM_CONFIG:ENABLED')"
          :action-buttons="tableAction"
          @beforeSearch="beforeSearch"
          @search="searchPageData"
          @edit="handleEdit"
          @delete="handleDelete"
          @enable="
            (record) =>
              handleStatus(
                { status: 'Y', id: record.id },
                'ENABLED',
                'ENABLED_DATA_INFO',
                'ENABLE_SUCCESS'
              )
          "
          @disable="
            (record) =>
              handleStatus(
                { status: 'N', id: record.id },
                'DISABLED',
                'DISABLED_DATA_INFO',
                'DISABLE_SUCCESS'
              )
          "
        >
          <a-row slot="toolbar" class="button-top-table">
            <a-button v-if="hasAuth('SYSTEM_CONFIG:ADD')" @click="handleAdd">
              <a-icon type="plus" />
              {{ $t("ADD") }}
            </a-button>
            <a-button
              v-if="hasAuth('SYSTEM_CONFIG:BATCH_DELETE')"
              type="danger"
              icon="delete"
              @click="handDelete"
            >
              {{ $t("BATCH_DELETE") }}
            </a-button>
          </a-row>
          <template slot="configLabel" slot-scope="text, record">
            <span>{{ $t(record.configLabel) }}</span>
          </template>
          <template slot="configType" slot-scope="text, record">
            <span>{{ formatData(typeOptions, record.configType) }}</span>
          </template>
          <div slot="enableFlag" slot-scope="text, record">
            <span v-if="record.enableFlag == 'Y'" style="color: #0fd19c">
              {{ formatData(stateList, record.enableFlag) }}
            </span>
            <span v-else style="color: #d45f5f">
              {{ formatData(stateList, record.enableFlag) }}
            </span>
          </div>
        </MomTable>
      </a-tab-pane>
      <a-tab-pane key="2" :tab="$t('PASSWORD_SETTING')">
        <PasswordSetting />
      </a-tab-pane>
      <a-tab-pane key="3" :tab="$t('THEME_SETTING')">
        <ThemeSetting />
      </a-tab-pane>
    </a-tabs>
    <MegaDrawer
      :visible.sync="drawerVisible"
      :title="isBatchAdd === true ? $t('ADD') : $t('EDIT')"
      width="520"
      @close="drawerVisible = false"
    >
      <a-form-model
        slot="main"
        ref="ruleForm"
        layout="vertical"
        :model="ruleForm"
      >
        <a-form-model-item
          :label="$t('CONFIG_CODE')"
          prop="configCode"
          :rules="{
            required: true,
            message: $t('PLACEENTER'),
            trigger: 'blur',
          }"
        >
          <a-input
            v-model="ruleForm.configCode"
            :placeholder="$t('PLACEENTER')"
          />
        </a-form-model-item>
        <a-form-model-item
          :label="$t('CONFIG_LABEL')"
          prop="name"
          :rules="{
            required: true,
            message: $t('PLACEENTER'),
            trigger: 'blur',
          }"
        >
          <a-row>
            <a-col>
              <SelectI18n
                ref="selectI18n"
                :value="ruleForm.name"
                @confirm="i18nSave"
                @handChange="handChange"
              ></SelectI18n>
            </a-col>
          </a-row>
        </a-form-model-item>
        <a-form-model-item
          :label="$t('CONFIG_TYPE')"
          prop="configType"
          :rules="{
            required: true,
            message: $t('PLACESELECT'),
            trigger: 'change',
          }"
        >
          <a-select
            v-model="ruleForm.configType"
            allow-clear
            show-search
            :placeholder="$t('PLACESELECT')"
          >
            <a-select-option
              v-for="item in typeOptions"
              :key="item.value"
              :value="item.value"
              >{{ item.label }}</a-select-option
            >
          </a-select>
        </a-form-model-item>
        <a-form-model-item
          v-if="ruleForm.configType"
          :label="$t('CONFIT_VALUE')"
          prop="objectName"
        >
          <a-input
            v-if="ruleForm.configType === 'INPUT'"
            v-model="ruleForm.configValue"
            allow-clear
          ></a-input>
          <a-input
            v-if="ruleForm.configType === 'PWD'"
            v-model="ruleForm.configValue"
            allow-clear
            name="password"
            type="password"
          >
          </a-input>
          <a-date-picker
            v-if="ruleForm.configType === 'DATE'"
            v-model="ruleForm.configValue"
            :placeholder="$t('PLACESELECT')"
            allow-clear
            style="width: 100%"
            format="YYYY-MM-DD"
          />
          <a-alert
            v-if="
              ruleForm.configType === 'IMG' &&
              ruleForm.configValue &&
              isBatchAdd === false
            "
            style="margin-bottom: 10px"
            :message="$t('SINGLE_PICTURE')"
            banner
          />
          <!-- 多图片上传 -->
          <MultipleUpload
            v-if="ruleForm.configType === 'MULT_IMG'"
            v-model="ruleForm.configValue"
            :limit="5"
            :image-url-list="fileUrlList"
            :mutiple="true"
          />
          <!-- 单图片上传 -->
          <MultipleUpload
            v-if="ruleForm.configType === 'IMG'"
            v-model="ruleForm.configValue"
            :image-url-list="fileUrlList"
            :limit="1"
            :mutiple="false"
          />
        </a-form-model-item>
      </a-form-model>
      <div slot="footer" class="drawer-footer">
        <a-button type="primary" @click="save">
          <Icon type="icon-cur-save_1" :size="18" /> {{ $t("SAVE") }}
        </a-button>
        <a-button @click="close">
          <Icon type="icon-dir-f-rollback" :size="18" /> {{ $t("CANCEL") }}
        </a-button>
      </div>
    </MegaDrawer>
  </div>
</template>

<script>
import { reduce as _reduce } from "lodash";
import { Drawer as MegaDrawer, Icon } from "@mega-design/ui-vue";
import { validCellphone, validEmail } from "@mega-apps/utils";
import { mapState } from "vuex";
import ApiConstant from "@/api/ApiConstant";
import MultipleUpload from "@/components/uploadPicture/multipleUpload";
import ThemeSetting from "@/components/AppSetting/ThemeSetting";
import SelectI18n from "@/components/SelectI18n/index";
import PasswordSetting from "@/components/AppSetting/PasswordSetting";

export default {
  components: {
    MultipleUpload,
    MegaDrawer,
    SelectI18n,
    ThemeSetting,
    PasswordSetting,
    Icon,
  },
  data() {
    return {
      activeName: "a",
      avatarUrl: "",
      modalVisible: false,
      objStr: {
        width: "220px",
      },
      fileUrlList: [],
      tableAction: [
        this.hasAuth("SYSTEM_CONFIG:EDIT") && "edit",
        this.hasAuth("SYSTEM_CONFIG:DELETE") && "delete",
      ],
      editPasswordForm: {
        oldPwd: "",
        newPwd: "",
        confirmPwd: "",
      },
      sexTypeList: [],
      isSave: true,
      userInfo: {
        userName: "", // 用户名
        password: "", // 密码
        employeeNo: "", // 员工工号
        name: "", // 姓名
        sex: "UNKNOWN", // 性别
        mobilePhone: "", // 手机号码
        email: "", // 邮箱
        workPhone: "", // 办公电话
      },
      selectedRowKeys: [],
      fileUrl: ``,
      drawerVisible: false,
      i18nDialogVisible: false,
      isBatchAdd: false,
      typeOptions: [],
      queryForm: {
        configCode: "", // 	名称
        configLabel: "", // 编码
        configType: "",
      },
      dictionaryCode: "DIC:EPM:PM_STATUS",
      // 表格的配置项
      tableData: [],
      stateList: [],
      total: 0,
      page: 1, // 页码
      limit: 1,
      fileList: [], // 文件列表
      dialogForm: {
        id: null,
        i18nCode: "",
        type: "",
      },
      oldI18nCode: null,
      typeList: [],
      // 表单的配置项详情
      dialogFormItem: {
        i18nCode: {
          i18n: "CODE", // 编码
          isRequired: true,
          rule: {
            max: 128,
            required: true,
            message: this.$t("PLACEENTER") + 128 + this.$t("LENGTH_TIP"),
            trigger: "blur",
          },
        },
        type: {
          itemType: "select",
          isRequired: true,
          i18n: "TYPE",
          width: 80,
          options: this.typeList,
        },
      },
      ruleForm: {
        configCode: "",
        configLabel: "",
        configType: "",
        configValue: "",
        name: "",
      },
    };
  },
  computed: {
    ...mapState({
      systemConfig: (state) => state.app.systemConfig,
    }),
    rowSelection() {
      return {
        selectedRowKeys: this.selectedRowKeys,
        onChange: (selectedRowKeys, selectedRows) => {
          this.selectedRowKeys = selectedRowKeys;
        },
      };
    },
    addFormRules() {
      return {
        mobilePhone: [
          {
            validator: (rule, value, callback) => {
              if (value && !validCellphone(value)) {
                callback(new Error(this.$t("PHONE_FORMAT_ERROR")));
              }
              callback();
            },
            trigger: "blur",
          },
        ],
        email: [
          {
            validator: (rule, value, callback) => {
              if (value && !validEmail(value)) {
                callback(new Error(this.$t("EMAIL_FORMAT_ERROR")));
              }
              callback();
            },
            trigger: "blur",
          },
        ],
      };
    },
    // 表单校验
    ruleFormRules() {
      return {
        oldPwd: [
          {
            required: true,
            message: this.$t("PLACEENTER"),
            trigger: "change",
          },
        ],
        newPwd: [
          {
            required: true,
            message: this.$t("PLACEENTER"),
            trigger: "change",
          },
        ],
        confirmPwd: [
          {
            required: true,
            message: this.$t("PLACEENTER"),
            trigger: "change",
          },
        ],
      };
    },

    ...mapState({
      locale: (state) => state.app.locale,
    }),
    hideUpload() {
      return this.fileList.length >= this.limit;
    },
    queryFormItem() {
      return this.$observable("queryFormItem", {
        configCode: {
          label: () => this.$t("CONFIG_CODE"),
        },
        configLabel: {
          label: () => this.$t("CONFIG_LABEL"),
        },
        configType: {
          label: () => this.$t("CONFIG_TYPE"),
          itemType: "select",
          options: [],
          optionsProps: {
            label: "label",
            value: "value",
          },
        },
      });
    },
    tableColumns() {
      return [
        {
          dataIndex: "configCode",
          width: 170,
          ellipsis: true,
          sorter: false,
          title: () => this.$t("CONFIG_CODE"),
        },
        {
          dataIndex: "configLabel",
          width: 180,
          ellipsis: true,
          sorter: false,
          title: () => this.$t("CONFIG_LABEL"),
          scopedSlots: { customRender: "configLabel" },
        },
        {
          dataIndex: "configType",
          title: () => this.$t("CONFIG_TYPE"),
          sorter: false,
          width: 180,
          scopedSlots: { customRender: "configType" },
        },
        {
          dataIndex: "configValue",
          width: 180,
          ellipsis: true,
          sorter: false,
          title: () => this.$t("CONFIT_VALUE"),
        },
        {
          dataIndex: "enableFlag",
          align: "left",
          sorter: false,
          width: 80,
          title: () => this.$t("STATUS"), // 状态
          scopedSlots: { customRender: "enableFlag" },
        },
        {
          dataIndex: "updateBy",
          sorter: false,
          title: () => this.$t("UPDATE_BY"),
          width: 120,
        },
        {
          dataIndex: "updateTime",
          sorter: false,
          title: () => this.$t("UPDATE_TIME"),
          width: 200,
        },
      ];
    },
  },
  beforeMount() {
    this.$store.state.app.languages.forEach((item) => {
      this.$set(this.dialogFormItem, item.value, {
        inputType: "textarea",
        i18n: item.label,
      });
    });
  },
  mounted() {},
  methods: {
    cancelPassword() {
      this.modalVisible = false;
      this.$refs.editPasswordForm.resetFields();
      this.editPasswordForm.oldPwd = "";
      this.editPasswordForm.newPwd = "";
      this.editPasswordForm.confirmPwd = "";
    },
    handUpdate() {
      this.$refs.userInfo.validate((valid) => {
        if (valid) {
          const params = {
            ...this.userInfo,
          };
          this.$axios
            .put(`${ApiConstant.PREFIX_CORE}/api/sys/user`, params)
            .then((res) => {
              this.$message.success(this.$t("SAVE_SUCCESS")); // 保存成功
            });
        }
      });
    },
    okPassword() {
      this.$refs.editPasswordForm.validate((valid) => {
        if (valid) {
          this.verification(
            this.editPasswordForm.newPwd,
            this.systemConfig.PWD_LENGTH,
            this.systemConfig.PWD_LEVEL
          );
          if (this.isSave) {
            if (
              this.editPasswordForm.newPwd !== this.editPasswordForm.confirmPwd
            ) {
              this.$message.error(this.$t("PASSWORD_SAMEWARN")); // 两次输入的密码必须相同
              return;
            }
            const { oldPwd, newPwd } = this.editPasswordForm;
            const req = {
              newPwd,
              oldPwd,
              passwordLevel: this.systemConfig.PWD_LEVEL,
            };
            this.$axios
              .put(`${ApiConstant.PREFIX_CORE}/api/sys/user/change-pwd`, req)
              .then(() => {
                this.modalVisible = false;
                this.$message.success(this.$t("SAVE_SUCCESS")); // 保存成功
              });
          }
        }
      });
    },
    verification(val, length, level) {
      if (val.length < length) {
        this.isSave = false;
        this.$message.error(this.$t("PASSWORD_LENGTH"));
      } else {
        if (level === "M") {
          const reg = /^(?![^a-zA-Z]+$)(?!\D+$)/;
          if (!reg.test(val)) {
            this.isSave = false;
            this.$message.error(this.$t("PASSWORD_LETTER"));
          } else {
            this.isSave = true;
          }
        }
        if (level === "H") {
          const res =
            /([0-9].*([a-zA-Z].*[!$#%?.&@~^]|[!$#%?.&~^].*[a-zA-Z])|[a-zA-Z].*([0-9].*[!$#%?.&~^]|[!$#%?.&~^].*[0-9])|[!$#%?.&].*([0-9].*[a-zA-Z]|[a-zA-Z].*[0-9]))/;
          if (!res.test(val)) {
            this.isSave = false;
            this.$message.error(this.$t("PASSWORD_SPECIAL"));
          } else {
            this.isSave = true;
          }
        }
      }
    },
    // 启用、禁用
    handleStatus(record, titleText, contentText, tips) {
      this.$confirm({
        title: this.$t(titleText),
        content: this.$t(contentText),
        okText: this.$t("CONFIRM"),
        cancelText: this.$t("CANCEL"),
        centered: false,
        icon: "exclamation-circle",
        onOk: () => {
          const { id, status } = record;
          this.$axios
            .put(
              `${ApiConstant.PREFIX_CORE}/api/sys/config/enable/${id}/${status}`
            )
            .then((res) => {
              this.$message.success(this.$t(tips));
              this.$refs.MomTable?.query();
            });
        },
      });
    },
    handChange(name, code) {
      this.$set(this.ruleForm, "name", name);
      this.ruleForm.configLabel = code;
    },
    formatData(data, status) {
      const result = data.find((item) => item.value === status.toString());
      return result ? result.label : "";
    },
    searchPageData(params) {
      this.$axios
        .get(`${ApiConstant.PREFIX_CORE}/api/sys/config/search`, { params })
        .then((res) => {
          this.tableData = res.data.data.records;
          this.total = res.data.data.total;
        });
    },
    handleAdd() {
      this.$set(this, "ruleForm", {
        configCode: "",
        configLabel: "",
        configType: "",
        configValue: "",
      });
      this.fileUrl = "";
      this.fileUrlList = [];
      this.isBatchAdd = true;
      this.drawerVisible = true;
      this.$nextTick(() => {
        this.$refs.ruleForm.clearValidate();
      });
    },
    handleEdit(row) {
      this.isBatchAdd = false;
      this.drawerVisible = true;
      this.$axios
        .get(`${ApiConstant.PREFIX_CORE}/api/sys/config/get-by-id/${row.id}`)
        .then((res) => {
          this.ruleForm = {
            ...res.data.data,
            name: `${res.data.data.configLabel}(${res.data.data.dataValue})`,
          };
          this.fileUrlList = this.ruleForm.configValue
            ? this.ruleForm.configValue?.split(",")
            : [];
          this.fileUrl = this.ruleForm.configValue;
        });
    },
    handDelete() {
      if (this.selectedRowKeys.length > 0) {
        this.$confirm({
          title: this.$t("DELETE"),
          content: this.$t("DELETE_INFO"),
          okType: "warning",
          okText: this.$t("DELETE"),
          cancelText: this.$t("CANCEL"),
          centered: false,
          icon: "close-circle",
          onOk: () => {
            this.$axios
              .delete(
                `${ApiConstant.PREFIX_CORE}/api/sys/config/batch-delete`,
                {
                  params: {
                    ids: this.selectedRowKeys.join(","),
                  },
                }
              )
              .then((res) => {
                this.$message.success(this.$t("DELETE_SUCCESS"));
                this.$refs.MomTable?.query();
              });
          },
        });
      } else {
        this.$message.error(this.$t("SELECT_ONE_DATA"));
      }
    },
    // 点击表格行内的删除
    handleDelete({ id }) {
      this.$confirm({
        title: this.$t("DELETE"),
        content: this.$t("DELETE_INFO"),
        okType: "warning",
        okText: this.$t("DELETE"),
        cancelText: this.$t("CANCEL"),
        centered: false,
        icon: "close-circle",
        onOk: () => {
          this.$axios
            .delete(`${ApiConstant.PREFIX_CORE}/api/sys/config/${id}`)
            .then((res) => {
              this.$message.success(this.$t("DELETE_SUCCESS"));
              this.$refs.MomTable?.query();
            });
        },
      });
    },
    i18nSave(val) {
      const { id, i18nCode, type } = val;
      const params = {
        i18nCode,
        type,
        items: this.$store.state.app.languages.map((item) => {
          const { label, value } = item;
          return {
            dataValue: val[value],
            i18nCode,
            languageCode: value,
            languageName: label,
          };
        }),
      };
      this.$refs.selectI18n.$refs.drawerForm.$refs.iForm.validate((valid) => {
        if (valid) {
          if (val.i18nCode === this.oldI18nCode && id) {
            this.$axios
              .put(`${ApiConstant.PREFIX_CORE}/api/sys/i18n`, {
                id,
                ...params,
              })
              .then(() => {
                this.$message.success(this.$t("EDIT_SUCCESS"));
                this.$emit("saveMenuCodeI18n", val.i18nCode);
                this.$refs.selectI18n.cancel();
                this.$emit("refreshTable");
              });
          } else {
            this.$axios
              .post(`${ApiConstant.PREFIX_CORE}/api/sys/i18n`, params)
              .then((res) => {
                this.$message.success(this.$t("ADD_SUCCESS"));
                this.$emit("saveMenuCodeI18n", val.i18nCode);
                this.$set(
                  this.ruleForm,
                  "name",
                  `${val.i18nCode}(${val[this.locale]})`
                );
                this.ruleForm.configLabel = val.i18nCode;
                this.$refs.selectI18n.cancel();
                this.$emit("refreshTable");
              });
          }
        }
      });
    },
    save() {
      this.$refs.ruleForm.validate((valid) => {
        if (valid) {
          const req = {
            ...this.ruleForm,
          };
          if (req.configType === "IMG") {
            const arr = req.configValue.split(",");
            if (arr.length > 1) {
              this.$message.error(this.$t("ONLY_ONE_UPLOADED"));
              return;
            }
          }
          if (this.isBatchAdd) {
            this.$axios
              .post(`${ApiConstant.PREFIX_CORE}/api/sys/config`, req)
              .then((res) => {
                this.$message.success(this.$t("ADD_SUCCESS"));
                this.$refs.MomTable?.query();
                this.drawerVisible = false;
              });
          } else {
            this.$axios
              .put(`${ApiConstant.PREFIX_CORE}/api/sys/config`, req)
              .then((res) => {
                this.$message.success(this.$t("EDIT_SUCCESS"));
                this.$refs.MomTable?.query();
                this.drawerVisible = false;
              });
          }
        } else {
          this.$message.error(this.$t("REQUIRED_INFO"));
        }
      });
    },
    close() {
      this.drawerVisible = false;
      this.$refs.ruleForm.clearValidate();
    },
    beforeSearch() {
      this.$axios
        .get(`${ApiConstant.PREFIX_CORE}/api/sys/config/list`)
        .then((res) => {
          this.ruleForm = res.data.data;
        });
      this.getDictByCode("DIC:CORE:CONFIG_TYPE").then((res) => {
        this.typeOptions = res.data.data;
        this.queryFormItem.configType.options = res.data.data;
      });
      this.getDictByCode("DIC:COMMON:ENABLE_FLAG").then((res) => {
        this.stateList = res?.data?.data || [];
      });
      // 类型
      this.getDictByCode("DIC:CORE:I18N_TYPE").then((res) => {
        this.dialogFormItem.type.options = res.data?.data;
      });
    },
  },
};
</script>

<style lang="less" scoped>
@import (optional, once) "@/theme/index.less";

.setting {
  padding-top: 20px;
  padding-right: 40px;
  /deep/ .ant-tabs .ant-tabs-left-content {
    min-height: calc(100vh - 126px);
  }
}
/deep/ .ant-tabs .ant-tabs-left-bar .ant-tabs-tab {
  text-align: left;
  margin: 0;
  line-height: 40px;
  font-size: 14px;
  padding: 8px 24px 8px 34px;
}
/deep/ .ant-tabs-nav .ant-tabs-tab-active {
  background: fade(@primary-color, 10%);
  border-right: 5px solid @primary-color;
}
/deep/ .ant-upload.ant-upload-select {
  width: 100%;
  height: 100%;
}
.editPassword {
  padding: 0 10px;
}
.passwordStr {
  display: flex;
  justify-content: space-between;
  padding: 10px 0 15px 0;
  border-bottom: 1px solid #d9d9d9;
  .edit {
    cursor: pointer;
    color: @primary-color;
  }
}
.expect {
  display: flex;
  justify-content: center;
  align-items: center;
}
</style>
