This commit is contained in:
shijing 2025-12-03 15:35:11 +08:00
commit 7d53a9cd0f
19 changed files with 304 additions and 225 deletions

View File

@ -144,7 +144,9 @@
z-index: 1;
height: 60upx;
padding: 12upx;
margin-left: -20upx;
left: 0;
background-color: white;
display: flex;
margin: auto;
}
</style>

View File

@ -25,9 +25,13 @@ import App from './App.vue'
import api from './utils/api'
import check from './utils/check'
import config from './utils/config.js'
import { authDirective } from '@/utils/directives.js'
export function createApp() {
const app = createSSRApp(App)
app.directive('auth', authDirective)
app.config.globalProperties.$api = api
app.config.globalProperties.$check = check
app.config.globalProperties.$config = config

View File

@ -95,7 +95,7 @@
"vueVersion" : "3",
"h5" : {
"router" : {
"base" : "/h5/",
"base" : "/h5x/",
"mode" : "hash"
},
"devServer" : {

View File

@ -27,21 +27,21 @@
}
},
{
"path" : "pages/ofm/booking_form",
"path" : "pages/ofm/mroombooking_form",
"style" :
{
"navigationBarTitleText" : "会议室预约"
}
},
{
"path" : "pages/ofm/sealForm",
"path" : "pages/ofm/seal_form",
"style" :
{
"navigationBarTitleText" : "印章申请"
}
},
{
"path" : "pages/ofm/vehicleForm",
"path" : "pages/ofm/vehicle_form",
"style" :
{
"navigationBarTitleText" : "用车申请"
@ -55,7 +55,7 @@
}
},
{
"path" : "pages/ofm/publicityForm",
"path" : "pages/ofm/publicity_form",
"style" :
{
"navigationBarTitleText" : "宣传报道"
@ -111,7 +111,7 @@
}
},
{
"path" : "pages/ofm/booking",
"path" : "pages/ofm/mroombooking",
"style" :
{
"navigationBarTitleText" : "预约记录",

View File

@ -48,6 +48,7 @@
<script>
import config from '/utils/config';
import { auth } from '@/utils/auth.js'
export default {
data() {
return {
@ -207,6 +208,7 @@
uni.setStorageSync('access', res.access)
that.$api.getUserInfo().then(res => {
uni.setStorageSync('userInfo', res)
auth.setPermissions(Object.keys(res.perms))
uni.reLaunch({
url: '/pages/index/index'
})
@ -237,6 +239,7 @@
uni.setStorageSync('access', res.access)
that.$api.getUserInfo().then(res => {
uni.setStorageSync('userInfo', res)
auth.setPermissions(Object.keys(res.perms))
uni.reLaunch({
url: '/pages/index/index'
})
@ -295,6 +298,7 @@
uni.setStorageSync('access', res.access)
that.$api.getUserInfo().then(res => {
uni.setStorageSync('userInfo', res)
auth.setPermissions(Object.keys(res.perms))
that.bindXX()
uni.reLaunch({
url: '/pages/index/index'
@ -311,6 +315,7 @@
that.bindXX()
that.$api.getUserInfo().then(res => {
uni.setStorageSync('userInfo', res)
auth.setPermissions(Object.keys(res.perms))
uni.reLaunch({
url: '/pages/index/index'
})

View File

@ -2,16 +2,16 @@
<template>
<view class="container">
<scroll-view scroll-y style="padding-bottom: 180rpx;background-color: #fff;">
<uni-forms v-model="form" label-width="150rpx" ref="customForm" :rules="customRules">
<uni-forms v-model="form" label-width="180rpx" ref="customForm" :rules="customRules">
<ticketd :ticket_="form.ticket_"></ticketd>
<uni-forms-item label="姓名" required>
<uni-easyinput v-model="form.employee_name" placeholder="请输入姓名" :disabled="mode=='show'"/>
<uni-forms-item label="姓名">
<uni-easyinput v-model="form.employee_name" placeholder="请输入姓名" :disabled="true"/>
</uni-forms-item>
<uni-forms-item label="部门" required>
<uni-easyinput v-model="form.belong_dept_name" placeholder="请输入岗位" :disabled="mode=='show'"/>
<uni-forms-item label="部门">
<uni-easyinput v-model="form.belong_dept_name" placeholder="请输入岗位" :disabled="true"/>
</uni-forms-item>
<uni-forms-item label="岗位" required>
<uni-easyinput v-model="form.post_name" placeholder="请输入岗位" :disabled="mode=='show'"/>
<uni-forms-item label="岗位">
<uni-easyinput v-model="form.post_name" placeholder="请输入岗位" :disabled="true"/>
</uni-forms-item>
<uni-forms-item label="离职时间" required>
<uni-datetime-picker type="date" :clear-icon="false" v-model="form.end_date" v-if="mode!='show'"/>
@ -22,15 +22,21 @@
<uni-forms-item label-width="100">
<textarea placeholder-style="color:#efefef" v-model="form.reason" placeholder="离职原因" style="width:100%; border: 2upx solid #e5e5e5;padding: 10upx;"/>
</uni-forms-item>
<uni-forms-item label="办理离职交接日期" required v-if="form.ticket_&&form.ticket_.state_">
<uni-datetime-picker type="date" :clear-icon="false" v-model="ticket_data.handle_date" v-if="form.ticket_?.state_?.name=='部门负责人'"/>
<span v-else>{{form.ticket_.ticket_data.handle_date}}</span>
<uni-forms-item label="办理离职交接日期" required>
<uni-datetime-picker type="date" v-model="ticket_data.handle_date" v-if="form.ticket_?.state_?.name=='部门负责人'"/>
<span v-else>{{form.handle_date}}</span>
</uni-forms-item>
</uni-forms>
</scroll-view>
<view class="footer_fixed">
<ticketd_b :workflow_key="'wf_resignation'" :title="form.employee_name + '-离职申请'" :t_id="form.id" :ticket_="form.ticket_"
:ticket_data="ticket_data" @success="submitSuccess" :submit_b_func="submit_b_func" ref="ticketd_b_start"></ticketd_b>
<button v-if="mode=='edit'" size="mini" @click="handleDel" :loading="saveLoading" :disabled="saveLoading" type="warn">
删除
</button>
<ticketd_b v-if="form.ticket_" :t_id="form.id" :ticket_="form.ticket_"
:ticket_data="ticket_data" @success="()=>{uni.navigateBack()}" ref="ticketd_b"></ticketd_b>
<button v-else size="mini" @click="handleSave" :loading="saveLoading" :disabled="saveLoading" type="primary">
提交审批
</button>
</view>
</view>
</template>
@ -43,7 +49,8 @@ import {actStateEnum} from "@/utils/enum.js"
components: { ticketd_b, ticketd },
data(){
return{
mode:"add",
saveLoading: false,
mode:"show",
t_id: null,
form:{
reason:"",
@ -78,17 +85,9 @@ import {actStateEnum} from "@/utils/enum.js"
},
async onLoad(options) {
let that = this;
let userInfo = uni.getStorageSync("userInfo");
that.form.employee_name = userInfo.name;
that.form.post_name = userInfo.post_name;
that.form.post = userInfo.post;
that.form.belong_dept = userInfo.belong_dept;
that.form.belong_dept_name = userInfo.belong_dept_name;
that.form.id='';
that.mode = options.mode?options.mode:'show';
that.t_id = options.t_id?options.t_id:null;
if(that.mode != "add"){
if(that.t_id) {
if(that.t_id) {
that.form = await that.$api.resignationItem(that.t_id);
if(that.form.ticket_.state_.type == 1 && that.form.create_by == uni.getStorageSync("userInfo").id ) {
that.mode = "edit";
@ -96,34 +95,33 @@ import {actStateEnum} from "@/utils/enum.js"
that.mode = "show";
}
}
}else{
else{
that.getEmployee();
}
},
methods:{
async getEmployee(){
let res = await this.$api.employeeInfo();
this.form.employee_name = res.name;
this.form.belong_dept_name = res.belong_dept_name;
this.form.post_name = res.post_name;
this.form.employee = res.id;
this.mode = "add";
},
async handleDel(){
let that = this;
let obj = {search:that.form.employee_name,page:0,query:'{name,id}'}
let res = await that.$api.employeeList(obj);
that.form.employee = res[0].id;
await that.$api.resignationDelete(that.form.id)
uni.navigateBack()
},
sealChange(){
console.log('seal1',this.seal1)
},
async submit_b_func(id){
async handleSave(){
let that = this;
that.$refs.customForm.validate().then(res => {
}).catch(err => {
console.log('err', err);
})
let res = await that.$api.resignationCreate(that.form)
that.form.id = res.id;
},
submitSuccess(){
uni.navigateTo({
url: "/pages/index/index"
})
await that.$api.resignationCreate(that.form)
uni.navigateBack()
},
}
}

View File

@ -12,120 +12,87 @@
<uni-col :span="12" style="border-radius: 20upx;">
<navigator class="middleNavigator" url="../wf/index?category=duty">
<span>待办</span>
<span class="numSpan">3</span>
<span class="numSpan">{{duty_count}}</span>
</navigator>
</uni-col>
<uni-col :span="12">
<navigator class="middleNavigator" url="../wf/index?category=owner">
<span>我的</span>
<span class="numSpan">3</span>
<span class="numSpan">{{owner_count}}</span>
</navigator>
</uni-col>
</uni-row>
<view style="height: 12rpx;"></view>
<uni-section title="功能入口" type="line">
<uni-grid :column="5" :show-border="false" :square="false">
<uni-grid-item v-for="(item ,index) in moduleList" :index="index" :key="index">
<view class="grid-item-box" @click="pageEnter(item)">
<image class="image" :src="item.url" mode="aspectFill" />
<text class="text">{{item.text}}</text>
<view v-if="item.badge" class="grid-dot">
<uni-badge :text="item.badge" :type="item.type" />
<uni-section title="发起申请" type="line">
<div v-for="group in wfOptions" :key="group.category">
<div style="padding-left:10px;color: #606266;">{{ group.category }}</div>
<uni-grid :column="5" :show-border="false" :square="false">
<uni-grid-item v-for="(item ,index) in group.items" :index="index" :key="index">
<view class="grid-item-box" @click="pageEnter(item)">
<image class="image" :src="item.icon_path?item.icon_path:'/static/yuding.png'" mode="aspectFill" />
<text class="text">{{item.name}}</text>
</view>
</view>
</uni-grid-item>
</uni-grid>
</uni-grid-item>
</uni-grid>
</div>
</uni-section>
</view>
</template>
<script>
import tool from "../../utils/tools.js";
import { auth } from '@/utils/auth.js'
export default {
data() {
return {
welTitle: "",
imageSrc:"",
currentDate: tool.getTodayDate(),
moduleList: [
{
navigate:'/pages/ofm/booking_form?mode=add',
url: '/static/yuding.png',
text: '会议预定',
type: "primary",
},
{
navigate:'/pages/ofm/sealForm?mode=add',
url: '/static/meetingRecord.png',
text: '印章申请',
type: "success"
},
{
navigate:'/pages/ofm/vehicleForm?mode=add',
url: '/static/meetingRecord.png',
text: '用车申请',
type: "success"
},
{
navigate:'/pages/ofm/borrowfile_form?mode=add',
url: '/static/meetingRecord.png',
text: '档案借阅',
type: "success"
},
{
navigate:'/pages/ofm/publicityForm?mode=add',
url: '/static/huiyishi.png',
text: '宣传报道',
type: "warning"
},
{
navigate:'/pages/srm/patent_form?mode=add',
url: '/static/huiyishi.png',
text: '专利审批',
type: "warning"
},
{
navigate:'/pages/srm/paperse_form?mode=add',
url: '/static/huiyishi.png',
text: '论文申密',
type: "warning"
},
{
navigate:'/pages/srm/plant_form?mode=add',
url: '/static/huiyishi.png',
text: '平台审批',
type: "warning"
},
{
navigate:'/pages/srm/project_form?mode=add',
url: '/static/huiyishi.png',
text: '立项审批',
type: "warning"
},
{
navigate:'/pages/hrm/resignation_form?mode=add',
url: '/static/huiyishi.png',
text: '离职申请',
type: "warning"
},
{
navigate:'/pages/pum/supplieraudit_form?mode=add',
url: '/static/huiyishi.png',
text: '供应商审批',
type: "warning"
}
]
wfOptions: [],
duty_count: 0,
owner_count: 0
}
},
mounted() {
this.initWelTitle();
this.getWfOptions();
},
onShow() {
// #ifdef MP-WEIXIN
uni.hideHomeButton()
// #endif
this.getTicketCount();
},
methods: {
getTicketCount() {
this.$api.getTicket({category:"duty", page:1, page_size:1}).then(res=>{
this.duty_count = res.count;
})
this.$api.getTicket({category:"owner", page:1, page_size:1}).then(res=>{
this.owner_count = res.count;
})
},
getWfOptions() {
let permissions = auth.getPermissions();
const groups = {};
this.$api.getWorkflow({ page: 0 }).then((res) => {
res.forEach((item) => {
if(item.key && permissions.includes(item.key)) {
let cate = item.cate;
if (!cate){cate="未分组"}
if (!groups[cate]) {
groups[cate] = [];
}
groups[cate].push(item);
}
})
// 便
this.wfOptions = Object.keys(groups).map(category => ({
category,
items: groups[category]
}));
});
},
initWelTitle() {
let userInfo = uni.getStorageSync("userInfo")
let name = userInfo.name;
@ -137,23 +104,12 @@
})
},
pageEnter(item){
const viewPath = item.view_path;
let view_path = item.view_path2?item.view_path2:item.view_path;
uni.navigateTo({
url:item.navigate
url:`/pages${view_path}?mode=add`
})
},
cameraClick(){
uni.chooseImage({
count: 1, // 1
sourceType: ['album', 'camera'], //
success: function (res) {
//
console.log(res.tempFilePaths[0]);
},
fail: function (err) {
console.log('选择或拍照失败', err);
}
});
},
}
}
}
</script>
@ -201,6 +157,7 @@
color: #2979ff;
font-size: 36rpx;
font-weight: bold;
margin-left: 24rpx;
}
.swiper {

View File

@ -55,8 +55,8 @@
<view>{{totalCount}}小时</view> -->
</view>
</scroll-view>
<view class="footer_sticky">
<ticketd_b :workflow_key="'wf_booking'" :title="form.title + '-会议室预定'" :t_id="form.id" :ticket_="form.ticket_"
<view class="footer_fixed">
<ticketd_b :workflow_key="'wf_mroombooking'" :title="form.title + '-会议室预定'" :t_id="form.id" :ticket_="form.ticket_"
@success="submitSuccess" :submit_b_func="submit_b_func" ref="ticketd_b_start"></ticketd_b>
</view>
</view>
@ -171,24 +171,24 @@ import {actStateEnum} from "@/utils/enum.js"
}
}
await that.getmRooms();
if(options.slots){
that.form.slots = [];
let slots = options.slots.split(',');
if(slots.length>0){
slots.forEach(item=>{
let slot = Number(item);
that.form.slots.push(slot);
if(slot<12){
that.timesListAm[slot].isSelect = true;
that.selectList.push(that.timesListAm[slot])
}else{
that.timesListPm[slot].isSelect = true;
that.selectList.push(that.timesListPm[slot])
}
})
that.totalCount = slots.length*0.5;
}
}
// if(options.slots){
// that.form.slots = [];
// let slots = options.slots.split(',');
// if(slots.length>0){
// slots.forEach(item=>{
// let slot = Number(item);
// that.form.slots.push(slot);
// if(slot<12){
// that.timesListAm[slot].isSelect = true;
// that.selectList.push(that.timesListAm[slot])
// }else{
// that.timesListPm[slot].isSelect = true;
// that.selectList.push(that.timesListPm[slot])
// }
// })
// that.totalCount = slots.length*0.5;
// }
// }
},
methods:{
async getmRooms(){
@ -270,11 +270,18 @@ import {actStateEnum} from "@/utils/enum.js"
that.$api.bookingSlot(form).then(res=>{
res.forEach(item=>{
if(item.slot<12){
that.timesListAm[item.slot].sloted = true;
if(item.booking == that.form.id) {
that.timesListAm[item.slot].isSelect = true;
}else{
that.timesListAm[item.slot].sloted = true;
}
}else{
that.timesListPm[item.slot-12].sloted = true;
if(item.booking == that.form.id) {
that.timesListPm[item.slot-12].isSelect = true;
}else{
that.timesListPm[item.slot-12].sloted = true;
}
}
})
})
},

View File

@ -43,6 +43,7 @@
<script>
import ticketd_b from "../wf/ticketd_b.vue"
import ticketd from "../wf/ticketd.vue"
import config from '/utils/config';
import {actStateEnum} from "@/utils/enum.js"
export default {
components: { ticketd_b, ticketd },
@ -135,7 +136,7 @@ import {actStateEnum} from "@/utils/enum.js"
let filePath = file.url;
//
uni.uploadFile({
url: "http://49.232.14.174:2226/api/file/",
url: `${config.baseUrl}/file/`,
filePath: filePath,
name: fieldName,
formData: {},

View File

@ -14,7 +14,7 @@
<uni-easyinput v-model="form.material_name" placeholder="请输入物料名称" :disabled="mode=='show'"/>
</uni-forms-item>
<uni-forms-item label="调查表" required>
<uni-file-picker limit="1" file-mediatype="all" v-model="form.survery_form" @success="uploadSuccess('1')"></uni-file-picker>
<uni-file-picker limit="1" file-mediatype="all" v-model="form.survery_form" @success="(e)=>{uploadSuccess('1', e)}"></uni-file-picker>
</uni-forms-item>
<uni-forms-item label="营业执照" required>
<uni-file-picker limit="1" file-mediatype="all" v-model="form.business_license" @success="uploadSuccess('2')"></uni-file-picker>
@ -25,8 +25,14 @@
</uni-forms>
</scroll-view>
<view class="footer_fixed">
<ticketd_b :workflow_key="'wf_resignation'" :title="form.employee_name + '-离职申请'" :t_id="form.id" :ticket_="form.ticket_"
@success="submitSuccess" :submit_b_func="submit_b_func" ref="ticketd_b_start"></ticketd_b>
<button v-if="mode=='edit'" size="mini" @click="handleDel" :loading="saveLoading" :disabled="saveLoading" type="warn">
删除
</button>
<ticketd_b v-if="form.ticket_" :t_id="form.id" :ticket_="form.ticket_"
:ticket_data="ticket_data" @success="()=>{uni.navigateBack()}" ref="ticketd_b"></ticketd_b>
<button v-else size="mini" @click="handleSave" :loading="saveLoading" :disabled="saveLoading" type="primary">
提交审批
</button>
</view>
</view>
</template>
@ -39,6 +45,7 @@ import {actStateEnum} from "@/utils/enum.js"
components: { ticketd_b, ticketd },
data(){
return{
saveLoading: false,
mode:"add",
t_id: null,
form:{
@ -71,42 +78,28 @@ import {actStateEnum} from "@/utils/enum.js"
that.t_id = options.t_id?options.t_id:null;
if(that.mode != "add"){
if(that.t_id) {
that.form = await that.$api.pfItem(that.t_id);
that.form = await that.$api.supplierauditItem(that.t_id);
if(that.form.ticket_.state_.type == 1 && that.form.create_by == uni.getStorageSync("userInfo").id ) {
that.mode = "edit";
}else{
that.mode = "show";
}
}
}else{
that.getEmployee();
}
},
methods:{
async getEmployee(){
let that = this;
let obj = {search:that.form.employee_name,page:0,query:'{name,id}'}
let res = await that.$api.employeeList(obj);
that.form.employee = res[0].id;
},
uploadSuccess(type){
console.log('type', type);
uploadSuccess(type, e){
console.log('type', type, e);
console.log('form.material_type',this.form.material_type)
},
async submit_b_func(id){
async handleSave(id){
let that = this;
that.$refs.customForm.validate().then(res => {
}).catch(err => {
console.log('err', err);
})
let res = await that.$api.pfCreate(that.form)
that.form.id = res.id;
},
submitSuccess(){
uni.navigateTo({
url: "/pages/index/index"
})
let res = await that.$api.supplierauditCreate(that.form)
},
}
}

View File

@ -51,6 +51,7 @@
<script>
import ticketd_b from "../wf/ticketd_b.vue"
import ticketd from "../wf/ticketd.vue"
import config from '/utils/config';
import {actStateEnum} from "@/utils/enum.js"
export default {
components: { ticketd_b, ticketd },
@ -190,7 +191,7 @@ import {actStateEnum} from "@/utils/enum.js"
let filePath = file.url;
//
uni.uploadFile({
url: "http://49.232.14.174:2226/api/file/",
url: `${config.baseUrl}/file/`,
filePath: filePath,
name: fieldName,
formData: {},

View File

@ -48,6 +48,7 @@
<script>
import ticketd_b from "../wf/ticketd_b.vue"
import ticketd from "../wf/ticketd.vue"
import config from '/utils/config';
import {actStateEnum} from "@/utils/enum.js"
export default {
components: { ticketd_b, ticketd },
@ -190,7 +191,7 @@ import {actStateEnum} from "@/utils/enum.js"
let filePath = file.url;
//
uni.uploadFile({
url: "http://49.232.14.174:2226/api/file/",
url: `${config.baseUrl}/file/`,
filePath: filePath,
name: fieldName,
formData: {},

View File

@ -1,7 +1,4 @@
<template>
<span v-if="actionShow">
<view style="display:flex">
<view style="margin:auto">
<button
v-for="item in transitions"
:key="item.id"
@ -9,16 +6,8 @@
:loading="isSaveing"
:disabled="isSaveing"
@click="handleTransition(item)"
style="margin-right: 2px"
size="mini"
>{{ item.name }}</button>
</view>
<!-- <view style="margin-left:auto">
<button v-if="props.ticket_?.state_.enable_retreat && isOwn" type="warn" size="mini"
@click="handleRetreat">撤回</button>
</view> -->
</view>
</span>
</template>
<script setup>
import { ref, reactive, onMounted, defineEmits, watch } from 'vue'
@ -35,37 +24,36 @@ const props = defineProps({
const workflow = ref(null);
const transitions = ref([]);
const currentUser = ref(uni.getStorageSync("userInfo").id);
onMounted(async () => {
// setTimeout(()=>{init()}, 500)
await init();
watch(
() => props.ticket_,
async (newVal) => {
if (newVal && Object.keys(newVal).length > 0) {
await init();
}
},
{ deep: true }
)
setTimeout(()=>{init()}, 1000)
// await init();
// watch(
// () => props.ticket_,
// async (newVal) => {
// if (newVal && Object.keys(newVal).length > 0) {
// await init();
// }
// },
// { deep: true }
// )
})
const actionShow = ref(false);
const suggestion = ref("")
const isOwn = ref(false)
const ticketId = ref(null)
const init = async () => {
transitions.value = [];
actionShow.value = false;
if (props.ticket_ && Object.keys(props.ticket_).length > 0) {
if (props.ticket_ && props.ticket_.id) {
isOwn.value = props.ticket_.create_by === currentUser.value;
ticketId.value = props.ticket_.id;
const isParticipant =
(props.ticket_.participant_type === 1 && props.ticket_.participant === currentUser.value) ||
(props.ticket_.participant_type === 2 && props.ticket_.participant.includes(currentUser.value))
if (isParticipant) {
actionShow.value = true;
transitions.value = await API.getTransition(props.ticket_.id);
}
}else if (props.workflow_key) {
let res = await API.workflowInitkey(props.workflow_key);
actionShow.value = true
transitions.value = res.transitions;
workflow.value = res.workflow
}else{
@ -85,11 +73,12 @@ const submit = async (transition_id) => {
try{
await props.submit_b_func();
}catch (e) {
console.log(e)
isSaveing.value = false;
return;
}
}
if (props.ticket_?.id) {
if (ticketId.value) {
console.log('props.ticket_data',props.ticket_data)
let params = new Object();
params.transition = transition_id;
@ -128,15 +117,21 @@ const submit = async (transition_id) => {
return;
}
ticket.transition = transition_id;
try {
let res = await API.ticketCreate(ticket);
isSaveing.value = false;
uni.showToast({
title: '提交成功',
icon: 'success'
});
emit("success", res.id)
ticketId.value = res.id;
try{
await API.ticketHandle(ticketId.value, {transition: transition_id, ticket_data: props.ticket_data?props.ticket_data:{}});
isSaveing.value = false;
uni.showToast({
title: '提交成功',
icon: 'success'
});
emit("success", res.id)
}catch (e) {
isSaveing.value = false;
return;
}
} catch (e) {
isSaveing.value = false;
return;

View File

@ -15,7 +15,9 @@ export default {
uploadFile:(data ) => http('/file/', 'POST', data),//上传文件
employeeList:(data) => http('/hrm/employee/', 'GET', data),
employeeInfo:() => http('/hrm/employee/info/', 'GET'),
getWorkflow: (data) => http('/wf/workflow/', 'GET', data),
getTicket:(data) => http('/wf/ticket/', 'GET', data),
getTicketItem:(id) => http(`/wf/ticket/${id}/`, 'GET'),
getTicketFlowLogs:(id) => http(`/wf/ticket/${id}/flowlogs/`, 'GET'),
@ -25,11 +27,13 @@ export default {
getTransition:(id) => http(`/wf/ticket/${id}/transitions/`, 'GET'),
workflowInitkey:(key) => http(`/wf/workflow/${key}/init_key/`, 'GET'),
getMroom:(data) => http('/ofm/mroom/', 'GET', data),
//会议室预定
bookingList:(data) => http('/ofm/mroombooking/', 'GET', data),
bookingItem:(id,data) => http(`/ofm/mroombooking/${id}/`, 'GET', data),
bookingCreate:(data) => http(`/ofm/mroombooking/`, 'POST', data),
bookingUpdate:(id,data) => http(`/ofm/mroombooking/${id}/`, 'PUT', data),
bookingDelete:(id) => http(`/ofm/mroombooking/${id}/`, 'DELETE'),
bookingSlot:(data) => http(`/ofm/mroomslot/`, 'GET' , data),
//印章申请
@ -78,5 +82,7 @@ export default {
resignationCreate:(data) => http(`/hrm/resignation/`, 'POST' , data),
resignationItem:(id,data) => http(`/hrm/resignation/${id}/`, 'GET', data),
resignationDelete:(id) => http(`/hrm/resignation/${id}/`, 'DELETE'),
//供应商审核
supplierauditCreate:(data) => http(`/pum/supplieraudit/`, 'POST' , data),
supplierauditItem:(id,data) => http(`/pum/supplieraudit/${id}/`, 'GET', data),
}

73
utils/auth.js Normal file
View File

@ -0,0 +1,73 @@
/**
* 权限管理类
*/
class AuthManager {
constructor() {
this.permissions = uni.getStorageSync('userPermissions') || []
}
/**
* 设置用户权限
* @param {Array} permissions - 权限数组
*/
setPermissions(permissions) {
this.permissions = permissions
uni.setStorageSync('userPermissions', permissions)
console.log('权限已设置:', permissions)
}
/**
* 清除权限
*/
clearPermissions() {
this.permissions = []
uni.removeStorageSync('userPermissions')
}
/**
* 检查权限
* @param {string|Array} permission - 单个权限或权限数组
* @returns {boolean}
*/
check(permission) {
if (!permission) return true
// 如果是数组,检查是否有任一权限
if (Array.isArray(permission)) {
return permission.some(p => this.hasPermission(p))
}
// 单个权限检查
return this.hasPermission(permission)
}
/**
* 检查所有权限
* @param {Array} permissions - 权限数组
* @returns {boolean}
*/
checkAll(permissions) {
if (!Array.isArray(permissions)) return false
return permissions.every(p => this.hasPermission(p))
}
/**
* 内部权限检查方法
* @param {string} permission
* @returns {boolean}
*/
hasPermission(permission) {
return this.permissions.includes(permission)
}
/**
* 获取当前权限列表
* @returns {Array}
*/
getPermissions() {
return [...this.permissions]
}
}
// 创建单例实例
export const auth = new AuthManager()

36
utils/directives.js Normal file
View File

@ -0,0 +1,36 @@
import { auth } from '@/utils/auth.js'
/**
* 权限指令
* 使用方式
* v-auth="'user:add'" // 单个权限
* v-auth="['user:add', 'user:edit']" // 多个权限(满足其一即可)
*/
export const authDirective = {
mounted(el, binding) {
checkAuth(el, binding)
},
updated(el, binding) {
checkAuth(el, binding)
}
}
/**
* 权限检查逻辑
*/
function checkAuth(el, binding) {
const hasAuth = auth.check(binding.value)
if (!hasAuth) {
// 没有权限时隐藏元素
el.style.display = 'none'
// 或者完全移除元素(根据需求选择)
// if (el.parentNode) {
// el.parentNode.removeChild(el)
// }
} else {
// 有权限时确保显示
el.style.display = ''
}
}