WorkCameraf/unpackage/dist/dev/app-plus/app-service.js
2025-08-20 11:45:36 +08:00

2828 lines
83 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

if (typeof Promise !== "undefined" && !Promise.prototype.finally) {
Promise.prototype.finally = function(callback) {
const promise = this.constructor;
return this.then(
(value) => promise.resolve(callback()).then(() => value),
(reason) => promise.resolve(callback()).then(() => {
throw reason;
})
);
};
}
;
if (typeof uni !== "undefined" && uni && uni.requireGlobal) {
const global = uni.requireGlobal();
ArrayBuffer = global.ArrayBuffer;
Int8Array = global.Int8Array;
Uint8Array = global.Uint8Array;
Uint8ClampedArray = global.Uint8ClampedArray;
Int16Array = global.Int16Array;
Uint16Array = global.Uint16Array;
Int32Array = global.Int32Array;
Uint32Array = global.Uint32Array;
Float32Array = global.Float32Array;
Float64Array = global.Float64Array;
BigInt64Array = global.BigInt64Array;
BigUint64Array = global.BigUint64Array;
}
;
if (uni.restoreGlobal) {
uni.restoreGlobal(Vue, weex, plus, setTimeout, clearTimeout, setInterval, clearInterval);
}
(function(vue) {
"use strict";
const ON_LOAD = "onLoad";
function formatAppLog(type, filename, ...args) {
if (uni.__log__) {
uni.__log__(type, filename, ...args);
} else {
console[type].apply(console, [...args, filename]);
}
}
function resolveEasycom(component, easycom) {
return typeof component === "string" ? easycom : component;
}
const createLifeCycleHook = (lifecycle, flag = 0) => (hook, target = vue.getCurrentInstance()) => {
!vue.isInSSRComponentSetup && vue.injectHook(lifecycle, hook, target);
};
const onLoad = /* @__PURE__ */ createLifeCycleHook(
ON_LOAD,
2
/* HookFlags.PAGE */
);
const fontData = [
{
"font_class": "arrow-down",
"unicode": ""
},
{
"font_class": "arrow-left",
"unicode": ""
},
{
"font_class": "arrow-right",
"unicode": ""
},
{
"font_class": "arrow-up",
"unicode": ""
},
{
"font_class": "auth",
"unicode": ""
},
{
"font_class": "auth-filled",
"unicode": ""
},
{
"font_class": "back",
"unicode": ""
},
{
"font_class": "bars",
"unicode": ""
},
{
"font_class": "calendar",
"unicode": ""
},
{
"font_class": "calendar-filled",
"unicode": ""
},
{
"font_class": "camera",
"unicode": ""
},
{
"font_class": "camera-filled",
"unicode": ""
},
{
"font_class": "cart",
"unicode": ""
},
{
"font_class": "cart-filled",
"unicode": ""
},
{
"font_class": "chat",
"unicode": ""
},
{
"font_class": "chat-filled",
"unicode": ""
},
{
"font_class": "chatboxes",
"unicode": ""
},
{
"font_class": "chatboxes-filled",
"unicode": ""
},
{
"font_class": "chatbubble",
"unicode": ""
},
{
"font_class": "chatbubble-filled",
"unicode": ""
},
{
"font_class": "checkbox",
"unicode": ""
},
{
"font_class": "checkbox-filled",
"unicode": ""
},
{
"font_class": "checkmarkempty",
"unicode": ""
},
{
"font_class": "circle",
"unicode": ""
},
{
"font_class": "circle-filled",
"unicode": ""
},
{
"font_class": "clear",
"unicode": ""
},
{
"font_class": "close",
"unicode": ""
},
{
"font_class": "closeempty",
"unicode": ""
},
{
"font_class": "cloud-download",
"unicode": ""
},
{
"font_class": "cloud-download-filled",
"unicode": ""
},
{
"font_class": "cloud-upload",
"unicode": ""
},
{
"font_class": "cloud-upload-filled",
"unicode": ""
},
{
"font_class": "color",
"unicode": ""
},
{
"font_class": "color-filled",
"unicode": ""
},
{
"font_class": "compose",
"unicode": ""
},
{
"font_class": "contact",
"unicode": ""
},
{
"font_class": "contact-filled",
"unicode": ""
},
{
"font_class": "down",
"unicode": ""
},
{
"font_class": "bottom",
"unicode": ""
},
{
"font_class": "download",
"unicode": ""
},
{
"font_class": "download-filled",
"unicode": ""
},
{
"font_class": "email",
"unicode": ""
},
{
"font_class": "email-filled",
"unicode": ""
},
{
"font_class": "eye",
"unicode": ""
},
{
"font_class": "eye-filled",
"unicode": ""
},
{
"font_class": "eye-slash",
"unicode": ""
},
{
"font_class": "eye-slash-filled",
"unicode": ""
},
{
"font_class": "fire",
"unicode": ""
},
{
"font_class": "fire-filled",
"unicode": ""
},
{
"font_class": "flag",
"unicode": ""
},
{
"font_class": "flag-filled",
"unicode": ""
},
{
"font_class": "folder-add",
"unicode": ""
},
{
"font_class": "folder-add-filled",
"unicode": ""
},
{
"font_class": "font",
"unicode": ""
},
{
"font_class": "forward",
"unicode": ""
},
{
"font_class": "gear",
"unicode": ""
},
{
"font_class": "gear-filled",
"unicode": ""
},
{
"font_class": "gift",
"unicode": ""
},
{
"font_class": "gift-filled",
"unicode": ""
},
{
"font_class": "hand-down",
"unicode": ""
},
{
"font_class": "hand-down-filled",
"unicode": ""
},
{
"font_class": "hand-up",
"unicode": ""
},
{
"font_class": "hand-up-filled",
"unicode": ""
},
{
"font_class": "headphones",
"unicode": ""
},
{
"font_class": "heart",
"unicode": ""
},
{
"font_class": "heart-filled",
"unicode": ""
},
{
"font_class": "help",
"unicode": ""
},
{
"font_class": "help-filled",
"unicode": ""
},
{
"font_class": "home",
"unicode": ""
},
{
"font_class": "home-filled",
"unicode": ""
},
{
"font_class": "image",
"unicode": ""
},
{
"font_class": "image-filled",
"unicode": ""
},
{
"font_class": "images",
"unicode": ""
},
{
"font_class": "images-filled",
"unicode": ""
},
{
"font_class": "info",
"unicode": ""
},
{
"font_class": "info-filled",
"unicode": ""
},
{
"font_class": "left",
"unicode": ""
},
{
"font_class": "link",
"unicode": ""
},
{
"font_class": "list",
"unicode": ""
},
{
"font_class": "location",
"unicode": ""
},
{
"font_class": "location-filled",
"unicode": ""
},
{
"font_class": "locked",
"unicode": ""
},
{
"font_class": "locked-filled",
"unicode": ""
},
{
"font_class": "loop",
"unicode": ""
},
{
"font_class": "mail-open",
"unicode": ""
},
{
"font_class": "mail-open-filled",
"unicode": ""
},
{
"font_class": "map",
"unicode": ""
},
{
"font_class": "map-filled",
"unicode": ""
},
{
"font_class": "map-pin",
"unicode": ""
},
{
"font_class": "map-pin-ellipse",
"unicode": ""
},
{
"font_class": "medal",
"unicode": ""
},
{
"font_class": "medal-filled",
"unicode": ""
},
{
"font_class": "mic",
"unicode": ""
},
{
"font_class": "mic-filled",
"unicode": ""
},
{
"font_class": "micoff",
"unicode": ""
},
{
"font_class": "micoff-filled",
"unicode": ""
},
{
"font_class": "minus",
"unicode": ""
},
{
"font_class": "minus-filled",
"unicode": ""
},
{
"font_class": "more",
"unicode": ""
},
{
"font_class": "more-filled",
"unicode": ""
},
{
"font_class": "navigate",
"unicode": ""
},
{
"font_class": "navigate-filled",
"unicode": ""
},
{
"font_class": "notification",
"unicode": ""
},
{
"font_class": "notification-filled",
"unicode": ""
},
{
"font_class": "paperclip",
"unicode": ""
},
{
"font_class": "paperplane",
"unicode": ""
},
{
"font_class": "paperplane-filled",
"unicode": ""
},
{
"font_class": "person",
"unicode": ""
},
{
"font_class": "person-filled",
"unicode": ""
},
{
"font_class": "personadd",
"unicode": ""
},
{
"font_class": "personadd-filled",
"unicode": ""
},
{
"font_class": "personadd-filled-copy",
"unicode": ""
},
{
"font_class": "phone",
"unicode": ""
},
{
"font_class": "phone-filled",
"unicode": ""
},
{
"font_class": "plus",
"unicode": ""
},
{
"font_class": "plus-filled",
"unicode": ""
},
{
"font_class": "plusempty",
"unicode": ""
},
{
"font_class": "pulldown",
"unicode": ""
},
{
"font_class": "pyq",
"unicode": ""
},
{
"font_class": "qq",
"unicode": ""
},
{
"font_class": "redo",
"unicode": ""
},
{
"font_class": "redo-filled",
"unicode": ""
},
{
"font_class": "refresh",
"unicode": ""
},
{
"font_class": "refresh-filled",
"unicode": ""
},
{
"font_class": "refreshempty",
"unicode": ""
},
{
"font_class": "reload",
"unicode": ""
},
{
"font_class": "right",
"unicode": ""
},
{
"font_class": "scan",
"unicode": ""
},
{
"font_class": "search",
"unicode": ""
},
{
"font_class": "settings",
"unicode": ""
},
{
"font_class": "settings-filled",
"unicode": ""
},
{
"font_class": "shop",
"unicode": ""
},
{
"font_class": "shop-filled",
"unicode": ""
},
{
"font_class": "smallcircle",
"unicode": ""
},
{
"font_class": "smallcircle-filled",
"unicode": ""
},
{
"font_class": "sound",
"unicode": ""
},
{
"font_class": "sound-filled",
"unicode": ""
},
{
"font_class": "spinner-cycle",
"unicode": ""
},
{
"font_class": "staff",
"unicode": ""
},
{
"font_class": "staff-filled",
"unicode": ""
},
{
"font_class": "star",
"unicode": ""
},
{
"font_class": "star-filled",
"unicode": ""
},
{
"font_class": "starhalf",
"unicode": ""
},
{
"font_class": "trash",
"unicode": ""
},
{
"font_class": "trash-filled",
"unicode": ""
},
{
"font_class": "tune",
"unicode": ""
},
{
"font_class": "tune-filled",
"unicode": ""
},
{
"font_class": "undo",
"unicode": ""
},
{
"font_class": "undo-filled",
"unicode": ""
},
{
"font_class": "up",
"unicode": ""
},
{
"font_class": "top",
"unicode": ""
},
{
"font_class": "upload",
"unicode": ""
},
{
"font_class": "upload-filled",
"unicode": ""
},
{
"font_class": "videocam",
"unicode": ""
},
{
"font_class": "videocam-filled",
"unicode": ""
},
{
"font_class": "vip",
"unicode": ""
},
{
"font_class": "vip-filled",
"unicode": ""
},
{
"font_class": "wallet",
"unicode": ""
},
{
"font_class": "wallet-filled",
"unicode": ""
},
{
"font_class": "weibo",
"unicode": ""
},
{
"font_class": "weixin",
"unicode": ""
}
];
const _export_sfc = (sfc, props) => {
const target = sfc.__vccOpts || sfc;
for (const [key, val] of props) {
target[key] = val;
}
return target;
};
const getVal = (val) => {
const reg = /^[0-9]*$/g;
return typeof val === "number" || reg.test(val) ? val + "px" : val;
};
const _sfc_main$5 = {
name: "UniIcons",
emits: ["click"],
props: {
type: {
type: String,
default: ""
},
color: {
type: String,
default: "#333333"
},
size: {
type: [Number, String],
default: 16
},
customPrefix: {
type: String,
default: ""
},
fontFamily: {
type: String,
default: ""
}
},
data() {
return {
icons: fontData
};
},
computed: {
unicode() {
let code = this.icons.find((v) => v.font_class === this.type);
if (code) {
return code.unicode;
}
return "";
},
iconSize() {
return getVal(this.size);
},
styleObj() {
if (this.fontFamily !== "") {
return `color: ${this.color}; font-size: ${this.iconSize}; font-family: ${this.fontFamily};`;
}
return `color: ${this.color}; font-size: ${this.iconSize};`;
}
},
methods: {
_onClick(e) {
this.$emit("click", e);
}
}
};
function _sfc_render$4(_ctx, _cache, $props, $setup, $data, $options) {
return vue.openBlock(), vue.createElementBlock(
"text",
{
style: vue.normalizeStyle($options.styleObj),
class: vue.normalizeClass(["uni-icons", ["uniui-" + $props.type, $props.customPrefix, $props.customPrefix ? $props.type : ""]]),
onClick: _cache[0] || (_cache[0] = (...args) => $options._onClick && $options._onClick(...args))
},
[
vue.renderSlot(_ctx.$slots, "default", {}, void 0, true)
],
6
/* CLASS, STYLE */
);
}
const __easycom_0$2 = /* @__PURE__ */ _export_sfc(_sfc_main$5, [["render", _sfc_render$4], ["__scopeId", "data-v-d31e1c47"], ["__file", "D:/代码/uniapp/WorkCameraf/uni_modules/uni-icons/components/uni-icons/uni-icons.vue"]]);
const _sfc_main$4 = {
name: "uniCombox",
emits: ["input", "update:modelValue", "select"],
props: {
clearAble: {
type: Boolean,
default: false
},
border: {
type: Boolean,
default: true
},
label: {
type: String,
default: ""
},
labelWidth: {
type: String,
default: "auto"
},
placeholder: {
type: String,
default: ""
},
candidates: {
type: Array,
default() {
return [];
}
},
emptyTips: {
type: String,
default: "无匹配项"
},
modelValue: {
type: [String, Number],
default: ""
}
},
data() {
return {
showSelector: false,
inputVal: ""
};
},
computed: {
labelStyle() {
if (this.labelWidth === "auto") {
return "";
}
return `width: ${this.labelWidth}`;
},
filterCandidates() {
return this.candidates.filter((item) => {
return item.toString().indexOf(this.inputVal) > -1;
});
},
filterCandidatesLength() {
return this.filterCandidates.length;
}
},
watch: {
modelValue: {
handler(newVal) {
this.inputVal = newVal;
},
immediate: true
}
},
methods: {
toggleSelector() {
this.showSelector = !this.showSelector;
},
onFocus() {
this.showSelector = true;
},
onBlur() {
setTimeout(() => {
this.showSelector = false;
}, 153);
},
onSelectorClick(index) {
this.inputVal = this.filterCandidates[index];
this.showSelector = false;
this.$emit("input", this.inputVal);
this.$emit("select", this.inputVal);
this.$emit("update:modelValue", this.inputVal);
},
onInput() {
setTimeout(() => {
this.$emit("input", this.inputVal);
this.$emit("update:modelValue", this.inputVal);
});
},
clean() {
this.inputVal = "";
this.onInput();
}
}
};
function _sfc_render$3(_ctx, _cache, $props, $setup, $data, $options) {
const _component_uni_icons = resolveEasycom(vue.resolveDynamicComponent("uni-icons"), __easycom_0$2);
return vue.openBlock(), vue.createElementBlock(
"view",
{
class: vue.normalizeClass(["uni-combox", $props.border ? "" : "uni-combox__no-border"])
},
[
$props.label ? (vue.openBlock(), vue.createElementBlock(
"view",
{
key: 0,
class: "uni-combox__label",
style: vue.normalizeStyle($options.labelStyle)
},
[
vue.createElementVNode(
"text",
null,
vue.toDisplayString($props.label),
1
/* TEXT */
)
],
4
/* STYLE */
)) : vue.createCommentVNode("v-if", true),
vue.createElementVNode("view", { class: "uni-combox__input-box" }, [
vue.withDirectives(vue.createElementVNode("input", {
class: "uni-combox__input",
type: "text",
placeholder: $props.placeholder,
"placeholder-class": "uni-combox__input-plac",
"onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => $data.inputVal = $event),
onInput: _cache[1] || (_cache[1] = (...args) => $options.onInput && $options.onInput(...args)),
onFocus: _cache[2] || (_cache[2] = (...args) => $options.onFocus && $options.onFocus(...args)),
onBlur: _cache[3] || (_cache[3] = (...args) => $options.onBlur && $options.onBlur(...args))
}, null, 40, ["placeholder"]), [
[vue.vModelText, $data.inputVal]
]),
!$data.inputVal || !$props.clearAble ? (vue.openBlock(), vue.createBlock(_component_uni_icons, {
key: 0,
type: $data.showSelector ? "top" : "bottom",
size: "14",
color: "#999",
onClick: $options.toggleSelector
}, null, 8, ["type", "onClick"])) : vue.createCommentVNode("v-if", true),
$data.inputVal && $props.clearAble ? (vue.openBlock(), vue.createBlock(_component_uni_icons, {
key: 1,
type: "clear",
size: "24",
color: "#999",
onClick: $options.clean
}, null, 8, ["onClick"])) : vue.createCommentVNode("v-if", true)
]),
$data.showSelector && $options.filterCandidatesLength > 0 ? (vue.openBlock(), vue.createElementBlock("view", {
key: 1,
class: "uni-combox__selector"
}, [
vue.createElementVNode("view", { class: "uni-popper__arrow" }),
vue.createElementVNode("scroll-view", {
"scroll-y": "true",
class: "uni-combox__selector-scroll"
}, [
$options.filterCandidatesLength === 0 ? (vue.openBlock(), vue.createElementBlock("view", {
key: 0,
class: "uni-combox__selector-empty"
}, [
vue.createElementVNode(
"text",
null,
vue.toDisplayString($props.emptyTips),
1
/* TEXT */
)
])) : vue.createCommentVNode("v-if", true),
(vue.openBlock(true), vue.createElementBlock(
vue.Fragment,
null,
vue.renderList($options.filterCandidates, (item, index) => {
return vue.openBlock(), vue.createElementBlock("view", {
class: "uni-combox__selector-item",
key: index,
onClick: ($event) => $options.onSelectorClick(index)
}, [
vue.createElementVNode(
"text",
null,
vue.toDisplayString(item),
1
/* TEXT */
)
], 8, ["onClick"]);
}),
128
/* KEYED_FRAGMENT */
))
])
])) : vue.createCommentVNode("v-if", true)
],
2
/* CLASS */
);
}
const __easycom_0$1 = /* @__PURE__ */ _export_sfc(_sfc_main$4, [["render", _sfc_render$3], ["__scopeId", "data-v-e602780e"], ["__file", "D:/代码/uniapp/WorkCameraf/uni_modules/uni-combox/components/uni-combox/uni-combox.vue"]]);
class MPAnimation {
constructor(options, _this) {
this.options = options;
this.animation = uni.createAnimation({
...options
});
this.currentStepAnimates = {};
this.next = 0;
this.$ = _this;
}
_nvuePushAnimates(type, args) {
let aniObj = this.currentStepAnimates[this.next];
let styles = {};
if (!aniObj) {
styles = {
styles: {},
config: {}
};
} else {
styles = aniObj;
}
if (animateTypes1.includes(type)) {
if (!styles.styles.transform) {
styles.styles.transform = "";
}
let unit = "";
if (type === "rotate") {
unit = "deg";
}
styles.styles.transform += `${type}(${args + unit}) `;
} else {
styles.styles[type] = `${args}`;
}
this.currentStepAnimates[this.next] = styles;
}
_animateRun(styles = {}, config = {}) {
let ref = this.$.$refs["ani"].ref;
if (!ref)
return;
return new Promise((resolve, reject) => {
nvueAnimation.transition(ref, {
styles,
...config
}, (res) => {
resolve();
});
});
}
_nvueNextAnimate(animates, step = 0, fn) {
let obj = animates[step];
if (obj) {
let {
styles,
config
} = obj;
this._animateRun(styles, config).then(() => {
step += 1;
this._nvueNextAnimate(animates, step, fn);
});
} else {
this.currentStepAnimates = {};
typeof fn === "function" && fn();
this.isEnd = true;
}
}
step(config = {}) {
this.animation.step(config);
return this;
}
run(fn) {
this.$.animationData = this.animation.export();
this.$.timer = setTimeout(() => {
typeof fn === "function" && fn();
}, this.$.durationTime);
}
}
const animateTypes1 = [
"matrix",
"matrix3d",
"rotate",
"rotate3d",
"rotateX",
"rotateY",
"rotateZ",
"scale",
"scale3d",
"scaleX",
"scaleY",
"scaleZ",
"skew",
"skewX",
"skewY",
"translate",
"translate3d",
"translateX",
"translateY",
"translateZ"
];
const animateTypes2 = ["opacity", "backgroundColor"];
const animateTypes3 = ["width", "height", "left", "right", "top", "bottom"];
animateTypes1.concat(animateTypes2, animateTypes3).forEach((type) => {
MPAnimation.prototype[type] = function(...args) {
this.animation[type](...args);
return this;
};
});
function createAnimation(option, _this) {
if (!_this)
return;
clearTimeout(_this.timer);
return new MPAnimation(option, _this);
}
const _sfc_main$3 = {
name: "uniTransition",
emits: ["click", "change"],
props: {
show: {
type: Boolean,
default: false
},
modeClass: {
type: [Array, String],
default() {
return "fade";
}
},
duration: {
type: Number,
default: 300
},
styles: {
type: Object,
default() {
return {};
}
},
customClass: {
type: String,
default: ""
},
onceRender: {
type: Boolean,
default: false
}
},
data() {
return {
isShow: false,
transform: "",
opacity: 0,
animationData: {},
durationTime: 300,
config: {}
};
},
watch: {
show: {
handler(newVal) {
if (newVal) {
this.open();
} else {
if (this.isShow) {
this.close();
}
}
},
immediate: true
}
},
computed: {
// 生成样式数据
stylesObject() {
let styles = {
...this.styles,
"transition-duration": this.duration / 1e3 + "s"
};
let transform = "";
for (let i in styles) {
let line = this.toLine(i);
transform += line + ":" + styles[i] + ";";
}
return transform;
},
// 初始化动画条件
transformStyles() {
return "transform:" + this.transform + ";opacity:" + this.opacity + ";" + this.stylesObject;
}
},
created() {
this.config = {
duration: this.duration,
timingFunction: "ease",
transformOrigin: "50% 50%",
delay: 0
};
this.durationTime = this.duration;
},
methods: {
/**
* ref 触发 初始化动画
*/
init(obj = {}) {
if (obj.duration) {
this.durationTime = obj.duration;
}
this.animation = createAnimation(Object.assign(this.config, obj), this);
},
/**
* 点击组件触发回调
*/
onClick() {
this.$emit("click", {
detail: this.isShow
});
},
/**
* ref 触发 动画分组
* @param {Object} obj
*/
step(obj, config = {}) {
if (!this.animation)
return this;
Object.keys(obj).forEach((key) => {
const value = obj[key];
if (typeof this.animation[key] === "function") {
Array.isArray(value) ? this.animation[key](...value) : this.animation[key](value);
}
});
this.animation.step(config);
return this;
},
/**
* ref 触发 执行动画
*/
run(fn) {
if (!this.animation)
return;
this.animation.run(fn);
},
// 开始过度动画
open() {
clearTimeout(this.timer);
this.isShow = true;
this.transform = this.styleInit(false).transform || "";
this.opacity = this.styleInit(false).opacity || 0;
this.$nextTick(() => {
this.timer = setTimeout(() => {
this.animation = createAnimation(this.config, this);
this.tranfromInit(false).step();
this.animation.run(() => {
this.transform = "";
this.opacity = this.styleInit(false).opacity || 1;
this.$emit("change", {
detail: this.isShow
});
});
}, 80);
});
},
// 关闭过度动画
close(type) {
if (!this.animation)
return;
this.tranfromInit(true).step().run(() => {
this.isShow = false;
this.animationData = null;
this.animation = null;
let { opacity, transform } = this.styleInit(false);
this.opacity = opacity || 1;
this.transform = transform;
this.$emit("change", {
detail: this.isShow
});
});
},
// 处理动画开始前的默认样式
styleInit(type) {
let styles = { transform: "", opacity: 1 };
const buildStyle = (type2, mode) => {
const value = this.animationType(type2)[mode];
if (mode.startsWith("fade")) {
styles.opacity = value;
} else {
styles.transform += value + " ";
}
};
if (typeof this.modeClass === "string") {
buildStyle(type, this.modeClass);
} else {
this.modeClass.forEach((mode) => buildStyle(type, mode));
}
return styles;
},
// 处理内置组合动画
tranfromInit(type) {
let buildTranfrom = (type2, mode) => {
let aniNum = null;
if (mode === "fade") {
aniNum = type2 ? 0 : 1;
} else {
aniNum = type2 ? "-100%" : "0";
if (mode === "zoom-in") {
aniNum = type2 ? 0.8 : 1;
}
if (mode === "zoom-out") {
aniNum = type2 ? 1.2 : 1;
}
if (mode === "slide-right") {
aniNum = type2 ? "100%" : "0";
}
if (mode === "slide-bottom") {
aniNum = type2 ? "100%" : "0";
}
}
this.animation[this.animationMode()[mode]](aniNum);
};
if (typeof this.modeClass === "string") {
buildTranfrom(type, this.modeClass);
} else {
this.modeClass.forEach((mode) => {
buildTranfrom(type, mode);
});
}
return this.animation;
},
animationType(type) {
return {
fade: type ? 1 : 0,
"slide-top": `translateY(${type ? "0" : "-100%"})`,
"slide-right": `translateX(${type ? "0" : "100%"})`,
"slide-bottom": `translateY(${type ? "0" : "100%"})`,
"slide-left": `translateX(${type ? "0" : "-100%"})`,
"zoom-in": `scaleX(${type ? 1 : 0.8}) scaleY(${type ? 1 : 0.8})`,
"zoom-out": `scaleX(${type ? 1 : 1.2}) scaleY(${type ? 1 : 1.2})`
};
},
// 内置动画类型与实际动画对应字典
animationMode() {
return {
fade: "opacity",
"slide-top": "translateY",
"slide-right": "translateX",
"slide-bottom": "translateY",
"slide-left": "translateX",
"zoom-in": "scale",
"zoom-out": "scale"
};
},
// 驼峰转中横线
toLine(name) {
return name.replace(/([A-Z])/g, "-$1").toLowerCase();
}
}
};
function _sfc_render$2(_ctx, _cache, $props, $setup, $data, $options) {
return vue.withDirectives((vue.openBlock(), vue.createElementBlock("view", {
ref: "ani",
animation: $data.animationData,
class: vue.normalizeClass($props.customClass),
style: vue.normalizeStyle($options.transformStyles),
onClick: _cache[0] || (_cache[0] = (...args) => $options.onClick && $options.onClick(...args))
}, [
vue.renderSlot(_ctx.$slots, "default")
], 14, ["animation"])), [
[vue.vShow, $data.isShow]
]);
}
const __easycom_0 = /* @__PURE__ */ _export_sfc(_sfc_main$3, [["render", _sfc_render$2], ["__file", "D:/代码/uniapp/WorkCameraf/uni_modules/uni-transition/components/uni-transition/uni-transition.vue"]]);
const _sfc_main$2 = {
name: "uniPopup",
components: {},
emits: ["change", "maskClick"],
props: {
// 开启动画
animation: {
type: Boolean,
default: true
},
// 弹出层类型可选值top: 顶部弹出层bottom底部弹出层center全屏弹出层
// message: 消息提示 ; dialog : 对话框
type: {
type: String,
default: "center"
},
// maskClick
isMaskClick: {
type: Boolean,
default: null
},
// TODO 2 个版本后废弃属性 ,使用 isMaskClick
maskClick: {
type: Boolean,
default: null
},
backgroundColor: {
type: String,
default: "none"
},
safeArea: {
type: Boolean,
default: true
},
maskBackgroundColor: {
type: String,
default: "rgba(0, 0, 0, 0.4)"
},
borderRadius: {
type: String
}
},
watch: {
/**
* 监听type类型
*/
type: {
handler: function(type) {
if (!this.config[type])
return;
this[this.config[type]](true);
},
immediate: true
},
isDesktop: {
handler: function(newVal) {
if (!this.config[newVal])
return;
this[this.config[this.type]](true);
},
immediate: true
},
/**
* 监听遮罩是否可点击
* @param {Object} val
*/
maskClick: {
handler: function(val) {
this.mkclick = val;
},
immediate: true
},
isMaskClick: {
handler: function(val) {
this.mkclick = val;
},
immediate: true
},
// H5 下禁止底部滚动
showPopup(show) {
}
},
data() {
return {
duration: 300,
ani: [],
showPopup: false,
showTrans: false,
popupWidth: 0,
popupHeight: 0,
config: {
top: "top",
bottom: "bottom",
center: "center",
left: "left",
right: "right",
message: "top",
dialog: "center",
share: "bottom"
},
maskClass: {
position: "fixed",
bottom: 0,
top: 0,
left: 0,
right: 0,
backgroundColor: "rgba(0, 0, 0, 0.4)"
},
transClass: {
backgroundColor: "transparent",
borderRadius: this.borderRadius || "0",
position: "fixed",
left: 0,
right: 0
},
maskShow: true,
mkclick: true,
popupstyle: "top"
};
},
computed: {
getStyles() {
let res = { backgroundColor: this.bg };
if (this.borderRadius || "0") {
res = Object.assign(res, { borderRadius: this.borderRadius });
}
return res;
},
isDesktop() {
return this.popupWidth >= 500 && this.popupHeight >= 500;
},
bg() {
if (this.backgroundColor === "" || this.backgroundColor === "none") {
return "transparent";
}
return this.backgroundColor;
}
},
mounted() {
const fixSize = () => {
const {
windowWidth,
windowHeight,
windowTop,
safeArea,
screenHeight,
safeAreaInsets
} = uni.getSystemInfoSync();
this.popupWidth = windowWidth;
this.popupHeight = windowHeight + (windowTop || 0);
if (safeArea && this.safeArea) {
this.safeAreaInsets = safeAreaInsets.bottom;
} else {
this.safeAreaInsets = 0;
}
};
fixSize();
},
// TODO vue3
unmounted() {
this.setH5Visible();
},
activated() {
this.setH5Visible(!this.showPopup);
},
deactivated() {
this.setH5Visible(true);
},
created() {
if (this.isMaskClick === null && this.maskClick === null) {
this.mkclick = true;
} else {
this.mkclick = this.isMaskClick !== null ? this.isMaskClick : this.maskClick;
}
if (this.animation) {
this.duration = 300;
} else {
this.duration = 0;
}
this.messageChild = null;
this.clearPropagation = false;
this.maskClass.backgroundColor = this.maskBackgroundColor;
},
methods: {
setH5Visible(visible = true) {
},
/**
* 公用方法,不显示遮罩层
*/
closeMask() {
this.maskShow = false;
},
/**
* 公用方法,遮罩层禁止点击
*/
disableMask() {
this.mkclick = false;
},
// TODO nvue 取消冒泡
clear(e) {
e.stopPropagation();
this.clearPropagation = true;
},
open(direction) {
if (this.showPopup) {
return;
}
let innerType = ["top", "center", "bottom", "left", "right", "message", "dialog", "share"];
if (!(direction && innerType.indexOf(direction) !== -1)) {
direction = this.type;
}
if (!this.config[direction]) {
formatAppLog("error", "at uni_modules/uni-popup/components/uni-popup/uni-popup.vue:310", "缺少类型:", direction);
return;
}
this[this.config[direction]]();
this.$emit("change", {
show: true,
type: direction
});
},
close(type) {
this.showTrans = false;
this.$emit("change", {
show: false,
type: this.type
});
clearTimeout(this.timer);
this.timer = setTimeout(() => {
this.showPopup = false;
}, 300);
},
// TODO 处理冒泡事件,头条的冒泡事件有问题 ,先这样兼容
touchstart() {
this.clearPropagation = false;
},
onTap() {
if (this.clearPropagation) {
this.clearPropagation = false;
return;
}
this.$emit("maskClick");
if (!this.mkclick)
return;
this.close();
},
/**
* 顶部弹出样式处理
*/
top(type) {
this.popupstyle = this.isDesktop ? "fixforpc-top" : "top";
this.ani = ["slide-top"];
this.transClass = {
position: "fixed",
left: 0,
right: 0,
backgroundColor: this.bg,
borderRadius: this.borderRadius || "0"
};
if (type)
return;
this.showPopup = true;
this.showTrans = true;
this.$nextTick(() => {
this.showPoptrans();
if (this.messageChild && this.type === "message") {
this.messageChild.timerClose();
}
});
},
/**
* 底部弹出样式处理
*/
bottom(type) {
this.popupstyle = "bottom";
this.ani = ["slide-bottom"];
this.transClass = {
position: "fixed",
left: 0,
right: 0,
bottom: 0,
paddingBottom: this.safeAreaInsets + "px",
backgroundColor: this.bg,
borderRadius: this.borderRadius || "0"
};
if (type)
return;
this.showPoptrans();
},
/**
* 中间弹出样式处理
*/
center(type) {
this.popupstyle = "center";
this.ani = ["zoom-out", "fade"];
this.transClass = {
position: "fixed",
display: "flex",
flexDirection: "column",
bottom: 0,
left: 0,
right: 0,
top: 0,
justifyContent: "center",
alignItems: "center",
borderRadius: this.borderRadius || "0"
};
if (type)
return;
this.showPoptrans();
},
left(type) {
this.popupstyle = "left";
this.ani = ["slide-left"];
this.transClass = {
position: "fixed",
left: 0,
bottom: 0,
top: 0,
backgroundColor: this.bg,
borderRadius: this.borderRadius || "0",
display: "flex",
flexDirection: "column"
};
if (type)
return;
this.showPoptrans();
},
right(type) {
this.popupstyle = "right";
this.ani = ["slide-right"];
this.transClass = {
position: "fixed",
bottom: 0,
right: 0,
top: 0,
backgroundColor: this.bg,
borderRadius: this.borderRadius || "0",
display: "flex",
flexDirection: "column"
};
if (type)
return;
this.showPoptrans();
},
showPoptrans() {
this.$nextTick(() => {
this.showPopup = true;
this.showTrans = true;
});
}
}
};
function _sfc_render$1(_ctx, _cache, $props, $setup, $data, $options) {
const _component_uni_transition = resolveEasycom(vue.resolveDynamicComponent("uni-transition"), __easycom_0);
return $data.showPopup ? (vue.openBlock(), vue.createElementBlock(
"view",
{
key: 0,
class: vue.normalizeClass(["uni-popup", [$data.popupstyle, $options.isDesktop ? "fixforpc-z-index" : ""]])
},
[
vue.createElementVNode(
"view",
{
onTouchstart: _cache[1] || (_cache[1] = (...args) => $options.touchstart && $options.touchstart(...args))
},
[
$data.maskShow ? (vue.openBlock(), vue.createBlock(_component_uni_transition, {
key: "1",
name: "mask",
"mode-class": "fade",
styles: $data.maskClass,
duration: $data.duration,
show: $data.showTrans,
onClick: $options.onTap
}, null, 8, ["styles", "duration", "show", "onClick"])) : vue.createCommentVNode("v-if", true),
vue.createVNode(_component_uni_transition, {
key: "2",
"mode-class": $data.ani,
name: "content",
styles: $data.transClass,
duration: $data.duration,
show: $data.showTrans,
onClick: $options.onTap
}, {
default: vue.withCtx(() => [
vue.createElementVNode(
"view",
{
class: vue.normalizeClass(["uni-popup__wrapper", [$data.popupstyle]]),
style: vue.normalizeStyle($options.getStyles),
onClick: _cache[0] || (_cache[0] = (...args) => $options.clear && $options.clear(...args))
},
[
vue.renderSlot(_ctx.$slots, "default", {}, void 0, true)
],
6
/* CLASS, STYLE */
)
]),
_: 3
/* FORWARDED */
}, 8, ["mode-class", "styles", "duration", "show", "onClick"])
],
32
/* NEED_HYDRATION */
)
],
2
/* CLASS */
)) : vue.createCommentVNode("v-if", true);
}
const __easycom_1 = /* @__PURE__ */ _export_sfc(_sfc_main$2, [["render", _sfc_render$1], ["__scopeId", "data-v-4dd3c44b"], ["__file", "D:/代码/uniapp/WorkCameraf/uni_modules/uni-popup/components/uni-popup/uni-popup.vue"]]);
const getLocation = async () => {
return new Promise((resolve, reject) => {
uni.getLocation({
isHighAccuracy: true,
altitude: true,
accuracy: "best",
success: (res) => {
resolve(res);
},
fail: (err) => {
reject(err);
}
});
});
};
const chooseImage = async () => {
return new Promise((resolve, reject) => {
uni.chooseImage({
count: 1,
success: (res) => {
resolve(res);
},
fail: (err) => {
reject(err);
}
});
});
};
const formatDate = (date, format = "YYYY-MM-DD HH:mm:ss") => {
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, "0");
const day = String(date.getDate()).padStart(2, "0");
const hours = String(date.getHours()).padStart(2, "0");
const minutes = String(date.getMinutes()).padStart(2, "0");
const seconds = String(date.getSeconds()).padStart(2, "0");
return format.replace("YYYY", year).replace("MM", month).replace("DD", day).replace("HH", hours).replace("mm", minutes).replace("ss", seconds);
};
const logoCache = /* @__PURE__ */ new Map();
const getCachedLogo = async (logoUrl) => {
if (logoCache.has(logoUrl)) {
formatAppLog("log", "at common/utils.js:70", "使用缓存的logo:", logoUrl);
return logoCache.get(logoUrl);
}
return new Promise((resolve, reject) => {
uni.downloadFile({
url: logoUrl,
success: (downloadRes) => {
if (downloadRes.statusCode === 200) {
formatAppLog("log", "at common/utils.js:102", "下载并缓存logo:", logoUrl);
logoCache.set(logoUrl, downloadRes.tempFilePath);
resolve(downloadRes.tempFilePath);
} else {
reject(new Error("下载失败: " + downloadRes.statusCode));
}
},
fail: (err) => {
formatAppLog("error", "at common/utils.js:110", "下载logo失败:", err);
reject(err);
}
});
});
};
const handleWatermarkExport = async (tempFilePath, originalFileSize, width, height, resolve) => {
try {
const watermarkFileSize = await getFileSize(tempFilePath);
formatAppLog("log", "at common/utils.js:145", "水印图片文件大小:", watermarkFileSize.sizeKB, "KB");
resolve({
filePath: tempFilePath,
originalSize: {
width,
height,
fileSize: originalFileSize
},
watermarkSize: {
width,
height,
fileSize: watermarkFileSize
}
});
} catch (err) {
formatAppLog("error", "at common/utils.js:160", "获取水印图片文件大小失败:", err);
resolve({
filePath: tempFilePath,
originalSize: {
width,
height,
fileSize: originalFileSize
},
watermarkSize: {
width,
height,
fileSize: null
}
});
}
};
const calculateQuality = (originalSizeKB) => {
if (!originalSizeKB || originalSizeKB <= 0) {
return 0.8;
}
if (originalSizeKB < 100) {
return 0.9;
} else if (originalSizeKB < 500) {
return 0.8;
} else {
return 0.7;
}
};
const calculateOutputSize = (width, height, maxWidth = 1920) => {
if (width <= maxWidth) {
return {
width,
height
};
}
const ratio = maxWidth / width;
return {
width: Math.round(width * ratio),
height: Math.round(height * ratio)
};
};
const getFileSize = async (filePath) => {
return new Promise((resolve, reject) => {
uni.getFileInfo({
filePath,
success: (res) => {
resolve({
size: res.size,
sizeKB: (res.size / 1024).toFixed(2),
sizeMB: (res.size / (1024 * 1024)).toFixed(2)
});
},
fail: (err) => {
formatAppLog("error", "at common/utils.js:304", "获取文件大小失败:", err);
reject(err);
}
});
});
};
const addWatermark = async (imagePath, watermarkInfo, logoUrl = null, logoOpacity = 1, quality = null, maxWidth = 1920) => {
return new Promise(async (resolve, reject) => {
try {
const originalFileSize = await getFileSize(imagePath);
formatAppLog("log", "at common/utils.js:603", "原图文件大小:", originalFileSize.sizeKB, "KB");
const compressionQuality = quality !== null ? quality : calculateQuality(originalFileSize.sizeKB);
formatAppLog("log", "at common/utils.js:607", "使用压缩质量:", compressionQuality);
uni.getImageInfo({
src: imagePath,
success: (imageInfo) => {
const { width, height } = imageInfo;
formatAppLog("log", "at common/utils.js:614", "原图尺寸:", width, "x", height);
const outputSize = calculateOutputSize(width, height, maxWidth);
formatAppLog("log", "at common/utils.js:618", "输出尺寸:", outputSize.width, "x", outputSize.height);
const canvas = uni.createCanvasContext("watermarkCanvas");
canvas.clearRect(0, 0, outputSize.width, outputSize.height);
canvas.drawImage(imagePath, 0, 0, outputSize.width, outputSize.height);
const processText = (text, maxChars = 25, maxLines = 3) => {
if (text.length <= maxChars) {
return [text];
}
const lines = [];
let currentLine = "";
let lineCount = 0;
for (let i = 0; i < text.length && lineCount < maxLines; i++) {
currentLine += text[i];
if (currentLine.length >= maxChars || i === text.length - 1) {
lines.push(currentLine);
lineCount++;
currentLine = "";
if (lineCount === maxLines && i < text.length - 1) {
lines[lines.length - 1] = lines[lines.length - 1].slice(0, -3) + "...";
break;
}
}
}
return lines;
};
const watermarkText = [
`时间: ${watermarkInfo.time}`,
`经度: ${watermarkInfo.longitude}`,
`维度: ${watermarkInfo.latitude}`
];
var location = processText("位置: " + watermarkInfo.location);
watermarkText.push(...location);
var department = processText("部门: " + watermarkInfo.department);
watermarkText.push(...department);
var status = processText("状态: " + watermarkInfo.status);
watermarkText.push(...status);
var workers = processText("人员: " + watermarkInfo.workers.join(", "));
watermarkText.push(...workers);
var remarks = processText("内容: " + watermarkInfo.remarks);
watermarkText.push(...remarks);
const drawTextWatermark = () => {
const padding = 30;
const fontSize = 40;
const lineHeight = 50;
const startX = padding;
const startY = outputSize.height - padding - watermarkText.length * lineHeight;
canvas.setFillStyle("rgba(255, 255, 255, 1)");
canvas.setFontSize(fontSize);
canvas.setTextBaseline("top");
watermarkText.forEach((text, index) => {
canvas.fillText(text, startX, startY + index * lineHeight);
});
if (logoUrl) {
getCachedLogo(logoUrl).then((cachedLogoPath) => {
const logoSize = 200;
const logoPadding = 30;
const logoX = logoPadding;
const logoY = startY - logoSize - 10;
canvas.setGlobalAlpha(logoOpacity);
canvas.drawImage(cachedLogoPath, logoX, logoY, logoSize, logoSize);
canvas.setGlobalAlpha(1);
canvas.draw(true, () => {
formatAppLog("log", "at common/utils.js:717", "Canvas绘制完成包含logo");
setTimeout(() => {
uni.canvasToTempFilePath({
canvasId: "watermarkCanvas",
width: outputSize.width,
height: outputSize.height,
fileType: "jpg",
// 使用jpg格式文件更小
quality: compressionQuality,
// 使用动态计算的压缩质量
success: (res) => {
formatAppLog("log", "at common/utils.js:728", "导出成功:", res.tempFilePath);
formatAppLog("log", "at common/utils.js:729", "水印图片尺寸:", outputSize.width, "x", outputSize.height);
handleWatermarkExport(res.tempFilePath, originalFileSize, outputSize.width, outputSize.height, resolve);
},
fail: (err) => {
formatAppLog("error", "at common/utils.js:733", "导出图片失败:", err);
reject(err);
}
});
}, 100);
});
}).catch((err) => {
formatAppLog("error", "at common/utils.js:740", "获取logo失败:", err);
canvas.draw(true, () => {
formatAppLog("log", "at common/utils.js:743", "Canvas绘制完成logo获取失败");
setTimeout(() => {
uni.canvasToTempFilePath({
canvasId: "watermarkCanvas",
width: outputSize.width,
height: outputSize.height,
fileType: "jpg",
// 使用jpg格式文件更小
quality: compressionQuality,
// 使用动态计算的压缩质量
success: (res) => {
formatAppLog("log", "at common/utils.js:754", "导出成功:", res.tempFilePath);
formatAppLog("log", "at common/utils.js:755", "水印图片尺寸:", outputSize.width, "x", outputSize.height);
handleWatermarkExport(res.tempFilePath, originalFileSize, outputSize.width, outputSize.height, resolve);
},
fail: (err2) => {
formatAppLog("error", "at common/utils.js:759", "导出图片失败:", err2);
reject(err2);
}
});
}, 100);
});
});
} else {
canvas.draw(true, () => {
formatAppLog("log", "at common/utils.js:769", "Canvas绘制完成无logo");
setTimeout(() => {
uni.canvasToTempFilePath({
canvasId: "watermarkCanvas",
width: outputSize.width,
height: outputSize.height,
fileType: "jpg",
// 使用jpg格式文件更小
quality: compressionQuality,
// 使用动态计算的压缩质量
success: (res) => {
formatAppLog("log", "at common/utils.js:780", "导出成功:", res.tempFilePath);
formatAppLog("log", "at common/utils.js:781", "水印图片尺寸:", outputSize.width, "x", outputSize.height);
handleWatermarkExport(res.tempFilePath, originalFileSize, outputSize.width, outputSize.height, resolve);
},
fail: (err) => {
formatAppLog("error", "at common/utils.js:785", "导出图片失败:", err);
reject(err);
}
});
}, 100);
});
}
};
drawTextWatermark();
},
fail: (err) => {
formatAppLog("error", "at common/utils.js:798", "获取图片信息失败:", err);
reject(err);
}
});
} catch (error) {
formatAppLog("error", "at common/utils.js:803", "处理图片失败:", error);
reject(error);
}
});
};
const saveImageToPhotosAlbum = (image) => {
return new Promise((resolve, reject) => {
uni.saveImageToPhotosAlbum({
filePath: image,
success: () => {
formatAppLog("log", "at common/utils.js:839", "图片保存到相册成功");
resolve(true);
},
fail: (err) => {
formatAppLog("error", "at common/utils.js:843", "保存到相册失败:", err);
if (err.errMsg && err.errMsg.includes("auth deny")) {
uni.showModal({
title: "提示",
content: "需要您授权保存图片到相册,请在设置中开启相册权限",
showCancel: false,
confirmText: "知道了"
});
}
resolve(false);
}
});
});
};
const imageToBase64 = (filePath) => {
return new Promise((resolve, reject) => {
plus.io.resolveLocalFileSystemURL(filePath, (entry) => {
entry.file((file) => {
const reader = new plus.io.FileReader();
reader.onloadend = (e) => {
resolve(e.target.result);
};
reader.readAsDataURL(file);
}, reject);
}, reject);
});
};
async function request(url, data, method) {
return new Promise((resolve, reject) => {
uni.request({
url,
data,
method,
success: function(res) {
resolve(res.data);
}
});
});
}
async function get(url, data) {
return request(url, data, "GET");
}
async function post(url, data) {
return request(url, data, "POST");
}
var base_url = "https://wc.zpc-xy.com/";
const getBaseUrl = () => {
return base_url;
};
const getConfig = async () => {
var url = base_url + "config";
const res = await get(url, {});
return res.data;
};
const addWatermarkRecord = async (data) => {
var url = base_url + "addworkrecord";
formatAppLog("log", "at common/server.js:23", url, data);
const res = await post(url, data);
return res;
};
const TENGXUN_BASE = getBaseUrl() + "webapi";
const getLocationTranslate = async (locations) => {
formatAppLog("log", "at common/mapTranslateResult.js:15", TENGXUN_BASE);
const url = `${TENGXUN_BASE}/GetLocationTranslate?locations=${locations}&type=1`;
const res = await get(url, {});
if (res.code == 200) {
return res.data;
}
return "";
};
const getLocationGeocoder = async (locations) => {
const url = `${TENGXUN_BASE}/GetLocationGeocoder?location=${locations}`;
const res = await get(url, {});
return res.data;
};
const _imports_0 = "/static/logo.jpg";
const _sfc_main$1 = {
__name: "index",
setup(__props, { expose: __expose }) {
__expose();
const title = vue.ref("水印相机");
const candidates = vue.ref([]);
const workContent = vue.ref("");
const popup = vue.ref(null);
const locations = vue.ref({
location: {
lat: null,
lng: null
},
translate: {
lat: null,
lng: null,
locationInfo: null
}
});
const imageSrc = vue.ref("");
const originalImageSrc = vue.ref("");
const imageSizeInfo = vue.ref({
original: {
width: 0,
height: 0,
fileSize: null
},
watermark: {
width: 0,
height: 0,
fileSize: null
}
});
const departments = vue.ref(["请选择"]);
const deptIndex = vue.ref(0);
const workers = vue.ref([""]);
const statusList = vue.ref([]);
const statusIndex = vue.ref(0);
const locationInfo = vue.ref("");
const currentTime = vue.ref("");
const isSubmitting = vue.ref(false);
let logo = "";
const handleStartCapture = async () => {
uni.showLoading({
title: "加载中。。。"
});
try {
const locationData2 = await getLocation();
formatAppLog("log", "at pages/index/index.vue:198", "系统坐标", locationData2);
const location = locationData2.latitude + "," + locationData2.longitude;
formatAppLog("log", "at pages/index/index.vue:201", "经纬度", location);
const translate = await getLocationTranslate(location);
formatAppLog("log", "at pages/index/index.vue:204", "转换后", translate);
const t_location = translate.lat + "," + translate.lng;
const geocoderResult = await getLocationGeocoder(t_location);
formatAppLog("log", "at pages/index/index.vue:208", "地理编码结果", geocoderResult);
locations.value.location.lat = locationData2.latitude;
locations.value.location.lng = locationData2.longitude;
locations.value.translate.lat = translate.lat;
locations.value.translate.lng = translate.lng;
locations.value.translate.locationInfo = geocoderResult || "未知位置";
locationInfo.value = geocoderResult || "未知位置";
currentTime.value = /* @__PURE__ */ new Date();
const image = await chooseImage();
formatAppLog("log", "at pages/index/index.vue:221", "图片", image);
originalImageSrc.value = image.tempFilePaths[0];
imageSrc.value = image.tempFilePaths[0];
await addWatermarkToImage();
uni.hideLoading();
popup.value.open();
} catch (error) {
formatAppLog("log", "at pages/index/index.vue:229", "错误", error);
uni.hideLoading();
}
};
const handlePreviewImage = () => {
uni.previewImage({
urls: [imageSrc.value]
});
};
const handleComboxSelect = async (value) => {
formatAppLog("log", "at pages/index/index.vue:243", "选择的工作内容:", value);
if (locationData[value] != null) {
var tempData = locationData[value];
if (tempData.dept && departments.value.includes(tempData.dept)) {
deptIndex.value = departments.value.indexOf(tempData.dept);
}
if (tempData.status && statusList.value.includes(tempData.status)) {
statusIndex.value = statusList.value.indexOf(tempData.status);
}
if (tempData.workers && Array.isArray(tempData.workers)) {
workers.value.splice(0, workers.value.length);
workers.value.push(...tempData.workers);
}
await addWatermarkToImage(value);
formatAppLog("log", "at pages/index/index.vue:263", "加载的历史数据:", tempData);
}
};
const handleDeptChange = (e) => {
deptIndex.value = e.detail.value;
};
const handleStatusChange = (e) => {
statusIndex.value = e.detail.value;
};
const addWorker = () => {
workers.value.push("");
};
const removeWorker = (index) => {
if (workers.value.length > 1) {
workers.value.splice(index, 1);
}
};
const addWatermarkToImage = async (work = "") => {
try {
const watermarkInfo = {
time: formatDate(currentTime.value),
location: locationInfo.value,
longitude: locations.value.translate.lng,
latitude: locations.value.translate.lat,
department: departments.value[deptIndex.value],
workers: workers.value.filter((worker) => worker.trim() !== ""),
status: statusList.value[statusIndex.value],
remarks: workContent.value
};
if (workContent.value == "" && work != "") {
watermarkInfo.remarks = work;
}
formatAppLog("log", "at pages/index/index.vue:303", "水印信息:", watermarkInfo);
formatAppLog("log", "at pages/index/index.vue:304", "原图路径:", originalImageSrc.value);
const watermarkResult = await addWatermark(
originalImageSrc.value,
watermarkInfo,
logo,
1
);
formatAppLog("log", "at pages/index/index.vue:313", "水印结果:", watermarkResult);
imageSrc.value = watermarkResult.filePath;
imageSizeInfo.value = {
original: watermarkResult.originalSize,
watermark: watermarkResult.watermarkSize
};
} catch (error) {
formatAppLog("error", "at pages/index/index.vue:320", "添加水印失败:", error);
uni.showToast({
title: "添加水印失败",
icon: "error"
});
}
};
const handleRetakePhoto = () => {
popup.value.close();
resetFormData();
};
const handleSaveImage = async () => {
if (isSubmitting.value) {
return;
}
if (!validateFormData(false)) {
return;
}
isSubmitting.value = true;
try {
uni.showLoading({
title: "保存中..."
});
await addWatermarkToImage();
if (imageSrc.value) {
await saveImageToPhotosAlbum(imageSrc.value);
}
uni.hideLoading();
uni.showToast({
title: "图片保存成功",
icon: "success"
});
} catch (error) {
formatAppLog("error", "at pages/index/index.vue:367", "保存图片失败:", error);
uni.hideLoading();
uni.showToast({
title: "保存图片失败",
icon: "error"
});
} finally {
setTimeout(() => {
isSubmitting.value = false;
}, 1e3);
}
};
const handleRetakeCancel = async () => {
workers.value.splice(0, workers.value.length);
workers.value.push("");
statusIndex.value = 0;
deptIndex.value = 0;
workContent.value = "";
loadCandidates();
await addWatermarkToImage();
};
var locationData = {};
const handleSaveAndSubmit = async () => {
if (isSubmitting.value) {
return;
}
if (!validateFormData(true)) {
return;
}
isSubmitting.value = true;
try {
uni.showLoading({
title: "保存中..."
});
await addWatermarkToImage();
var saveData = {
workContent: workContent.value,
workers: workers.value.filter((worker) => worker.trim() !== ""),
status: statusList.value[statusIndex.value],
dept: departments.value[deptIndex.value],
date: (/* @__PURE__ */ new Date()).toISOString()
// 使用ISO格式确保时间格式一致
};
formatAppLog("log", "at pages/index/index.vue:419", saveData);
locationData[workContent.value] = saveData;
uni.setStorageSync("locationData", locationData);
var fromData = {
locations: locations.value,
workContent: workContent.value,
workers: workers.value,
status: statusList.value[statusIndex.value],
dept: departments.value[deptIndex.value]
};
var _remarks = JSON.stringify(locations.value);
var imageBase64 = await imageToBase64(imageSrc.value);
formatAppLog("log", "at pages/index/index.vue:431", fromData);
const camRecordWorkDto = {
// 部门名称
DeptName: departments.value[deptIndex.value],
// 图片地址
Image: imageBase64,
// 工作记录时间
RecordTime: formatDate(currentTime.value),
// 经度
Longitude: locations.value.translate.lng,
// 纬度
Latitude: locations.value.translate.lat,
// 工作地点
Address: locationInfo.value,
// 工作内容
Content: workContent.value,
// 状态
StatusName: statusList.value[statusIndex.value],
// 备注
Remarks: _remarks,
// 工作人员列表
Workers: workers.value
};
var res = await addWatermarkRecord(camRecordWorkDto);
formatAppLog("log", "at pages/index/index.vue:456", res);
if (res.code != 200) {
uni.hideLoading();
uni.showToast({
title: res.msg,
icon: "error"
});
return;
}
if (imageSrc.value) {
await saveImageToPhotosAlbum(imageSrc.value);
}
uni.hideLoading();
uni.showToast({
title: "保存成功",
icon: "success"
});
handleRetakePhoto();
} catch (error) {
formatAppLog("error", "at pages/index/index.vue:478", "保存失败:", error);
uni.hideLoading();
uni.showToast({
title: "保存失败",
icon: "error"
});
} finally {
setTimeout(() => {
isSubmitting.value = false;
}, 1e3);
}
};
const validateFormData = (isSubmit = false) => {
if (!locationInfo.value || locationInfo.value.trim() === "") {
uni.showToast({
title: "位置信息不能为空",
icon: "error"
});
return false;
}
if (isSubmit) {
if (!workContent.value || workContent.value.trim() === "") {
uni.showToast({
title: "请填写工作内容",
icon: "error"
});
return false;
}
if (deptIndex.value === 0) {
uni.showToast({
title: "请选择部门",
icon: "error"
});
return false;
}
const validWorkers = workers.value.filter((worker) => worker.trim() !== "");
if (validWorkers.length === 0) {
uni.showToast({
title: "请填写施工人员",
icon: "error"
});
return false;
}
if (statusIndex.value === 0) {
uni.showToast({
title: "请选择项目状态",
icon: "error"
});
return false;
}
}
return true;
};
const resetFormData = () => {
imageSrc.value = "";
originalImageSrc.value = "";
locationInfo.value = "";
currentTime.value = "";
imageSizeInfo.value = {
original: {
width: 0,
height: 0,
fileSize: null
},
watermark: {
width: 0,
height: 0,
fileSize: null
}
};
workers.value.splice(0, workers.value.length);
workers.value.push("");
statusIndex.value = 0;
deptIndex.value = 0;
workContent.value = "";
loadCandidates();
};
const loadCandidates = () => {
candidates.value.splice(0, candidates.value.length);
const sortedEntries = Object.entries(locationData).filter(([key, data]) => data && data.date).sort((a, b) => {
const dateA = new Date(a[1].date);
const dateB = new Date(b[1].date);
return dateB - dateA;
});
sortedEntries.forEach(([key, data]) => {
formatAppLog("log", "at pages/index/index.vue:583", `工作内容: ${key}, 时间: ${data.date}`);
candidates.value.push(key);
});
};
onLoad(async () => {
uni.showLoading({
title: "loading..."
});
try {
const config = await getConfig();
formatAppLog("log", "at pages/index/index.vue:595", "配置", config);
logo = config.logo;
departments.value.push(...config.deptList);
statusList.value.push(...config.construction);
await getCachedLogo(logo);
var _locationData = uni.getStorageSync("locationData");
if (_locationData != null) {
locationData = _locationData;
loadCandidates();
}
} catch (error) {
formatAppLog("error", "at pages/index/index.vue:610", "初始化失败:", error);
} finally {
uni.hideLoading();
}
});
const __returned__ = { title, candidates, workContent, popup, locations, imageSrc, originalImageSrc, imageSizeInfo, departments, deptIndex, workers, statusList, statusIndex, locationInfo, currentTime, isSubmitting, get logo() {
return logo;
}, set logo(v) {
logo = v;
}, handleStartCapture, handlePreviewImage, handleComboxSelect, handleDeptChange, handleStatusChange, addWorker, removeWorker, addWatermarkToImage, handleRetakePhoto, handleSaveImage, handleRetakeCancel, get locationData() {
return locationData;
}, set locationData(v) {
locationData = v;
}, handleSaveAndSubmit, validateFormData, resetFormData, loadCandidates, ref: vue.ref, get getLocation() {
return getLocation;
}, get chooseImage() {
return chooseImage;
}, get addWatermark() {
return addWatermark;
}, get formatDate() {
return formatDate;
}, get getCachedLogo() {
return getCachedLogo;
}, get saveImageToPhotosAlbum() {
return saveImageToPhotosAlbum;
}, get imageToBase64() {
return imageToBase64;
}, get getLocationTranslate() {
return getLocationTranslate;
}, get getLocationGeocoder() {
return getLocationGeocoder;
}, get getConfig() {
return getConfig;
}, get addWatermarkRecord() {
return addWatermarkRecord;
}, get onLoad() {
return onLoad;
} };
Object.defineProperty(__returned__, "__isScriptSetup", { enumerable: false, value: true });
return __returned__;
}
};
function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
const _component_uni_combox = resolveEasycom(vue.resolveDynamicComponent("uni-combox"), __easycom_0$1);
const _component_uni_popup = resolveEasycom(vue.resolveDynamicComponent("uni-popup"), __easycom_1);
return vue.openBlock(), vue.createElementBlock("view", null, [
vue.createCommentVNode(" 主页面内容 "),
vue.createElementVNode("view", null, [
vue.createElementVNode("image", {
class: "logo",
src: _imports_0
}),
vue.createElementVNode(
"text",
{ class: "title" },
vue.toDisplayString($setup.title),
1
/* TEXT */
),
vue.createElementVNode("view", { class: "btn-view" }, [
vue.createElementVNode("button", {
type: "primary",
class: "btn",
onClick: $setup.handleStartCapture
}, " 开始拍摄 ")
])
]),
vue.createCommentVNode(" 隐藏的canvas用于水印处理仅App/小程序端使用) "),
vue.createElementVNode("canvas", {
"canvas-id": "watermarkCanvas",
style: { "position": "fixed", "top": "-9999px", "left": "-9999px", "width": "2000px", "height": "2000px" }
}),
vue.createCommentVNode(" 弹窗内容 "),
vue.createVNode(
_component_uni_popup,
{
ref: "popup",
"is-mask-click": false,
type: "bottom",
"border-radius": "0 0 0 0"
},
{
default: vue.withCtx(() => [
vue.createElementVNode("view", { class: "container" }, [
vue.createElementVNode("view", { style: { "height": "80rpx" } }),
vue.createCommentVNode(" 图片预览区域 "),
vue.createElementVNode("view", { class: "preview-box" }, [
vue.createElementVNode("text", { class: "preview-title" }, "图片预览"),
vue.createElementVNode("view", { class: "preview-img" }, [
vue.createElementVNode("image", {
src: $setup.imageSrc,
onClick: $setup.handlePreviewImage,
mode: "aspectFit",
class: "img"
}, null, 8, ["src"])
]),
vue.createCommentVNode(" 图片尺寸和文件大小信息 "),
$setup.imageSizeInfo.original.width > 0 && false ? (vue.openBlock(), vue.createElementBlock("view", {
key: 0,
class: "size-info"
}, [
vue.createElementVNode(
"text",
{ class: "size-text" },
" 原图尺寸: " + vue.toDisplayString($setup.imageSizeInfo.original.width) + " x " + vue.toDisplayString($setup.imageSizeInfo.original.height),
1
/* TEXT */
),
$setup.imageSizeInfo.original.fileSize ? (vue.openBlock(), vue.createElementBlock(
"text",
{
key: 0,
class: "size-text"
},
" 原图大小: " + vue.toDisplayString($setup.imageSizeInfo.original.fileSize.sizeKB) + " KB ",
1
/* TEXT */
)) : vue.createCommentVNode("v-if", true),
vue.createElementVNode(
"text",
{ class: "size-text" },
" 水印图片尺寸: " + vue.toDisplayString($setup.imageSizeInfo.watermark.width) + " x " + vue.toDisplayString($setup.imageSizeInfo.watermark.height),
1
/* TEXT */
),
$setup.imageSizeInfo.watermark.fileSize ? (vue.openBlock(), vue.createElementBlock(
"text",
{
key: 1,
class: "size-text"
},
" 水印图片大小: " + vue.toDisplayString($setup.imageSizeInfo.watermark.fileSize.sizeKB) + " KB ",
1
/* TEXT */
)) : vue.createCommentVNode("v-if", true)
])) : vue.createCommentVNode("v-if", true)
]),
vue.createCommentVNode(" 表单区域 "),
vue.createElementVNode("view", { class: "form-item" }, [
vue.createElementVNode("text", { class: "label" }, "位置:"),
vue.withDirectives(vue.createElementVNode(
"input",
{
"onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => $setup.locationInfo = $event),
type: "text",
class: "input worker-input"
},
null,
512
/* NEED_PATCH */
), [
[vue.vModelText, $setup.locationInfo]
])
]),
vue.createCommentVNode(" 表单区域 "),
vue.createElementVNode("view", { class: "form-item" }, [
vue.createElementVNode("text", { class: "label" }, "请填写工作内容:"),
vue.createVNode(_component_uni_combox, {
candidates: $setup.candidates,
"clear-able": true,
placeholder: "请填写工作内容",
onSelect: $setup.handleComboxSelect,
modelValue: $setup.workContent,
"onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => $setup.workContent = $event)
}, null, 8, ["candidates", "modelValue"])
]),
vue.createElementVNode("view", { class: "form-item" }, [
vue.createElementVNode("text", { class: "label" }, "请选择部门:"),
vue.createElementVNode("picker", {
range: $setup.departments,
onChange: $setup.handleDeptChange
}, [
vue.createElementVNode(
"view",
{ class: "picker" },
vue.toDisplayString($setup.departments[$setup.deptIndex]),
1
/* TEXT */
)
], 40, ["range"])
]),
vue.createElementVNode("view", { class: "form-item" }, [
vue.createElementVNode("text", { class: "label" }, "请填写施工人员:"),
(vue.openBlock(true), vue.createElementBlock(
vue.Fragment,
null,
vue.renderList($setup.workers, (worker, index) => {
return vue.openBlock(), vue.createElementBlock("view", {
key: index,
class: "worker-row"
}, [
vue.withDirectives(vue.createElementVNode("input", {
type: "text",
"onUpdate:modelValue": ($event) => $setup.workers[index] = $event,
class: "input worker-input"
}, null, 8, ["onUpdate:modelValue"]), [
[vue.vModelText, $setup.workers[index]]
]),
vue.createElementVNode("view", { class: "btns" }, [
vue.createElementVNode("button", {
class: "btn_f",
size: "mini",
onClick: $setup.addWorker
}, "+"),
$setup.workers.length > 0 ? (vue.openBlock(), vue.createElementBlock("button", {
key: 0,
class: "btn_f",
size: "mini",
onClick: ($event) => $setup.removeWorker(index)
}, " - ", 8, ["onClick"])) : vue.createCommentVNode("v-if", true)
])
]);
}),
128
/* KEYED_FRAGMENT */
))
]),
vue.createElementVNode("view", { class: "form-item" }, [
vue.createElementVNode("text", { class: "label" }, "请选择项目状态:"),
vue.createElementVNode("picker", {
range: $setup.statusList,
onChange: $setup.handleStatusChange
}, [
vue.createElementVNode(
"view",
{ class: "picker" },
vue.toDisplayString($setup.statusList[$setup.statusIndex]),
1
/* TEXT */
)
], 40, ["range"])
]),
vue.createCommentVNode(" 底部操作按钮 "),
vue.createElementVNode("view", { class: "footer" }, [
vue.createElementVNode("button", {
type: "primary",
class: "btn-cancel",
onClick: $setup.handleRetakePhoto
}, " 重拍 "),
vue.createElementVNode("button", {
type: "primary",
class: "btn-cancel",
onClick: $setup.handleRetakeCancel
}, " 清空 "),
vue.createElementVNode("button", {
type: "primary",
class: "btn-save",
onClick: $setup.handleSaveImage,
disabled: $setup.isSubmitting
}, " 保存图片 ", 8, ["disabled"]),
vue.createElementVNode("button", {
type: "primary",
class: "btn-submit",
onClick: $setup.handleSaveAndSubmit,
disabled: $setup.isSubmitting
}, " 提交数据 ", 8, ["disabled"])
])
])
]),
_: 1
/* STABLE */
},
512
/* NEED_PATCH */
)
]);
}
const PagesIndexIndex = /* @__PURE__ */ _export_sfc(_sfc_main$1, [["render", _sfc_render], ["__file", "D:/代码/uniapp/WorkCameraf/pages/index/index.vue"]]);
__definePage("pages/index/index", PagesIndexIndex);
const _sfc_main = {
onLaunch: function() {
formatAppLog("log", "at App.vue:4", "App Launch");
},
onShow: function() {
formatAppLog("log", "at App.vue:7", "App Show");
},
onHide: function() {
formatAppLog("log", "at App.vue:10", "App Hide");
}
};
const App = /* @__PURE__ */ _export_sfc(_sfc_main, [["__file", "D:/代码/uniapp/WorkCameraf/App.vue"]]);
function createApp() {
const app = vue.createVueApp(App);
return {
app
};
}
const { app: __app__, Vuex: __Vuex__, Pinia: __Pinia__ } = createApp();
uni.Vuex = __Vuex__;
uni.Pinia = __Pinia__;
__app__.provide("__globalStyles", __uniConfig.styles);
__app__._component.mpType = "app";
__app__._component.render = () => {
};
__app__.mount("#app");
})(Vue);