u
This commit is contained in:
1 parent
1806808d11
commit
349db76d3d
19 files changed
+1312
-189
No files matched your search
+4
@@ -0,0 +1,4 @@
|
|||||||
|
VITE_APP_PORT = 8080
|
||||||
|
|
||||||
|
VITE_ALIYUN_BUCKET = 'g3xc'
|
||||||
|
|
||||||
@@ -8,7 +8,7 @@ onLaunch(() => {
|
|||||||
console.log('App Launch')
|
console.log('App Launch')
|
||||||
})
|
})
|
||||||
onShow(() => {
|
onShow(() => {
|
||||||
// userStore.requireLogin()
|
userStore.requireLogin()
|
||||||
|
|
||||||
console.log('App Show')
|
console.log('App Show')
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -13,6 +13,8 @@ interface ImportMetaEnv {
|
|||||||
readonly VITE_SERVER_PORT: string
|
readonly VITE_SERVER_PORT: string
|
||||||
/** 是否清除console */
|
/** 是否清除console */
|
||||||
readonly VITE_DELETE_CONSOLE: string
|
readonly VITE_DELETE_CONSOLE: string
|
||||||
|
|
||||||
|
readonly VITE_ALIYUN_BUCKET: string
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ImportMeta {
|
interface ImportMeta {
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
import { useUserStore } from '@/store'
|
import { useUserStore } from '@/store'
|
||||||
|
|
||||||
const whiteList = [
|
const whiteList = [
|
||||||
'/pages-sub/login/index',
|
'/pages-sub/login/index'
|
||||||
'/pages/account/index',
|
|
||||||
]
|
]
|
||||||
|
|
||||||
export const navigateToInterceptor = {
|
export const navigateToInterceptor = {
|
||||||
@@ -34,9 +33,9 @@ export const navigateToInterceptor = {
|
|||||||
|
|
||||||
export const routeInterceptor = {
|
export const routeInterceptor = {
|
||||||
install() {
|
install() {
|
||||||
// uni.addInterceptor('navigateTo', navigateToInterceptor)
|
uni.addInterceptor('navigateTo', navigateToInterceptor)
|
||||||
// uni.addInterceptor('reLaunch', navigateToInterceptor)
|
uni.addInterceptor('reLaunch', navigateToInterceptor)
|
||||||
// uni.addInterceptor('redirectTo', navigateToInterceptor)
|
uni.addInterceptor('redirectTo', navigateToInterceptor)
|
||||||
// uni.addInterceptor('switchTab', navigateToInterceptor)
|
uni.addInterceptor('switchTab', navigateToInterceptor)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,147 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import type { UploadFile, UploadFileItem } from 'sard-uniapp'
|
||||||
|
import { isImageUrl, isVideoUrl, toast } from 'sard-uniapp'
|
||||||
|
import { aliyunpluploadApi, delSubRecordApi, searchdataApi } from '@/request/api'
|
||||||
|
import { downloadFile, formatFileSize, imageCompress, isImage, uploadFileToAliyun } from '@/utils/file'
|
||||||
|
import { isH5 } from '@/utils/platform'
|
||||||
|
|
||||||
|
const fileList = ref<UploadFileItem[]>([])
|
||||||
|
|
||||||
|
const isEdit = ref(true)
|
||||||
|
|
||||||
|
const aliyunBucket = import.meta.env.VITE_ALIYUN_BUCKET
|
||||||
|
const father = ref('')
|
||||||
|
const moduleid = ref('')
|
||||||
|
const cateid = ref('')
|
||||||
|
|
||||||
|
onLoad((options) => {
|
||||||
|
father.value = options.father
|
||||||
|
moduleid.value = options.moduleid
|
||||||
|
cateid.value = options.cateid || ''
|
||||||
|
|
||||||
|
const edit = options.edit || '0'
|
||||||
|
isEdit.value = edit === '1'
|
||||||
|
|
||||||
|
nextTick(() => {
|
||||||
|
loadFileData()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
async function loadFileData() {
|
||||||
|
let searchcondition = ` father = '${father.value}' and mx_moduleid = '${moduleid.value}'`
|
||||||
|
if (cateid.value !== '') {
|
||||||
|
searchcondition += ` and mx_cate_id = '${cateid.value}'`
|
||||||
|
}
|
||||||
|
searchdataApi({
|
||||||
|
viewname: 'bf_files',
|
||||||
|
searchcondition,
|
||||||
|
orderfield: '',
|
||||||
|
}).then((res) => {
|
||||||
|
fileList.value = res.data.map((item) => {
|
||||||
|
return {
|
||||||
|
...item,
|
||||||
|
name: item.mx_filename,
|
||||||
|
url: item.mx_mapfilename,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
console.log(fileList.value)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function onItemClick(fileItem: UploadFileItem) {
|
||||||
|
if (!isImageUrl(fileItem.mx_mapfilename) && !isVideoUrl(fileItem.mx_mapfilename)) {
|
||||||
|
downloadFile(fileItem.mx_mapfilename)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function beforeRead(file: UploadFile): boolean | Promise<UploadFile> {
|
||||||
|
// 非图片直接允许上传
|
||||||
|
if (!isImage(file.name))
|
||||||
|
return true
|
||||||
|
|
||||||
|
// 图片异步压缩,返回修改后的 UploadFile 对象
|
||||||
|
return imageCompress(file.path).then((res) => {
|
||||||
|
console.log(res)
|
||||||
|
|
||||||
|
file.path = res.path
|
||||||
|
file.size = res.size
|
||||||
|
return file
|
||||||
|
}).catch((err) => {
|
||||||
|
console.error('图片压缩失败:', err)
|
||||||
|
return file
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
async function afterRead(fileItem: UploadFileItem) {
|
||||||
|
try {
|
||||||
|
// 设置上传中状态
|
||||||
|
fileItem.status = 'uploading'
|
||||||
|
fileItem.message = '正在上传'
|
||||||
|
fileList.value = [...fileList.value]
|
||||||
|
|
||||||
|
// 上传到阿里云
|
||||||
|
const res = await uploadFileToAliyun(
|
||||||
|
fileItem.file.path,
|
||||||
|
fileItem.file.name,
|
||||||
|
fileItem.file.type,
|
||||||
|
)
|
||||||
|
|
||||||
|
if (!res.url)
|
||||||
|
throw new Error('上传失败:未获取到文件 URL')
|
||||||
|
|
||||||
|
// 调用后端接口保存文件信息
|
||||||
|
const saveRes = await aliyunpluploadApi({
|
||||||
|
despathfile: res.url,
|
||||||
|
myfilename: fileItem.file.name,
|
||||||
|
size: formatFileSize(fileItem.file.size),
|
||||||
|
tablename: 'bf_files',
|
||||||
|
sid: father.value,
|
||||||
|
mx_moduleid: moduleid.value,
|
||||||
|
mx_cate_id: cateid.value,
|
||||||
|
})
|
||||||
|
|
||||||
|
if (saveRes.data === 'OK') {
|
||||||
|
// 上传完成
|
||||||
|
fileItem.status = 'done'
|
||||||
|
fileItem.message = '上传成功'
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// 后端返回非 OK
|
||||||
|
throw new Error(saveRes.data || '上传失败')
|
||||||
|
}
|
||||||
|
|
||||||
|
fileList.value = [...fileList.value]
|
||||||
|
}
|
||||||
|
catch (err: any) {
|
||||||
|
console.error('上传失败:', err)
|
||||||
|
fileItem.status = 'failed'
|
||||||
|
fileItem.message = err.message || '上传失败'
|
||||||
|
fileList.value = [...fileList.value]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function onRemove(index: number, item: UploadFileItem) {
|
||||||
|
delSubRecordApi({
|
||||||
|
module: 'bf_files',
|
||||||
|
id: item.subid,
|
||||||
|
bucketName: aliyunBucket,
|
||||||
|
}).then((res) => {
|
||||||
|
if (res.data.result) {
|
||||||
|
toast.success('删除成功')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<view class="file">
|
||||||
|
<sar-upload v-model="fileList" :readonly="!isEdit" :after-read="afterRead" :before-read="beforeRead" multiple @item-click="onItemClick" @remove="onRemove" />
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.file {
|
||||||
|
padding: 36rpx;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -34,9 +34,16 @@ function onSubmit() {
|
|||||||
formRef.value
|
formRef.value
|
||||||
?.validate()
|
?.validate()
|
||||||
.then(() => {
|
.then(() => {
|
||||||
|
_loading.value = true
|
||||||
|
loginOrgApi({
|
||||||
|
orgid: formModel.orgid,
|
||||||
|
userid: formModel.userid,
|
||||||
|
password: formModel.password,
|
||||||
|
}).then((res) => {
|
||||||
|
if (res.data) {
|
||||||
userStore.userInfo.orgid = formModel.orgid
|
userStore.userInfo.orgid = formModel.orgid
|
||||||
userStore.userInfo.userid = formModel.userid
|
userStore.userInfo.userid = formModel.userid
|
||||||
userStore.userInfo.token = '123'
|
userStore.userInfo.token = res.data
|
||||||
|
|
||||||
uni.showToast({
|
uni.showToast({
|
||||||
title: '登录成功',
|
title: '登录成功',
|
||||||
@@ -46,35 +53,16 @@ function onSubmit() {
|
|||||||
uni.switchTab({
|
uni.switchTab({
|
||||||
url: '/pages/home/index',
|
url: '/pages/home/index',
|
||||||
})
|
})
|
||||||
// _loading.value = true
|
}
|
||||||
// loginOrgApi({
|
else {
|
||||||
// orgid: formModel.orgid,
|
uni.showToast({
|
||||||
// userid: formModel.userid,
|
title: '登录失败,请稍后再试',
|
||||||
// password: formModel.password,
|
icon: 'error',
|
||||||
// }).then((res) => {
|
})
|
||||||
// if (res.data) {
|
}
|
||||||
// userStore.userInfo.orgid = formModel.orgid
|
}).finally(() => {
|
||||||
// userStore.userInfo.userid = formModel.userid
|
_loading.value = false
|
||||||
// userStore.userInfo.token = res.data
|
})
|
||||||
|
|
||||||
// uni.showToast({
|
|
||||||
// title: '登录成功',
|
|
||||||
// icon: 'success',
|
|
||||||
// })
|
|
||||||
|
|
||||||
// uni.switchTab({
|
|
||||||
// url: '/pages/home/index',
|
|
||||||
// })
|
|
||||||
// }
|
|
||||||
// else {
|
|
||||||
// uni.showToast({
|
|
||||||
// title: '登录失败,请稍后再试',
|
|
||||||
// icon: 'error',
|
|
||||||
// })
|
|
||||||
// }
|
|
||||||
// }).finally(() => {
|
|
||||||
// _loading.value = false
|
|
||||||
// })
|
|
||||||
})
|
})
|
||||||
.catch((error: FieldValidateError[]) => {
|
.catch((error: FieldValidateError[]) => {
|
||||||
toast.fail(error[0].message)
|
toast.fail(error[0].message)
|
||||||
|
|||||||
@@ -0,0 +1,243 @@
|
|||||||
|
<script lang="ts" setup>
|
||||||
|
import type { FieldValidateError, FormExpose, FormRules } from 'sard-uniapp'
|
||||||
|
import { getWindowInfo, toast } from 'sard-uniapp'
|
||||||
|
import { reactive, ref } from 'vue'
|
||||||
|
import { saveobjtApi, searchdataApi } from '@/request/api'
|
||||||
|
import { useUserStore } from '@/store'
|
||||||
|
|
||||||
|
const userStore = useUserStore()
|
||||||
|
|
||||||
|
const startOffset = ref(getWindowInfo().statusBarHeight + 60)
|
||||||
|
|
||||||
|
const submitLoading = ref(false)
|
||||||
|
|
||||||
|
const formModel = reactive({
|
||||||
|
oldPassword: '',
|
||||||
|
newPassword: '',
|
||||||
|
confirmPassword: '',
|
||||||
|
})
|
||||||
|
|
||||||
|
const formRules: FormRules = {
|
||||||
|
}
|
||||||
|
|
||||||
|
const formRef = ref<FormExpose>()
|
||||||
|
|
||||||
|
async function onSubmit() {
|
||||||
|
try {
|
||||||
|
await formRef.value?.validate()
|
||||||
|
|
||||||
|
if (formModel.confirmPassword !== formModel.newPassword) {
|
||||||
|
toast.fail('两次输入的密码不一致,请重新输入')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
submitLoading.value = true
|
||||||
|
|
||||||
|
const searchRes = await searchdataApi({
|
||||||
|
viewname: 'b_user',
|
||||||
|
searchcondition: `b_id = '${userStore.userInfo.userid}' and b_password = '${formModel.oldPassword}'`,
|
||||||
|
orderfield: 'b_id',
|
||||||
|
})
|
||||||
|
|
||||||
|
if (!searchRes.data || searchRes.data.length === 0) {
|
||||||
|
toast.fail('旧密码错误,请重新输入')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const updateObj = {
|
||||||
|
b_id: userStore.userInfo.userid,
|
||||||
|
b_password: formModel.newPassword,
|
||||||
|
}
|
||||||
|
|
||||||
|
const saveobjtRes = await saveobjtApi({
|
||||||
|
tables: '[b_user]',
|
||||||
|
insertValues: '[]',
|
||||||
|
updateValues: `[${JSON.stringify(updateObj)}]`,
|
||||||
|
delValues: '[]',
|
||||||
|
keys: 'b_id',
|
||||||
|
})
|
||||||
|
|
||||||
|
if (saveobjtRes.data === 'OK') {
|
||||||
|
toast.success('密码修改成功,请重新登录')
|
||||||
|
setTimeout(() => {
|
||||||
|
uni.navigateTo({
|
||||||
|
url: '/pages-sub/login/index',
|
||||||
|
})
|
||||||
|
}, 500)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
toast.fail(saveobjtRes.data || '修改失败')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (error: any) {
|
||||||
|
// 表单校验错误
|
||||||
|
if (Array.isArray(error) && error[0]?.message) {
|
||||||
|
toast.fail(error[0].message)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
toast.fail('操作失败,请重试')
|
||||||
|
console.error(error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
// 7️⃣ 关闭 loading
|
||||||
|
submitLoading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<view class="form-container">
|
||||||
|
<sar-form-plain
|
||||||
|
ref="formRef"
|
||||||
|
:model="formModel"
|
||||||
|
:rules="formRules"
|
||||||
|
scroll-to-first-error
|
||||||
|
:scroll-into-view-options="{
|
||||||
|
startOffset,
|
||||||
|
position: 'start',
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<view class="form-description">
|
||||||
|
<view class="form-title">
|
||||||
|
密码修改
|
||||||
|
</view>
|
||||||
|
<view class="form-subtitle">
|
||||||
|
确保账户安全,请谨慎操作
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="form-list">
|
||||||
|
<sar-form-item-plain name="password">
|
||||||
|
<template #custom="{ fieldId }">
|
||||||
|
<view class="form-label" :class="fieldId">
|
||||||
|
旧密码
|
||||||
|
</view>
|
||||||
|
<view class="form-input">
|
||||||
|
<sar-input
|
||||||
|
v-model="formModel.oldPassword"
|
||||||
|
placeholder="请输入旧密码"
|
||||||
|
type="password"
|
||||||
|
show-eye
|
||||||
|
>
|
||||||
|
<template #prepend>
|
||||||
|
<sar-icon family="iconfont" name="lock" size="36rpx" />
|
||||||
|
</template>
|
||||||
|
</sar-input>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
</sar-form-item-plain>
|
||||||
|
<sar-form-item-plain name="password">
|
||||||
|
<template #custom="{ fieldId }">
|
||||||
|
<view class="form-label" :class="fieldId">
|
||||||
|
新密码
|
||||||
|
</view>
|
||||||
|
<view class="form-input">
|
||||||
|
<sar-input
|
||||||
|
v-model="formModel.newPassword"
|
||||||
|
placeholder="请输入新密码"
|
||||||
|
type="password"
|
||||||
|
show-eye
|
||||||
|
>
|
||||||
|
<template #prepend>
|
||||||
|
<sar-icon family="iconfont" name="lock" size="36rpx" />
|
||||||
|
</template>
|
||||||
|
</sar-input>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
</sar-form-item-plain>
|
||||||
|
<sar-form-item-plain name="password">
|
||||||
|
<template #custom="{ fieldId }">
|
||||||
|
<view class="form-label" :class="fieldId">
|
||||||
|
确认密码
|
||||||
|
</view>
|
||||||
|
<view class="form-input">
|
||||||
|
<sar-input
|
||||||
|
v-model="formModel.confirmPassword"
|
||||||
|
placeholder="请输入确认密码"
|
||||||
|
type="password"
|
||||||
|
show-eye
|
||||||
|
>
|
||||||
|
<template #prepend>
|
||||||
|
<sar-icon family="iconfont" name="lock" size="36rpx" />
|
||||||
|
</template>
|
||||||
|
</sar-input>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
</sar-form-item-plain>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="footer">
|
||||||
|
<sar-button loading-type="clock" :loading="submitLoading" @click="onSubmit">
|
||||||
|
确认修改
|
||||||
|
</sar-button>
|
||||||
|
</view>
|
||||||
|
</sar-form-plain>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
page {
|
||||||
|
background-color: #fff;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
@import '@/style/mixins.scss';
|
||||||
|
|
||||||
|
.form-container {
|
||||||
|
padding: 0rpx 32rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-description {
|
||||||
|
padding: 64rpx 0 64rpx;
|
||||||
|
color: var(--sar-secondary-color);
|
||||||
|
|
||||||
|
.form-title {
|
||||||
|
font-size: 42rpx;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #000;
|
||||||
|
}
|
||||||
|
.form-subtitle {
|
||||||
|
margin-top: 16rpx;
|
||||||
|
font-size: 24rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-list {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
@include flexGap(36rpx, column);
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-label {
|
||||||
|
display: flex;
|
||||||
|
font-size: 28rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-star {
|
||||||
|
color: var(--sar-danger);
|
||||||
|
}
|
||||||
|
.form-input {
|
||||||
|
margin-top: 20rpx;
|
||||||
|
:deep(.sar-input) {
|
||||||
|
background-color: #fff;
|
||||||
|
.sar-icon {
|
||||||
|
color: var(--sar-input-placeholder-color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
:deep(.sar-input_focused) {
|
||||||
|
.sar-input__prepend {
|
||||||
|
.sar-icon {
|
||||||
|
color: var(--sar-input-focused-border-color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer {
|
||||||
|
// position: sticky;
|
||||||
|
// bottom: 0;
|
||||||
|
padding-top: 64rpx;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,310 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import { toast } from 'sard-uniapp'
|
||||||
|
import { ref } from 'vue'
|
||||||
|
import { searchdatapageindexApi } from '@/request/api'
|
||||||
|
import { useUserStore } from '@/store'
|
||||||
|
|
||||||
|
const userStore = useUserStore()
|
||||||
|
|
||||||
|
const pagingRef = ref<any>(null)
|
||||||
|
const dataList = ref<any[]>([])
|
||||||
|
|
||||||
|
// 自定义 tabs
|
||||||
|
const tabList = computed(() => [
|
||||||
|
{ name: '未完成', count: 0 },
|
||||||
|
{ name: '已完成', count: 0 },
|
||||||
|
{ name: '全部', count: 0 },
|
||||||
|
])
|
||||||
|
const activeTab = ref(tabList.value[0])
|
||||||
|
|
||||||
|
// 搜索关键字
|
||||||
|
const searchValue = ref('')
|
||||||
|
|
||||||
|
// 切换 tab
|
||||||
|
function switchTab(tab: any) {
|
||||||
|
activeTab.value = tab
|
||||||
|
|
||||||
|
pagingRef.value.reload()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 搜索
|
||||||
|
function handleSearch() {
|
||||||
|
pagingRef.value.reload()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 模拟分页请求
|
||||||
|
function queryList(pageNo: number, pageSize: number) {
|
||||||
|
toast.loading('正在加载中')
|
||||||
|
|
||||||
|
const userid = userStore.userInfo.userid
|
||||||
|
|
||||||
|
let searchcondition = `2>1 AND b_kd_finish = '1' AND b_yx_finish = '1' `
|
||||||
|
|
||||||
|
if (activeTab.value.name === '未完成') {
|
||||||
|
searchcondition += ` AND ISNULL(b_dc_finish,'') <> '1' AND ISNULL(b_dcman_id,'') IN ('', '${userid}')`
|
||||||
|
}
|
||||||
|
else if (activeTab.value.name === '已完成') {
|
||||||
|
searchcondition += ` AND ISNULL(b_dc_finish,'') = '1' AND ISNULL(b_dcman_id,'') = '${userid}'`
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
searchcondition += ` AND (
|
||||||
|
(ISNULL(b_dc_finish,'') <> '1' AND ISNULL(b_dcman_id,'') IN ('', '${userid}'))
|
||||||
|
OR (ISNULL(b_dc_finish,'') = '1' AND ISNULL(b_dcman_id,'') = '${userid}')
|
||||||
|
)`
|
||||||
|
}
|
||||||
|
|
||||||
|
if (searchValue.value) {
|
||||||
|
searchcondition += ` and (b_conno like '%${searchValue.value}%')`
|
||||||
|
}
|
||||||
|
|
||||||
|
searchdatapageindexApi({
|
||||||
|
viewname: 'v_xc_conyard_in',
|
||||||
|
searchcondition,
|
||||||
|
userid,
|
||||||
|
page: pageNo,
|
||||||
|
rows: pageSize,
|
||||||
|
orderfield: 'b_jcdatetime desc',
|
||||||
|
})
|
||||||
|
.then((res) => {
|
||||||
|
const rows = res.data.rows || []
|
||||||
|
pagingRef.value.complete(rows)
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
toast.hide()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleToFile(itemData) {
|
||||||
|
uni.navigateTo({
|
||||||
|
url: `/pages-sub/file/index?moduleid=xc_conyard_in&father=${itemData.b_id}&cateid=014&edit=1`,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<view>
|
||||||
|
<z-paging ref="pagingRef" v-model="dataList" @query="queryList">
|
||||||
|
<template #top>
|
||||||
|
<sar-search
|
||||||
|
v-model="searchValue"
|
||||||
|
placeholder="请输入箱号搜索"
|
||||||
|
@search="handleSearch"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<view class="tabs">
|
||||||
|
<view
|
||||||
|
v-for="tab in tabList"
|
||||||
|
:key="tab.name"
|
||||||
|
class="tabs__item"
|
||||||
|
:class="{ 'tabs__item--active': activeTab.name === tab.name }"
|
||||||
|
@click="switchTab(tab)"
|
||||||
|
>
|
||||||
|
<sar-badge :value="tab.count">
|
||||||
|
{{ tab.name }}
|
||||||
|
</sar-badge>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 列表内容 -->
|
||||||
|
<view
|
||||||
|
v-for="(item, index) in dataList"
|
||||||
|
:key="index"
|
||||||
|
class="list-item"
|
||||||
|
>
|
||||||
|
<view class="list-item__header">
|
||||||
|
<view class="list-item__main">
|
||||||
|
箱号:{{ item.b_conno }}
|
||||||
|
</view>
|
||||||
|
<view class="list-item__extra">
|
||||||
|
<sar-tag v-if="item.b_dc_finish === '1'" theme="success" size="small">
|
||||||
|
已完成
|
||||||
|
</sar-tag>
|
||||||
|
<sar-tag v-else>
|
||||||
|
未完成
|
||||||
|
</sar-tag>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="list-item__body">
|
||||||
|
<sar-row>
|
||||||
|
<sar-col :span="12">
|
||||||
|
<view class="list-item__info">
|
||||||
|
<view class="list-item__label">
|
||||||
|
进场单号:
|
||||||
|
</view>
|
||||||
|
<view class="list-item__value">
|
||||||
|
{{ item.b_id }}
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</sar-col>
|
||||||
|
<sar-col :span="12">
|
||||||
|
<view class="list-item__info">
|
||||||
|
<view class="list-item__label">
|
||||||
|
进场指令号:
|
||||||
|
</view>
|
||||||
|
<view class="list-item__value">
|
||||||
|
{{ item.b_blno }}
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</sar-col>
|
||||||
|
<sar-col :span="6">
|
||||||
|
<view class="list-item__info">
|
||||||
|
<view class="list-item__label">
|
||||||
|
箱型:
|
||||||
|
</view>
|
||||||
|
<view class="list-item__value">
|
||||||
|
{{ item.b_contype }}
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</sar-col>
|
||||||
|
<sar-col :span="6">
|
||||||
|
<view class="list-item__info">
|
||||||
|
<view class="list-item__label">
|
||||||
|
空重:
|
||||||
|
</view>
|
||||||
|
<view class="list-item__value">
|
||||||
|
{{ item.b_conkz }}
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</sar-col>
|
||||||
|
<sar-col :span="6">
|
||||||
|
<view class="list-item__info">
|
||||||
|
<view class="list-item__label">
|
||||||
|
箱态:
|
||||||
|
</view>
|
||||||
|
<view class="list-item__value">
|
||||||
|
{{ item.b_constate }}
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</sar-col>
|
||||||
|
<sar-col :span="6">
|
||||||
|
<view class="list-item__info">
|
||||||
|
<view class="list-item__label">
|
||||||
|
箱况:
|
||||||
|
</view>
|
||||||
|
<view class="list-item__value">
|
||||||
|
{{ item.b_conxk }}
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</sar-col>
|
||||||
|
<sar-col :span="6">
|
||||||
|
<view class="list-item__info">
|
||||||
|
<view class="list-item__label">
|
||||||
|
箱位:
|
||||||
|
</view>
|
||||||
|
<view class="list-item__value">
|
||||||
|
{{ item.b_xwt }}
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</sar-col>
|
||||||
|
</sar-row>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="list-item__footer">
|
||||||
|
<sar-button inline size="mini" square @click="handleToFile(item)">
|
||||||
|
拍照
|
||||||
|
</sar-button>
|
||||||
|
<sar-button
|
||||||
|
v-if="item.b_dc_finish !== '1'"
|
||||||
|
inline
|
||||||
|
square
|
||||||
|
type="default"
|
||||||
|
theme="success"
|
||||||
|
size="mini"
|
||||||
|
>
|
||||||
|
确认
|
||||||
|
</sar-button>
|
||||||
|
</view>
|
||||||
|
<view class="list-item__line" />
|
||||||
|
</view>
|
||||||
|
</z-paging>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
@import '@/style/mixins.scss';
|
||||||
|
|
||||||
|
/* tab 栏 */
|
||||||
|
.tabs {
|
||||||
|
display: flex;
|
||||||
|
border-bottom: 2rpx solid #eee;
|
||||||
|
background-color: #fff;
|
||||||
|
|
||||||
|
.tabs__item {
|
||||||
|
flex: 1;
|
||||||
|
text-align: center;
|
||||||
|
padding: 16rpx 0;
|
||||||
|
font-size: 30rpx;
|
||||||
|
color: #888;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tabs__item--active {
|
||||||
|
color: var(--sar-primary);
|
||||||
|
font-weight: bold;
|
||||||
|
border-bottom: 4rpx solid var(--sar-primary);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 列表项 */
|
||||||
|
.list-item {
|
||||||
|
position: relative;
|
||||||
|
padding: 16rpx;
|
||||||
|
background-color: #fff;
|
||||||
|
|
||||||
|
.list-item__header {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
|
||||||
|
.list-item__main {
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 30rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.list-item__body {
|
||||||
|
.list-item__info {
|
||||||
|
display: flex;
|
||||||
|
align-items: start;
|
||||||
|
width: 100%;
|
||||||
|
font-size: 26rpx;
|
||||||
|
line-height: 1;
|
||||||
|
margin-top: 16rpx;
|
||||||
|
|
||||||
|
.list-item__label {
|
||||||
|
display: block;
|
||||||
|
width: 5rem;
|
||||||
|
color: #4b5563;
|
||||||
|
text-align: right;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.list-item__value {
|
||||||
|
flex: 1;
|
||||||
|
color: #111827;
|
||||||
|
word-break: break-all;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.list-item__footer {
|
||||||
|
margin-top: 16rpx;
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
@include flexGap(36rpx, '');
|
||||||
|
|
||||||
|
:deep(.sar-button) {
|
||||||
|
padding: 0rpx 48rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.list-item__line {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0rpx;
|
||||||
|
left: 0rpx;
|
||||||
|
height: 1px;
|
||||||
|
width: 100%;
|
||||||
|
background-color: #dcdcdc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -52,7 +52,7 @@
|
|||||||
"layout": "default",
|
"layout": "default",
|
||||||
"style": {
|
"style": {
|
||||||
"navigationBarTitleText": "个人中心",
|
"navigationBarTitleText": "个人中心",
|
||||||
"navigationStyle": "custom"
|
"navigationStyle": "default"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@@ -66,6 +66,27 @@
|
|||||||
"navigationBarTitleText": "登录",
|
"navigationBarTitleText": "登录",
|
||||||
"navigationStyle": "default"
|
"navigationStyle": "default"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "file/index",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "附件管理",
|
||||||
|
"navigationStyle": "default"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "update-password/index",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "修改密码",
|
||||||
|
"navigationStyle": "default"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "xcjin/index",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "进场堆高机",
|
||||||
|
"navigationStyle": "default"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ function handleLoginOut() {
|
|||||||
title: '提示',
|
title: '提示',
|
||||||
message: '确定退出登录?',
|
message: '确定退出登录?',
|
||||||
onConfirm() {
|
onConfirm() {
|
||||||
toast.success('退出成功')
|
|
||||||
userStore.reset()
|
userStore.reset()
|
||||||
|
|
||||||
uni.navigateTo({
|
uni.navigateTo({
|
||||||
@@ -18,27 +17,75 @@ function handleLoginOut() {
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function handleToLogin() {
|
||||||
|
if (userStore.isLogined) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
uni.navigateTo({
|
||||||
|
url: '/pages-sub/login/index',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleToUpdatePassword() {
|
||||||
|
handleToLogin()
|
||||||
|
|
||||||
|
uni.navigateTo({
|
||||||
|
url: '/pages-sub/update-password/index',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const avatarText = computed(() => {
|
||||||
|
if (!userStore.isLogined) {
|
||||||
|
return '登'
|
||||||
|
}
|
||||||
|
|
||||||
|
const id = userStore.userInfo?.userid
|
||||||
|
if (!id || id.length === 0)
|
||||||
|
return 'A'
|
||||||
|
|
||||||
|
return id.charAt(0).toUpperCase()
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<view class="account-container">
|
<view>
|
||||||
<view class="account-header">
|
<view class="account-header" @click="handleToLogin">
|
||||||
<sar-avatar background="#7f8c8d" color="#fff">
|
<sar-avatar size="96rpx" icon-size="48rpx" background="var(--sar-primary)" color="#fff">
|
||||||
A
|
{{ avatarText }}
|
||||||
</sar-avatar>
|
</sar-avatar>
|
||||||
<view class="user-info">
|
<view class="user-info">
|
||||||
<text class="user-account">
|
<text class="user-userid">
|
||||||
123
|
{{ userStore.isLogined ? userStore.userInfo.userid : "尚未登录!" }}
|
||||||
</text>
|
</text>
|
||||||
<text class="user-orgid">
|
<text class="user-orgid">
|
||||||
123
|
{{ userStore.isLogined ? userStore.userInfo.orgid : "点击前去登录。" }}
|
||||||
</text>
|
</text>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<view class="actions">
|
<view class="actions">
|
||||||
<sar-list-item title="修改资料" />
|
<sar-list-item title="修改密码" hover arrow @click="handleToUpdatePassword">
|
||||||
<sar-list-item title="退出登录" value="值" />
|
<template #icon>
|
||||||
|
<sar-icon
|
||||||
|
family="iconfont"
|
||||||
|
name="updatePassword"
|
||||||
|
color="var(--sar-primary)"
|
||||||
|
size="36rpx"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</sar-list-item>
|
||||||
|
|
||||||
|
<sar-list-item title="退出登录" hover arrow @click="handleLoginOut">
|
||||||
|
<template #icon>
|
||||||
|
<sar-icon
|
||||||
|
family="iconfont"
|
||||||
|
name="exitLogin"
|
||||||
|
color="var(--sar-primary)"
|
||||||
|
size="36rpx"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</sar-list-item>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
@@ -47,34 +94,30 @@ function handleLoginOut() {
|
|||||||
.account-header {
|
.account-header {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
padding: 40rpx 32rpx;
|
padding: 36rpx 28rpx;
|
||||||
background-color: #2c3e50; /* 工业风深色 */
|
background-color: #fff;
|
||||||
border-radius: 2rpx; /* 轻微卡片感 */
|
|
||||||
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.15);
|
|
||||||
|
|
||||||
.user-info {
|
.user-info {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
margin-left: 32rpx;
|
margin-left: 32rpx;
|
||||||
color: #fff;
|
justify-content: space-between;
|
||||||
|
.user-userid {
|
||||||
.user-account {
|
font-size: 36rpx;
|
||||||
font-size: 34rpx;
|
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
line-height: 42rpx;
|
line-height: 36rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.user-orgid {
|
.user-orgid {
|
||||||
font-size: 28rpx;
|
font-size: 28rpx;
|
||||||
margin-top: 6rpx;
|
margin-top: 12rpx;
|
||||||
color: #6b788e;
|
color: #6b788e;
|
||||||
line-height: 34rpx;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.actions{
|
.actions {
|
||||||
margin-top: 32rpx;
|
margin-top: 32rpx;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
@@ -7,6 +7,15 @@ const swiperList = [
|
|||||||
{},
|
{},
|
||||||
{},
|
{},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
function toLinkUrl(url) {
|
||||||
|
if (!url) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
uni.navigateTo({
|
||||||
|
url,
|
||||||
|
})
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@@ -70,6 +79,12 @@ const swiperList = [
|
|||||||
<text>内容</text>
|
<text>内容</text>
|
||||||
</view>
|
</view>
|
||||||
</sar-grid-item>
|
</sar-grid-item>
|
||||||
|
<sar-grid-item @click="toLinkUrl('/pages-sub/xcjin/index')">
|
||||||
|
<view class="grid-item">
|
||||||
|
<image src="@/static/images/柴犬.png" />
|
||||||
|
<text>进场堆高机</text>
|
||||||
|
</view>
|
||||||
|
</sar-grid-item>
|
||||||
</sar-grid>
|
</sar-grid>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
@@ -85,6 +100,9 @@ const swiperList = [
|
|||||||
}
|
}
|
||||||
.grid-container {
|
.grid-container {
|
||||||
margin-top: 32rpx;
|
margin-top: 32rpx;
|
||||||
|
:deep(.sar-grid__content) {
|
||||||
|
background-color: var(--sar-primary);
|
||||||
|
}
|
||||||
.grid-item {
|
.grid-item {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
@@ -98,6 +116,7 @@ const swiperList = [
|
|||||||
text {
|
text {
|
||||||
margin-top: 16rpx;
|
margin-top: 16rpx;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
|
color: #fff;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,3 +38,67 @@ interface GetAutocompleteDataExParams {
|
|||||||
export function getAutocompleteDataExApi(params: GetAutocompleteDataExParams) {
|
export function getAutocompleteDataExApi(params: GetAutocompleteDataExParams) {
|
||||||
return request.postForm('/getAutocompleteDataEx.jsp', params)
|
return request.postForm('/getAutocompleteDataEx.jsp', params)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface SaveobjtParams {
|
||||||
|
tables: string
|
||||||
|
insertValues: string
|
||||||
|
delValues: string
|
||||||
|
updateValues: string
|
||||||
|
keys: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export function saveobjtApi(params: SaveobjtParams) {
|
||||||
|
return request.postForm('/saveobjt.jsp', params)
|
||||||
|
}
|
||||||
|
|
||||||
|
interface SearchdataParams {
|
||||||
|
viewname: string
|
||||||
|
searchcondition: string
|
||||||
|
orderfield: string
|
||||||
|
}
|
||||||
|
export function searchdataApi(params: SearchdataParams) {
|
||||||
|
return request.postForm('/searchdata.jsp', params)
|
||||||
|
}
|
||||||
|
|
||||||
|
interface SearchdatapageindexParams {
|
||||||
|
viewname: string
|
||||||
|
searchcondition: string
|
||||||
|
userid: string
|
||||||
|
orderfield: string
|
||||||
|
page: number
|
||||||
|
rows: number
|
||||||
|
}
|
||||||
|
|
||||||
|
export function searchdatapageindexApi(params: SearchdatapageindexParams) {
|
||||||
|
return request.postForm(`/searchdatapageindex.jsp`, params)
|
||||||
|
}
|
||||||
|
interface DelSubRecordParams {
|
||||||
|
id: string
|
||||||
|
module: string
|
||||||
|
bucketName: string
|
||||||
|
}
|
||||||
|
export function delSubRecordApi(params: DelSubRecordParams) {
|
||||||
|
return request.postForm('/DelSubRecord.jsp', params)
|
||||||
|
}
|
||||||
|
|
||||||
|
interface getaliyunkeyParams {
|
||||||
|
orgid: string
|
||||||
|
bucket: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getaliyunkeyApi(params: getaliyunkeyParams) {
|
||||||
|
return request.postForm(`/getaliyunkey.jsp`, params)
|
||||||
|
}
|
||||||
|
|
||||||
|
interface aliyunpluploadParams {
|
||||||
|
despathfile: string
|
||||||
|
myfilename: string
|
||||||
|
size: string
|
||||||
|
tablename: string
|
||||||
|
sid: string
|
||||||
|
mx_moduleid: string
|
||||||
|
mx_cate_id: string
|
||||||
|
}
|
||||||
|
export function aliyunpluploadApi(params: aliyunpluploadParams) {
|
||||||
|
return request.postForm(`/aliyunplupload.jsp`, params)
|
||||||
|
}
|
||||||
@@ -109,7 +109,7 @@ function request<T = any>(option: UniApp.RequestOptions): Promise<IResData<T>> &
|
|||||||
}
|
}
|
||||||
catch {
|
catch {
|
||||||
// 如果解析失败,保持原始字符串即可
|
// 如果解析失败,保持原始字符串即可
|
||||||
console.warn('data.data 不是合法 JSON 字符串', data.data)
|
// console.warn('data.data 不是合法 JSON 字符串', data.data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,17 +1,25 @@
|
|||||||
@font-face {
|
@font-face {
|
||||||
font-family: 'iconfont'; /* Project id 5031675 */
|
font-family: 'iconfont'; /* Project id 5031675 */
|
||||||
src: url('data:font/ttf;charset=utf-8;base64,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 truncated
|
src: url('data:font/ttf;charset=utf-8;base64,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 truncated
|
||||||
format('truetype');
|
format('truetype');
|
||||||
}
|
}
|
||||||
|
|
||||||
.iconfont {
|
.iconfont {
|
||||||
font-family: 'iconfont' !important;
|
font-family: 'iconfont' !important;
|
||||||
font-size: 32rpx;
|
font-size: 16px;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
-webkit-font-smoothing: antialiased;
|
-webkit-font-smoothing: antialiased;
|
||||||
-moz-osx-font-smoothing: grayscale;
|
-moz-osx-font-smoothing: grayscale;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.iconfont-updatePassword:before {
|
||||||
|
content: '\e628';
|
||||||
|
}
|
||||||
|
|
||||||
|
.iconfont-exitLogin:before {
|
||||||
|
content: '\e600';
|
||||||
|
}
|
||||||
|
|
||||||
.iconfont-chaiquan:before {
|
.iconfont-chaiquan:before {
|
||||||
content: '\e647';
|
content: '\e647';
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,224 @@
|
|||||||
|
import { getaliyunkeyApi } from '@/request/api'
|
||||||
|
import { useUserStore } from '@/store'
|
||||||
|
import { isH5 } from './platform'
|
||||||
|
|
||||||
|
const aliyunBucket = import.meta.env.VITE_ALIYUN_BUCKET
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 压缩图片(多端通用)
|
||||||
|
* @param url 图片路径
|
||||||
|
* @param name 图片名称
|
||||||
|
* @returns Promise<{ path: string, size: number }>
|
||||||
|
*/
|
||||||
|
export async function imageCompress(url: string): Promise<{ path: string, size: number }> {
|
||||||
|
// #ifndef H5
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
uni.compressImage({
|
||||||
|
src: url,
|
||||||
|
quality: 80,
|
||||||
|
success: async (res) => {
|
||||||
|
try {
|
||||||
|
// 获取文件信息
|
||||||
|
const fileInfo = await uni.getFileInfo({ filePath: res.tempFilePath })
|
||||||
|
resolve({
|
||||||
|
path: res.tempFilePath,
|
||||||
|
size: fileInfo.size,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
reject(e)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
fail: reject,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
// #ifdef H5
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const img = new Image()
|
||||||
|
img.crossOrigin = 'Anonymous'
|
||||||
|
img.src = url
|
||||||
|
|
||||||
|
img.onload = () => {
|
||||||
|
try {
|
||||||
|
const canvas = document.createElement('canvas')
|
||||||
|
const ctx = canvas.getContext('2d')!
|
||||||
|
const maxSize = 600
|
||||||
|
let { width, height } = img
|
||||||
|
|
||||||
|
// 按比例压缩
|
||||||
|
if (width > height && width > maxSize) {
|
||||||
|
height = (maxSize * height) / width
|
||||||
|
width = maxSize
|
||||||
|
}
|
||||||
|
else if (height > width && height > maxSize) {
|
||||||
|
width = (maxSize * width) / height
|
||||||
|
height = maxSize
|
||||||
|
}
|
||||||
|
|
||||||
|
canvas.width = width
|
||||||
|
canvas.height = height
|
||||||
|
ctx.clearRect(0, 0, width, height)
|
||||||
|
ctx.drawImage(img, 0, 0, width, height)
|
||||||
|
|
||||||
|
const base64 = canvas.toDataURL('image/jpeg', 0.8)
|
||||||
|
|
||||||
|
// 计算 Base64 大小
|
||||||
|
const sizeInBytes = Math.round((base64.length - (base64.indexOf(',') + 1)) * 0.75)
|
||||||
|
|
||||||
|
resolve({
|
||||||
|
path: base64,
|
||||||
|
size: sizeInBytes,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
reject(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
img.onerror = reject
|
||||||
|
})
|
||||||
|
// #endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断文件名是否为图片类型
|
||||||
|
* @param fileName 文件名(如 "photo.png"、"avatar.JPG")
|
||||||
|
*/
|
||||||
|
export function isImage(fileName: string): boolean {
|
||||||
|
if (!fileName || typeof fileName !== 'string')
|
||||||
|
return false
|
||||||
|
|
||||||
|
// 常见图片扩展名(全小写)
|
||||||
|
const imageExtensions = ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp', 'svg', 'heic']
|
||||||
|
|
||||||
|
// 取文件名的后缀
|
||||||
|
const ext = fileName.split('.').pop()?.toLowerCase()
|
||||||
|
|
||||||
|
// 检查是否在图片后缀列表中
|
||||||
|
return !!ext && imageExtensions.includes(ext)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 文件大小格式化
|
||||||
|
export function formatFileSize(size: number): string {
|
||||||
|
if (size < 1024)
|
||||||
|
return `${size} B`
|
||||||
|
else if (size < 1024 * 1024)
|
||||||
|
return `${(size / 1024).toFixed(2)} KB`
|
||||||
|
else if (size < 1024 * 1024 * 1024)
|
||||||
|
return `${(size / (1024 * 1024)).toFixed(2)} MB`
|
||||||
|
else return `${(size / (1024 * 1024 * 1024)).toFixed(2)} GB`
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface AliyunUploadResult {
|
||||||
|
url: string // 上传后的完整 URL
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 上传文件到阿里云 OSS
|
||||||
|
* @param filePath 本地文件路径
|
||||||
|
* @param fileName 文件名
|
||||||
|
* @param fileType 文件类型,可选:image/video/file
|
||||||
|
* @returns Promise<AliyunUploadResult>
|
||||||
|
*/
|
||||||
|
export async function uploadFileToAliyun(
|
||||||
|
filePath: string,
|
||||||
|
fileName: string,
|
||||||
|
fileType: any,
|
||||||
|
): Promise<AliyunUploadResult> {
|
||||||
|
const userStore = useUserStore()
|
||||||
|
|
||||||
|
// 获取 OSS 临时上传凭证
|
||||||
|
const keyRes = await getaliyunkeyApi({
|
||||||
|
orgid: userStore.userInfo.orgid,
|
||||||
|
bucket: aliyunBucket,
|
||||||
|
})
|
||||||
|
const { accessid, callback, dir, host, policy, signature } = keyRes.data
|
||||||
|
|
||||||
|
// 构建文件在 OSS 的存储路径
|
||||||
|
const fileExtension = fileName.split('.').pop()?.toLowerCase() || 'tmp'
|
||||||
|
const timestamp = Date.now()
|
||||||
|
const random = Math.floor(Math.random() * 1000)
|
||||||
|
const key = `${dir}/${timestamp + random}.${fileExtension}`
|
||||||
|
|
||||||
|
const formData: Record<string, any> = {
|
||||||
|
key,
|
||||||
|
OSSAccessKeyId: accessid,
|
||||||
|
policy,
|
||||||
|
signature,
|
||||||
|
success_action_status: '200',
|
||||||
|
name: fileName,
|
||||||
|
}
|
||||||
|
if (callback)
|
||||||
|
formData.callback = callback
|
||||||
|
|
||||||
|
// 使用 Promise 包裹 uni.uploadFile
|
||||||
|
return new Promise<AliyunUploadResult>((resolve, reject) => {
|
||||||
|
uni.uploadFile({
|
||||||
|
url: host,
|
||||||
|
filePath,
|
||||||
|
name: 'file',
|
||||||
|
fileName,
|
||||||
|
fileType,
|
||||||
|
formData,
|
||||||
|
success: (res) => {
|
||||||
|
if (res.statusCode === 200) {
|
||||||
|
resolve({
|
||||||
|
url: `${host}/${key}`,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
reject(new Error(`上传失败,状态码: ${res.statusCode}`))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
fail: (err) => {
|
||||||
|
reject(err)
|
||||||
|
},
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function downloadFile(fileUrl: string, fileName?: string) {
|
||||||
|
if (isH5) {
|
||||||
|
// H5 平台下载逻辑
|
||||||
|
const name = fileName || fileUrl.split('/').pop() || 'file'
|
||||||
|
const a = document.createElement('a')
|
||||||
|
a.href = fileUrl
|
||||||
|
a.download = name
|
||||||
|
a.target = '_blank'
|
||||||
|
document.body.appendChild(a)
|
||||||
|
a.click()
|
||||||
|
document.body.removeChild(a)
|
||||||
|
console.log('H5 文件下载已触发:', name)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// APP / 小程序下载逻辑
|
||||||
|
uni.downloadFile({
|
||||||
|
url: fileUrl,
|
||||||
|
success: (response) => {
|
||||||
|
if (response.statusCode === 200 && response.tempFilePath) {
|
||||||
|
uni.saveFile({
|
||||||
|
tempFilePath: response.tempFilePath,
|
||||||
|
success: (resData) => {
|
||||||
|
console.log('保存路径', resData.savedFilePath)
|
||||||
|
uni.showToast({ title: '下载成功' })
|
||||||
|
},
|
||||||
|
fail: (error) => {
|
||||||
|
console.error('保存失败', error)
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
console.error('下载失败或 tempFilePath 不存在', response)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
fail: (err) => {
|
||||||
|
console.error('downloadFile 失败', err)
|
||||||
|
},
|
||||||
|
progress: (res) => {
|
||||||
|
console.log(`下载进度: ${res.progress}%`)
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,74 @@
|
|||||||
|
import dayjs from 'dayjs'
|
||||||
|
|
||||||
|
// 定义单位的类型
|
||||||
|
type Unit = 'day' | 'week' | 'month' | 'year'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取指定日期之前的日期
|
||||||
|
* @param value 数字,表示要减去的时间量
|
||||||
|
* @param unit 时间单位,可以是 'day'、'week'、'month' 或 'year'
|
||||||
|
* @returns 返回计算后的日期
|
||||||
|
*/
|
||||||
|
export function getDateBefore(value: number, unit: Unit): string {
|
||||||
|
return dayjs().subtract(value, unit).format('YYYY-MM-DD')
|
||||||
|
}
|
||||||
|
export function getTimeDifference(dateStr1: string, dateStr2: string) {
|
||||||
|
const date1 = new Date(dateStr1)
|
||||||
|
|
||||||
|
if (!dateStr2) {
|
||||||
|
return Number.NaN
|
||||||
|
}
|
||||||
|
|
||||||
|
const date2 = new Date(dateStr2)
|
||||||
|
const differenceInMilliseconds = date2.getTime() - date1.getTime()
|
||||||
|
|
||||||
|
return differenceInMilliseconds
|
||||||
|
}
|
||||||
|
// 获取当前年份
|
||||||
|
|
||||||
|
export function getYear(): string {
|
||||||
|
return dayjs().year().toString()
|
||||||
|
}
|
||||||
|
export function getMonth(): string {
|
||||||
|
// 获取当前月份并加1,确保是1-12范围
|
||||||
|
const month = (dayjs().month() + 1).toString()
|
||||||
|
return month.padStart(2, '0') // 如果是单数月,前面加0
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getDay(): string {
|
||||||
|
// 获取当前日期并转换为字符串
|
||||||
|
const day = dayjs().date().toString()
|
||||||
|
return day.padStart(2, '0') // 如果是单数天,前面加0
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getCurrentDate() {
|
||||||
|
return dayjs().format('YYYY-MM-DD')
|
||||||
|
}
|
||||||
|
export function getCurrentDateTimeWithSeconds() {
|
||||||
|
return dayjs().format('YYYY-MM-DD HH:mm:ss')
|
||||||
|
}
|
||||||
|
export function stringToTimestamp(timeString: string, format: string): number {
|
||||||
|
const parsedDate = dayjs(timeString, format)
|
||||||
|
if (!parsedDate.isValid()) {
|
||||||
|
throw new Error('Invalid date string or format')
|
||||||
|
}
|
||||||
|
return parsedDate.valueOf() // 返回时间戳(以毫秒为单位)
|
||||||
|
}
|
||||||
|
export function timestampToString(timestamp: number, format: string): string {
|
||||||
|
const parsedDate = dayjs(timestamp)
|
||||||
|
return parsedDate.format(format)
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 判断传入日期是否在今天的60天以内(含60天)
|
||||||
|
* @param dateStr - 日期字符串(如 '2025-02-01')
|
||||||
|
* @returns boolean - true 表示在60天内(包括第60天),false 表示超过60天
|
||||||
|
*/
|
||||||
|
export function isWithin60Days(dateStr: string): boolean {
|
||||||
|
if (!dateStr.trim()) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
const inputDate = dayjs(dateStr)
|
||||||
|
const today = dayjs()
|
||||||
|
const diffDays = today.diff(inputDate, 'day')
|
||||||
|
return diffDays >= 0 && diffDays <= 60
|
||||||
|
}
|
||||||
@@ -1,138 +1,119 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="zh-CN">
|
<html lang="zh">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<title>个人中心</title>
|
<title>附件管理</title>
|
||||||
<style>
|
<style>
|
||||||
:root {
|
body {
|
||||||
--theme-color: #2c3e50;
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
||||||
--text-main: #2c3e50;
|
background-color: #f8f9fa;
|
||||||
--text-sub: #7f8c8d;
|
|
||||||
--bg-light: #f4f5f7;
|
|
||||||
--card-bg: #ffffff;
|
|
||||||
}
|
|
||||||
|
|
||||||
body {
|
|
||||||
margin: 0;
|
margin: 0;
|
||||||
font-family: "SF Pro Text", "Roboto", "Segoe UI", Arial, sans-serif;
|
padding: 0;
|
||||||
background: var(--bg-light);
|
}
|
||||||
color: var(--text-main);
|
.header {
|
||||||
}
|
background-color: #2c3e50;
|
||||||
|
|
||||||
/* 卡片式 Header */
|
|
||||||
.header-card {
|
|
||||||
background: var(--theme-color);
|
|
||||||
color: #fff;
|
color: #fff;
|
||||||
margin: 20px 16px 0;
|
padding: 15px;
|
||||||
padding: 20px;
|
text-align: center;
|
||||||
display: flex;
|
font-size: 18px;
|
||||||
align-items: center;
|
}
|
||||||
box-shadow: 0 2px 8px rgba(0,0,0,0.15);
|
.upload-area {
|
||||||
}
|
background: #fff;
|
||||||
|
margin: 15px;
|
||||||
.avatar {
|
padding: 15px;
|
||||||
width: 70px;
|
border-radius: 8px;
|
||||||
height: 70px;
|
box-shadow: 0 2px 5px rgba(0,0,0,0.05);
|
||||||
background: #7f8c8d;
|
}
|
||||||
color: #fff;
|
.upload-area input[type="file"] {
|
||||||
font-size: 28px;
|
display: none;
|
||||||
display: flex;
|
}
|
||||||
align-items: center;
|
.upload-label {
|
||||||
justify-content: center;
|
|
||||||
margin-right: 20px;
|
|
||||||
flex-shrink: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.user-info {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
justify-content: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.welcome {
|
|
||||||
font-size: 14px;
|
|
||||||
color: #c0cfd8;
|
|
||||||
margin-bottom: 6px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.user-name {
|
|
||||||
font-size: 20px;
|
|
||||||
font-weight: 600;
|
|
||||||
margin-bottom: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.user-details span {
|
|
||||||
display: block;
|
display: block;
|
||||||
font-size: 14px;
|
|
||||||
color: #d0d6db;
|
|
||||||
line-height: 1.6;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 操作按钮区 */
|
|
||||||
.actions {
|
|
||||||
margin: 28px 16px;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
gap: 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn {
|
|
||||||
background: var(--theme-color);
|
|
||||||
color: #fff;
|
|
||||||
text-align: center;
|
text-align: center;
|
||||||
padding: 14px 0;
|
padding: 20px;
|
||||||
font-size: 15px;
|
border: 2px dashed #ccc;
|
||||||
border: none;
|
border-radius: 8px;
|
||||||
border-radius: 2px;
|
color: #666;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: 0.2s;
|
}
|
||||||
}
|
.attachment-list {
|
||||||
|
margin: 15px;
|
||||||
.btn:hover {
|
}
|
||||||
background: #1e2d3a;
|
.attachment-item {
|
||||||
}
|
background: #fff;
|
||||||
|
border-radius: 8px;
|
||||||
.btn.secondary {
|
padding: 10px;
|
||||||
background: transparent;
|
margin-bottom: 10px;
|
||||||
color: var(--theme-color);
|
display: flex;
|
||||||
border: 1px solid var(--theme-color);
|
align-items: center;
|
||||||
}
|
justify-content: space-between;
|
||||||
|
box-shadow: 0 2px 5px rgba(0,0,0,0.05);
|
||||||
.btn.secondary:hover {
|
}
|
||||||
background: rgba(44,62,80,0.05);
|
.attachment-info {
|
||||||
}
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
/* 底部 */
|
gap: 10px;
|
||||||
.footer {
|
}
|
||||||
text-align: center;
|
.attachment-thumb {
|
||||||
margin-top: 32px;
|
width: 50px;
|
||||||
font-size: 12px;
|
height: 50px;
|
||||||
color: #999;
|
border-radius: 4px;
|
||||||
}
|
object-fit: cover;
|
||||||
</style>
|
background-color: #eaeaea;
|
||||||
|
}
|
||||||
|
.attachment-name {
|
||||||
|
font-size: 14px;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
.attachment-actions button {
|
||||||
|
margin-left: 5px;
|
||||||
|
padding: 5px 10px;
|
||||||
|
border-radius: 4px;
|
||||||
|
border: none;
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
.btn-primary {
|
||||||
|
background-color: #2c3e50;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
.btn-danger {
|
||||||
|
background-color: #e74c3c;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<!-- 卡片式 Header -->
|
<div class="header">附件管理</div>
|
||||||
<div class="header-card">
|
|
||||||
<div class="avatar">U</div>
|
<div class="upload-area">
|
||||||
<div class="user-info">
|
<label for="file-upload" class="upload-label">点击上传附件</label>
|
||||||
<div class="welcome">欢迎登录!</div>
|
<input type="file" id="file-upload" multiple />
|
||||||
<div class="user-name">张三</div>
|
|
||||||
<div class="user-details">
|
|
||||||
<span>账号:zhangsan</span>
|
|
||||||
<span>机构码:A-102938</span>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="attachment-list">
|
||||||
|
<div class="attachment-item">
|
||||||
|
<div class="attachment-info">
|
||||||
|
<img src="https://via.placeholder.com/50" class="attachment-thumb" />
|
||||||
|
<div class="attachment-name">工单图片1.jpg</div>
|
||||||
|
</div>
|
||||||
|
<div class="attachment-actions">
|
||||||
|
<button class="btn-primary">预览</button>
|
||||||
|
<button class="btn-danger">删除</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 操作按钮区 -->
|
<div class="attachment-item">
|
||||||
<div class="actions">
|
<div class="attachment-info">
|
||||||
<button class="btn">修改资料</button>
|
<div class="attachment-thumb"></div>
|
||||||
<button class="btn secondary">退出登录</button>
|
<div class="attachment-name">报告文档.pdf</div>
|
||||||
|
</div>
|
||||||
|
<div class="attachment-actions">
|
||||||
|
<button class="btn-primary">预览</button>
|
||||||
|
<button class="btn-danger">删除</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 底部 -->
|
|
||||||
<div class="footer">© 2025 工业控制系统中心</div>
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
@@ -87,7 +87,6 @@ public class WebSocketApplication {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@OnMessage
|
@OnMessage
|
||||||
public void onMessage(String message, Session session) throws IOException {
|
public void onMessage(String message, Session session) throws IOException {
|
||||||
ImAcceptMessageDTO baseDto = null;
|
ImAcceptMessageDTO baseDto = null;
|
||||||
@@ -136,7 +135,6 @@ public class WebSocketApplication {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@OnError
|
@OnError
|
||||||
public void onError(Session session, Throwable throwable) {
|
public void onError(Session session, Throwable throwable) {
|
||||||
|
|
||||||
|
|||||||
@@ -31,6 +31,4 @@ public class ImMessage {
|
|||||||
private String quoteId;// 引用id
|
private String quoteId;// 引用id
|
||||||
@TableField(value = "b_create_time", fill = FieldFill.INSERT)
|
@TableField(value = "b_create_time", fill = FieldFill.INSERT)
|
||||||
private String createTime;
|
private String createTime;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user