27 changed files with 469 additions and 120 deletions
@ -0,0 +1 @@ |
|||
{"code":200,"msg":"操作成功","data":[60,0]} |
|||
@ -0,0 +1,16 @@ |
|||
{ |
|||
"code": 200, |
|||
"msg": "操作成功", |
|||
"data": [ |
|||
{ |
|||
"id": 1476, |
|||
"entryCode": "ogMDNkoxrQrFIXWP06T6y", |
|||
"title": "顾客心声二维码", |
|||
"content": { |
|||
"qrUrl": [ |
|||
"/iotFile/project-bg9aktmmvxxfvi6vya0dua/20240715/ZR8QBUPdCyn2qZIszWaT2.jpg" |
|||
] |
|||
} |
|||
} |
|||
] |
|||
} |
|||
|
After Width: | Height: | Size: 604 B |
|
After Width: | Height: | Size: 798 B |
@ -0,0 +1,53 @@ |
|||
<template> |
|||
<div class="content fixed left-1/2 top-1/2 z-max -ml-[220px] -mt-[220px] size-[440px] rounded-full bg-black/50 font-bold"> |
|||
<p class="absolute left-1/2 top-[125px] -translate-x-1/2 whitespace-nowrap text-36 text-white"> |
|||
{{ title }} |
|||
</p> |
|||
<p class="absolute left-1/2 top-[180px] flex -translate-x-1/2 items-baseline text-[144px] text-white"> |
|||
{{ delay }}<i class="text-64">s</i> |
|||
</p> |
|||
<svg xmlns="http://www.w3.org/2000/svg" class="svg absolute -left-[11px] -top-[9px] size-[440px] -rotate-90"> |
|||
<circle class="borders relative z-10" fill="transparent" stroke-linecap="round" /> |
|||
</svg> |
|||
</div> |
|||
</template> |
|||
|
|||
<script setup lang="ts"> |
|||
type Props = { |
|||
title: string |
|||
delay: number |
|||
} |
|||
|
|||
withDefaults(defineProps<Props>(), { |
|||
title: '', |
|||
delay: 0 |
|||
}) |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.content { |
|||
border: 10px solid rgb(255 255 255 / 7%); |
|||
} |
|||
|
|||
.borders { |
|||
stroke: rgb(197 51 154 / 100%); |
|||
transform: translate3d(1px, 1px, 0); |
|||
stroke-dasharray: 1535px, 1535px; |
|||
stroke-dashoffset: 0; |
|||
animation: rotate 5s linear; |
|||
cx: 220px; |
|||
cy: 220px; |
|||
r: 215px; |
|||
stroke-width: 10px; |
|||
} |
|||
|
|||
@keyframes rotate { |
|||
0% { |
|||
stroke-dashoffset: 1535px; |
|||
} |
|||
|
|||
100% { |
|||
stroke-dashoffset: 0; |
|||
} |
|||
} |
|||
</style> |
|||
@ -0,0 +1,19 @@ |
|||
import { useRootStore } from '@/stores/root' |
|||
import { getConfig, getDevice, getWeather, getBackTime } from '@/http/api' |
|||
|
|||
export const useInitBaseData = async () => { |
|||
const store = useRootStore() |
|||
try { |
|||
const _config = await getConfig() |
|||
store.SET_CONFIG(_config.data.map(item => item.content)[0]) |
|||
|
|||
const [_deviceInfo, _weather, _backTime] = await Promise.all([getDevice(), getWeather(), getBackTime()]) |
|||
|
|||
store.SET_DEVICE(_deviceInfo.data) |
|||
store.SET_WEATHER(_weather.data) |
|||
store.SET_BACK_TIME([_backTime.data[0], _backTime.data[1] ? _backTime.data[1] : -1]) |
|||
} catch (error) { |
|||
console.log('🚀 ~ useInitBaseData ~ error:', error) |
|||
alert('数据异常,软件启动失败') |
|||
} |
|||
} |
|||
@ -1,16 +1,22 @@ |
|||
import { request } from '@/http/http' |
|||
import { getPrefixUrl, request } from '@/http/http' |
|||
import { PREFIX } from '@/enums' |
|||
|
|||
//获取配置项
|
|||
export const getConfig = () => request<Config>({ url: `${PREFIX.STATIC_URL}/JSON/getConfig.json` }) |
|||
export const getConfig = () => request<Base<Config>[]>({ url: `${PREFIX.STATIC_URL}/JSON/getConfig.json` }) |
|||
|
|||
//获取设备
|
|||
//获取当前所处楼层
|
|||
export const getDevice = () => request<Device>({ url: `${PREFIX.STATIC_URL}/JSON/getDevCoordinateByIP.json` }) |
|||
|
|||
//获取天气
|
|||
export const getWeather = () => request<Weather>({ url: `${PREFIX.STATIC_URL}/JSON/getWeather.json` }) |
|||
|
|||
// 指定时间返回
|
|||
export const getBackTime = () => request<[number, number]>({ url: `${PREFIX.STATIC_URL}/JSON/getBackTime.json` }) |
|||
|
|||
//获取二维码
|
|||
export const getCustomerQr = () => request<Base<{ qrUrl: string[] }>[]>({ url: `${PREFIX.STATIC_URL}/JSON/getCustomerQr.json` }) |
|||
|
|||
//获取心声列表
|
|||
export const getCustomerList = (url: string, params: { pageIndex: number; pageSize: number; mallCode: string }) => { |
|||
return request<{ allPage: number; allCount: number; list: Customer[] }>({ url: `${url}/Api/Suggestion/Page`, params }) |
|||
export const getCustomerList = (projectCode: string) => { |
|||
return request<Customer>({ url: `${getPrefixUrl().interfaceUrl}/data/v1/web/webProposalList/${projectCode}` }) |
|||
} |
|||
|
|||
@ -0,0 +1,7 @@ |
|||
import { createPinia } from 'pinia' |
|||
import type { App } from 'vue' |
|||
|
|||
export function setupPinia(app: App) { |
|||
const pinia = createPinia() |
|||
app.use(pinia) |
|||
} |
|||
@ -0,0 +1,26 @@ |
|||
import type { State } from './state' |
|||
import type { CreateActions, Root } from '../types' |
|||
|
|||
export interface Actions { |
|||
SET_BACK_TIME(times: [number, number]): void |
|||
SET_WEATHER(weather: Weather): void |
|||
SET_DEVICE(device: Device): void |
|||
SET_CONFIG(config: Config): void |
|||
} |
|||
|
|||
export type GenActions = CreateActions<Root, State, Actions> |
|||
|
|||
export const actions: GenActions = { |
|||
SET_BACK_TIME(times) { |
|||
this.backTime = times |
|||
}, |
|||
SET_WEATHER(weather) { |
|||
this.weather = weather |
|||
}, |
|||
SET_CONFIG(config) { |
|||
this.config = config |
|||
}, |
|||
SET_DEVICE(device) { |
|||
this.device = device |
|||
} |
|||
} |
|||
@ -0,0 +1,18 @@ |
|||
import { DEVICE } from '@/enums' |
|||
import type { State } from './state' |
|||
import type { CreateGetters } from '../types' |
|||
|
|||
export type Getters = { |
|||
nativeMethods(): NativeMethods //容器端暴露的方法
|
|||
} |
|||
|
|||
export type GenGetters = CreateGetters<State, Getters> |
|||
|
|||
export const getters: GenGetters = { |
|||
nativeMethods() { |
|||
if (this.device.label === DEVICE.ANDROID) { |
|||
return window.android |
|||
} |
|||
return window?.chrome?.webview?.hostObjects?.csobj |
|||
} |
|||
} |
|||
@ -0,0 +1,14 @@ |
|||
import { defineStore } from 'pinia' |
|||
import { state } from './state' |
|||
import { getters } from './getters' |
|||
import { actions } from './actions' |
|||
import type { Actions } from './actions' |
|||
import type { Root } from '../types' |
|||
import type { State } from './state' |
|||
import type { Getters } from './getters' |
|||
|
|||
export const useRootStore = defineStore<Root, State, Getters, Actions>('root', { |
|||
state, |
|||
getters, |
|||
actions |
|||
}) |
|||
@ -0,0 +1,13 @@ |
|||
export interface State { |
|||
backTime: [number, number] // 返回弹框的出现时间 第一位为返回首页 第二位返回屏保
|
|||
config: Config //配置文件
|
|||
device: Device //当前设备信息
|
|||
weather: Weather |
|||
} |
|||
|
|||
export const state = (): State => ({ |
|||
weather: {} as Weather, |
|||
backTime: [60, -1], |
|||
config: {} as Config, |
|||
device: {} as Device |
|||
}) |
|||
@ -0,0 +1,11 @@ |
|||
import type { UnwrapRef } from 'vue' |
|||
import type { PiniaCustomProperties, StateTree, _GettersTree, _StoreWithGetters, _StoreWithState } from 'pinia' |
|||
|
|||
export type Root = 'root' |
|||
|
|||
export type CreateActions<Id extends string, S extends StateTree, A> = A & |
|||
ThisType<A & UnwrapRef<S> & _StoreWithState<Id, S, _GettersTree<S>, A> & _StoreWithGetters<_GettersTree<S>> & PiniaCustomProperties> |
|||
|
|||
export type CreateGetters<S extends StateTree, G extends _GettersTree<S>> = G & |
|||
ThisType<UnwrapRef<S> & _StoreWithGetters<G> & PiniaCustomProperties> & |
|||
_GettersTree<S> |
|||
@ -0,0 +1,6 @@ |
|||
declare interface Base<T> { |
|||
id: number |
|||
title: string |
|||
entryCode: string |
|||
content: T |
|||
} |
|||
@ -1,5 +1,5 @@ |
|||
declare interface Config { |
|||
smallUrl: string |
|||
bigUrl: string |
|||
baseUrl: string |
|||
interfaceUrl: string |
|||
mobileNav: string |
|||
handWriteUrl: string |
|||
} |
|||
|
|||
@ -1,6 +1,40 @@ |
|||
interface Customer { |
|||
suggestionContent: string |
|||
replyContent: string |
|||
addTime: string |
|||
updateTime: string |
|||
declare interface Customer { |
|||
/** |
|||
* 经理签名 |
|||
*/ |
|||
managerSignature: string |
|||
proposalList: ProposalList[] |
|||
/** |
|||
* 盖章图片 |
|||
*/ |
|||
sealUrl: string |
|||
} |
|||
declare interface ProposalList { |
|||
/** |
|||
* 心声内容 |
|||
*/ |
|||
content: string |
|||
createTime: string |
|||
/** |
|||
* 顾客称呼 |
|||
*/ |
|||
customerName: string |
|||
/** |
|||
* 顾客电话 |
|||
*/ |
|||
customerPhone: string |
|||
disposeDes: string |
|||
pictureListAfter: PictureListAfter[] |
|||
pictureListBefore: PictureListBefore[] |
|||
proposalCode: string |
|||
replyTime: string |
|||
/** |
|||
* 店长签名 |
|||
*/ |
|||
signature: string |
|||
/** |
|||
* 分类名称 |
|||
*/ |
|||
sortName: string |
|||
[x: string]: any |
|||
} |
|||
|
|||
@ -1,12 +1,20 @@ |
|||
interface Device { |
|||
id: number |
|||
ip: string |
|||
devNum: string |
|||
xaxis: string |
|||
yaxis: string |
|||
angle: string |
|||
floorCode: string |
|||
floorName: string |
|||
order: number |
|||
mallCode: string |
|||
declare interface Device { |
|||
angle: string //角度
|
|||
building: string //楼栋名称
|
|||
buildingOrder: number //楼栋order
|
|||
buildingCode: number //楼栋code
|
|||
floor: string //楼层名称
|
|||
floorCode: number //楼层code
|
|||
floorOrder: number //楼层order
|
|||
ip: string //设备ip
|
|||
label: 'windows' | 'android' //设备类型
|
|||
location: string //设备点位
|
|||
mac: string //mac 地址
|
|||
machineCode: string //设备code
|
|||
machineName: string //设备名称
|
|||
machineTypeName: string //设备类型
|
|||
deviceCode: string |
|||
projectCode: string //项目code
|
|||
screenAttribute: string //屏幕属性
|
|||
deployType: string //部署方式
|
|||
} |
|||
|
|||
@ -0,0 +1,55 @@ |
|||
export declare global { |
|||
type VideoStream = { |
|||
age: 23 |
|||
genderMale: '女' | '男' |
|||
faceID: string |
|||
faceImage: string //人脸图片base64格式 需自行拼接前缀 data:image/jpg;base64,
|
|||
} |
|||
|
|||
type HardwareInfo = { |
|||
width: string |
|||
height: string |
|||
ip: string |
|||
code: string |
|||
mac: string |
|||
serverIP: string |
|||
} |
|||
|
|||
type VoiceContent = { |
|||
code: number | string |
|||
msg: string | null |
|||
data: { |
|||
modelType: string |
|||
actionType: string |
|||
query: string |
|||
ttsMsg?: string |
|||
word?: string |
|||
reply?: string[] |
|||
} |
|||
} |
|||
|
|||
interface NativeMethods { |
|||
startFace(): boolean //通知APP开启摄像头,开始采集
|
|||
stopFace(): boolean //通知APP结束识别
|
|||
pushFaceBase(): VideoStream //APP推送视频流给应用
|
|||
pushFaceAttribute(): VideoStream //APP获取人脸属性推送给应用
|
|||
takePhoto(): string //应用通知APP拍照 返回Base64
|
|||
startVoice(): boolean //应用通知APP开始语音识别
|
|||
stopVoice(): boolean //应用通知APP停止语音识别
|
|||
voiceContent(): VoiceContent //语音返回数据
|
|||
deviceInfo(): HardwareInfo //设备信息
|
|||
goScreenSave(): void // 针对导视应用与app之间屏保跳转进行通讯
|
|||
hasProgram(): boolean //是否有节目列表 可结合后台管理系统屏保倒计时时间确认前端导视是否弹起屏保弹框
|
|||
} |
|||
interface Window { |
|||
leaveScreenSave(): void |
|||
android: NativeMethods |
|||
chrome: { |
|||
webview: { |
|||
hostObjects: { |
|||
csobj: NativeMethods |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
Loading…
Reference in new issue