diff --git a/package.json b/package.json
index 13f0bc8..eed6763 100644
--- a/package.json
+++ b/package.json
@@ -30,7 +30,8 @@
"vue-router": "3.0.6",
"vuex": "3.1.0",
"vxe-table": "^3.8.22",
- "wujie-vue2": "^1.0.22"
+ "wujie-vue2": "^1.0.22",
+ "moment": "^2.29.4"
},
"devDependencies": {
"@vue/cli-plugin-babel": "4.4.4",
diff --git a/src/api/attendance.js b/src/api/attendance.js
new file mode 100644
index 0000000..524dcea
--- /dev/null
+++ b/src/api/attendance.js
@@ -0,0 +1,19 @@
+import request from '@/utils/request'
+
+export function index(params, isLoading = true) {
+ return request({
+ method: 'get',
+ url: '/api/oa/attendance/index',
+ params,
+ isLoading
+ })
+}
+
+export function sign(params,isLoading = true) {
+ return request({
+ method: 'get',
+ url: '/api/oa/attendance/sign',
+ params,
+ isLoading
+ })
+}
diff --git a/src/api/document.js b/src/api/document.js
new file mode 100644
index 0000000..994d61f
--- /dev/null
+++ b/src/api/document.js
@@ -0,0 +1,72 @@
+// 公共文件柜
+import request from '@/utils/request'
+
+// 导航栏
+export function index(params) {
+ return request({
+ url: '/api/oa/document/index',
+ method: 'get',
+ params
+ })
+}
+export function show(params, isLoading = true) {
+ return request({
+ method: 'get',
+ url: '/api/oa/document/show',
+ params,
+ isLoading
+ })
+}
+
+export function save(data, isLoading = true) {
+ return request({
+ method: 'post',
+ url: '/api/oa/document/save',
+ data,
+ isLoading
+ })
+}
+
+export function destroy(params, isLoading = true) {
+ return request({
+ method: 'get',
+ url: '/api/oa/document/destroy',
+ params,
+ isLoading
+ })
+}
+
+// 文件柜
+export function menuIndex(params) {
+ return request({
+ url: '/api/oa/document-menu/index',
+ method: 'get',
+ params
+ })
+}
+export function menuShow(params, isLoading = true) {
+ return request({
+ method: 'get',
+ url: '/api/oa/document-menu/show',
+ params,
+ isLoading
+ })
+}
+
+export function menuSave(data, isLoading = true) {
+ return request({
+ method: 'post',
+ url: '/api/oa/document-menu/save',
+ data,
+ isLoading
+ })
+}
+
+export function menuDestroy(params, isLoading = true) {
+ return request({
+ method: 'get',
+ url: '/api/oa/document-menu/destroy',
+ params,
+ isLoading
+ })
+}
diff --git a/src/api/specialDays.js b/src/api/specialDays.js
new file mode 100644
index 0000000..8367765
--- /dev/null
+++ b/src/api/specialDays.js
@@ -0,0 +1,35 @@
+import request from '@/utils/request'
+
+export function index(params) {
+ return request({
+ method: 'get',
+ url: '/api/oa/special-days/index',
+ params
+ })
+}
+
+export function show(params) {
+ return request({
+ method: 'get',
+ url: '/api/oa/special-days/show',
+ params
+ })
+}
+
+export function save(data, isLoading = true) {
+ return request({
+ method: 'post',
+ url: '/api/oa/special-days/save',
+ data,
+ isLoading
+ })
+}
+
+export function destroy(params, isLoading = true) {
+ return request({
+ method: 'get',
+ url: '/api/oa/special-days/destroy',
+ params,
+ isLoading
+ })
+}
diff --git a/src/icons/svg/attendance.svg b/src/icons/svg/attendance.svg
new file mode 100644
index 0000000..c8530c8
--- /dev/null
+++ b/src/icons/svg/attendance.svg
@@ -0,0 +1 @@
+
diff --git a/src/icons/svg/data.svg b/src/icons/svg/data.svg
new file mode 100644
index 0000000..6a0deb2
--- /dev/null
+++ b/src/icons/svg/data.svg
@@ -0,0 +1 @@
+
diff --git a/src/icons/svg/filing-cabinet.svg b/src/icons/svg/filing-cabinet.svg
new file mode 100644
index 0000000..793739e
--- /dev/null
+++ b/src/icons/svg/filing-cabinet.svg
@@ -0,0 +1 @@
+
diff --git a/src/icons/svg/special-day.svg b/src/icons/svg/special-day.svg
new file mode 100644
index 0000000..8dbbc12
--- /dev/null
+++ b/src/icons/svg/special-day.svg
@@ -0,0 +1 @@
+
diff --git a/src/icons/svg/type.svg b/src/icons/svg/type.svg
new file mode 100644
index 0000000..4938c45
--- /dev/null
+++ b/src/icons/svg/type.svg
@@ -0,0 +1 @@
+
diff --git a/src/main.js b/src/main.js
index 725aebd..a6df84b 100644
--- a/src/main.js
+++ b/src/main.js
@@ -1,19 +1,19 @@
-import Vue from "vue";
+import Vue from 'vue'
-import "normalize.css/normalize.css"; // A modern alternative to CSS resets
+import 'normalize.css/normalize.css' // A modern alternative to CSS resets
-import ElementUI from "element-ui";
-import "element-ui/lib/theme-chalk/index.css";
-import locale from "element-ui/lib/locale/lang/en"; // lang i18n
+import ElementUI from 'element-ui'
+import 'element-ui/lib/theme-chalk/index.css'
+//import locale from 'element-ui/lib/locale/lang/en' // lang i18n
-import "@/styles/index.scss"; // global css
+import '@/styles/index.scss' // global css
-import App from "./App";
-import store from "./store";
-import router from "./router";
+import App from './App'
+import store from './store'
+import router from './router'
-import "@/icons"; // icon
-import "@/permission"; // permission control
+import '@/icons' // icon
+import '@/permission' // permission control
/**
* If you don't want to use mock-server
@@ -23,34 +23,37 @@ import "@/permission"; // permission control
* Currently MockJs will be used in the production environment,
* please remove it before going online ! ! !
*/
-if (process.env.NODE_ENV === "production") {
- const { mockXHR } = require("../mock");
- mockXHR();
+if (process.env.NODE_ENV === 'production') {
+ const { mockXHR } = require('../mock')
+ mockXHR()
}
+//moment
+import moment from 'moment'
+Vue.prototype.$moment = moment
// set ElementUI lang to EN
-//Vue.use(ElementUI, { locale });
+// Vue.use(ElementUI, { locale });
// 如果想要中文版 element-ui,按如下方式声明
- Vue.use(ElementUI)
+Vue.use(ElementUI)
-//vxetable
-import { VxeIcon, VxeTable, VxeColumn, VxeColgroup, VxeTableEditModule, VxeTableValidatorModule, VxeModal, VxeToolbar } from "vxe-table";
-import "vxe-table/styles/index.scss"
-Vue.use(VxeTableEditModule);
-Vue.use(VxeTableValidatorModule);
-Vue.use(VxeIcon);
-Vue.use(VxeTable);
-Vue.use(VxeColumn);
-Vue.use(VxeColgroup);
-Vue.use(VxeModal);
-Vue.use(VxeToolbar);
-//treeselect
+// vxetable
+import { VxeIcon, VxeTable, VxeColumn, VxeColgroup, VxeTableEditModule, VxeTableValidatorModule, VxeModal, VxeToolbar } from 'vxe-table'
+import 'vxe-table/styles/index.scss'
+Vue.use(VxeTableEditModule)
+Vue.use(VxeTableValidatorModule)
+Vue.use(VxeIcon)
+Vue.use(VxeTable)
+Vue.use(VxeColumn)
+Vue.use(VxeColgroup)
+Vue.use(VxeModal)
+Vue.use(VxeToolbar)
+// treeselect
import '@riophae/vue-treeselect/dist/vue-treeselect.css'
-import Treeselect from "@riophae/vue-treeselect"
-Vue.component("Treeselect",Treeselect);
+import Treeselect from '@riophae/vue-treeselect'
+Vue.component('Treeselect', Treeselect)
-import CardContainer from "@/layout/CardContainer.vue"
-Vue.component("CardContainer",CardContainer)
-//wujie
+import CardContainer from '@/layout/CardContainer.vue'
+Vue.component('CardContainer', CardContainer)
+// wujie
// import Wujie from "wujie-vue2";
// Vue.use(Wujie);
// const { setupApp, preloadApp } = Wujie;
@@ -62,11 +65,11 @@ Vue.component("CardContainer",CardContainer)
// url: "http://localhost:9530/admin/#/",
// exec: true,
// });
-Vue.config.productionTip = false;
+Vue.config.productionTip = false
new Vue({
- el: "#app",
+ el: '#app',
router,
store,
render: (h) => h(App)
-});
+})
diff --git a/src/views/DocumentMenu/index.vue b/src/views/DocumentMenu/index.vue
new file mode 100644
index 0000000..7c37403
--- /dev/null
+++ b/src/views/DocumentMenu/index.vue
@@ -0,0 +1,48 @@
+
+
+
+
+
+ 新增
+ 搜索
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/SpecialDays/components/addSpecialDays.vue b/src/views/SpecialDays/components/addSpecialDays.vue
new file mode 100644
index 0000000..1a5b91c
--- /dev/null
+++ b/src/views/SpecialDays/components/addSpecialDays.vue
@@ -0,0 +1,87 @@
+
+
+ $emit('update:isShow',e)"
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 确认
+
+
+
+
+
+
+
+
diff --git a/src/views/SpecialDays/index.vue b/src/views/SpecialDays/index.vue
new file mode 100644
index 0000000..72bdc17
--- /dev/null
+++ b/src/views/SpecialDays/index.vue
@@ -0,0 +1,203 @@
+
+
+
+
+
+ 新增
+ 搜索
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 保存
+ 取消
+
+
+ 编辑
+ 删除
+
+
+
+
+
+ {
+ select.page_size = e;
+ select.page = 1;
+ getList();
+ }"
+ @current-change="e => {
+ select.page = e;
+ getList();
+ }"
+ />
+
+
+
+
+
+
+
+
diff --git a/src/views/attendance/components/MonthStatics.vue b/src/views/attendance/components/MonthStatics.vue
new file mode 100644
index 0000000..451ea79
--- /dev/null
+++ b/src/views/attendance/components/MonthStatics.vue
@@ -0,0 +1,85 @@
+
+
+
+
+
+
{{ data.day.split('-')[2] }}
+
+ {{ $moment(dayAttendances(data.day).attendance.sign_in_at).format('HH:mm:ss') }}
+ {{ $moment(dayAttendances(data.day).attendance.sign_out_at).format('HH:mm:ss') }}
+
+ {{ $moment(dayAttendances(data.day).attendance.sign_in_at1).format('HH:mm:ss') }}
+ {{ $moment(dayAttendances(data.day).attendance.sign_out_at1).format('HH:mm:ss') }}
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/attendance/index.vue b/src/views/attendance/index.vue
new file mode 100644
index 0000000..5fa3b61
--- /dev/null
+++ b/src/views/attendance/index.vue
@@ -0,0 +1,95 @@
+
+
+
+
+
+
+
当前位置:
+
当前距离:
+
最大打卡范围:
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/document/index.vue b/src/views/document/index.vue
new file mode 100644
index 0000000..65244a5
--- /dev/null
+++ b/src/views/document/index.vue
@@ -0,0 +1,45 @@
+
+
+
+
+
+ 新增
+ 搜索
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/system/components/ModuleAuth.vue b/src/views/system/components/ModuleAuth.vue
index e97587d..6da0e47 100644
--- a/src/views/system/components/ModuleAuth.vue
+++ b/src/views/system/components/ModuleAuth.vue
@@ -6,36 +6,42 @@
direction="rtl"
size="72%"
append-to-body
- @close="$emit('update:isShow',false)">
-
-
+ @close="$emit('update:isShow',false)"
+ >
+
+
+ 展开
新增
搜索
-
-
+ :data="menus"
+ >
+
+
-
+
{{ row.path }}
@@ -45,7 +51,7 @@
-
+
{{ row.url }}
@@ -55,20 +61,20 @@
-
+
{{ row.api_profix }}
-
+
-
+
-
+
@@ -92,17 +98,18 @@
-
-
+ :data="roles"
+ >
+
+
@@ -110,7 +117,7 @@
-
+
@@ -130,18 +137,19 @@
-
-
-
+ :data="users"
+ >
+
+
+
@@ -149,7 +157,7 @@
-
+
绑定角色
@@ -162,10 +170,10 @@
-
-
-
-
+
+
+
+
@@ -173,7 +181,7 @@
import SvgIcon from '@/components/SvgIcon/index.vue'
import ModuleAuthAddMenu from './ModuleAuthAddMenu.vue'
import ModuleAuthAddRole from './ModuleAuthAddRole.vue'
-import Icon from "@/layout/components/Navbar/Icon.vue"
+import Icon from '@/layout/components/Navbar/Icon.vue'
import ModuleAuthBindPermissions from './ModuleAuthBindPermissions.vue'
import ModuleAuthBindRole from './ModuleAuthBindRole.vue'
import { menu, menuSave, menuDestroy, role, roleDestroy, roleSave, grant } from '@/api/module'
@@ -197,32 +205,32 @@ export default {
data() {
return {
loading: false,
- activeName: "menu",
- moduleId: "",
+ activeName: 'menu',
+ moduleId: '',
visible: false,
isShowAddMenu: false,
menus: [],
validMenuRules: {
name: [
- { required: true, message: "请输入名称" }
+ { required: true, message: '请输入名称' }
],
path: [
- { required: true, message: "请输入路由路径" },
+ { required: true, message: '请输入路由路径' }
],
api_profix: [
- { required: true, message: "请输入api前缀" }
+ { required: true, message: '请输入api前缀' }
]
},
menuForm: {
- id: "",
- module_id: "",
- pid: "",
- name: "",
- url: "",
- path: "",
- api_profix: "",
- icon: "",
+ id: '',
+ module_id: '',
+ pid: '',
+ name: '',
+ url: '',
+ path: '',
+ api_profix: '',
+ icon: '',
visible: 1,
sortnumber: 0
},
@@ -232,38 +240,74 @@ export default {
roleTotal: 0,
validRoleRules: {
name: [
- { required: true, message: "请输入角色" }
+ { required: true, message: '请输入角色' }
]
},
roleForm: {
- id: "",
- module_id: "",
- name: "",
+ id: '',
+ module_id: '',
+ name: '',
sortnumber: 0
},
isShowBindPermissions: false,
users: [],
userTotal: 0,
- isShowBindRoles: false,
+ isShowBindRoles: false
+ }
+ },
+ computed: {
+ isActiveStatus() {
+ return function(row, table) {
+ if (this.$refs[table]) {
+ return this.$refs[table].isEditByRow(row)
+ }
+ }
+ }
+ },
+ watch: {
+ isShow(newVal) {
+ this.visible = newVal
+ this.getMenu()
+ },
+ visible(newVal) {
+ this.$emit('update:isShow', newVal)
+ },
+ activeName: {
+ handler: function(newVal) {
+ switch (newVal) {
+ case 'menu':
+ this.getMenu()
+ break
+ case 'role':
+ this.getRole()
+ break
+ case 'permission':
+ this.getUsers()
+ break
+ }
+ }
}
},
+ created() {
+ this.getRole()
+ },
methods: {
bindPermission(row) {
- this.$refs['ModuleAuthBindPermissions'].setForm(['permission_id'],[row.permissions?.map(i => i.id)||[]])
+ this.$refs['ModuleAuthBindPermissions'].setForm(['permission_id'], [row.permissions?.map(i => i.id) || []])
this.isShowBindPermissions = true
},
bindRole(row) {
- this.$refs['ModuleAuthBindRole'].setForm(['id','role_id'],[row.id,row.roles?.map(i => i.id)||[]])
- this.isShowBindRoles = true;
+ this.$refs['ModuleAuthBindRole'].setForm(['id', 'role_id'], [row.id, row.roles?.map(i => i.id) || []])
+ this.isShowBindRoles = true
},
- editRowEvent (row,table) {
+ editRowEvent(row, table) {
if (this.$refs[table]) {
this.$refs[table].setEditRow(row)
}
},
- cancelRowEvent (row,table) {
+ cancelRowEvent(row, table) {
if (this.$refs[table]) {
this.$refs[table].clearEdit().then(() => {
// 还原行数据
@@ -277,7 +321,7 @@ export default {
},
async getMenu() {
- this.loading = true;
+ this.loading = true
try {
const res = await menu({
with_root: 1,
@@ -285,161 +329,127 @@ export default {
module_id: this.moduleId
})
console.log(res)
- this.menus = res;
- this.loading = false;
+ this.menus = res
+ this.loading = false
+ this.$nextTick(() => {
+ this.$refs['menuTable'].setAllTreeExpand(true)
+ })
} catch (err) {
console.error(err)
- this.loading = false;
+ this.loading = false
}
},
- async saveMenuRowEvent (row) {
+ async saveMenuRowEvent(row) {
try {
- await this.$confirm("确认保存?","提示",{
- confirmButtonText: "确认",
- cancelButtonText: "取消"
+ await this.$confirm('确认保存?', '提示', {
+ confirmButtonText: '确认',
+ cancelButtonText: '取消'
})
await this.$refs['menuTable'].clearEdit()
- let form = deepCopy(this.menuForm)
- for (let key in form) {
+ const form = deepCopy(this.menuForm)
+ for (const key in form) {
form[key] = row[key]
}
- this.loading = true;
+ this.loading = true
await menuSave(form)
- await this.getMenu();
- this.loading = false;
+ await this.getMenu()
+ this.loading = false
} catch (err) {
- this.loading = false;
+ this.loading = false
}
},
- async destroyMenuRowEvent (row) {
+ async destroyMenuRowEvent(row) {
try {
- await this.$confirm("确认删除?","提示",{
- confirmButtonText: "确认",
- cancelButtonText: "取消"
+ await this.$confirm('确认删除?', '提示', {
+ confirmButtonText: '确认',
+ cancelButtonText: '取消'
})
- this.loading = true;
+ this.loading = true
if (row.id) {
await menuDestroy({
id: row.id
})
- await this.getMenu();
+ await this.getMenu()
} else {
- this.menus.splice(this.menus.findIndex(i => i._X_ROW_KEY === row._X_ROW_KEY),1)
+ this.menus.splice(this.menus.findIndex(i => i._X_ROW_KEY === row._X_ROW_KEY), 1)
}
- this.loading = false;
+ this.loading = false
} catch (err) {
- this.loading = false;
+ this.loading = false
}
},
-
async getRole() {
- this.loading = true;
+ this.loading = true
try {
const res = await role({
module_id: this.moduleId
})
console.log(res)
- this.roles = res.rows;
- this.roleTotal = res.total;
- this.loading = false;
+ this.roles = res.rows
+ this.roleTotal = res.total
+ this.loading = false
} catch (err) {
console.error(err)
- this.loading = false;
+ this.loading = false
}
},
- async saveRoleRowEvent (row) {
+ async saveRoleRowEvent(row) {
try {
- await this.$confirm("确认保存?","提示",{
- confirmButtonText: "确认",
- cancelButtonText: "取消"
+ await this.$confirm('确认保存?', '提示', {
+ confirmButtonText: '确认',
+ cancelButtonText: '取消'
})
await this.$refs['menuTable'].clearEdit()
- let form = deepCopy(this.menuForm)
- for (let key in form) {
+ const form = deepCopy(this.menuForm)
+ for (const key in form) {
form[key] = row[key]
}
- this.loading = true;
+ this.loading = true
await roleSave(form)
- await this.getRole();
- this.loading = false;
+ await this.getRole()
+ this.loading = false
} catch (err) {
- this.loading = false;
+ this.loading = false
}
},
- async destroyRoleRowEvent (row) {
+ async destroyRoleRowEvent(row) {
try {
- await this.$confirm("确认删除?","提示",{
- confirmButtonText: "确认",
- cancelButtonText: "取消"
+ await this.$confirm('确认删除?', '提示', {
+ confirmButtonText: '确认',
+ cancelButtonText: '取消'
})
- this.loading = true;
+ this.loading = true
if (row.id) {
await roleDestroy({
id: row.id
})
- await this.getRole();
+ await this.getRole()
} else {
- this.roles.splice(this.roles.findIndex(i => i._X_ROW_KEY === row._X_ROW_KEY),1)
+ this.roles.splice(this.roles.findIndex(i => i._X_ROW_KEY === row._X_ROW_KEY), 1)
}
- this.loading = false;
+ this.loading = false
} catch (err) {
- this.loading = false;
+ this.loading = false
}
},
async getUsers() {
- this.loading = true;
+ this.loading = true
try {
const res = await grant({
module_id: this.moduleId
})
console.log(res)
- this.users = res.rows;
- this.userTotal = res.total;
- this.loading = false;
+ this.users = res.rows
+ this.userTotal = res.total
+ this.loading = false
} catch (err) {
console.error(err)
- this.loading = false;
- }
- }
- },
- computed: {
- isActiveStatus () {
- return function (row,table) {
- if (this.$refs[table]) {
- return this.$refs[table].isEditByRow(row)
- }
- }
- },
- },
- watch: {
- isShow(newVal) {
- this.visible = newVal;
- this.getMenu()
- },
- visible(newVal) {
- this.$emit('update:isShow', newVal);
- },
- activeName: {
- handler:function(newVal) {
- switch (newVal){
- case 'menu':
- this.getMenu()
- break;
- case 'role':
- this.getRole()
- break;
- case 'permission':
- this.getUsers()
- break;
- }
+ this.loading = false
}
}
- },
- created() {
- this.getRole()
}
}
diff --git a/src/views/system/department.vue b/src/views/system/department.vue
index 8d60160..961133d 100644
--- a/src/views/system/department.vue
+++ b/src/views/system/department.vue
@@ -73,14 +73,14 @@ export default {
tableData: [],
validRules: {
name: [
- { required: true, message: "请输入模块名称" }
+ { required: true, message: '请输入模块名称' }
]
},
form: {
- id: "",
- name: "",
- manager_id: "",
- leader_id: "",
+ id: '',
+ name: '',
+ manager_id: '',
+ leader_id: '',
sortnumber: 0
}
}
diff --git a/src/views/wujie/index.vue b/src/views/wujie/index.vue
index 18ce2bf..8d891ca 100644
--- a/src/views/wujie/index.vue
+++ b/src/views/wujie/index.vue
@@ -1,9 +1,7 @@
-
+
@@ -14,17 +12,27 @@
-
+
+
@@ -98,6 +108,13 @@ export default {
width: 100%;
height: 100%;
+ .loading {
+ position: absolute;
+ width: 100%;
+ height: 100%;
+ top: 0;
+ left: 0;
+ }
iframe {
width: 100%;
height: 100%;