Merge branch 'minJeecg' into 'master'

Min jeecg

See merge request cxcxt/jeecguniapp!6
This commit is contained in:
闵 年泽 2025-05-26 15:01:00 +08:00
commit 61a1034efd
14 changed files with 609 additions and 74 deletions

9
.hbuilderx/launch.json Normal file
View File

@ -0,0 +1,9 @@
{
"version" : "1.0",
"configurations" : [
{
"playground" : "standard",
"type" : "uni-app:app-android"
}
]
}

View File

@ -4,5 +4,5 @@ NODE_ENV = 'development'
VITE_DELETE_CONSOLE = false VITE_DELETE_CONSOLE = false
# 是否开启sourcemap # 是否开启sourcemap
VITE_SHOW_SOURCEMAP = true VITE_SHOW_SOURCEMAP = true
VITE_SERVER_BASEURL = 'http://10.75.15.249:8080/jeecg-boot' VITE_SERVER_BASEURL = 'http://10.75.15.247:8080/jeecg-boot'
#VITE_SERVER_BASEURL = 'https://36.112.48.190/jeecg-boot' #VITE_SERVER_BASEURL = 'https://36.112.48.190/jeecg-boot'

View File

@ -0,0 +1,46 @@
<template>
<view>
<wd-upload accept="all" multiple :file-list="fileList" :action="action" @change="handleChange"
:multiple="multiple"></wd-upload>
</view>
</template>
<script lang="ts" setup>
import { ref, watch } from 'vue'
import { useToast, useMessage, useNotify, dayjs } from 'wot-design-uni'
import { http } from '@/utils/http'
import {
getEnvBaseUrl
} from '@/utils/index'
defineOptions({ // by
name: 'Mupload',
options: {
styleIsolation: 'shared'
}
})
const props = defineProps({
modelValue: {
type: String,
default: '',
},
multiple: { //
type: String,
default: false
},
path: { //path
type: String,
default: ''
}
})
const emit = defineEmits(['change', 'update:modelValue'])
const fileList = ref([])
const action = ref('')
const handleChange = (val)=>{ //
}
</script>
<style lang="scss" scoped></style>

View File

@ -125,7 +125,7 @@ const props = defineProps({
default: '', default: '',
}, },
}) })
const emit = defineEmits(['change', 'close']) const emit = defineEmits(['change', 'close','realNameChange'])
const toast = useToast() const toast = useToast()
const show = ref(true) const show = ref(true)
const api = { const api = {

View File

@ -0,0 +1,223 @@
<template>
<wd-cell-group border>
<wd-cell title="职工姓名" :value="info.username_dictText" />
<wd-cell title="所属单位" :value="info.sysOrgCode_dictText" />
<wd-cell title="联系方式" :value="info.phone" />
<wd-cell title="请假类型" :value="info.type" />
<wd-cell title="请假开始时间" :value="info.begintime" />
<wd-cell title="请假结束时间" :value="info.endtime" />
<wd-cell title="请假天数" :value="info.days + '天'" />
<wd-cell title="出发地" :value="info.departure" />
<wd-cell title="目的地" :value="info.destination" />
<wd-cell title="请假原因" :value="info.reason" />
<wd-cell title="附件" v-if="info.path&&info.path.length>0">
<template v-for="(img, index) in info.path" :key="index">
<wd-img :width="100" :height="100" :src="img" :enable-preview="true" />
</template>
</wd-cell>
</wd-cell-group>
</template>
<script setup lang="ts">
import {
ref,
onMounted
} from 'vue'
import {
queryByIdApi
} from '@/api/humanResource/absence'
import {
getEnvBaseUrl,
imgUrl
} from '@/utils/index'
import {
useUserStore
} from '@/store/user'
defineOptions({
name: 'index',
options: {
styleIsolation: 'shared',
},
})
const userStore = useUserStore();
const examineleader = ref('')
const imageValue = ref([])
const ifShowFj = ref(false)
const imageStyles = {
width: 64,
height: 64,
border: {
color: "#dce7e1",
width: 2,
style: 'dashed',
radius: '2px'
}
}
const uploadUrl = getEnvBaseUrl() + '/sys/common/upload?appPath=职工请假/' + userStore.userInfo.department + '/' +
userStore.userInfo.realname
const props = defineProps({
history: {
type: String,
default: ""
},
activeKey: {
type: String,
default: ""
},
formData: {
type: Object,
default: () => { },
}
})
const info = ref({})
//
const qjQueryById = () => {
console.log(props.formData)
queryByIdApi(props.formData.dataId).then((res) => {
if (res.success) {
if (res.result.records[0].zwmc == '单位专家' || res.result.records[0].zwmc == '基层正职' ||
res.result.records[0].zwmc == '高级主管') {
examineleader.value = '分管领导';
} else {
examineleader.value = '审批领导';
}
info.value = res.result.records[0]
// imageValue
info.value.path = info.value.path.split(',').map(path => imgUrl(path))
console.log(info)
}
})
}
onMounted(() => {
qjQueryById()
})
</script>
<style lang="scss" scoped>
.info_box {
padding: 40rpx 30rpx 16rpx 30rpx;
width: 630rpx;
background: #FFFFFF;
box-shadow: 0rpx 2rpx 4rpx 0rpx rgba(0, 0, 0, 0.5);
border-radius: 16rpx;
margin-top: 30rpx;
.title {
font-size: 28rpx;
color: #333333;
background-image: url(../../static/index/line.png);
background-size: 44rpx 12rpx;
background-repeat: no-repeat;
background-position: left bottom;
margin-bottom: 30rpx;
display: flex;
justify-content: space-between;
}
.info {
font-size: 28rpx;
margin-bottom: 24rpx;
view {
color: #666666;
}
text {
color: #333333;
}
}
}
.progress {
background: #FFFFFF;
box-shadow: 0rpx 2rpx 4rpx 0rpx rgba(0, 0, 0, 0.5);
border-radius: 16rpx;
width: 630rpx;
padding: 40rpx 30rpx 16rpx 30rpx;
margin-top: 30rpx;
margin-bottom: 30rpx;
.status {
padding: 4rpx 8rpx;
display: inline-block;
color: #FFFFFF;
font-size: 20rpx;
margin-left: 8rpx;
border-radius: 8rpx;
}
.complete {
background-color: #7AC756;
}
.refuse {
background-color: #FE4600;
}
.title {
font-size: 28rpx;
color: #333333;
background-image: url(../../static/index/line.png);
background-size: 44rpx 12rpx;
background-repeat: no-repeat;
background-position: left bottom;
margin-bottom: 40rpx;
}
// .box:not(:first-child) {
// padding-top: 60rpx;
// }
.box:not(:last-child) {
position: relative;
padding-bottom: 60rpx;
&::before {
position: absolute;
content: ' ';
width: 1px;
height: 100%;
background: #efefef;
left: -42rpx;
top: 10rpx;
}
}
.box {
margin-left: 50rpx;
.topic {
position: relative;
font-size: 28rpx;
color: #333333;
&::before {
position: absolute;
content: ' ';
width: 18rpx;
height: 18rpx;
background: #01508B;
border-radius: 14rpx;
left: -50rpx;
top: 50%;
transform: translateY(-50%);
}
}
.name_time {
font-size: 24rpx;
color: #888888;
margin-top: 12rpx;
}
}
}
</style>

View File

@ -1,64 +1,67 @@
<!-- component标签可以变换组件 --> <!-- component标签可以变换组件 -->
<template> <template>
<component :is="compUrl" :formData="formData" :history="history" :activeKey="activeKey" v-if="compUrl" @getStampSuc="getStampSuccess"></component> <component :is="asyncComponent" :formData="formData" :history="history" :activeKey="activeKey" v-if="asyncComponent"
@getStampSuc="getStampSuccess"></component>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, reactive, onMounted,computed, watch, nextTick } from 'vue'; import { ref, reactive, onMounted, computed, watch, nextTick } from 'vue';
const compName = ref(''); const compName = ref('');
const compUrl = ref(null); const asyncComponent = ref(null);
const modules = import.meta.glob('/src/pages-bpm/**/*.vue');
defineOptions({ defineOptions({
name: 'DynamicLink', name: 'DynamicLink',
options: { options: {
styleIsolation: 'shared', styleIsolation: 'shared',
}, },
}) })
const props = defineProps({ const props = defineProps({
path: { path: {
type: String, type: String,
default: "" default: ""
}, },
history: { history: {
type: String, type: String,
default: "" default: ""
}, },
activeKey: { activeKey: {
type: String, type: String,
default: "" default: ""
}, },
formData: { formData: {
type: Object, type: Object,
default: () => {}, default: () => { },
} }
}) })
// option // option
watch(() => props.path, (newVal) => { watch(() => props.path, (newVal) => {
console.log(newVal) console.log(newVal)
// if(newVal) compName.value = newVal; if (newVal) compName.value = newVal;
if(newVal) compName.value = 'pages-process/test'; //
compUrl.value = defineAsyncComponent(() => import(`@/${compName.value}.vue`)); const comp = modules[`/src/pages-bpm/${compName.value}.vue`]
comp().then((myModule) => {
asyncComponent.value = myModule.default
}).catch(() => {
})
}, { }, {
deep: true, deep: true,
// #ifdef MP-WEIXIN // #ifdef MP-WEIXIN
immediate: true immediate: true
// #endif // #endif
}); });
const comp = reactive({
component:compUrl.value
})
const getStampSuccess=(val)=>{ const getStampSuccess = (val) => {
// this.$emit('getStampSuc', val) // this.$emit('getStampSuc', val)
// //<component>使vuex // //<component>使vuex
// // // //
// this.$store.commit("cache/setEsignTags", { // this.$store.commit("cache/setEsignTags", {
// esignTag: val // esignTag: val
// }); // });
} }
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>

View File

@ -0,0 +1,266 @@
<template>
<view class="containerTask">
<view class="cu-bar bg-white solid-bottom height">
<view class="action">
当前环节
<text class="text-bold">[部门领导]</text>
</view>
</view>
<view class="margin-top-sm">
<wd-collapse style="width: 100%;" v-model="value">
<wd-collapse-item name="item1">
<template #title="{expanded,disabled, isFirst }">
<view class="header">
<wd-img class="taskImg" src="/static/user27.png" />
<text class="text-collapse">委托人办理</text>
<wd-icon v-if="expanded" style="float: right;color: #d8d8d8;" name="arrow-down"
size="22px"></wd-icon>
<wd-icon v-else style="float: right;color: #d8d8d8;" name="arrow-up" size="22px"></wd-icon>
</view>
</template>
<view
style="position: relative; display: inline-block; min-width: 60px; margin: 2px 5px;text-align: center;">
<wd-img v-if="!model.entrust" @click="showSelectuser('show1')"
style="width: 32px; height: 32px; margin: 0px auto;margin-top: 10px;"
src="/static/add.png" />
<view v-if="!model.entrust" style="margin-bottom: 10px;">选择</view>
<view @click="reset('show1')">
<wd-img v-if="model.entrust"
style="width: 32px; height: 32px; margin: 0px auto;margin-top: 10px;"
:src="getFileAccessHttpUrl(modelShow.avatar1)" />
<view v-if="model.entrust" style="margin-bottom: 10px;">
{{modelShow.text1}}
</view>
</view>
<SelectUserModal v-if="modelShow.show1" :selected="model.entrust"
@change="(val)=>{show1Change(val,'show1')}" modalTitle="用户选择" :multi="false"
@close="() => (modelShow.show1 = false)"></SelectUserModal>
</view>
</wd-collapse-item>
</wd-collapse>
</view>
<view>
<view class="cu-bar bg-white solid-bottom margin-top-sm">
<view class="action">
<text>
<span>处理意见</span>
</text>
<wd-picker :columns="dropOptions" label="单列选项" v-model="model.reason" use-default-slot>
<view class="cu-tag line-blue margin-left-sm">
<span>选择常用审批语</span>
</view>
</wd-picker>
</view>
</view>
<view class="bg-white" style="height: 100px;">
<wd-textarea v-model="model.reason" placeholder="请输入审批语句" />
</view>
<view class="cu-bar bg-white solid-top">
<view class="action">
<view>
<text class="text" style="font-size: 15px;">
<span>上传附件</span>
</text>
</view>
<Mupload></Mupload>
</view>
</view>
</view>
</view>
</template>
<script setup lang="ts">
import { ref, reactive, onMounted, computed, watch, nextTick } from 'vue';
import SelectUserModal from '@/components/SelectUser/components/SelectUserModal.vue'
import { getFileAccessHttpUrl } from '@/common/uitls'
import { useQueue } from 'wot-design-uni'
import Mupload from '@/components/Mupload/Mupload.vue'
defineOptions({
name: 'taskDeal',
options: {
styleIsolation: 'shared',
},
})
const value = ref([])
const modelShow = ref({
show1: false,
text1: '',
avatar1: ''
})
const model = ref({
taskId: '', //taskid
nextnode: '', //
nextCodeCount: '',
reason: '同意', //
processModel: 1, //:
rejectModelNode: '', //
nextUserName: '', //
nextUserId: '', //id
ccUserIds: '', //ids
ccUserRealNames: '', //usernames
fileList: '', //list
ysjqx: true, //
entrust: '', //
})
const { closeOutside } = useQueue()
const dropOptions = ref([ //
{ label: '同意', value: '同意' },
{ label: '同意***的意见', value: '同意***的意见' },
{ label: '请指示', value: '请指示' },
{ label: '请***阅示', value: '请***阅示' },
{ label: '请处理', value: '请处理' },
{ label: '不同意', value: '不同意' },
{ label: '请审批', value: '请审批' },
{ label: '审核无误', value: '审核无误' },
])
const props = defineProps({
formData: {
type: Object,
default: () => { },
}
})
const showSelectuser = (val : string) => { //
modelShow.value[val] = true;
}
const show1Change = (val, type) => {
let selectUser = val[0]
console.log(selectUser)
switch (type) {
case 'show1':
model.value.entrust = selectUser.username
modelShow.value['text1'] = selectUser.realname
modelShow.value['avatar1'] = selectUser.avatar
break;
default:
break;
}
}
const reset = (val : string) => { //
switch (val) {
case 'show1':
model.value.entrust = ''
modelShow.value['text1'] = ''
modelShow.value['avatar1'] = ''
break;
default:
break;
}
}
</script>
<style lang="scss" scoped>
.bg-white {
background-color: #fff;
color: #666;
}
.height {
height: 48px;
}
.cu-bar {
display: flex;
position: relative;
align-items: center;
min-height: 50px;
justify-content: space-between;
}
.cu-bar .action:last-child {
margin-right: 15px;
}
.cu-bar .action:first-child {
margin-left: 15px;
font-size: 15px;
}
.cu-bar .action {
display: flex;
align-items: center;
height: 100%;
justify-content: center;
max-width: 100%;
}
.margin-top-sm {
margin-top: 10px;
}
.containerTask {
background-color: #f7f7f7;
}
.text-bold {
font-weight: 700;
}
.text-collapse {
flex: 1;
font-size: 14px;
white-space: nowrap;
color: inherit;
overflow: hidden;
text-overflow: ellipsis;
}
.taskImg {
height: 17px;
width: 17px;
margin-right: 10px;
vertical-align: -15%
}
.solid-bottom::after {
border-bottom: 1px solid rgba(0, 0, 0, .1);
}
.text-blue, .line-blue, .lines-blue {
color: #0081ff;
}
.margin-left-sm {
margin-left: 10px;
}
.cu-tag {
font-size: 12px;
vertical-align: middle;
position: relative;
display: inline-flex;
align-items: center;
justify-content: center;
box-sizing: border-box;
padding: 0px 8px;
height: 24px;
font-family: Helvetica Neue, Helvetica, sans-serif;
white-space: nowrap;
}
.cu-tag[class*="line-"]::after {
border-radius: 0;
}
.cu-tag[class*="line-"]::after {
content: " ";
width: 200%;
height: 200%;
position: absolute;
top: 0;
left: 0;
border: 1px solid currentColor;
-webkit-transform: scale(.5);
transform: scale(.5);
-webkit-transform-origin: 0 0;
transform-origin: 0 0;
box-sizing: border-box;
border-radius: inherit;
z-index: 1;
pointer-events: none;
}
</style>

View File

@ -14,8 +14,7 @@
<DynamicLink ref="linkRef" :path="path" :formData="formData" ></DynamicLink> <DynamicLink ref="linkRef" :path="path" :formData="formData" ></DynamicLink>
</wd-tab> </wd-tab>
<wd-tab title="任务处理"> <wd-tab title="任务处理">
<view class="content">内容2</view> <taskDeal :formData="formData"></taskDeal>
</wd-tab> </wd-tab>
<wd-tab title="流程图"> <wd-tab title="流程图">
<view class="container"> <view class="container">
@ -76,6 +75,7 @@
import qs from 'qs'; import qs from 'qs';
import { getCurrentInstance } from 'vue' import { getCurrentInstance } from 'vue'
import DynamicLink from './components/DynamicLink.vue' import DynamicLink from './components/DynamicLink.vue'
import taskDeal from './components/taskDeal.vue'
const { proxy } = getCurrentInstance() const { proxy } = getCurrentInstance()

View File

@ -1,18 +0,0 @@
<template>
<view>
<text>test</text>
</view>
</template>
<script setup lang="ts">
defineOptions({
name: 'DynamicLink',
options: {
styleIsolation: 'shared',
},
})
</script>
<style lang="scss" scoped>
</style>

View File

@ -479,9 +479,14 @@
"navigationStyle": "custom", "navigationStyle": "custom",
"navigationBarTitleText": "任务处理" "navigationBarTitleText": "任务处理"
} }
}, }
]
},
{
"root": "pages-bpm",
"pages": [
{ {
"path": "test", "path": "leaveApplication/index",
"type": "page" "type": "page"
} }
] ]

BIN
src/static/add.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
src/static/user27.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -53,7 +53,7 @@ interface NavigateToOptions {
"/pages-politics/health/add" | "/pages-politics/health/add" |
"/pages-process/approvalTabbar" | "/pages-process/approvalTabbar" |
"/pages-process/taskHandle" | "/pages-process/taskHandle" |
"/pages-process/test"; "/pages-bpm/leaveApplication/index";
} }
interface RedirectToOptions extends NavigateToOptions {} interface RedirectToOptions extends NavigateToOptions {}

View File

@ -70,6 +70,7 @@ export default ({ command, mode }) => {
'src/pages-integrated', 'src/pages-integrated',
'src/pages-politics', 'src/pages-politics',
'src/pages-process', 'src/pages-process',
'src/pages-bpm'
], // pages ], // pages
dts: 'src/types/uni-pages.d.ts', dts: 'src/types/uni-pages.d.ts',
}), }),