登录功能
This commit is contained in:
parent
118aab4f3b
commit
4286fa07f0
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
@ -1,49 +1,43 @@
|
||||
{
|
||||
"hash": "cb5d0200",
|
||||
"configHash": "ed1743b1",
|
||||
"lockfileHash": "dc2ce3eb",
|
||||
"browserHash": "7eb5a1d0",
|
||||
"hash": "21acb680",
|
||||
"configHash": "f8279dd9",
|
||||
"lockfileHash": "3f41a995",
|
||||
"browserHash": "9ba88dfd",
|
||||
"optimized": {
|
||||
"@vue/devtools-api": {
|
||||
"src": "../../../../node_modules/@vue/devtools-api/dist/index.js",
|
||||
"file": "@vue_devtools-api.js",
|
||||
"fileHash": "78218010",
|
||||
"fileHash": "51d28fb6",
|
||||
"needsInterop": false
|
||||
},
|
||||
"@vuepress/shared": {
|
||||
"src": "../../../../node_modules/@vuepress/shared/dist/index.js",
|
||||
"file": "@vuepress_shared.js",
|
||||
"fileHash": "97474d81",
|
||||
"fileHash": "1c5d8c58",
|
||||
"needsInterop": false
|
||||
},
|
||||
"vue": {
|
||||
"src": "../../../../node_modules/vue/dist/vue.runtime.esm-bundler.js",
|
||||
"file": "vue.js",
|
||||
"fileHash": "bf4f1bd0",
|
||||
"fileHash": "aff3e00e",
|
||||
"needsInterop": false
|
||||
},
|
||||
"vue-router": {
|
||||
"src": "../../../../node_modules/vue-router/dist/vue-router.esm-bundler.js",
|
||||
"file": "vue-router.js",
|
||||
"fileHash": "1ed8f5d8",
|
||||
"fileHash": "d25827a8",
|
||||
"needsInterop": false
|
||||
},
|
||||
"pinia": {
|
||||
"src": "../../../../node_modules/pinia/dist/pinia.mjs",
|
||||
"file": "pinia.js",
|
||||
"fileHash": "cec75367",
|
||||
"fileHash": "b5e4c171",
|
||||
"needsInterop": false
|
||||
},
|
||||
"axios": {
|
||||
"src": "../../../../node_modules/axios/index.js",
|
||||
"file": "axios.js",
|
||||
"fileHash": "5ad3ff1a",
|
||||
"needsInterop": false
|
||||
},
|
||||
"@vueuse/core": {
|
||||
"src": "../../../../node_modules/@vueuse/core/index.mjs",
|
||||
"file": "@vueuse_core.js",
|
||||
"fileHash": "ece7d2ca",
|
||||
"fileHash": "a24178aa",
|
||||
"needsInterop": false
|
||||
}
|
||||
},
|
||||
|
||||
@ -46,8 +46,8 @@ var isPlainObject = (val) => {
|
||||
if (kindOf(val) !== "object") {
|
||||
return false;
|
||||
}
|
||||
const prototype3 = getPrototypeOf(val);
|
||||
return (prototype3 === null || prototype3 === Object.prototype || Object.getPrototypeOf(prototype3) === null) && !(toStringTag in val) && !(iterator in val);
|
||||
const prototype2 = getPrototypeOf(val);
|
||||
return (prototype2 === null || prototype2 === Object.prototype || Object.getPrototypeOf(prototype2) === null) && !(toStringTag in val) && !(iterator in val);
|
||||
};
|
||||
var isEmptyObject = (val) => {
|
||||
if (!isObject(val) || isBuffer(val)) {
|
||||
@ -130,10 +130,8 @@ function merge() {
|
||||
result[targetKey] = merge({}, val);
|
||||
} else if (isArray(val)) {
|
||||
result[targetKey] = val.slice();
|
||||
} else {
|
||||
if (!skipUndefined || !isUndefined(val)) {
|
||||
result[targetKey] = val;
|
||||
}
|
||||
} else if (!skipUndefined || !isUndefined(val)) {
|
||||
result[targetKey] = val;
|
||||
}
|
||||
};
|
||||
for (let i = 0, l = arguments.length; i < l; i++) {
|
||||
@ -144,9 +142,19 @@ function merge() {
|
||||
var extend = (a, b, thisArg, { allOwnKeys } = {}) => {
|
||||
forEach(b, (val, key) => {
|
||||
if (thisArg && isFunction(val)) {
|
||||
a[key] = bind(val, thisArg);
|
||||
Object.defineProperty(a, key, {
|
||||
value: bind(val, thisArg),
|
||||
writable: true,
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
});
|
||||
} else {
|
||||
a[key] = val;
|
||||
Object.defineProperty(a, key, {
|
||||
value: val,
|
||||
writable: true,
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
});
|
||||
}
|
||||
}, { allOwnKeys });
|
||||
return a;
|
||||
@ -157,9 +165,14 @@ var stripBOM = (content) => {
|
||||
}
|
||||
return content;
|
||||
};
|
||||
var inherits = (constructor, superConstructor, props, descriptors2) => {
|
||||
constructor.prototype = Object.create(superConstructor.prototype, descriptors2);
|
||||
constructor.prototype.constructor = constructor;
|
||||
var inherits = (constructor, superConstructor, props, descriptors) => {
|
||||
constructor.prototype = Object.create(superConstructor.prototype, descriptors);
|
||||
Object.defineProperty(constructor.prototype, "constructor", {
|
||||
value: constructor,
|
||||
writable: true,
|
||||
enumerable: false,
|
||||
configurable: true
|
||||
});
|
||||
Object.defineProperty(constructor, "super", {
|
||||
value: superConstructor.prototype
|
||||
});
|
||||
@ -240,9 +253,9 @@ var toCamelCase = (str) => {
|
||||
var hasOwnProperty = (({ hasOwnProperty: hasOwnProperty2 }) => (obj, prop) => hasOwnProperty2.call(obj, prop))(Object.prototype);
|
||||
var isRegExp = kindOfTest("RegExp");
|
||||
var reduceDescriptors = (obj, reducer) => {
|
||||
const descriptors2 = Object.getOwnPropertyDescriptors(obj);
|
||||
const descriptors = Object.getOwnPropertyDescriptors(obj);
|
||||
const reducedDescriptors = {};
|
||||
forEach(descriptors2, (descriptor, name) => {
|
||||
forEach(descriptors, (descriptor, name) => {
|
||||
let ret;
|
||||
if ((ret = reducer(descriptor, name, obj)) !== false) {
|
||||
reducedDescriptors[name] = ret || descriptor;
|
||||
@ -397,25 +410,38 @@ var utils_default = {
|
||||
};
|
||||
|
||||
// node_modules/axios/lib/core/AxiosError.js
|
||||
function AxiosError(message, code, config, request, response) {
|
||||
Error.call(this);
|
||||
if (Error.captureStackTrace) {
|
||||
Error.captureStackTrace(this, this.constructor);
|
||||
} else {
|
||||
this.stack = new Error().stack;
|
||||
var AxiosError = class _AxiosError extends Error {
|
||||
static from(error, code, config, request, response, customProps) {
|
||||
const axiosError = new _AxiosError(error.message, code || error.code, config, request, response);
|
||||
axiosError.cause = error;
|
||||
axiosError.name = error.name;
|
||||
customProps && Object.assign(axiosError, customProps);
|
||||
return axiosError;
|
||||
}
|
||||
this.message = message;
|
||||
this.name = "AxiosError";
|
||||
code && (this.code = code);
|
||||
config && (this.config = config);
|
||||
request && (this.request = request);
|
||||
if (response) {
|
||||
this.response = response;
|
||||
this.status = response.status ? response.status : null;
|
||||
/**
|
||||
* Create an Error with the specified message, config, error code, request and response.
|
||||
*
|
||||
* @param {string} message The error message.
|
||||
* @param {string} [code] The error code (for example, 'ECONNABORTED').
|
||||
* @param {Object} [config] The config.
|
||||
* @param {Object} [request] The request.
|
||||
* @param {Object} [response] The response.
|
||||
*
|
||||
* @returns {Error} The created error.
|
||||
*/
|
||||
constructor(message, code, config, request, response) {
|
||||
super(message);
|
||||
this.name = "AxiosError";
|
||||
this.isAxiosError = true;
|
||||
code && (this.code = code);
|
||||
config && (this.config = config);
|
||||
request && (this.request = request);
|
||||
if (response) {
|
||||
this.response = response;
|
||||
this.status = response.status;
|
||||
}
|
||||
}
|
||||
}
|
||||
utils_default.inherits(AxiosError, Error, {
|
||||
toJSON: function toJSON() {
|
||||
toJSON() {
|
||||
return {
|
||||
// Standard
|
||||
message: this.message,
|
||||
@ -434,45 +460,19 @@ utils_default.inherits(AxiosError, Error, {
|
||||
status: this.status
|
||||
};
|
||||
}
|
||||
});
|
||||
var prototype = AxiosError.prototype;
|
||||
var descriptors = {};
|
||||
[
|
||||
"ERR_BAD_OPTION_VALUE",
|
||||
"ERR_BAD_OPTION",
|
||||
"ECONNABORTED",
|
||||
"ETIMEDOUT",
|
||||
"ERR_NETWORK",
|
||||
"ERR_FR_TOO_MANY_REDIRECTS",
|
||||
"ERR_DEPRECATED",
|
||||
"ERR_BAD_RESPONSE",
|
||||
"ERR_BAD_REQUEST",
|
||||
"ERR_CANCELED",
|
||||
"ERR_NOT_SUPPORT",
|
||||
"ERR_INVALID_URL"
|
||||
// eslint-disable-next-line func-names
|
||||
].forEach((code) => {
|
||||
descriptors[code] = { value: code };
|
||||
});
|
||||
Object.defineProperties(AxiosError, descriptors);
|
||||
Object.defineProperty(prototype, "isAxiosError", { value: true });
|
||||
AxiosError.from = (error, code, config, request, response, customProps) => {
|
||||
const axiosError = Object.create(prototype);
|
||||
utils_default.toFlatObject(error, axiosError, function filter2(obj) {
|
||||
return obj !== Error.prototype;
|
||||
}, (prop) => {
|
||||
return prop !== "isAxiosError";
|
||||
});
|
||||
const msg = error && error.message ? error.message : "Error";
|
||||
const errCode = code == null && error ? error.code : code;
|
||||
AxiosError.call(axiosError, msg, errCode, config, request, response);
|
||||
if (error && axiosError.cause == null) {
|
||||
Object.defineProperty(axiosError, "cause", { value: error, configurable: true });
|
||||
}
|
||||
axiosError.name = error && error.name || "Error";
|
||||
customProps && Object.assign(axiosError, customProps);
|
||||
return axiosError;
|
||||
};
|
||||
AxiosError.ERR_BAD_OPTION_VALUE = "ERR_BAD_OPTION_VALUE";
|
||||
AxiosError.ERR_BAD_OPTION = "ERR_BAD_OPTION";
|
||||
AxiosError.ECONNABORTED = "ECONNABORTED";
|
||||
AxiosError.ETIMEDOUT = "ETIMEDOUT";
|
||||
AxiosError.ERR_NETWORK = "ERR_NETWORK";
|
||||
AxiosError.ERR_FR_TOO_MANY_REDIRECTS = "ERR_FR_TOO_MANY_REDIRECTS";
|
||||
AxiosError.ERR_DEPRECATED = "ERR_DEPRECATED";
|
||||
AxiosError.ERR_BAD_RESPONSE = "ERR_BAD_RESPONSE";
|
||||
AxiosError.ERR_BAD_REQUEST = "ERR_BAD_REQUEST";
|
||||
AxiosError.ERR_CANCELED = "ERR_CANCELED";
|
||||
AxiosError.ERR_NOT_SUPPORT = "ERR_NOT_SUPPORT";
|
||||
AxiosError.ERR_INVALID_URL = "ERR_INVALID_URL";
|
||||
var AxiosError_default = AxiosError;
|
||||
|
||||
// node_modules/axios/lib/helpers/null.js
|
||||
@ -612,11 +612,11 @@ function AxiosURLSearchParams(params, options) {
|
||||
this._pairs = [];
|
||||
params && toFormData_default(params, this, options);
|
||||
}
|
||||
var prototype2 = AxiosURLSearchParams.prototype;
|
||||
prototype2.append = function append(name, value) {
|
||||
var prototype = AxiosURLSearchParams.prototype;
|
||||
prototype.append = function append(name, value) {
|
||||
this._pairs.push([name, value]);
|
||||
};
|
||||
prototype2.toString = function toString2(encoder) {
|
||||
prototype.toString = function toString2(encoder) {
|
||||
const _encode = encoder ? function(value) {
|
||||
return encoder.call(this, value, encode);
|
||||
} : encode;
|
||||
@ -635,17 +635,15 @@ function buildURL(url, params, options) {
|
||||
return url;
|
||||
}
|
||||
const _encode = options && options.encode || encode2;
|
||||
if (utils_default.isFunction(options)) {
|
||||
options = {
|
||||
serialize: options
|
||||
};
|
||||
}
|
||||
const serializeFn = options && options.serialize;
|
||||
const _options = utils_default.isFunction(options) ? {
|
||||
serialize: options
|
||||
} : options;
|
||||
const serializeFn = _options && _options.serialize;
|
||||
let serializedParams;
|
||||
if (serializeFn) {
|
||||
serializedParams = serializeFn(params, options);
|
||||
serializedParams = serializeFn(params, _options);
|
||||
} else {
|
||||
serializedParams = utils_default.isURLSearchParams(params) ? params.toString() : new AxiosURLSearchParams_default(params, options).toString(_encode);
|
||||
serializedParams = utils_default.isURLSearchParams(params) ? params.toString() : new AxiosURLSearchParams_default(params, _options).toString(_encode);
|
||||
}
|
||||
if (serializedParams) {
|
||||
const hashmarkIndex = url.indexOf("#");
|
||||
@ -667,6 +665,7 @@ var InterceptorManager = class {
|
||||
*
|
||||
* @param {Function} fulfilled The function to handle `then` for a `Promise`
|
||||
* @param {Function} rejected The function to handle `reject` for a `Promise`
|
||||
* @param {Object} options The options for the interceptor, synchronous and runWhen
|
||||
*
|
||||
* @return {Number} An ID used to remove interceptor later
|
||||
*/
|
||||
@ -684,7 +683,7 @@ var InterceptorManager = class {
|
||||
*
|
||||
* @param {Number} id The ID that was returned by `use`
|
||||
*
|
||||
* @returns {Boolean} `true` if the interceptor was removed, `false` otherwise
|
||||
* @returns {void}
|
||||
*/
|
||||
eject(id) {
|
||||
if (this.handlers[id]) {
|
||||
@ -1197,11 +1196,11 @@ var AxiosHeaders = class {
|
||||
accessors: {}
|
||||
};
|
||||
const accessors = internals.accessors;
|
||||
const prototype3 = this.prototype;
|
||||
const prototype2 = this.prototype;
|
||||
function defineAccessor(_header) {
|
||||
const lHeader = normalizeHeader(_header);
|
||||
if (!accessors[lHeader]) {
|
||||
buildAccessors(prototype3, _header);
|
||||
buildAccessors(prototype2, _header);
|
||||
accessors[lHeader] = true;
|
||||
}
|
||||
}
|
||||
@ -1241,13 +1240,22 @@ function isCancel(value) {
|
||||
}
|
||||
|
||||
// node_modules/axios/lib/cancel/CanceledError.js
|
||||
function CanceledError(message, config, request) {
|
||||
AxiosError_default.call(this, message == null ? "canceled" : message, AxiosError_default.ERR_CANCELED, config, request);
|
||||
this.name = "CanceledError";
|
||||
}
|
||||
utils_default.inherits(CanceledError, AxiosError_default, {
|
||||
__CANCEL__: true
|
||||
});
|
||||
var CanceledError = class extends AxiosError_default {
|
||||
/**
|
||||
* A `CanceledError` is an object that is thrown when an operation is canceled.
|
||||
*
|
||||
* @param {string=} message The message.
|
||||
* @param {Object=} config The config.
|
||||
* @param {Object=} request The request.
|
||||
*
|
||||
* @returns {CanceledError} The created error.
|
||||
*/
|
||||
constructor(message, config, request) {
|
||||
super(message == null ? "canceled" : message, AxiosError_default.ERR_CANCELED, config, request);
|
||||
this.name = "CanceledError";
|
||||
this.__CANCEL__ = true;
|
||||
}
|
||||
};
|
||||
var CanceledError_default = CanceledError;
|
||||
|
||||
// node_modules/axios/lib/core/settle.js
|
||||
@ -1391,20 +1399,33 @@ var isURLSameOrigin_default = platform_default.hasStandardBrowserEnv ? /* @__PUR
|
||||
var cookies_default = platform_default.hasStandardBrowserEnv ? (
|
||||
// Standard browser envs support document.cookie
|
||||
{
|
||||
write(name, value, expires, path, domain, secure) {
|
||||
const cookie = [name + "=" + encodeURIComponent(value)];
|
||||
utils_default.isNumber(expires) && cookie.push("expires=" + new Date(expires).toGMTString());
|
||||
utils_default.isString(path) && cookie.push("path=" + path);
|
||||
utils_default.isString(domain) && cookie.push("domain=" + domain);
|
||||
secure === true && cookie.push("secure");
|
||||
write(name, value, expires, path, domain, secure, sameSite) {
|
||||
if (typeof document === "undefined") return;
|
||||
const cookie = [`${name}=${encodeURIComponent(value)}`];
|
||||
if (utils_default.isNumber(expires)) {
|
||||
cookie.push(`expires=${new Date(expires).toUTCString()}`);
|
||||
}
|
||||
if (utils_default.isString(path)) {
|
||||
cookie.push(`path=${path}`);
|
||||
}
|
||||
if (utils_default.isString(domain)) {
|
||||
cookie.push(`domain=${domain}`);
|
||||
}
|
||||
if (secure === true) {
|
||||
cookie.push("secure");
|
||||
}
|
||||
if (utils_default.isString(sameSite)) {
|
||||
cookie.push(`SameSite=${sameSite}`);
|
||||
}
|
||||
document.cookie = cookie.join("; ");
|
||||
},
|
||||
read(name) {
|
||||
const match = document.cookie.match(new RegExp("(^|;\\s*)(" + name + ")=([^;]*)"));
|
||||
return match ? decodeURIComponent(match[3]) : null;
|
||||
if (typeof document === "undefined") return null;
|
||||
const match = document.cookie.match(new RegExp("(?:^|; )" + name + "=([^;]*)"));
|
||||
return match ? decodeURIComponent(match[1]) : null;
|
||||
},
|
||||
remove(name) {
|
||||
this.write(name, "", Date.now() - 864e5);
|
||||
this.write(name, "", Date.now() - 864e5, "/");
|
||||
}
|
||||
}
|
||||
) : (
|
||||
@ -1702,7 +1723,7 @@ var composeSignals = (signals, timeout) => {
|
||||
};
|
||||
let timer = timeout && setTimeout(() => {
|
||||
timer = null;
|
||||
onabort(new AxiosError_default(`timeout ${timeout} of ms exceeded`, AxiosError_default.ETIMEDOUT));
|
||||
onabort(new AxiosError_default(`timeout of ${timeout}ms exceeded`, AxiosError_default.ETIMEDOUT));
|
||||
}, timeout);
|
||||
const unsubscribe = () => {
|
||||
if (signals) {
|
||||
@ -1802,8 +1823,7 @@ var trackStream = (stream, chunkSize, onProgress, onFinish) => {
|
||||
// node_modules/axios/lib/adapters/fetch.js
|
||||
var DEFAULT_CHUNK_SIZE = 64 * 1024;
|
||||
var { isFunction: isFunction2 } = utils_default;
|
||||
var globalFetchAPI = (({ fetch, Request, Response }) => ({
|
||||
fetch,
|
||||
var globalFetchAPI = (({ Request, Response }) => ({
|
||||
Request,
|
||||
Response
|
||||
}))(utils_default.global);
|
||||
@ -1819,8 +1839,11 @@ var test = (fn, ...args) => {
|
||||
}
|
||||
};
|
||||
var factory = (env) => {
|
||||
const { fetch, Request, Response } = Object.assign({}, globalFetchAPI, env);
|
||||
const isFetchSupported = isFunction2(fetch);
|
||||
env = utils_default.merge.call({
|
||||
skipUndefined: true
|
||||
}, globalFetchAPI, env);
|
||||
const { fetch: envFetch, Request, Response } = env;
|
||||
const isFetchSupported = envFetch ? isFunction2(envFetch) : typeof fetch === "function";
|
||||
const isRequestSupported = isFunction2(Request);
|
||||
const isResponseSupported = isFunction2(Response);
|
||||
if (!isFetchSupported) {
|
||||
@ -1898,6 +1921,7 @@ var factory = (env) => {
|
||||
withCredentials = "same-origin",
|
||||
fetchOptions
|
||||
} = resolveConfig_default(config);
|
||||
let _fetch = envFetch || fetch;
|
||||
responseType = responseType ? (responseType + "").toLowerCase() : "text";
|
||||
let composedSignal = composeSignals_default([signal, cancelToken && cancelToken.toAbortSignal()], timeout);
|
||||
let request = null;
|
||||
@ -1938,7 +1962,7 @@ var factory = (env) => {
|
||||
credentials: isCredentialsSupported ? withCredentials : void 0
|
||||
};
|
||||
request = isRequestSupported && new Request(url, resolvedOptions);
|
||||
let response = await (isRequestSupported ? fetch(request, fetchOptions) : fetch(url, resolvedOptions));
|
||||
let response = await (isRequestSupported ? _fetch(request, fetchOptions) : _fetch(url, resolvedOptions));
|
||||
const isStreamResponse = supportsResponseStream && (responseType === "stream" || responseType === "response");
|
||||
if (supportsResponseStream && (onDownloadProgress || isStreamResponse && unsubscribe)) {
|
||||
const options = {};
|
||||
@ -1987,14 +2011,12 @@ var factory = (env) => {
|
||||
};
|
||||
var seedCache = /* @__PURE__ */ new Map();
|
||||
var getFetch = (config) => {
|
||||
let env = utils_default.merge.call({
|
||||
skipUndefined: true
|
||||
}, globalFetchAPI, config ? config.env : null);
|
||||
const { fetch, Request, Response } = env;
|
||||
let env = config && config.env || {};
|
||||
const { fetch: fetch2, Request, Response } = env;
|
||||
const seeds = [
|
||||
Request,
|
||||
Response,
|
||||
fetch
|
||||
fetch2
|
||||
];
|
||||
let len = seeds.length, i = len, seed, target, map = seedCache;
|
||||
while (i--) {
|
||||
@ -2026,40 +2048,49 @@ utils_default.forEach(knownAdapters, (fn, value) => {
|
||||
});
|
||||
var renderReason = (reason) => `- ${reason}`;
|
||||
var isResolvedHandle = (adapter2) => utils_default.isFunction(adapter2) || adapter2 === null || adapter2 === false;
|
||||
function getAdapter(adapters, config) {
|
||||
adapters = utils_default.isArray(adapters) ? adapters : [adapters];
|
||||
const { length } = adapters;
|
||||
let nameOrAdapter;
|
||||
let adapter2;
|
||||
const rejectedReasons = {};
|
||||
for (let i = 0; i < length; i++) {
|
||||
nameOrAdapter = adapters[i];
|
||||
let id;
|
||||
adapter2 = nameOrAdapter;
|
||||
if (!isResolvedHandle(nameOrAdapter)) {
|
||||
adapter2 = knownAdapters[(id = String(nameOrAdapter)).toLowerCase()];
|
||||
if (adapter2 === void 0) {
|
||||
throw new AxiosError_default(`Unknown adapter '${id}'`);
|
||||
}
|
||||
}
|
||||
if (adapter2 && (utils_default.isFunction(adapter2) || (adapter2 = adapter2.get(config)))) {
|
||||
break;
|
||||
}
|
||||
rejectedReasons[id || "#" + i] = adapter2;
|
||||
}
|
||||
if (!adapter2) {
|
||||
const reasons = Object.entries(rejectedReasons).map(
|
||||
([id, state]) => `adapter ${id} ` + (state === false ? "is not supported by the environment" : "is not available in the build")
|
||||
);
|
||||
let s = length ? reasons.length > 1 ? "since :\n" + reasons.map(renderReason).join("\n") : " " + renderReason(reasons[0]) : "as no adapter specified";
|
||||
throw new AxiosError_default(
|
||||
`There is no suitable adapter to dispatch the request ` + s,
|
||||
"ERR_NOT_SUPPORT"
|
||||
);
|
||||
}
|
||||
return adapter2;
|
||||
}
|
||||
var adapters_default = {
|
||||
getAdapter: (adapters, config) => {
|
||||
adapters = utils_default.isArray(adapters) ? adapters : [adapters];
|
||||
const { length } = adapters;
|
||||
let nameOrAdapter;
|
||||
let adapter2;
|
||||
const rejectedReasons = {};
|
||||
for (let i = 0; i < length; i++) {
|
||||
nameOrAdapter = adapters[i];
|
||||
let id;
|
||||
adapter2 = nameOrAdapter;
|
||||
if (!isResolvedHandle(nameOrAdapter)) {
|
||||
adapter2 = knownAdapters[(id = String(nameOrAdapter)).toLowerCase()];
|
||||
if (adapter2 === void 0) {
|
||||
throw new AxiosError_default(`Unknown adapter '${id}'`);
|
||||
}
|
||||
}
|
||||
if (adapter2 && (utils_default.isFunction(adapter2) || (adapter2 = adapter2.get(config)))) {
|
||||
break;
|
||||
}
|
||||
rejectedReasons[id || "#" + i] = adapter2;
|
||||
}
|
||||
if (!adapter2) {
|
||||
const reasons = Object.entries(rejectedReasons).map(
|
||||
([id, state]) => `adapter ${id} ` + (state === false ? "is not supported by the environment" : "is not available in the build")
|
||||
);
|
||||
let s = length ? reasons.length > 1 ? "since :\n" + reasons.map(renderReason).join("\n") : " " + renderReason(reasons[0]) : "as no adapter specified";
|
||||
throw new AxiosError_default(
|
||||
`There is no suitable adapter to dispatch the request ` + s,
|
||||
"ERR_NOT_SUPPORT"
|
||||
);
|
||||
}
|
||||
return adapter2;
|
||||
},
|
||||
/**
|
||||
* Resolve an adapter from a list of adapter names or functions.
|
||||
* @type {Function}
|
||||
*/
|
||||
getAdapter,
|
||||
/**
|
||||
* Exposes all known adapters
|
||||
* @type {Object<string, Function|Object>}
|
||||
*/
|
||||
adapters: knownAdapters
|
||||
};
|
||||
|
||||
@ -2109,7 +2140,7 @@ function dispatchRequest(config) {
|
||||
}
|
||||
|
||||
// node_modules/axios/lib/env/data.js
|
||||
var VERSION = "1.12.0";
|
||||
var VERSION = "1.13.4";
|
||||
|
||||
// node_modules/axios/lib/helpers/validator.js
|
||||
var validators = {};
|
||||
@ -2292,7 +2323,6 @@ var Axios = class {
|
||||
}
|
||||
len = requestInterceptorChain.length;
|
||||
let newConfig = config;
|
||||
i = 0;
|
||||
while (i < len) {
|
||||
const onFulfilled = requestInterceptorChain[i++];
|
||||
const onRejected = requestInterceptorChain[i++];
|
||||
@ -2522,7 +2552,13 @@ var HttpStatusCode = {
|
||||
InsufficientStorage: 507,
|
||||
LoopDetected: 508,
|
||||
NotExtended: 510,
|
||||
NetworkAuthenticationRequired: 511
|
||||
NetworkAuthenticationRequired: 511,
|
||||
WebServerIsDown: 521,
|
||||
ConnectionTimedOut: 522,
|
||||
OriginIsUnreachable: 523,
|
||||
TimeoutOccurred: 524,
|
||||
SslHandshakeFailed: 525,
|
||||
InvalidSslCertificate: 526
|
||||
};
|
||||
Object.entries(HttpStatusCode).forEach(([key, value]) => {
|
||||
HttpStatusCode[value] = key;
|
||||
@ -2578,7 +2614,7 @@ var {
|
||||
AxiosHeaders: AxiosHeaders2,
|
||||
HttpStatusCode: HttpStatusCode2,
|
||||
formToJSON,
|
||||
getAdapter,
|
||||
getAdapter: getAdapter2,
|
||||
mergeConfig: mergeConfig2
|
||||
} = axios_default;
|
||||
export {
|
||||
@ -2593,7 +2629,7 @@ export {
|
||||
all2 as all,
|
||||
axios_default as default,
|
||||
formToJSON,
|
||||
getAdapter,
|
||||
getAdapter2 as getAdapter,
|
||||
isAxiosError2 as isAxiosError,
|
||||
isCancel2 as isCancel,
|
||||
mergeConfig2 as mergeConfig,
|
||||
|
||||
File diff suppressed because one or more lines are too long
@ -9,8 +9,7 @@ import * as clientConfig7 from 'D:/xue/dma_handbook/docs/.vuepress/.temp/prismjs
|
||||
import * as clientConfig8 from 'D:/xue/dma_handbook/docs/.vuepress/.temp/markdown-tab/config.js'
|
||||
import * as clientConfig9 from 'D:/xue/dma_handbook/node_modules/@vuepress/plugin-theme-data/lib/client/config.js'
|
||||
import * as clientConfig10 from 'D:/xue/dma_handbook/node_modules/@vuepress/theme-default/lib/client/config.js'
|
||||
import * as clientConfig11 from 'D:/xue/dma_handbook/node_modules/@vuepress/plugin-search/lib/client/config.js'
|
||||
import * as clientConfig12 from 'D:/xue/dma_handbook/docs/.vuepress/client.js'
|
||||
import * as clientConfig11 from 'D:/xue/dma_handbook/docs/.vuepress/client.js'
|
||||
|
||||
export const clientConfigs = [
|
||||
clientConfig0,
|
||||
@ -25,5 +24,4 @@ export const clientConfigs = [
|
||||
clientConfig9,
|
||||
clientConfig10,
|
||||
clientConfig11,
|
||||
clientConfig12,
|
||||
].map((m) => m.default).filter(Boolean)
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
export const siteData = JSON.parse("{\"base\":\"/dma_handbook/\",\"lang\":\"zh-CN\",\"title\":\"DMA服务人员服务操作手册\",\"description\":\"DMA服务人员服务操作手册\",\"head\":[[\"meta\",{\"name\":\"og:type\",\"content\":\"website\"}],[\"meta\",{\"property\":\"og:title\",\"content\":\"DMA服务人员操作手册\"}],[\"meta\",{\"name\":\"description\",\"content\":\"DMA服务操作手册\"}],[\"meta\",{\"property\":\"og:description\",\"content\":\"DMA服务全流程操作指南\"}],[\"meta\",{\"property\":\"og:image\",\"content\":\"https://images.health.ufutx.com/202503/12/1f227399ffc2ddbf6c58eafa80627d19.png?v=1770021719831\"}],[\"link\",{\"rel\":\"icon\",\"href\":\"https://images.health.ufutx.com/202503/12/1f227399ffc2ddbf6c58eafa80627d19.png?v=1770021719831\"}]],\"locales\":{}}")
|
||||
export const siteData = JSON.parse("{\"base\":\"/dma_handbook/\",\"lang\":\"zh-CN\",\"title\":\"DMA服务人员服务操作手册\",\"description\":\"DMA服务人员服务操作手册\",\"head\":[[\"meta\",{\"name\":\"og:type\",\"content\":\"website\"}],[\"meta\",{\"property\":\"og:title\",\"content\":\"DMA服务人员操作手册\"}],[\"meta\",{\"name\":\"description\",\"content\":\"DMA服务操作手册\"}],[\"meta\",{\"property\":\"og:description\",\"content\":\"DMA服务全流程操作指南\"}],[\"meta\",{\"property\":\"og:image\",\"content\":\"https://images.health.ufutx.com/202503/12/1f227399ffc2ddbf6c58eafa80627d19.png?v=1770343814876\"}],[\"link\",{\"rel\":\"icon\",\"href\":\"https://images.health.ufutx.com/202503/12/1f227399ffc2ddbf6c58eafa80627d19.png?v=1770343814876\"}]],\"locales\":{}}")
|
||||
|
||||
if (import.meta.webpackHot) {
|
||||
import.meta.webpackHot.accept()
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import comp from "D:/xue/dma_handbook/docs/.vuepress/.temp/pages/index.html.vue"
|
||||
const data = JSON.parse("{\"path\":\"/\",\"title\":\"首页\",\"lang\":\"zh-CN\",\"frontmatter\":{},\"headers\":[{\"level\":2,\"title\":\"一、手册目的\",\"slug\":\"一、手册目的\",\"link\":\"#一、手册目的\",\"children\":[]},{\"level\":2,\"title\":\"二、适用范围\",\"slug\":\"二、适用范围\",\"link\":\"#二、适用范围\",\"children\":[]},{\"level\":2,\"title\":\"三、核心原则\",\"slug\":\"三、核心原则\",\"link\":\"#三、核心原则\",\"children\":[]},{\"level\":2,\"title\":\"四、岗位权责\",\"slug\":\"四、岗位权责\",\"link\":\"#四、岗位权责\",\"children\":[{\"level\":3,\"title\":\"(一)行政\",\"slug\":\"一-行政\",\"link\":\"#一-行政\",\"children\":[]},{\"level\":3,\"title\":\"(二)客服\",\"slug\":\"二-客服\",\"link\":\"#二-客服\",\"children\":[]},{\"level\":3,\"title\":\"(三)健康管理师\",\"slug\":\"三-健康管理师\",\"link\":\"#三-健康管理师\",\"children\":[]},{\"level\":3,\"title\":\"(四)系统审核员\",\"slug\":\"四-系统审核员\",\"link\":\"#四-系统审核员\",\"children\":[]},{\"level\":3,\"title\":\"(五)主教练、副教练\",\"slug\":\"五-主教练、副教练\",\"link\":\"#五-主教练、副教练\",\"children\":[]}]},{\"level\":2,\"title\":\"五、服务规范与沟通话术\",\"slug\":\"五、服务规范与沟通话术\",\"link\":\"#五、服务规范与沟通话术\",\"children\":[{\"level\":3,\"title\":\"(一)仪容仪表规范\",\"slug\":\"一-仪容仪表规范\",\"link\":\"#一-仪容仪表规范\",\"children\":[]},{\"level\":3,\"title\":\"(二)沟通话术规范\",\"slug\":\"二-沟通话术规范\",\"link\":\"#二-沟通话术规范\",\"children\":[]}]},{\"level\":2,\"title\":\"六、系统工具使用说明\",\"slug\":\"六、系统工具使用说明\",\"link\":\"#六、系统工具使用说明\",\"children\":[{\"level\":3,\"title\":\"(一)后台系统常用功能\",\"slug\":\"一-后台系统常用功能\",\"link\":\"#一-后台系统常用功能\",\"children\":[]},{\"level\":3,\"title\":\"(二)群聊管理工具使用\",\"slug\":\"二-群聊管理工具使用\",\"link\":\"#二-群聊管理工具使用\",\"children\":[]}]},{\"level\":2,\"title\":\"七、考核与反馈机制\",\"slug\":\"七、考核与反馈机制\",\"link\":\"#七、考核与反馈机制\",\"children\":[{\"level\":3,\"title\":\"(一)考核指标\",\"slug\":\"一-考核指标\",\"link\":\"#一-考核指标\",\"children\":[]},{\"level\":3,\"title\":\"(二)反馈渠道\",\"slug\":\"二-反馈渠道\",\"link\":\"#二-反馈渠道\",\"children\":[]}]},{\"level\":2,\"title\":\"八、更新日志\",\"slug\":\"八、更新日志\",\"link\":\"#八、更新日志\",\"children\":[]},{\"level\":2,\"title\":\"附录:流程节点时效汇总表\",\"slug\":\"附录-流程节点时效汇总表\",\"link\":\"#附录-流程节点时效汇总表\",\"children\":[]}],\"git\":{\"updatedTime\":1766471007000,\"contributors\":[{\"name\":\"lanzhihui\",\"username\":\"\",\"email\":\"503792708@qq.com\",\"commits\":4}],\"changelog\":[{\"hash\":\"326fedda6067ab0da7a7c497e8fef608057cb12e\",\"time\":1766471007000,\"email\":\"503792708@qq.com\",\"author\":\"lanzhihui\",\"message\":\"update\"},{\"hash\":\"169908d04e7a4ef15ffea1d8ca58004c9c7451c4\",\"time\":1762222814000,\"email\":\"503792708@qq.com\",\"author\":\"lanzhihui\",\"message\":\"update\"},{\"hash\":\"7799842e4c8bfd3bbd24d9cbc89c8ac4c28c918b\",\"time\":1761103662000,\"email\":\"503792708@qq.com\",\"author\":\"lanzhihui\",\"message\":\"更新\"},{\"hash\":\"e73bbe09086600f49aec344301695549746ba3c4\",\"time\":1759135896000,\"email\":\"503792708@qq.com\",\"author\":\"lanzhihui\",\"message\":\"初始化\"}]},\"filePathRelative\":\"README.md\"}")
|
||||
const data = JSON.parse("{\"path\":\"/\",\"title\":\"首页\",\"lang\":\"zh-CN\",\"frontmatter\":{},\"headers\":[{\"level\":2,\"title\":\"一、手册目的\",\"slug\":\"一、手册目的\",\"link\":\"#一、手册目的\",\"children\":[]},{\"level\":2,\"title\":\"二、适用范围\",\"slug\":\"二、适用范围\",\"link\":\"#二、适用范围\",\"children\":[]},{\"level\":2,\"title\":\"三、核心原则\",\"slug\":\"三、核心原则\",\"link\":\"#三、核心原则\",\"children\":[]},{\"level\":2,\"title\":\"四、岗位权责\",\"slug\":\"四、岗位权责\",\"link\":\"#四、岗位权责\",\"children\":[{\"level\":3,\"title\":\"(一)行政\",\"slug\":\"一-行政\",\"link\":\"#一-行政\",\"children\":[]},{\"level\":3,\"title\":\"(二)客服\",\"slug\":\"二-客服\",\"link\":\"#二-客服\",\"children\":[]},{\"level\":3,\"title\":\"(三)健康管理师\",\"slug\":\"三-健康管理师\",\"link\":\"#三-健康管理师\",\"children\":[]},{\"level\":3,\"title\":\"(四)系统审核员\",\"slug\":\"四-系统审核员\",\"link\":\"#四-系统审核员\",\"children\":[]},{\"level\":3,\"title\":\"(五)主教练、副教练\",\"slug\":\"五-主教练、副教练\",\"link\":\"#五-主教练、副教练\",\"children\":[]}]},{\"level\":2,\"title\":\"五、服务规范与沟通话术\",\"slug\":\"五、服务规范与沟通话术\",\"link\":\"#五、服务规范与沟通话术\",\"children\":[{\"level\":3,\"title\":\"(一)仪容仪表规范\",\"slug\":\"一-仪容仪表规范\",\"link\":\"#一-仪容仪表规范\",\"children\":[]},{\"level\":3,\"title\":\"(二)沟通话术规范\",\"slug\":\"二-沟通话术规范\",\"link\":\"#二-沟通话术规范\",\"children\":[]}]},{\"level\":2,\"title\":\"六、系统工具使用说明\",\"slug\":\"六、系统工具使用说明\",\"link\":\"#六、系统工具使用说明\",\"children\":[{\"level\":3,\"title\":\"(一)后台系统常用功能\",\"slug\":\"一-后台系统常用功能\",\"link\":\"#一-后台系统常用功能\",\"children\":[]},{\"level\":3,\"title\":\"(二)群聊管理工具使用\",\"slug\":\"二-群聊管理工具使用\",\"link\":\"#二-群聊管理工具使用\",\"children\":[]}]},{\"level\":2,\"title\":\"七、考核与反馈机制\",\"slug\":\"七、考核与反馈机制\",\"link\":\"#七、考核与反馈机制\",\"children\":[{\"level\":3,\"title\":\"(一)考核指标\",\"slug\":\"一-考核指标\",\"link\":\"#一-考核指标\",\"children\":[]},{\"level\":3,\"title\":\"(二)反馈渠道\",\"slug\":\"二-反馈渠道\",\"link\":\"#二-反馈渠道\",\"children\":[]}]},{\"level\":2,\"title\":\"八、更新日志\",\"slug\":\"八、更新日志\",\"link\":\"#八、更新日志\",\"children\":[]},{\"level\":2,\"title\":\"附录:流程节点时效汇总表\",\"slug\":\"附录-流程节点时效汇总表\",\"link\":\"#附录-流程节点时效汇总表\",\"children\":[]}],\"git\":{\"updatedTime\":1770258280000,\"contributors\":[{\"name\":\"lanzhihui\",\"username\":\"\",\"email\":\"503792708@qq.com\",\"commits\":5}],\"changelog\":[{\"hash\":\"118aab4f3bb5c4790ce2ecfc3c5897cfd7146161\",\"time\":1770258280000,\"email\":\"503792708@qq.com\",\"author\":\"lanzhihui\",\"message\":\"增加登录功能和权限验证\"},{\"hash\":\"326fedda6067ab0da7a7c497e8fef608057cb12e\",\"time\":1766471007000,\"email\":\"503792708@qq.com\",\"author\":\"lanzhihui\",\"message\":\"update\"},{\"hash\":\"169908d04e7a4ef15ffea1d8ca58004c9c7451c4\",\"time\":1762222814000,\"email\":\"503792708@qq.com\",\"author\":\"lanzhihui\",\"message\":\"update\"},{\"hash\":\"7799842e4c8bfd3bbd24d9cbc89c8ac4c28c918b\",\"time\":1761103662000,\"email\":\"503792708@qq.com\",\"author\":\"lanzhihui\",\"message\":\"更新\"},{\"hash\":\"e73bbe09086600f49aec344301695549746ba3c4\",\"time\":1759135896000,\"email\":\"503792708@qq.com\",\"author\":\"lanzhihui\",\"message\":\"初始化\"}]},\"filePathRelative\":\"README.md\"}")
|
||||
export { comp, data }
|
||||
|
||||
if (import.meta.webpackHot) {
|
||||
|
||||
File diff suppressed because one or more lines are too long
@ -12,9 +12,6 @@
|
||||
<p>您可通过以下方式查看手环电量:</p>
|
||||
<ul>
|
||||
<li>
|
||||
<p>直接查看手环屏幕,通常会显示电量百分比;</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>打开友福同享APP,进入「设备管理」页面,找到对应手环设备,即可查看实时电量信息。</p>
|
||||
</li>
|
||||
<li>
|
||||
@ -22,7 +19,7 @@
|
||||
</li>
|
||||
<li>
|
||||
<p>也可以通过APP手环首页顶部电量百分比查看,电量低于30%的情况,请及时充电。</p>
|
||||
<longPic src="https://images.health.ufutx.com/202408/16/d2b5ca33bd970f64a6301fa75ae2eb221723775855837.jpeg"></longPic><p>后续会规划低电量预警警告提醒功能,请耐心等待。</p>
|
||||
<longPic src="https://images.health.ufutx.com/202602/05/ef2e5a95d213ba80b022eff89877fd1c.jpg"></longPic><p>后续会规划低电量预警警告提醒功能,请耐心等待。</p>
|
||||
</li>
|
||||
</ul>
|
||||
<h3 id="_4-手环正确佩戴方式是什么" tabindex="-1"><a class="header-anchor" href="#_4-手环正确佩戴方式是什么"><span>4. 手环正确佩戴方式是什么?</span></a></h3>
|
||||
@ -124,7 +121,7 @@
|
||||
<p><strong><a href="https://images.health.ufutx.com/202410/15/2024101401.mp4" target="_blank" rel="noopener noreferrer">点击查看使用健康体脂秤用视频</a></strong></p>
|
||||
</li>
|
||||
</ul>
|
||||
<h3 id="_14-购买25800元友福同享dma智能健康方案-它包含哪些服务-及相关的流程是什么" tabindex="-1"><a class="header-anchor" href="#_14-购买25800元友福同享dma智能健康方案-它包含哪些服务-及相关的流程是什么"><span>14. 购买25800元友福同享DMA智能健康方案,它包含哪些服务,及相关的流程是什么?</span></a></h3>
|
||||
<h3 id="_14-购买友福同享dma智能健康方案-它包含哪些服务-及相关的流程是什么" tabindex="-1"><a class="header-anchor" href="#_14-购买友福同享dma智能健康方案-它包含哪些服务-及相关的流程是什么"><span>14. 购买友福同享DMA智能健康方案,它包含哪些服务,及相关的流程是什么?</span></a></h3>
|
||||
<p>友福同享DMA智能健康方案包含以下服务与流程(具体以实际为准,建议咨询客服确认):</p>
|
||||
<ul>
|
||||
<li>
|
||||
@ -304,7 +301,7 @@
|
||||
<div class="hint-container tip">
|
||||
<p class="hint-container-title">✅ 支持换货的情形</p>
|
||||
<ul>
|
||||
<li>非电池原因导致 <strong>屏幕无法显示</strong> 或 <strong>无法测量数据</strong>;</li>
|
||||
<li>非电池原因导致 <strong>无法测量数据</strong>;</li>
|
||||
<li>出厂即存在功能缺陷。</li>
|
||||
</ul>
|
||||
</div>
|
||||
@ -325,7 +322,7 @@
|
||||
<ol>
|
||||
<li>
|
||||
<p><strong>客服介入</strong><br>
|
||||
由 DMA 服务群内的专属客服全程跟进换货事宜。</p>
|
||||
由DMA群里的客服跟进。</p>
|
||||
</li>
|
||||
<li>
|
||||
<p><strong>资料收集与申请</strong><br>
|
||||
@ -338,11 +335,36 @@
|
||||
<span class="line"> - 手环 / 体脂秤</span>
|
||||
<span class="line"> - 若为手环,请注明类型:A(已测试)或 B(未拆封)</span>
|
||||
<span class="line"> - 是否需同步配发 Type-C 转 USB 转换头?</span>
|
||||
<span class="line"></span>
|
||||
<span class="line"></span>
|
||||
<span class="line"></span>
|
||||
<span class="line"></span></code></pre>
|
||||
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div></li>
|
||||
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div></li>
|
||||
<li>
|
||||
<p><strong>正在方案用户处理</strong><br>
|
||||
对于正在方案中的用户,可以同步配送新机和退货;</p>
|
||||
</li>
|
||||
<li>
|
||||
<p><strong>已完成方案用户处理</strong><br>
|
||||
对于已完成方案的用户,需要先将旧的商品退回我司;</p>
|
||||
</li>
|
||||
<li>
|
||||
<p><strong>退货跟进</strong><br>
|
||||
退货:由服务群的客服跟进,以确保用户会处理退货;并提供相关的退货快递单号,方便公司收件跟进。</p>
|
||||
</li>
|
||||
<li>
|
||||
<p><strong>退货寄件要求</strong><br>
|
||||
用户寄回商品,采用到付方式,收件信息如下:</p>
|
||||
<div class="language-text line-numbers-mode" data-highlighter="prismjs" data-ext="text"><pre v-pre><code><span class="line">收件人: 陈声飞 </span>
|
||||
<span class="line">手机号码: 13471927441 </span>
|
||||
<span class="line">收件地址: 广东省深圳市南山区南山街道东滨路阳光科创中心B座3302 </span>
|
||||
<span class="line"></span></code></pre>
|
||||
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div></li>
|
||||
<li>
|
||||
<p><strong>新机出库配送</strong><br>
|
||||
当更换的物料(手环或体脂秤)准备好后,通知客服来领取相关物料。双方确认物料齐全后出库,由客服发快递寄出。如果客服不在深圳,由供应链工作人员代发邮寄,但需客服根据邮寄照片确认物料齐全。</p>
|
||||
</li>
|
||||
<li>
|
||||
<p><strong>用户通知</strong><br>
|
||||
客服在DMA用户群发送快递单号,通知用户留意查收。</p>
|
||||
</li>
|
||||
</ol>
|
||||
<h2 id="四、培训业务类" tabindex="-1"><a class="header-anchor" href="#四、培训业务类"><span>四、培训业务类</span></a></h2>
|
||||
<h3 id="_1-友福同享健康教练双证报考条件是什么" tabindex="-1"><a class="header-anchor" href="#_1-友福同享健康教练双证报考条件是什么"><span>1. 友福同享健康教练双证报考条件是什么?</span></a></h3>
|
||||
|
||||
@ -2,12 +2,10 @@
|
||||
<h2 id="一、进入「收益提现」模块" tabindex="-1"><a class="header-anchor" href="#一、进入「收益提现」模块"><span>一、进入「收益提现」模块</span></a></h2>
|
||||
<p><strong>操作步骤</strong>:</p>
|
||||
<ol>
|
||||
<li>打开APP,点击底部导航栏的 <strong>【应用】</strong> 模块。</li>
|
||||
<li>在【应用】界面,选择 <strong>「智能健康」入口</strong>,进入对应页面。</li>
|
||||
<li>打开APP,点击底部导航栏的 <strong>【我的】</strong> 模块。</li>
|
||||
<li>在【我的】界面,选择 <strong>「我的收益」入口</strong>,进入对应页面。</li>
|
||||
</ol>
|
||||
<img alt="" src="/images/shareBenefit/img.png" loading="lazy" style="width:300px;height:auto;marginTop:10px;">
|
||||
<br>
|
||||
<img alt="" src="/images/shareBenefit/img_1.png" loading="lazy" style="width:300px;height:auto;marginTop:10px;">
|
||||
<img alt="" src="https://images.health.ufutx.com/202602/05/a159dc901155fc12d1e9510dbe46c3b3.png" loading="lazy" style="width:300px;height:auto;marginTop:10px;">
|
||||
<h2 id="二、提现操作流程-分润订单提现" tabindex="-1"><a class="header-anchor" href="#二、提现操作流程-分润订单提现"><span>二、提现操作流程(分润订单提现)</span></a></h2>
|
||||
<h3 id="_2-1-发起提现申请" tabindex="-1"><a class="header-anchor" href="#_2-1-发起提现申请"><span>2.1 发起提现申请</span></a></h3>
|
||||
<ol>
|
||||
|
||||
@ -60,49 +60,49 @@ export default defineClientConfig({
|
||||
|
||||
// 全局路由守卫:VuePress 2.x 适配版(白名单+未登录跳登录)
|
||||
const whiteList = ['/login.html'] // 无需登录的页面
|
||||
// 隐藏登录功能
|
||||
// router.beforeEach(async (to, from, next) => {
|
||||
// const userStore = useUserStore()
|
||||
// const isLogin = userStore.isLogin
|
||||
//
|
||||
// // 白名单页面,直接放行
|
||||
// if (whiteList.includes(to.path)) {
|
||||
// next()
|
||||
// return
|
||||
// }
|
||||
//
|
||||
// // 未登录:跳登录页并记录跳转前地址(适配base: /dma_handbook/)
|
||||
// // 替换client.js中路由守卫的未登录跳转代码
|
||||
// if (!isLogin) {
|
||||
// showToast('请先登录后访问')
|
||||
// // 核心修复:直接使用to.fullPath(已包含SITE_BASE),无需手动拼接
|
||||
// let redirectPath = to.fullPath
|
||||
// // 兜底校验:极端情况若fullPath未带SITE_BASE,手动拼接(防止地址栏手动修改)
|
||||
// if (!redirectPath.startsWith(SITE_BASE)) {
|
||||
// redirectPath = `${SITE_BASE}${redirectPath.replace(/^\//, '')}` // 去掉开头的/,避免双斜杠
|
||||
// }
|
||||
// // 编码后拼接登录页地址
|
||||
// const redirect = encodeURIComponent(redirectPath)
|
||||
// window.location.href = `${SITE_BASE}login.html?redirect=${redirect}`
|
||||
// return
|
||||
// }
|
||||
// // 核心修改:仅【已登录 + 未拉取过用户信息】时,才调用接口
|
||||
// if (!userStore.isUserInfoFetched) {
|
||||
// await getUserInfo(userStore)
|
||||
// // 拉取成功后,更新标记为true(本次会话不再重复调用)
|
||||
// userStore.setUserInfoFetched(true)
|
||||
// }
|
||||
// // 已登录,正常放行
|
||||
// next()
|
||||
// })
|
||||
|
||||
// 全局退出登录方法:6. 挂载到window,所有环境(Markdown/组件)都能调用
|
||||
window.$logout = () => {
|
||||
const userStore = useUserStore()
|
||||
userStore.resetStore() // 清除Pinia+localStorage状态
|
||||
showToast('退出登录成功')
|
||||
window.location.href = `${SITE_BASE}login.html`
|
||||
if (typeof window !== 'undefined') {
|
||||
return
|
||||
}
|
||||
// 隐藏登录功能
|
||||
router.beforeEach(async (to, from, next) => {
|
||||
const userStore = useUserStore()
|
||||
const isLogin = userStore.isLogin
|
||||
|
||||
// 白名单页面,直接放行
|
||||
if (whiteList.includes(to.path)) {
|
||||
next()
|
||||
return
|
||||
}
|
||||
if (typeof window == 'undefined') {
|
||||
next()
|
||||
return
|
||||
}
|
||||
// 未登录:跳登录页并记录跳转前地址(适配base: /dma_handbook/)
|
||||
// 替换client.js中路由守卫的未登录跳转代码
|
||||
if (!isLogin) {
|
||||
showToast('请先登录后访问')
|
||||
// 核心修复:直接使用to.fullPath(已包含SITE_BASE),无需手动拼接
|
||||
let redirectPath = to.fullPath
|
||||
// 兜底校验:极端情况若fullPath未带SITE_BASE,手动拼接(防止地址栏手动修改)
|
||||
if (!redirectPath.startsWith(SITE_BASE)) {
|
||||
redirectPath = `${SITE_BASE}${redirectPath.replace(/^\//, '')}` // 去掉开头的/,避免双斜杠
|
||||
}
|
||||
// 编码后拼接登录页地址
|
||||
const redirect = encodeURIComponent(redirectPath)
|
||||
window.location.href = `${SITE_BASE}login.html?redirect=${redirect}`
|
||||
return
|
||||
}
|
||||
// 核心修改:仅【已登录 + 未拉取过用户信息】时,才调用接口
|
||||
if (!userStore.isUserInfoFetched) {
|
||||
await getUserInfo(userStore)
|
||||
// 拉取成功后,更新标记为true(本次会话不再重复调用)
|
||||
userStore.setUserInfoFetched(true)
|
||||
}
|
||||
// 已登录,正常放行
|
||||
next()
|
||||
})
|
||||
|
||||
|
||||
},
|
||||
setup() {},
|
||||
})
|
||||
|
||||
@ -40,6 +40,9 @@ const redirect = ref('');
|
||||
|
||||
// 初始化,获取跳转前地址
|
||||
onMounted(() => {
|
||||
if (typeof window === "undefined"){
|
||||
return
|
||||
}
|
||||
const searchParams = new URLSearchParams(window.location.search);
|
||||
console.log(searchParams,'searchParams');
|
||||
// 获取URL中的redirect参数
|
||||
|
||||
@ -3,7 +3,7 @@ import { defaultTheme } from '@vuepress/theme-default'
|
||||
import { defineUserConfig } from 'vuepress'
|
||||
import fs from 'fs-extra'
|
||||
import path from 'path'
|
||||
import { searchPlugin } from '@vuepress/plugin-search'
|
||||
// import { searchPlugin } from '@vuepress/plugin-search'
|
||||
// 核心修改:从全局常量文件导入,替代本地定义
|
||||
import { SITE_BASE, CDN_BASE} from './constants.js';
|
||||
// import * as path from "path";
|
||||
@ -276,16 +276,16 @@ export default defineUserConfig({
|
||||
}
|
||||
}
|
||||
}],
|
||||
searchPlugin({
|
||||
// 可选:自定义最大建议条数
|
||||
maxSuggestions: 10,
|
||||
|
||||
// 可选:设置触发搜索的快捷键(支持多个)
|
||||
hotKeys: ['s', '/'],
|
||||
|
||||
// 可选:自定义搜索索引字段(默认包含 title 和 frontmatter)
|
||||
// getExtraFields: (page) => page.frontmatter.tags,
|
||||
}),
|
||||
// searchPlugin({
|
||||
// // 可选:自定义最大建议条数
|
||||
// maxSuggestions: 10,
|
||||
//
|
||||
// // 可选:设置触发搜索的快捷键(支持多个)
|
||||
// hotKeys: ['s', '/'],
|
||||
//
|
||||
// // 可选:自定义搜索索引字段(默认包含 title 和 frontmatter)
|
||||
// // getExtraFields: (page) => page.frontmatter.tags,
|
||||
// }),
|
||||
// registerComponentsPlugin({
|
||||
// // 配置项
|
||||
// componentsDir: path.resolve(__dirname, '../../', 'components'), // 自动注册全局组件,
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
import { defineStore } from 'pinia'
|
||||
export const useUserStore = defineStore('user', {
|
||||
state: () => ({
|
||||
token: localStorage.getItem('rt_token') || '',
|
||||
userInfo: JSON.parse(localStorage.getItem('userInfo') || '{}'),
|
||||
roles: JSON.parse(localStorage.getItem('roles') || '[]'),
|
||||
token: typeof window !== 'undefined' ? localStorage.getItem('rt_token') || '' :'',
|
||||
userInfo: typeof window !== 'undefined' ? JSON.parse(localStorage.getItem('userInfo') || '{}') : {},
|
||||
roles: typeof window !== 'undefined' ? JSON.parse(localStorage.getItem('roles') || '[]') : [],
|
||||
// 新增:会话级标记(是否已拉取过用户信息,不持久化,刷新自动重置)
|
||||
isUserInfoFetched: false
|
||||
}),
|
||||
@ -15,12 +15,16 @@ export const useUserStore = defineStore('user', {
|
||||
// 确保该方法存在:设置用户信息
|
||||
setUserInfo(userInfo) {
|
||||
this.userInfo = userInfo;
|
||||
localStorage.setItem('userInfo', JSON.stringify(userInfo)); // 持久化到本地
|
||||
if (typeof window !== 'undefined') {
|
||||
localStorage.setItem('userInfo', JSON.stringify(userInfo)); // 持久化到本地
|
||||
}
|
||||
},
|
||||
// 确保该方法存在:设置权限角色
|
||||
setRoles(roleList) {
|
||||
this.roles = roleList;
|
||||
localStorage.setItem('roles', JSON.stringify(roleList)); // 持久化到本地
|
||||
if (typeof window !== 'undefined') {
|
||||
localStorage.setItem('roles', JSON.stringify(roleList)); // 持久化到本地
|
||||
}
|
||||
},
|
||||
// 新增:更新用户信息拉取标记
|
||||
setUserInfoFetched(status) {
|
||||
@ -30,13 +34,17 @@ export const useUserStore = defineStore('user', {
|
||||
this.token = ''
|
||||
this.userInfo = {}
|
||||
this.roles = []
|
||||
localStorage.removeItem('rt_token')
|
||||
localStorage.removeItem('userInfo')
|
||||
localStorage.removeItem('roles')
|
||||
if (typeof window !== 'undefined') {
|
||||
localStorage.removeItem('rt_token')
|
||||
localStorage.removeItem('userInfo')
|
||||
localStorage.removeItem('roles')
|
||||
}
|
||||
},
|
||||
setToken(token) {
|
||||
this.token = token
|
||||
localStorage.setItem('rt_token', token)
|
||||
if (typeof window !== 'undefined') {
|
||||
localStorage.setItem('rt_token', token)
|
||||
}
|
||||
},
|
||||
// 其他setUserInfo/setRoles方法...
|
||||
},
|
||||
|
||||
@ -17,12 +17,11 @@ Type-C充电接口具备充电速度快、支持双向充电、接口可逆插
|
||||
|
||||
### 3. 手环电量怎么查看?
|
||||
您可通过以下方式查看手环电量:
|
||||
- 直接查看手环屏幕,通常会显示电量百分比;
|
||||
- 打开友福同享APP,进入「设备管理」页面,找到对应手环设备,即可查看实时电量信息。
|
||||
- 按下手环右侧按钮查看显示灯颜色,绿灯表示电量充足,正常使用没有问题。红灯闪烁表示电量不足,指示灯不亮表示没有电,请及时充电。
|
||||
- 也可以通过APP手环首页顶部电量百分比查看,电量低于30%的情况,请及时充电。
|
||||
|
||||
<longPic src="https://images.health.ufutx.com/202408/16/d2b5ca33bd970f64a6301fa75ae2eb221723775855837.jpeg"></longPic>
|
||||
<longPic src="https://images.health.ufutx.com/202602/05/ef2e5a95d213ba80b022eff89877fd1c.jpg"></longPic>
|
||||
|
||||
后续会规划低电量预警警告提醒功能,请耐心等待。
|
||||
|
||||
@ -116,7 +115,7 @@ Type-C充电接口具备充电速度快、支持双向充电、接口可逆插
|
||||
- **[点击查看使用健康体脂秤用视频](https://images.health.ufutx.com/202410/15/2024101401.mp4)**
|
||||
|
||||
|
||||
### 14. 购买25800元友福同享DMA智能健康方案,它包含哪些服务,及相关的流程是什么?
|
||||
### 14. 购买友福同享DMA智能健康方案,它包含哪些服务,及相关的流程是什么?
|
||||
友福同享DMA智能健康方案包含以下服务与流程(具体以实际为准,建议咨询客服确认):
|
||||
- **服务内容**:专属健康评估、定制运动计划、营养膳食指导、定期健康监测(含手环、体脂秤等设备使用)、健康教练在线咨询等;
|
||||
- **服务流程**:支付成功后,客服将联系您预约健康评估,随后根据评估结果定制方案,配送设备并指导使用,后续将定期跟踪健康数据并调整方案。
|
||||
@ -270,7 +269,7 @@ DMA健康方案的体检项目通常包括(具体以实际套餐为准):
|
||||
#### (二)体脂秤换货标准
|
||||
|
||||
::: tip ✅ 支持换货的情形
|
||||
- 非电池原因导致 **屏幕无法显示** 或 **无法测量数据**;
|
||||
- 非电池原因导致 **无法测量数据**;
|
||||
- 出厂即存在功能缺陷。
|
||||
:::
|
||||
|
||||
@ -289,7 +288,7 @@ DMA健康方案的体检项目通常包括(具体以实际套餐为准):
|
||||
### 3、不良设备换货操作流程
|
||||
|
||||
1. **客服介入**
|
||||
由 DMA 服务群内的专属客服全程跟进换货事宜。
|
||||
由DMA群里的客服跟进。
|
||||
|
||||
2. **资料收集与申请**
|
||||
客服需整理以下信息,并通过微信发送至 **“友福审核”** 申请新设备:
|
||||
@ -303,7 +302,23 @@ DMA健康方案的体检项目通常包括(具体以实际套餐为准):
|
||||
- 手环 / 体脂秤
|
||||
- 若为手环,请注明类型:A(已测试)或 B(未拆封)
|
||||
- 是否需同步配发 Type-C 转 USB 转换头?
|
||||
3. **正在方案用户处理**
|
||||
对于正在方案中的用户,可以同步配送新机和退货;
|
||||
|
||||
4. **已完成方案用户处理**
|
||||
对于已完成方案的用户,需要先将旧的商品退回我司;
|
||||
5. **退货跟进**
|
||||
退货:由服务群的客服跟进,以确保用户会处理退货;并提供相关的退货快递单号,方便公司收件跟进。
|
||||
6. **退货寄件要求**
|
||||
用户寄回商品,采用到付方式,收件信息如下:
|
||||
```text
|
||||
收件人: 陈声飞
|
||||
手机号码: 13471927441
|
||||
收件地址: 广东省深圳市南山区南山街道东滨路阳光科创中心B座3302
|
||||
7. **新机出库配送**
|
||||
当更换的物料(手环或体脂秤)准备好后,通知客服来领取相关物料。双方确认物料齐全后出库,由客服发快递寄出。如果客服不在深圳,由供应链工作人员代发邮寄,但需客服根据邮寄照片确认物料齐全。
|
||||
8. **用户通知**
|
||||
客服在DMA用户群发送快递单号,通知用户留意查收。
|
||||
|
||||
|
||||
## 四、培训业务类
|
||||
|
||||
@ -3,13 +3,11 @@
|
||||
|
||||
## 一、进入「收益提现」模块
|
||||
**操作步骤**:
|
||||
1. 打开APP,点击底部导航栏的 **【应用】** 模块。
|
||||
2. 在【应用】界面,选择 **「智能健康」入口**,进入对应页面。
|
||||
1. 打开APP,点击底部导航栏的 **【我的】** 模块。
|
||||
2. 在【我的】界面,选择 **「我的收益」入口**,进入对应页面。
|
||||
|
||||
[//]: # ( )
|
||||
<img alt="" src="/images/shareBenefit/img.png" loading="lazy" style="width:300px;height:auto;marginTop:10px;">
|
||||
<br>
|
||||
<img alt="" src="/images/shareBenefit/img_1.png" loading="lazy" style="width:300px;height:auto;marginTop:10px;">
|
||||
<img alt="" src="https://images.health.ufutx.com/202602/05/a159dc901155fc12d1e9510dbe46c3b3.png" loading="lazy" style="width:300px;height:auto;marginTop:10px;">
|
||||
|
||||
|
||||
|
||||
|
||||
@ -2,8 +2,10 @@ import { PERMISSIONS } from '../.vuepress/roles';
|
||||
import axios from 'axios'
|
||||
export function getCurrentUserRole() {
|
||||
console.log('32-')
|
||||
// 从store或localStorage获取用户角色
|
||||
return localStorage.getItem('userRole') || 'coach';
|
||||
if (typeof window !== 'undefined') {
|
||||
// 从store或localStorage获取用户角色
|
||||
return localStorage.getItem('userRole') || 'coach';
|
||||
}
|
||||
}
|
||||
|
||||
export function checkPermission(currentRole, requiredPath) {
|
||||
@ -18,7 +20,9 @@ const allowedPaths = PERMISSIONS[currentRole] || [];
|
||||
}
|
||||
|
||||
export function isLoggedIn() {
|
||||
return !!localStorage.getItem('authToken');
|
||||
if (typeof window !== 'undefined') {
|
||||
return !!localStorage.getItem('authToken');
|
||||
}
|
||||
}
|
||||
|
||||
export function showLoginModal() {
|
||||
@ -27,7 +31,9 @@ export function showLoginModal() {
|
||||
|
||||
// 添加登录API调用方法
|
||||
export async function login(credentials) {
|
||||
const response = await axios.post('/api/login', credentials);
|
||||
localStorage.setItem('authToken', response.data.token);
|
||||
localStorage.setItem('userRole', response.data.role);
|
||||
if (typeof window !== 'undefined') {
|
||||
const response = await axios.post('/api/login', credentials);
|
||||
localStorage.setItem('authToken', response.data.token);
|
||||
localStorage.setItem('userRole', response.data.role);
|
||||
}
|
||||
}
|
||||
|
||||
@ -6,7 +6,9 @@
|
||||
export function backFillLoginData(res, userStore) {
|
||||
if (res.token) {
|
||||
userStore.setToken(res.token);
|
||||
localStorage.setItem('rt_token', res.token);
|
||||
if (typeof window !== 'undefined'){
|
||||
localStorage.setItem('rt_token', res.token);
|
||||
}
|
||||
}
|
||||
if (res.userInfo) {
|
||||
userStore.setUserInfo(res.userInfo);
|
||||
|
||||
@ -58,7 +58,7 @@ service.interceptors.request.use(
|
||||
// 携带Token(仅保留核心rt_token,联动Pinia)
|
||||
if (isBrowser) {
|
||||
const userStore = useUserStore();
|
||||
const token = userStore.token || localStorage.getItem('rt_token') || '';
|
||||
const token = userStore.token || typeof window !== 'undefined' ? localStorage.getItem('rt_token') : '' || '';
|
||||
if (token) config.headers['Authorization'] = `Bearer ${token}`;
|
||||
}
|
||||
// 处理POST表单参数
|
||||
@ -100,7 +100,9 @@ service.interceptors.response.use(
|
||||
const userStore = useUserStore();
|
||||
// 清除状态,跳登录页并记录跳转地址
|
||||
userStore.resetStore();
|
||||
localStorage.removeItem('rt_token');
|
||||
if (typeof window !== 'undefined') {
|
||||
localStorage.removeItem('rt_token');
|
||||
}
|
||||
const redirect = encodeURIComponent(window.location.href);
|
||||
window.location.href = `/dma_handbook/login?redirect=${redirect}`;
|
||||
}
|
||||
|
||||
10
package-lock.json
generated
10
package-lock.json
generated
@ -12,7 +12,7 @@
|
||||
"@fortawesome/fontawesome-free": "^6.7.2",
|
||||
"@vuepress/plugin-medium-zoom": "^2.0.0-rc.86",
|
||||
"@vueuse/core": "^13.5.0",
|
||||
"axios": "^1.10.0",
|
||||
"axios": "^1.12.0",
|
||||
"pinia": "^3.0.3",
|
||||
"vue-router": "^4.5.1",
|
||||
"vuepress-plugin-seo": "^0.2.0"
|
||||
@ -2728,13 +2728,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/axios": {
|
||||
"version": "1.10.0",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-1.10.0.tgz",
|
||||
"integrity": "sha512-/1xYAC4MP/HEG+3duIhFr4ZQXR4sQXOIe+o6sdqzeykGLx6Upp/1p8MHqhINOvGeP7xyNHe7tsiJByc4SSVUxw==",
|
||||
"version": "1.13.4",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-1.13.4.tgz",
|
||||
"integrity": "sha512-1wVkUaAO6WyaYtCkcYCOx12ZgpGf9Zif+qXa4n+oYzK558YryKqiL6UWwd5DqiH3VRW0GYhTZQ/vlgJrCoNQlg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"follow-redirects": "^1.15.6",
|
||||
"form-data": "^4.0.0",
|
||||
"form-data": "^4.0.4",
|
||||
"proxy-from-env": "^1.1.0"
|
||||
}
|
||||
},
|
||||
|
||||
@ -21,7 +21,6 @@
|
||||
"dependencies": {
|
||||
"@fortawesome/fontawesome-free": "^6.7.2",
|
||||
"@vuepress/plugin-medium-zoom": "^2.0.0-rc.86",
|
||||
"@vuepress/plugin-search": "^2.0.0-rc.86",
|
||||
"@vueuse/core": "^13.5.0",
|
||||
"axios": "^1.12.0",
|
||||
"pinia": "^3.0.3",
|
||||
|
||||
Loading…
Reference in New Issue
Block a user