feat: 生产部署 + 会议全链路 (执行方分配/费用结算/签到脱敏/H5相机)

- 生产 nginx 三路径: ry-vue3 /hg/, ry-h5 /camera/, API /hg-api, .env 分环境
- 签约链接/摄像头 base-url 走 yml, 不再硬编码 /hg 与 localhost
- 新增 biz_project_executor_assign (镜像 sponsor_assign) 执行方项目级分配
- 会议费用后台汇总 FeeCalcScheduler + 结算回写项目金额 + 状态流转调度
- 签到表拍照高斯模糊脱敏 extra_oss_url, 新增 PosterService/StageDeriver
- 清理 biz_support_intent 旧表 (6 Java/XML 删除)
- ry-h5 相机黑屏修复: 显式 video.play() + 动态 apiBase 上传
- 资源: simhei 字体 / logo.png / qrcode_1.png / favicon.ico

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
郭庆泰
2026-08-24 01:00:09 +08:00
co-authored by Claude
parent 80a276e661
commit 904e28710f
123 changed files with 6008 additions and 1706 deletions
+48 -12
View File
@@ -8,11 +8,27 @@
* - 返回 ref 和方法,业务页只需负责 UI 布局
*/
import { ref, onMounted, onBeforeUnmount } from 'vue'
import { openCamera, stopCamera, captureFrame, describeCameraError, type Facing } from '@/utils/camera'
import {
openCamera,
stopCamera,
captureFrame,
captureFrameWithBlur,
describeCameraError,
type Facing,
} from '@/utils/camera'
import { uploadCameraPhoto } from '@/utils/upload'
export function useCamera(videoId: string) {
/** 条带高斯模糊配置 (签到表脱敏用): 对截图竖直 [start, end] 比例区间做高斯模糊 */
export type BlurConfig = {
start: number
end: number
radius: number
}
export function useCamera(videoId: string, blur?: BlurConfig) {
const facing = ref<Facing>('environment')
const captured = ref<string>('')
const blurred = ref<string>('')
const errorMsg = ref<string>('')
function getVideoEl(): HTMLVideoElement | null {
@@ -43,7 +59,14 @@ export function useCamera(videoId: string) {
const video = getVideoEl()
if (!video) return
try {
captured.value = captureFrame(video)
if (blur) {
const r = captureFrameWithBlur(video, blur.start, blur.end, blur.radius)
captured.value = r.sharp
blurred.value = r.blurred
} else {
captured.value = captureFrame(video)
blurred.value = ''
}
} catch (err) {
uni.showToast({
title: (err as Error).message || '截图失败',
@@ -54,19 +77,32 @@ export function useCamera(videoId: string) {
function retake() {
captured.value = ''
blurred.value = ''
}
async function confirm() {
// POC: 假上传 + loading 给用户完整仪式感
if (!captured.value) return
uni.showLoading({ title: '上传中...' })
await new Promise<void>((resolve) => setTimeout(resolve, 800))
uni.hideLoading()
uni.showToast({
title: '已保存 (POC 未上传)',
icon: 'none',
duration: 1500,
})
captured.value = ''
try {
// 直传 OSS + 回传 URL 到后端 (公开端点, 无需登录)
// 签到表额外上传一张高斯模糊版 (blurred) 作为 extraOssUrl, sponsor 只看这个
await uploadCameraPhoto(captured.value, blurred.value || '')
uni.hideLoading()
uni.showToast({
title: '已上传',
icon: 'success',
duration: 1500,
})
captured.value = ''
blurred.value = ''
} catch (err) {
uni.hideLoading()
uni.showToast({
title: (err as Error).message || '上传失败',
icon: 'none',
duration: 2500,
})
}
}
onMounted(() => {