Browse Source

Merge branch 'han_v5'

master
han2015 4 days ago
parent
commit
d080eef185
  1. 35
      src/api/doc/space.ts
  2. 71
      src/views/doc/spacesimpletable.vue
  3. 30
      src/views/hr/archives/index.vue
  4. 88
      src/views/hr/archives/yunpaninfo.vue

35
src/api/doc/space.ts

@ -63,6 +63,41 @@ export function doAccessManage(uid:string,data?: any){
});
}
/**
*
* uid: manager's id
* userid: object's id
*/
export function doGetUserInfo(uid:string,data:{uuid:string}){
return request({
url: '/hxpan/api/user/info',
method: 'post',
headers: {
'Identifier':uid,
'Content-Type': 'application/x-www-form-urlencoded',
'App-Api-Token': apptoken
},
data: data
});
}
/**
*
* uid: manager's id
* userid: object's id
*/
export function doSetUserInfo(uid:string,data:{uuid:string,totalSizeLimit:number}){
return request({
url: '/hxpan/api/user/edit',
method: 'post',
headers: {
'Identifier':uid,
'App-Api-Token': apptoken
},
data: data
});
}
/**
*
*/

71
src/views/doc/spacesimpletable.vue

@ -13,13 +13,78 @@ const props = withDefaults(defineProps<{
}>(),{})
const weburls=ref<string[]>([])
const tags = ref<string[]>([])
const extractLtag = (url: string) => {
if(!url) return ''
try {
const u = new URL(url)
return u.searchParams.get('ltag') || ''
} catch (e) {
// fallback for non-absolute urls
const qIdx = url.indexOf('?')
if (qIdx === -1) return ''
const qs = url.slice(qIdx + 1)
const params = new URLSearchParams(qs)
return params.get('ltag') || ''
}
}
const updateUrlWithTag = (url: string, tag: string) => {
try {
const u = new URL(url || 'http://example.com') // base for relative fallback
if (tag) u.searchParams.set('ltag', tag)
else u.searchParams.delete('ltag')
// if original url had no origin and we used example.com, strip it
if (!/^[a-zA-Z]+:\/\//.test(url || '')) {
const path = u.pathname + (u.search ? u.search : '') + (u.hash ? u.hash : '')
return path === '/' ? (u.search ? u.search.slice(1) : '') : path
}
return u.toString()
} catch (e) {
const hasQ = url.includes('?')
const parts = url.split('?')
const base = parts[0]
const qs = parts[1] || ''
const params = new URLSearchParams(qs)
if (tag) params.set('ltag', tag)
else params.delete('ltag')
const qsStr = params.toString()
return qsStr ? `${base}?${qsStr}` : base
}
}
// /
const sanitizeTag = (val: string) => {
if (!val) return ''
try {
// 使 Unicode property escapes
return val.replace(/[^\p{L}\p{N}]+/gu, '')
} catch (e) {
// fallback ASCII /
return val.replace(/[^0-9a-zA-Z\u4e00-\u9fff]+/g, '')
}
}
const addUrl = () => {
weburls.value.push('')
tags.value.push('')
}
const removeUrl = (index: number) => {
weburls.value.splice(index, 1)
tags.value.splice(index, 1)
}
const onTagChange = (index: number, val: string) => {
const clean = sanitizeTag(val)
tags.value[index] = clean
weburls.value[index] = updateUrlWithTag(weburls.value[index] || '', clean)
}
const onUrlChange = (index: number, val: string) => {
weburls.value[index] = val
tags.value[index] = extractLtag(val)
}
const onSaveChange = () => {
@ -29,17 +94,19 @@ const onSaveChange = () => {
onMounted(() => {
weburls.value = props.urlstr ? props.urlstr.split(",") : []
tags.value = weburls.value.map(extractLtag)
})
</script>
<template>
<el-dialog :model-value="true" :style="{'max-height': '880px','--el-dialog-width': '33%'}" @close="props.closeFunc">
<el-dialog :model-value="true" :style="{'max-height': '880px','--el-dialog-width': '63%'}" @close="props.closeFunc">
<template #header>
<span style="font-weight: bold;">{{props.title}}</span>
</template>
<div class="tablelist">
<div v-for="(url, index) in weburls" :key="index" style="display:flex;align-items:center;margin:8px 0;">
<el-input v-model="weburls[index]" placeholder="输入网址" style="flex:1;margin-right:8px;"></el-input>
<el-input v-model="tags[index]" :maxlength="20" @input="onTagChange(index, $event)" placeholder="输入网址标签" style="margin-right:8px;width: 30%;"></el-input>
<el-input v-model="weburls[index]" @input="onUrlChange(index, $event)" placeholder="输入网址" style="flex:1;margin-right:8px;"></el-input>
<el-button circle size="small" type="danger" :icon="Delete" @click="removeUrl(index)"></el-button>
</div>

30
src/views/hr/archives/index.vue

@ -6,6 +6,7 @@
<script lang='ts' setup>
import { emptypeOptions } from "@/api/hr/people/datacont";
import { orgInfo } from "@/api/hr/org/type";
import { h } from 'vue'
import { authorizeOrgTree,authorizePeopleList } from '@/api/system/roleapi/power'
import { archivesCont } from "@/api/hr/people/type";
import {
@ -23,6 +24,7 @@ import UploadTemplate from "@/views/hr/archives/unitpage/uploadTemplate.vue"
import XingGeFengXi from "@/views/hr/archives/downpage/xingGeFengXi.vue";
import ArchivesContPage from "@/views/hr/archives/archivescont.vue";
import AddUserPage from "@/views/hr/archives/unitpage/addUserPage.vue";
import Yunpaninfo from "./yunpaninfo.vue";
@ -39,6 +41,8 @@ const peoplecont = ref<archivesCont>(); //个人信息
const excelUploadStaff = ref<any>();
const innerRef = ref<HTMLDivElement>();
const scrollbarRef = ref<InstanceType<typeof ElScrollbarType>>();
const dynamicVNode = ref<VNode | null>(null) //
//
const piLiangBox = ref(false);
const orgTreeProps = {
@ -405,6 +409,23 @@ function lookPeopleCont(cont: archivesCont) {
peoplecont.value = cont;
archivesBox.value = true;
}
/**
* 查看设置云盘大小
*/
const onHxpanSetting=(row:archivesCont)=>{
dynamicVNode.value = h(Yunpaninfo, {
title: "用户云盘空间信息",
userid: "p0"+row.keystr,
confirmFunc: (urlstr:string) => {
dynamicVNode.value=null
},
closeFunc: () => {
dynamicVNode.value=null
}
})
}
/**
* 更新个人信息
*/
@ -600,6 +621,11 @@ onMounted(() => {
align="center"
/>
<el-table-column label="联系方式" prop="mobilephone" width="120" />
<el-table-column label="网盘管理">
<template #default="scope">
<el-button link size="small" @click="onHxpanSetting(scope.row)">设置</el-button>
</template>
</el-table-column>
<el-table-column label="居住地" prop="currentresidence" />
<el-table-column fixed="right" align="center" label="操作" width="120">
<template #default="scope">
@ -859,7 +885,9 @@ onMounted(() => {
@update-info="getArchivesPage"
/>
<div v-if="dynamicVNode">
<component :is="dynamicVNode" />
</div>
</div>
</template>

88
src/views/hr/archives/yunpaninfo.vue

@ -0,0 +1,88 @@
<!--
@ 时间: 2026-01-12
@ 备注: 云盘info 是用于设置用户的云盘大小
-->
<script setup lang="ts">
import { onMounted } from 'vue'
import {doGetUserInfo,doSetUserInfo} from "@/api/doc/space"
import { useUserStore } from "@/store/modules/user";
const userStore = useUserStore();
const uid=btoa("p0"+userStore.userInfoCont.userId);
const props = withDefaults(defineProps<{
title:string;
userid:string;
confirmFunc:(urlstr:string)=>void, // dataid
closeFunc:()=>void, //
}>(),{})
const userInfo=ref({totalSizeLimit:10*1024*1024*1024,totalSize:1})
const newsize=ref(15)
const reset=ref(false)
const onSaveChange = () => {
if(newsize.value<1 || newsize.value>=1000){
alert("请输入1~1000内的数字")
return
}
doSetUserInfo(uid,{
uuid:props.userid,
totalSizeLimit:newsize.value*1024*1024*1024
}).then(resp=>{
if(resp.code==200){
userInfo.value=resp.data
ElMessage({
message: '设置成功',
type: 'success',
plain: true,
})
}else{
console.log(resp)
alert("设置出错!")
}
})
}
onMounted(() => {
doGetUserInfo(uid,{uuid:props.userid}).then((resp)=>{
userInfo.value=resp.data
})
})
</script>
<template>
<el-dialog :model-value="true" :style="{'max-height': '880px','--el-dialog-width': '43%'}" @close="props.closeFunc">
<template #header>
<span style="font-weight: bold;">{{props.title}}</span>
</template>
<div class="tablelist">
<p><strong>空间总大小:</strong> {{ userInfo.totalSizeLimit/1024/1024 }}M </p>
<el-progress style="width: 80%;margin: 10px 0;" :text-inside="true" :stroke-width="14" :percentage="((userInfo.totalSize/userInfo.totalSizeLimit)*100).toFixed(2)" />
<br>
<el-switch style="width:max-content;" v-model="reset" inactive-text="调整"/>
<div v-if="reset" >
<strong>分配空间大小: {{ newsize}}GB !! </strong><br>
<el-input v-model="newsize" style="width: 40%;" placeholder="请输入新空间数值" type="number" maxlength="3"/>
</div>
</div>
<template #footer>
<div class="dialog-footer">
<el-button @click="props.closeFunc()">取消</el-button>
<el-button type="primary" @click="onSaveChange">保存</el-button>
</div>
</template>
</el-dialog>
</template>
<style lang="scss" scoped>
.tablelist{
margin-bottom:20px;
display:flex;
flex-direction:column;
width: 90%;
}
</style>
Loading…
Cancel
Save