diff --git a/src/views/system/user/index.vue b/src/views/system/user/index.vue index c0f922e8..2b4bcc41 100644 --- a/src/views/system/user/index.vue +++ b/src/views/system/user/index.vue @@ -10,9 +10,12 @@ placeholder="请输入部门名称" clearable size="small" - prefix-icon="el-icon-search" style="margin-bottom: 20px" - /> + > + <template #prefix> + <Icon icon="ep:search" /> + </template> + </el-input> </div> <div class="head-container"> <el-tree @@ -20,10 +23,11 @@ :props="defaultProps" :expand-on-click-node="false" :filter-node-method="filterNode" - ref="tree" + ref="treeRef" + node-key="id" default-expand-all highlight-current - @node-click="handleNodeClick" + @node-click="handleDeptNodeClick" /> </div> </el-col> @@ -43,7 +47,7 @@ placeholder="请输入用户名称" clearable style="width: 240px" - @keyup.enter.native="handleQuery" + @keyup.enter="handleQuery" /> </el-form-item> <el-form-item label="手机号码" prop="mobile"> @@ -52,7 +56,7 @@ placeholder="请输入手机号码" clearable style="width: 240px" - @keyup.enter.native="handleQuery" + @keyup.enter="handleQuery" /> </el-form-item> <el-form-item label="状态" prop="status"> @@ -83,8 +87,8 @@ /> </el-form-item> <el-form-item> - <el-button type="primary" icon="el-icon-search" @click="handleQuery">搜索</el-button> - <el-button icon="el-icon-refresh" @click="resetQuery">重置</el-button> + <el-button type="primary" @click="handleQuery"><Icon icon="ep:search" />搜索</el-button> + <el-button @click="resetQuery"><Icon icon="ep:refresh" />重置</el-button> </el-form-item> </el-form> @@ -93,41 +97,37 @@ <el-button type="primary" plain - icon="el-icon-plus" - size="mini" + size="small" @click="handleAdd" v-hasPermi="['system:user:create']" - >新增</el-button + ><Icon icon="ep:plus" />新增</el-button > </el-col> <el-col :span="1.5"> <el-button type="info" - icon="el-icon-upload2" - size="mini" + size="small" @click="handleImport" v-hasPermi="['system:user:import']" - >导入</el-button + ><Icon icon="ep:upload" />导入</el-button > </el-col> <el-col :span="1.5"> <el-button type="warning" - icon="el-icon-download" - size="mini" + size="small" @click="handleExport" :loading="exportLoading" v-hasPermi="['system:user:export']" - >导出</el-button + ><Icon icon="ep:download" />导出</el-button > </el-col> - <right-toolbar + <!-- <right-toolbar :showSearch.sync="showSearch" @queryTable="getList" :columns="columns" - ></right-toolbar> + ></right-toolbar> --> </el-row> - <el-table v-loading="loading" :data="userList"> <el-table-column label="用户编号" @@ -169,7 +169,7 @@ width="120" /> <el-table-column label="状态" key="status" v-if="columns[5].visible" align="center"> - <template v-slot="scope"> + <template #default="scope"> <el-switch v-model="scope.row.status" :active-value="0" @@ -185,7 +185,7 @@ v-if="columns[6].visible" width="160" > - <template v-slot="scope"> + <template #default="scope"> <span>{{ parseTime(scope.row.createTime) }}</span> </template> </el-table-column> @@ -195,14 +195,13 @@ width="160" class-name="small-padding fixed-width" > - <template v-slot="scope"> + <template #default="scope"> <el-button - size="mini" + size="small" type="text" - icon="el-icon-edit" @click="handleUpdate(scope.row)" v-hasPermi="['system:user:update']" - >修改</el-button + ><Icon icon="ep:edit" />修改</el-button > <el-dropdown @command="(command) => handleCommand(command, scope.$index, scope.row)" @@ -212,630 +211,184 @@ 'system:permission:assign-user-role' ]" > - <el-button size="mini" type="text" icon="el-icon-d-arrow-right">更多</el-button> - <el-dropdown-menu slot="dropdown"> - <el-dropdown-item - command="handleDelete" - v-if="scope.row.id !== 1" - size="mini" - type="text" - icon="el-icon-delete" - v-hasPermi="['system:user:delete']" - >删除</el-dropdown-item - > - <el-dropdown-item - command="handleResetPwd" - size="mini" - type="text" - icon="el-icon-key" - v-hasPermi="['system:user:update-password']" - >重置密码</el-dropdown-item - > - <el-dropdown-item - command="handleRole" - size="mini" - type="text" - icon="el-icon-circle-check" - v-hasPermi="['system:permission:assign-user-role']" - >分配角色</el-dropdown-item - > - </el-dropdown-menu> + <el-button size="small" type="text"><Icon icon="ep:d-arrow-right" />更多</el-button> + <template #dropdown> + <el-dropdown-menu> + <el-dropdown-item + command="handleDelete" + v-if="scope.row.id !== 1" + size="small" + type="text" + v-hasPermi="['system:user:delete']" + ><Icon icon="ep:delete" />删除</el-dropdown-item + > + <el-dropdown-item + command="handleResetPwd" + size="small" + type="text" + v-hasPermi="['system:user:update-password']" + ><Icon icon="ep:key" />重置密码</el-dropdown-item + > + <el-dropdown-item + command="handleRole" + size="small" + type="text" + v-hasPermi="['system:permission:assign-user-role']" + ><Icon icon="ep:circle-check" />分配角色</el-dropdown-item + > + </el-dropdown-menu> + </template> </el-dropdown> </template> </el-table-column> </el-table> - <pagination v-show="total > 0" :total="total" - :page.sync="queryParams.pageNo" - :limit.sync="queryParams.pageSize" + v-model:page="queryParams.pageNo" + v-model:limit="queryParams.pageSize" @pagination="getList" /> </el-col> </el-row> - - <!-- 添加或修改参数配置对话框 --> - <el-dialog :title="title" :visible.sync="open" width="600px" append-to-body> - <el-form ref="form" :model="form" :rules="rules" label-width="80px"> - <el-row> - <el-col :span="12"> - <el-form-item label="用户昵称" prop="nickname"> - <el-input v-model="form.nickname" placeholder="请输入用户昵称" /> - </el-form-item> - </el-col> - <el-col :span="12"> - <el-form-item label="归属部门" prop="deptId"> - <treeselect - v-model="form.deptId" - :options="deptOptions" - :show-count="true" - :clearable="false" - placeholder="请选择归属部门" - :normalizer="normalizer" - /> - </el-form-item> - </el-col> - </el-row> - <el-row> - <el-col :span="12"> - <el-form-item label="手机号码" prop="mobile"> - <el-input v-model="form.mobile" placeholder="请输入手机号码" maxlength="11" /> - </el-form-item> - </el-col> - <el-col :span="12"> - <el-form-item label="邮箱" prop="email"> - <el-input v-model="form.email" placeholder="请输入邮箱" maxlength="50" /> - </el-form-item> - </el-col> - </el-row> - <el-row> - <el-col :span="12"> - <el-form-item v-if="form.id === undefined" label="用户名称" prop="username"> - <el-input v-model="form.username" placeholder="请输入用户名称" /> - </el-form-item> - </el-col> - <el-col :span="12"> - <el-form-item v-if="form.id === undefined" label="用户密码" prop="password"> - <el-input - v-model="form.password" - placeholder="请输入用户密码" - type="password" - show-password - /> - </el-form-item> - </el-col> - </el-row> - <el-row> - <el-col :span="12"> - <el-form-item label="用户性别"> - <el-select v-model="form.sex" placeholder="请选择"> - <el-option - v-for="dict in sexDictDatas" - :key="parseInt(dict.value)" - :label="dict.label" - :value="parseInt(dict.value)" - /> - </el-select> - </el-form-item> - </el-col> - <el-col :span="12"> - <el-form-item label="岗位"> - <el-select v-model="form.postIds" multiple placeholder="请选择"> - <el-option - v-for="item in postOptions" - :key="item.id" - :label="item.name" - :value="item.id" - ></el-option> - </el-select> - </el-form-item> - </el-col> - </el-row> - <el-row> - <el-col :span="24"> - <el-form-item label="备注"> - <el-input v-model="form.remark" type="textarea" placeholder="请输入内容"></el-input> - </el-form-item> - </el-col> - </el-row> - </el-form> - <div slot="footer" class="dialog-footer"> - <el-button type="primary" @click="submitForm">确 定</el-button> - <el-button @click="cancel">取 消</el-button> - </div> - </el-dialog> - - <!-- 用户导入对话框 --> - <el-dialog :title="upload.title" :visible.sync="upload.open" width="400px" append-to-body> - <el-upload - ref="upload" - :limit="1" - accept=".xlsx, .xls" - :headers="upload.headers" - :action="upload.url + '?updateSupport=' + upload.updateSupport" - :disabled="upload.isUploading" - :on-progress="handleFileUploadProgress" - :on-success="handleFileSuccess" - :auto-upload="false" - drag - > - <i class="el-icon-upload"></i> - <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div> - <div class="el-upload__tip text-center" slot="tip"> - <div class="el-upload__tip" slot="tip"> - <el-checkbox v-model="upload.updateSupport" /> 是否更新已经存在的用户数据 - </div> - <span>仅允许导入xls、xlsx格式文件。</span> - <el-link - type="primary" - :underline="false" - style="font-size: 12px; vertical-align: baseline" - @click="importTemplate" - >下载模板</el-link - > - </div> - </el-upload> - <div slot="footer" class="dialog-footer"> - <el-button type="primary" @click="submitFileForm">确 定</el-button> - <el-button @click="upload.open = false">取 消</el-button> - </div> - </el-dialog> - - <!-- 分配角色 --> - <el-dialog title="分配角色" :visible.sync="openRole" width="500px" append-to-body> - <el-form :model="form" label-width="80px"> - <el-form-item label="用户名称"> - <el-input v-model="form.username" :disabled="true" /> - </el-form-item> - <el-form-item label="用户昵称"> - <el-input v-model="form.nickname" :disabled="true" /> - </el-form-item> - <el-form-item label="角色"> - <el-select v-model="form.roleIds" multiple placeholder="请选择"> - <el-option - v-for="item in roleOptions" - :key="parseInt(item.id)" - :label="item.name" - :value="parseInt(item.id)" - ></el-option> - </el-select> - </el-form-item> - </el-form> - <div slot="footer" class="dialog-footer"> - <el-button type="primary" @click="submitRole">确 定</el-button> - <el-button @click="cancelRole">取 消</el-button> - </div> - </el-dialog> </div> </template> -<script> -import { - createUserApi as addUser, - updateUserStatusApi as changeUserStatus, - deleteUserApi as delUser, - exportUserApi as exportUser, - // TODO: praseStrEmpty(id) - getUserApi as getUser, - importUserTemplateApi as importTemplate, - getUserPageApi as listUser, - resetUserPwdApi as resetUserPwd, - updateUserApi as updateUser -} from '@/api/system/user' -// TODO: change -import Treeselect from '@riophae/vue-treeselect' -// TODO: change??? -import '@riophae/vue-treeselect/dist/vue-treeselect.css' - +<script setup lang="ts" name="User"> +import type { ElTree } from 'element-plus' +import { handleTree, defaultProps } from '@/utils/tree' import { listSimpleDeptApi } from '@/api/system/dept' -import { listSimplePostsApi } from '@/api/system/post' +import { listSimplePostsApi, PostVO } from '@/api/system/post' +import { DICT_TYPE, getDictOptions } from '@/utils/dict' +import { UserVO } from '@/api/system/user' +import { + // createUserApi, + // updateUserStatusApi, + // deleteUserApi, + // exportUserApi, + // getUserApi, + // importUserTemplateApi, + getUserPageApi + // resetUserPwdApid, + // updateUserApi +} from '@/api/system/user' -import { CommonStatusEnum } from '@/utils/constants' -import { DICT_TYPE, getDictDatas } from '@/utils/dict' -import { assignUserRole, listUserRoles } from '@/api/system/permission' -import { listSimpleRoles } from '@/api/system/role' -import { getBaseHeader } from '@/utils/request' +const queryParams = reactive({ + pageNo: 1, + pageSize: 10, + username: undefined, + mobile: undefined, + status: undefined, + deptId: undefined, + createTime: [] +}) +const showSearch = ref(true) +// 数据字典 +const statusDictDatas = getDictOptions(DICT_TYPE.COMMON_STATUS) +// const sexDictDatas = getDictOptions(DICT_TYPE.SYSTEM_USER_SEX) -export default { - name: 'User', - components: { Treeselect }, - data() { - return { - // 遮罩层 - loading: true, - // 导出遮罩层 - exportLoading: false, - // 显示搜索条件 - showSearch: true, - // 总条数 - total: 0, - // 用户表格数据 - userList: null, - // 弹出层标题 - title: '', - // 部门树选项 - deptOptions: undefined, - // 是否显示弹出层 - open: false, - // 部门名称 - deptName: undefined, - // 默认密码 - initPassword: undefined, - // 性别状态字典 - sexOptions: [], - // 岗位选项 - postOptions: [], - // 角色选项 - roleOptions: [], - // 表单参数 - form: {}, - defaultProps: { - children: 'children', - label: 'name' - }, - // 用户导入参数 - upload: { - // 是否显示弹出层(用户导入) - open: false, - // 弹出层标题(用户导入) - title: '', - // 是否禁用上传 - isUploading: false, - // 是否更新已经存在的用户数据 - updateSupport: 0, - // 设置上传的请求头部 - headers: getBaseHeader(), - // 上传的地址 - url: process.env.VUE_APP_BASE_API + '/admin-api/system/user/import' - }, - // 查询参数 - queryParams: { - pageNo: 1, - pageSize: 10, - username: undefined, - mobile: undefined, - status: undefined, - deptId: undefined, - createTime: [] - }, - // 列信息 - columns: [ - { key: 0, label: `用户编号`, visible: true }, - { key: 1, label: `用户名称`, visible: true }, - { key: 2, label: `用户昵称`, visible: true }, - { key: 3, label: `部门`, visible: true }, - { key: 4, label: `手机号码`, visible: true }, - { key: 5, label: `状态`, visible: true }, - { key: 6, label: `创建时间`, visible: true } - ], - // 表单校验 - rules: { - username: [{ required: true, message: '用户名称不能为空', trigger: 'blur' }], - nickname: [{ required: true, message: '用户昵称不能为空', trigger: 'blur' }], - password: [{ required: true, message: '用户密码不能为空', trigger: 'blur' }], - email: [ - { - type: 'email', - message: "'请输入正确的邮箱地址", - trigger: ['blur', 'change'] - } - ], - mobile: [ - { - pattern: - /^(?:(?:\+|00)86)?1(?:3[\d]|4[5-79]|5[0-35-9]|6[5-7]|7[0-8]|8[\d]|9[189])\d{8}$/, - message: '请输入正确的手机号码', - trigger: 'blur' - } - ] - }, - // 是否显示弹出层(角色权限) - openRole: false, +// ========== 创建部门树结构 ========== +const deptName = ref('') +const deptOptions = ref<Tree[]>([]) // 树形结构 +const treeRef = ref<InstanceType<typeof ElTree>>() +const getTree = async () => { + const res = await listSimpleDeptApi() + deptOptions.value.push(...handleTree(res)) +} +const filterNode = (value: string, data: Tree) => { + if (!value) return true + return data.name.includes(value) +} +const handleDeptNodeClick = async (row: { [key: string]: any }) => { + queryParams.deptId = row.id + // await reload() + getList() +} +// 获取岗位列表 +const postOptions = ref<PostVO[]>([]) //岗位列表 +const getPostOptions = async () => { + const res = await listSimplePostsApi() + postOptions.value.push(...res) +} +// 用户列表 +const userList = ref<UserVO[]>([]) +const loading = ref(false) +const total = ref(0) +const columns = ref([ + { key: 0, label: `用户编号`, visible: true }, + { key: 1, label: `用户名称`, visible: true }, + { key: 2, label: `用户昵称`, visible: true }, + { key: 3, label: `部门`, visible: true }, + { key: 4, label: `手机号码`, visible: true }, + { key: 5, label: `状态`, visible: true }, + { key: 6, label: `创建时间`, visible: true } +]) +const getList = () => { + loading.value = true + getUserPageApi(queryParams).then((response) => { + userList.value = response.list + total.value = response.total + loading.value = false + }) +} +const handleQuery = () => {} +const resetQuery = () => {} +const handleAdd = () => {} +const handleImport = () => {} +const exportLoading = ref(false) +const handleExport = () => {} +const handleStatusChange = () => {} +const handleUpdate = () => {} +const handleCommand = () => {} +// ========== 初始化 ========== +onMounted(async () => { + getList() + await getPostOptions() + await getTree() +}) - // 枚举 - SysCommonStatusEnum: CommonStatusEnum, - // 数据字典 - statusDictDatas: getDictDatas(DICT_TYPE.COMMON_STATUS), - sexDictDatas: getDictDatas(DICT_TYPE.SYSTEM_USER_SEX) - } - }, - watch: { - // 根据名称筛选部门树 - deptName(val) { - this.$refs.tree.filter(val) - } - }, - created() { - this.getList() - this.getTreeselect() - // this.getConfigKey("sys.user.init-password").then(response => { - // this.initPassword = response.msg; - // }); - }, - methods: { - // 更多操作 - handleCommand(command, index, row) { - switch (command) { - case 'handleUpdate': - this.handleUpdate(row) //修改客户信息 - break - case 'handleDelete': - this.handleDelete(row) //红号变更 - break - case 'handleResetPwd': - this.handleResetPwd(row) - break - case 'handleRole': - this.handleRole(row) - break - default: - break - } - }, - /** 查询用户列表 */ - getList() { - this.loading = true - listUser(this.queryParams).then((response) => { - this.userList = response.data.list - this.total = response.data.total - this.loading = false - }) - }, - /** 查询部门下拉树结构 + 岗位下拉 */ - getTreeselect() { - listSimpleDeptApi().then((response) => { - // 处理 deptOptions 参数 - this.deptOptions = [] - this.deptOptions.push(...this.handleTree(response.data, 'id')) - }) - listSimplePostsApi().then((response) => { - // 处理 postOptions 参数 - this.postOptions = [] - this.postOptions.push(...response.data) - }) - }, - // 筛选节点 - filterNode(value, data) { - if (!value) return true - return data.name.indexOf(value) !== -1 - }, - // 节点单击事件 - handleNodeClick(data) { - this.queryParams.deptId = data.id - this.getList() - }, - // 用户状态修改 - handleStatusChange(row) { - let text = row.status === CommonStatusEnum.ENABLE ? '启用' : '停用' - this.$modal - .confirm('确认要"' + text + '""' + row.username + '"用户吗?') - .then(function () { - return changeUserStatus(row.id, row.status) - }) - .then(() => { - this.$modal.msgSuccess(text + '成功') - }) - .catch(function () { - row.status = - row.status === CommonStatusEnum.ENABLE - ? CommonStatusEnum.DISABLE - : CommonStatusEnum.ENABLE - }) - }, - // 取消按钮 - cancel() { - this.open = false - this.reset() - }, - // 取消按钮(角色权限) - cancelRole() { - this.openRole = false - this.reset() - }, - // 表单重置 - reset() { - this.form = { - id: undefined, - deptId: undefined, - username: undefined, - nickname: undefined, - password: undefined, - mobile: undefined, - email: undefined, - sex: undefined, - status: '0', - remark: undefined, - postIds: [], - roleIds: [] - } - this.resetForm('form') - }, - /** 搜索按钮操作 */ - handleQuery() { - this.queryParams.pageNo = 1 - this.getList() - }, - /** 重置按钮操作 */ - resetQuery() { - this.resetForm('queryForm') - this.handleQuery() - }, - /** 新增按钮操作 */ - handleAdd() { - this.reset() - // 获得下拉数据 - this.getTreeselect() - // 打开表单,并设置初始化 - this.open = true - this.title = '添加用户' - this.form.password = this.initPassword - }, - /** 修改按钮操作 */ - handleUpdate(row) { - this.reset() - this.getTreeselect() - const id = row.id - getUser(id).then((response) => { - this.form = response.data - this.open = true - this.title = '修改用户' - this.form.password = '' - }) - }, - /** 重置密码按钮操作 */ - handleResetPwd(row) { - this.$prompt('请输入"' + row.username + '"的新密码', '提示', { - confirmButtonText: '确定', - cancelButtonText: '取消' - }) - .then(({ value }) => { - resetUserPwd(row.id, value).then((response) => { - this.$modal.msgSuccess('修改成功,新密码是:' + value) - }) - }) - .catch(() => {}) - }, - /** 分配用户角色操作 */ - handleRole(row) { - this.reset() - const id = row.id - // 处理了 form 的用户 username 和 nickname 的展示 - this.form.id = id - this.form.username = row.username - this.form.nickname = row.nickname - // 打开弹窗 - this.openRole = true - // 获得角色列表 - listSimpleRoles().then((response) => { - // 处理 roleOptions 参数 - this.roleOptions = [] - this.roleOptions.push(...response.data) - }) - // 获得角色拥有的菜单集合 - listUserRoles(id).then((response) => { - // 设置选中 - this.form.roleIds = response.data - }) - }, - /** 提交按钮 */ - submitForm: function () { - this.$refs['form'].validate((valid) => { - if (valid) { - if (this.form.id !== undefined) { - updateUser(this.form).then((response) => { - this.$modal.msgSuccess('修改成功') - this.open = false - this.getList() - }) - } else { - addUser(this.form).then((response) => { - this.$modal.msgSuccess('新增成功') - this.open = false - this.getList() - }) - } - } - }) - }, - /** 提交按钮(角色权限) */ - submitRole: function () { - if (this.form.id !== undefined) { - assignUserRole({ - userId: this.form.id, - roleIds: this.form.roleIds - }).then((response) => { - this.$modal.msgSuccess('分配角色成功') - this.openRole = false - this.getList() - }) - } - }, - /** 删除按钮操作 */ - handleDelete(row) { - const ids = row.id || this.ids - this.$modal - .confirm('是否确认删除用户编号为"' + ids + '"的数据项?') - .then(function () { - return delUser(ids) - }) - .then(() => { - this.getList() - this.$modal.msgSuccess('删除成功') - }) - .catch(() => {}) - }, - /** 导出按钮操作 */ - handleExport() { - this.$modal - .confirm('是否确认导出所有用户数据项?') - .then(() => { - // 处理查询参数 - let params = { ...this.queryParams } - params.pageNo = undefined - params.pageSize = undefined - this.exportLoading = true - return exportUser(params) - }) - .then((response) => { - this.$download.excel(response, '用户数据.xls') - this.exportLoading = false - }) - .catch(() => {}) - }, - /** 导入按钮操作 */ - handleImport() { - this.upload.title = '用户导入' - this.upload.open = true - }, - /** 下载模板操作 */ - importTemplate() { - importTemplate().then((response) => { - this.$download.excel(response, '用户导入模板.xls') - }) - }, - // 文件上传中处理 - handleFileUploadProgress(event, file, fileList) { - this.upload.isUploading = true - }, - // 文件上传成功处理 - handleFileSuccess(response, file, fileList) { - if (response.code !== 0) { - this.$modal.msgError(response.msg) - return - } - this.upload.open = false - this.upload.isUploading = false - this.$refs.upload.clearFiles() - // 拼接提示语 - let data = response.data - let text = '创建成功数量:' + data.createUsernames.length - for (const username of data.createUsernames) { - text += '<br /> ' + username - } - text += '<br />更新成功数量:' + data.updateUsernames.length - for (const username of data.updateUsernames) { - text += '<br /> ' + username - } - text += '<br />更新失败数量:' + Object.keys(data.failureUsernames).length - for (const username in data.failureUsernames) { - text += '<br /> ' + username + ':' + data.failureUsernames[username] - } - this.$alert(text, '导入结果', { dangerouslyUseHTMLString: true }) - this.getList() - }, - // 提交上传文件 - submitFileForm() { - this.$refs.upload.submit() - }, - // 格式化部门的下拉框 - normalizer(node) { - return { - id: node.id, - label: node.name, - children: node.children - } - } +const parseTime = (time) => { + if (!time) { + return null } + const format = '{y}-{m}-{d} {h}:{i}:{s}' + let date + if (typeof time === 'object') { + date = time + } else { + if (typeof time === 'string' && /^[0-9]+$/.test(time)) { + time = parseInt(time) + } else if (typeof time === 'string') { + time = time + .replace(new RegExp(/-/gm), '/') + .replace('T', ' ') + .replace(new RegExp(/\.[\d]{3}/gm), '') + } + if (typeof time === 'number' && time.toString().length === 10) { + time = time * 1000 + } + date = new Date(time) + } + const formatObj = { + y: date.getFullYear(), + m: date.getMonth() + 1, + d: date.getDate(), + h: date.getHours(), + i: date.getMinutes(), + s: date.getSeconds(), + a: date.getDay() + } + const time_str = format.replace(/{(y|m|d|h|i|s|a)+}/g, (result, key) => { + let value = formatObj[key] + // Note: getDay() returns 0 on Sunday + if (key === 'a') { + return ['日', '一', '二', '三', '四', '五', '六'][value] + } + if (result.length > 0 && value < 10) { + value = '0' + value + } + return value || 0 + }) + return time_str } </script>