王文杰 8 months ago
parent afc252ed32
commit b43f705aac

@ -3,6 +3,3 @@
npm run lint-staged
#//
npm run lint

@ -0,0 +1,29 @@
{
"hash": "99c6afa7",
"browserHash": "cd41f883",
"optimized": {
"vue": {
"src": "../../node_modules/vue/dist/vue.runtime.esm-bundler.js",
"file": "vue.js",
"fileHash": "89e69c76",
"needsInterop": false
},
"pinia": {
"src": "../../node_modules/pinia/dist/pinia.mjs",
"file": "pinia.js",
"fileHash": "73db4f45",
"needsInterop": false
},
"pinia-plugin-persistedstate": {
"src": "../../node_modules/pinia-plugin-persistedstate/dist/index.mjs",
"file": "pinia-plugin-persistedstate.js",
"fileHash": "e1c37dbb",
"needsInterop": false
}
},
"chunks": {
"chunk-IH3XMDLU": {
"file": "chunk-IH3XMDLU.js"
}
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

@ -0,0 +1,3 @@
{
"type": "module"
}

@ -0,0 +1,138 @@
// node_modules/pinia-plugin-persistedstate/dist/index.mjs
function isObject(v) {
return typeof v === "object" && v !== null;
}
function normalizeOptions(options, factoryOptions) {
options = isObject(options) ? options : /* @__PURE__ */ Object.create(null);
return new Proxy(options, {
get(target, key, receiver) {
if (key === "key")
return Reflect.get(target, key, receiver);
return Reflect.get(target, key, receiver) || Reflect.get(factoryOptions, key, receiver);
}
});
}
function get(state, path) {
return path.reduce((obj, p) => {
return obj == null ? void 0 : obj[p];
}, state);
}
function set(state, path, val) {
return path.slice(0, -1).reduce((obj, p) => {
if (/^(__proto__)$/.test(p))
return {};
else
return obj[p] = obj[p] || {};
}, state)[path[path.length - 1]] = val, state;
}
function pick(baseState, paths) {
return paths.reduce((substate, path) => {
const pathArray = path.split(".");
return set(substate, pathArray, get(baseState, pathArray));
}, {});
}
function parsePersistence(factoryOptions, store) {
return (o) => {
var _a;
try {
const {
storage = localStorage,
beforeRestore = void 0,
afterRestore = void 0,
serializer = {
serialize: JSON.stringify,
deserialize: JSON.parse
},
key = store.$id,
paths = null,
debug = false
} = o;
return {
storage,
beforeRestore,
afterRestore,
serializer,
key: ((_a = factoryOptions.key) != null ? _a : (k) => k)(typeof key == "string" ? key : key(store.$id)),
paths,
debug
};
} catch (e) {
if (o.debug)
console.error("[pinia-plugin-persistedstate]", e);
return null;
}
};
}
function hydrateStore(store, { storage, serializer, key, debug }) {
try {
const fromStorage = storage == null ? void 0 : storage.getItem(key);
if (fromStorage)
store.$patch(serializer == null ? void 0 : serializer.deserialize(fromStorage));
} catch (e) {
if (debug)
console.error("[pinia-plugin-persistedstate]", e);
}
}
function persistState(state, { storage, serializer, key, paths, debug }) {
try {
const toStore = Array.isArray(paths) ? pick(state, paths) : state;
storage.setItem(key, serializer.serialize(toStore));
} catch (e) {
if (debug)
console.error("[pinia-plugin-persistedstate]", e);
}
}
function createPersistedState(factoryOptions = {}) {
return (context) => {
const { auto = false } = factoryOptions;
const {
options: { persist = auto },
store,
pinia
} = context;
if (!persist)
return;
if (!(store.$id in pinia.state.value)) {
const original_store = pinia._s.get(store.$id.replace("__hot:", ""));
if (original_store)
Promise.resolve().then(() => original_store.$persist());
return;
}
const persistences = (Array.isArray(persist) ? persist.map((p) => normalizeOptions(p, factoryOptions)) : [normalizeOptions(persist, factoryOptions)]).map(parsePersistence(factoryOptions, store)).filter(Boolean);
store.$persist = () => {
persistences.forEach((persistence) => {
persistState(store.$state, persistence);
});
};
store.$hydrate = ({ runHooks = true } = {}) => {
persistences.forEach((persistence) => {
const { beforeRestore, afterRestore } = persistence;
if (runHooks)
beforeRestore == null ? void 0 : beforeRestore(context);
hydrateStore(store, persistence);
if (runHooks)
afterRestore == null ? void 0 : afterRestore(context);
});
};
persistences.forEach((persistence) => {
const { beforeRestore, afterRestore } = persistence;
beforeRestore == null ? void 0 : beforeRestore(context);
hydrateStore(store, persistence);
afterRestore == null ? void 0 : afterRestore(context);
store.$subscribe(
(_mutation, state) => {
persistState(state, persistence);
},
{
detached: true
}
);
});
};
}
var src_default = createPersistedState();
export {
createPersistedState,
src_default as default
};
//# sourceMappingURL=pinia-plugin-persistedstate.js.map

@ -0,0 +1,7 @@
{
"version": 3,
"sources": ["../../node_modules/pinia-plugin-persistedstate/dist/index.mjs"],
"sourcesContent": ["// src/normalize.ts\nfunction isObject(v) {\n return typeof v === \"object\" && v !== null;\n}\nfunction normalizeOptions(options, factoryOptions) {\n options = isObject(options) ? options : /* @__PURE__ */ Object.create(null);\n return new Proxy(options, {\n get(target, key, receiver) {\n if (key === \"key\")\n return Reflect.get(target, key, receiver);\n return Reflect.get(target, key, receiver) || Reflect.get(factoryOptions, key, receiver);\n }\n });\n}\n\n// src/pick.ts\nfunction get(state, path) {\n return path.reduce((obj, p) => {\n return obj == null ? void 0 : obj[p];\n }, state);\n}\nfunction set(state, path, val) {\n return path.slice(0, -1).reduce((obj, p) => {\n if (/^(__proto__)$/.test(p))\n return {};\n else\n return obj[p] = obj[p] || {};\n }, state)[path[path.length - 1]] = val, state;\n}\nfunction pick(baseState, paths) {\n return paths.reduce((substate, path) => {\n const pathArray = path.split(\".\");\n return set(substate, pathArray, get(baseState, pathArray));\n }, {});\n}\n\n// src/plugin.ts\nfunction parsePersistence(factoryOptions, store) {\n return (o) => {\n var _a;\n try {\n const {\n storage = localStorage,\n beforeRestore = void 0,\n afterRestore = void 0,\n serializer = {\n serialize: JSON.stringify,\n deserialize: JSON.parse\n },\n key = store.$id,\n paths = null,\n debug = false\n } = o;\n return {\n storage,\n beforeRestore,\n afterRestore,\n serializer,\n key: ((_a = factoryOptions.key) != null ? _a : (k) => k)(typeof key == \"string\" ? key : key(store.$id)),\n paths,\n debug\n };\n } catch (e) {\n if (o.debug)\n console.error(\"[pinia-plugin-persistedstate]\", e);\n return null;\n }\n };\n}\nfunction hydrateStore(store, { storage, serializer, key, debug }) {\n try {\n const fromStorage = storage == null ? void 0 : storage.getItem(key);\n if (fromStorage)\n store.$patch(serializer == null ? void 0 : serializer.deserialize(fromStorage));\n } catch (e) {\n if (debug)\n console.error(\"[pinia-plugin-persistedstate]\", e);\n }\n}\nfunction persistState(state, { storage, serializer, key, paths, debug }) {\n try {\n const toStore = Array.isArray(paths) ? pick(state, paths) : state;\n storage.setItem(key, serializer.serialize(toStore));\n } catch (e) {\n if (debug)\n console.error(\"[pinia-plugin-persistedstate]\", e);\n }\n}\nfunction createPersistedState(factoryOptions = {}) {\n return (context) => {\n const { auto = false } = factoryOptions;\n const {\n options: { persist = auto },\n store,\n pinia\n } = context;\n if (!persist)\n return;\n if (!(store.$id in pinia.state.value)) {\n const original_store = pinia._s.get(store.$id.replace(\"__hot:\", \"\"));\n if (original_store)\n Promise.resolve().then(() => original_store.$persist());\n return;\n }\n const persistences = (Array.isArray(persist) ? persist.map((p) => normalizeOptions(p, factoryOptions)) : [normalizeOptions(persist, factoryOptions)]).map(parsePersistence(factoryOptions, store)).filter(Boolean);\n store.$persist = () => {\n persistences.forEach((persistence) => {\n persistState(store.$state, persistence);\n });\n };\n store.$hydrate = ({ runHooks = true } = {}) => {\n persistences.forEach((persistence) => {\n const { beforeRestore, afterRestore } = persistence;\n if (runHooks)\n beforeRestore == null ? void 0 : beforeRestore(context);\n hydrateStore(store, persistence);\n if (runHooks)\n afterRestore == null ? void 0 : afterRestore(context);\n });\n };\n persistences.forEach((persistence) => {\n const { beforeRestore, afterRestore } = persistence;\n beforeRestore == null ? void 0 : beforeRestore(context);\n hydrateStore(store, persistence);\n afterRestore == null ? void 0 : afterRestore(context);\n store.$subscribe(\n (_mutation, state) => {\n persistState(state, persistence);\n },\n {\n detached: true\n }\n );\n });\n };\n}\n\n// src/index.ts\nvar src_default = createPersistedState();\nexport {\n createPersistedState,\n src_default as default\n};\n"],
"mappings": ";AACA,SAAS,SAAS,GAAG;AACnB,SAAO,OAAO,MAAM,YAAY,MAAM;AACxC;AACA,SAAS,iBAAiB,SAAS,gBAAgB;AACjD,YAAU,SAAS,OAAO,IAAI,UAA0B,uBAAO,OAAO,IAAI;AAC1E,SAAO,IAAI,MAAM,SAAS;AAAA,IACxB,IAAI,QAAQ,KAAK,UAAU;AACzB,UAAI,QAAQ;AACV,eAAO,QAAQ,IAAI,QAAQ,KAAK,QAAQ;AAC1C,aAAO,QAAQ,IAAI,QAAQ,KAAK,QAAQ,KAAK,QAAQ,IAAI,gBAAgB,KAAK,QAAQ;AAAA,IACxF;AAAA,EACF,CAAC;AACH;AAGA,SAAS,IAAI,OAAO,MAAM;AACxB,SAAO,KAAK,OAAO,CAAC,KAAK,MAAM;AAC7B,WAAO,OAAO,OAAO,SAAS,IAAI,CAAC;AAAA,EACrC,GAAG,KAAK;AACV;AACA,SAAS,IAAI,OAAO,MAAM,KAAK;AAC7B,SAAO,KAAK,MAAM,GAAG,EAAE,EAAE,OAAO,CAAC,KAAK,MAAM;AAC1C,QAAI,gBAAgB,KAAK,CAAC;AACxB,aAAO,CAAC;AAAA;AAER,aAAO,IAAI,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC;AAAA,EAC/B,GAAG,KAAK,EAAE,KAAK,KAAK,SAAS,CAAC,CAAC,IAAI,KAAK;AAC1C;AACA,SAAS,KAAK,WAAW,OAAO;AAC9B,SAAO,MAAM,OAAO,CAAC,UAAU,SAAS;AACtC,UAAM,YAAY,KAAK,MAAM,GAAG;AAChC,WAAO,IAAI,UAAU,WAAW,IAAI,WAAW,SAAS,CAAC;AAAA,EAC3D,GAAG,CAAC,CAAC;AACP;AAGA,SAAS,iBAAiB,gBAAgB,OAAO;AAC/C,SAAO,CAAC,MAAM;AACZ,QAAI;AACJ,QAAI;AACF,YAAM;AAAA,QACJ,UAAU;AAAA,QACV,gBAAgB;AAAA,QAChB,eAAe;AAAA,QACf,aAAa;AAAA,UACX,WAAW,KAAK;AAAA,UAChB,aAAa,KAAK;AAAA,QACpB;AAAA,QACA,MAAM,MAAM;AAAA,QACZ,QAAQ;AAAA,QACR,QAAQ;AAAA,MACV,IAAI;AACJ,aAAO;AAAA,QACL;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,OAAO,KAAK,eAAe,QAAQ,OAAO,KAAK,CAAC,MAAM,GAAG,OAAO,OAAO,WAAW,MAAM,IAAI,MAAM,GAAG,CAAC;AAAA,QACtG;AAAA,QACA;AAAA,MACF;AAAA,IACF,SAAS,GAAG;AACV,UAAI,EAAE;AACJ,gBAAQ,MAAM,iCAAiC,CAAC;AAClD,aAAO;AAAA,IACT;AAAA,EACF;AACF;AACA,SAAS,aAAa,OAAO,EAAE,SAAS,YAAY,KAAK,MAAM,GAAG;AAChE,MAAI;AACF,UAAM,cAAc,WAAW,OAAO,SAAS,QAAQ,QAAQ,GAAG;AAClE,QAAI;AACF,YAAM,OAAO,cAAc,OAAO,SAAS,WAAW,YAAY,WAAW,CAAC;AAAA,EAClF,SAAS,GAAG;AACV,QAAI;AACF,cAAQ,MAAM,iCAAiC,CAAC;AAAA,EACpD;AACF;AACA,SAAS,aAAa,OAAO,EAAE,SAAS,YAAY,KAAK,OAAO,MAAM,GAAG;AACvE,MAAI;AACF,UAAM,UAAU,MAAM,QAAQ,KAAK,IAAI,KAAK,OAAO,KAAK,IAAI;AAC5D,YAAQ,QAAQ,KAAK,WAAW,UAAU,OAAO,CAAC;AAAA,EACpD,SAAS,GAAG;AACV,QAAI;AACF,cAAQ,MAAM,iCAAiC,CAAC;AAAA,EACpD;AACF;AACA,SAAS,qBAAqB,iBAAiB,CAAC,GAAG;AACjD,SAAO,CAAC,YAAY;AAClB,UAAM,EAAE,OAAO,MAAM,IAAI;AACzB,UAAM;AAAA,MACJ,SAAS,EAAE,UAAU,KAAK;AAAA,MAC1B;AAAA,MACA;AAAA,IACF,IAAI;AACJ,QAAI,CAAC;AACH;AACF,QAAI,EAAE,MAAM,OAAO,MAAM,MAAM,QAAQ;AACrC,YAAM,iBAAiB,MAAM,GAAG,IAAI,MAAM,IAAI,QAAQ,UAAU,EAAE,CAAC;AACnE,UAAI;AACF,gBAAQ,QAAQ,EAAE,KAAK,MAAM,eAAe,SAAS,CAAC;AACxD;AAAA,IACF;AACA,UAAM,gBAAgB,MAAM,QAAQ,OAAO,IAAI,QAAQ,IAAI,CAAC,MAAM,iBAAiB,GAAG,cAAc,CAAC,IAAI,CAAC,iBAAiB,SAAS,cAAc,CAAC,GAAG,IAAI,iBAAiB,gBAAgB,KAAK,CAAC,EAAE,OAAO,OAAO;AACjN,UAAM,WAAW,MAAM;AACrB,mBAAa,QAAQ,CAAC,gBAAgB;AACpC,qBAAa,MAAM,QAAQ,WAAW;AAAA,MACxC,CAAC;AAAA,IACH;AACA,UAAM,WAAW,CAAC,EAAE,WAAW,KAAK,IAAI,CAAC,MAAM;AAC7C,mBAAa,QAAQ,CAAC,gBAAgB;AACpC,cAAM,EAAE,eAAe,aAAa,IAAI;AACxC,YAAI;AACF,2BAAiB,OAAO,SAAS,cAAc,OAAO;AACxD,qBAAa,OAAO,WAAW;AAC/B,YAAI;AACF,0BAAgB,OAAO,SAAS,aAAa,OAAO;AAAA,MACxD,CAAC;AAAA,IACH;AACA,iBAAa,QAAQ,CAAC,gBAAgB;AACpC,YAAM,EAAE,eAAe,aAAa,IAAI;AACxC,uBAAiB,OAAO,SAAS,cAAc,OAAO;AACtD,mBAAa,OAAO,WAAW;AAC/B,sBAAgB,OAAO,SAAS,aAAa,OAAO;AACpD,YAAM;AAAA,QACJ,CAAC,WAAW,UAAU;AACpB,uBAAa,OAAO,WAAW;AAAA,QACjC;AAAA,QACA;AAAA,UACE,UAAU;AAAA,QACZ;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH;AACF;AAGA,IAAI,cAAc,qBAAqB;",
"names": []
}

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

@ -0,0 +1,323 @@
import {
BaseTransition,
BaseTransitionPropsValidators,
Comment,
DeprecationTypes,
EffectScope,
ErrorCodes,
ErrorTypeStrings,
Fragment,
KeepAlive,
ReactiveEffect,
Static,
Suspense,
Teleport,
Text,
TrackOpTypes,
Transition,
TransitionGroup,
TriggerOpTypes,
VueElement,
assertNumber,
callWithAsyncErrorHandling,
callWithErrorHandling,
camelize,
capitalize,
cloneVNode,
compatUtils,
compile,
computed,
createApp,
createBaseVNode,
createBlock,
createCommentVNode,
createElementBlock,
createHydrationRenderer,
createPropsRestProxy,
createRenderer,
createSSRApp,
createSlots,
createStaticVNode,
createTextVNode,
createVNode,
customRef,
defineAsyncComponent,
defineComponent,
defineCustomElement,
defineEmits,
defineExpose,
defineModel,
defineOptions,
defineProps,
defineSSRCustomElement,
defineSlots,
devtools,
effect,
effectScope,
getCurrentInstance,
getCurrentScope,
getTransitionRawChildren,
guardReactiveProps,
h,
handleError,
hasInjectionContext,
hydrate,
initCustomFormatter,
initDirectivesForSSR,
inject,
isMemoSame,
isProxy,
isReactive,
isReadonly,
isRef,
isRuntimeOnly,
isShallow,
isVNode,
markRaw,
mergeDefaults,
mergeModels,
mergeProps,
nextTick,
normalizeClass,
normalizeProps,
normalizeStyle,
onActivated,
onBeforeMount,
onBeforeUnmount,
onBeforeUpdate,
onDeactivated,
onErrorCaptured,
onMounted,
onRenderTracked,
onRenderTriggered,
onScopeDispose,
onServerPrefetch,
onUnmounted,
onUpdated,
openBlock,
popScopeId,
provide,
proxyRefs,
pushScopeId,
queuePostFlushCb,
reactive,
readonly,
ref,
registerRuntimeCompiler,
render,
renderList,
renderSlot,
resolveComponent,
resolveDirective,
resolveDynamicComponent,
resolveFilter,
resolveTransitionHooks,
setBlockTracking,
setDevtoolsHook,
setTransitionHooks,
shallowReactive,
shallowReadonly,
shallowRef,
ssrContextKey,
ssrUtils,
stop,
toDisplayString,
toHandlerKey,
toHandlers,
toRaw,
toRef,
toRefs,
toValue,
transformVNodeArgs,
triggerRef,
unref,
useAttrs,
useCssModule,
useCssVars,
useModel,
useSSRContext,
useSlots,
useTransitionState,
vModelCheckbox,
vModelDynamic,
vModelRadio,
vModelSelect,
vModelText,
vShow,
version,
warn,
watch,
watchEffect,
watchPostEffect,
watchSyncEffect,
withAsyncContext,
withCtx,
withDefaults,
withDirectives,
withKeys,
withMemo,
withModifiers,
withScopeId
} from "./chunk-IH3XMDLU.js";
export {
BaseTransition,
BaseTransitionPropsValidators,
Comment,
DeprecationTypes,
EffectScope,
ErrorCodes,
ErrorTypeStrings,
Fragment,
KeepAlive,
ReactiveEffect,
Static,
Suspense,
Teleport,
Text,
TrackOpTypes,
Transition,
TransitionGroup,
TriggerOpTypes,
VueElement,
assertNumber,
callWithAsyncErrorHandling,
callWithErrorHandling,
camelize,
capitalize,
cloneVNode,
compatUtils,
compile,
computed,
createApp,
createBlock,
createCommentVNode,
createElementBlock,
createBaseVNode as createElementVNode,
createHydrationRenderer,
createPropsRestProxy,
createRenderer,
createSSRApp,
createSlots,
createStaticVNode,
createTextVNode,
createVNode,
customRef,
defineAsyncComponent,
defineComponent,
defineCustomElement,
defineEmits,
defineExpose,
defineModel,
defineOptions,
defineProps,
defineSSRCustomElement,
defineSlots,
devtools,
effect,
effectScope,
getCurrentInstance,
getCurrentScope,
getTransitionRawChildren,
guardReactiveProps,
h,
handleError,
hasInjectionContext,
hydrate,
initCustomFormatter,
initDirectivesForSSR,
inject,
isMemoSame,
isProxy,
isReactive,
isReadonly,
isRef,
isRuntimeOnly,
isShallow,
isVNode,
markRaw,
mergeDefaults,
mergeModels,
mergeProps,
nextTick,
normalizeClass,
normalizeProps,
normalizeStyle,
onActivated,
onBeforeMount,
onBeforeUnmount,
onBeforeUpdate,
onDeactivated,
onErrorCaptured,
onMounted,
onRenderTracked,
onRenderTriggered,
onScopeDispose,
onServerPrefetch,
onUnmounted,
onUpdated,
openBlock,
popScopeId,
provide,
proxyRefs,
pushScopeId,
queuePostFlushCb,
reactive,
readonly,
ref,
registerRuntimeCompiler,
render,
renderList,
renderSlot,
resolveComponent,
resolveDirective,
resolveDynamicComponent,
resolveFilter,
resolveTransitionHooks,
setBlockTracking,
setDevtoolsHook,
setTransitionHooks,
shallowReactive,
shallowReadonly,
shallowRef,
ssrContextKey,
ssrUtils,
stop,
toDisplayString,
toHandlerKey,
toHandlers,
toRaw,
toRef,
toRefs,
toValue,
transformVNodeArgs,
triggerRef,
unref,
useAttrs,
useCssModule,
useCssVars,
useModel,
useSSRContext,
useSlots,
useTransitionState,
vModelCheckbox,
vModelDynamic,
vModelRadio,
vModelSelect,
vModelText,
vShow,
version,
warn,
watch,
watchEffect,
watchPostEffect,
watchSyncEffect,
withAsyncContext,
withCtx,
withDefaults,
withDirectives,
withKeys,
withMemo,
withModifiers,
withScopeId
};
//# sourceMappingURL=vue.js.map

@ -0,0 +1,7 @@
{
"version": 3,
"sources": [],
"sourcesContent": [],
"mappings": "",
"names": []
}

@ -9,5 +9,6 @@
"files.associations": {
"pages.json": "jsonc", // pages.json
"manifest.json": "jsonc" // manifest.json
}
},
"eggHelper.serverPort": 53488
}

@ -1,29 +1,32 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<script>
var coverSupport =
'CSS' in window &&
typeof CSS.supports === 'function' &&
(CSS.supports('top: env(a)') || CSS.supports('top: constant(a)'))
document.write(
'<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0' +
(coverSupport ? ', viewport-fit=cover' : '') +
'" />',
)
</script>
<title></title>
<!--preload-links-->
<!--app-context-->
</head>
<body>
<div id="app">
<!--app-html-->
</div>
<script type="module" src="/src/main.ts"></script>
// <script>
<head>
<meta charset="UTF-8" />
<script>
var coverSupport =
'CSS' in window &&
typeof CSS.supports === 'function' &&
(CSS.supports('top: env(a)') || CSS.supports('top: constant(a)'))
document.write(
'<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0' +
(coverSupport ? ', viewport-fit=cover' : '') +
'" />',
)
</script>
<title></title>
<!--preload-links-->
<!--app-context-->
</head>
<body>
<div id="app">
<!--app-html-->
</div>
<script type="module" src="/src/main.ts"></script>
//
<script>
// var _hmt = _hmt || []
// ;(function () {
// var hm = document.createElement('script')
@ -31,6 +34,9 @@
// var s = document.getElementsByTagName('script')[0]
// s.parentNode.insertBefore(hm, s)
// })()
// </script>
</body>
//
</script>
</body>
</html>

142
package-lock.json generated

@ -48,10 +48,12 @@
"husky": "^8.0.0",
"lint-staged": "^13.0.3",
"miniprogram-api-typings": "^3.12.0",
"mockjs": "^1.1.0",
"prettier": "^2.7.1",
"sass": "^1.56.1",
"typescript": "^5.1.6",
"vite": "^4.0.3",
"vite-plugin-mock": "^3.0.1",
"vue-tsc": "^1.8.8"
}
},
@ -4629,6 +4631,12 @@
"integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==",
"dev": true
},
"node_modules/@types/mockjs": {
"version": "1.0.10",
"resolved": "https://r.cnpmjs.org/@types/mockjs/-/mockjs-1.0.10.tgz",
"integrity": "sha512-SXgrhajHG7boLv6oU93CcmdDm0HYRiceuz6b+7z+/2lCJPTWDv0V5YiwFHT2ejE4bQqgSXQiVPQYPWv7LGsK1g==",
"dev": true
},
"node_modules/@types/node": {
"version": "18.19.4",
"resolved": "https://r.cnpmjs.org/@types/node/-/node-18.19.4.tgz",
@ -5952,6 +5960,21 @@
"integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
"devOptional": true
},
"node_modules/bundle-require": {
"version": "4.0.2",
"resolved": "https://r.cnpmjs.org/bundle-require/-/bundle-require-4.0.2.tgz",
"integrity": "sha512-jwzPOChofl67PSTW2SGubV9HBQAhhR2i6nskiOThauo9dzwDUgOWQScFVaJkjEfYX+UXiD+LEx8EblQMc2wIag==",
"dev": true,
"dependencies": {
"load-tsconfig": "^0.2.3"
},
"engines": {
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
},
"peerDependencies": {
"esbuild": ">=0.17"
}
},
"node_modules/bytes": {
"version": "3.1.2",
"resolved": "https://r.cnpmjs.org/bytes/-/bytes-3.1.2.tgz",
@ -6257,6 +6280,75 @@
"integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
"dev": true
},
"node_modules/connect": {
"version": "3.7.0",
"resolved": "https://r2.cnpmjs.org/connect/-/connect-3.7.0.tgz",
"integrity": "sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ==",
"dev": true,
"dependencies": {
"debug": "2.6.9",
"finalhandler": "1.1.2",
"parseurl": "~1.3.3",
"utils-merge": "1.0.1"
},
"engines": {
"node": ">= 0.10.0"
}
},
"node_modules/connect/node_modules/debug": {
"version": "2.6.9",
"resolved": "https://r2.cnpmjs.org/debug/-/debug-2.6.9.tgz",
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
"dev": true,
"dependencies": {
"ms": "2.0.0"
}
},
"node_modules/connect/node_modules/finalhandler": {
"version": "1.1.2",
"resolved": "https://r2.cnpmjs.org/finalhandler/-/finalhandler-1.1.2.tgz",
"integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==",
"dev": true,
"dependencies": {
"debug": "2.6.9",
"encodeurl": "~1.0.2",
"escape-html": "~1.0.3",
"on-finished": "~2.3.0",
"parseurl": "~1.3.3",
"statuses": "~1.5.0",
"unpipe": "~1.0.0"
},
"engines": {
"node": ">= 0.8"
}
},
"node_modules/connect/node_modules/ms": {
"version": "2.0.0",
"resolved": "https://r2.cnpmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
"dev": true
},
"node_modules/connect/node_modules/on-finished": {
"version": "2.3.0",
"resolved": "https://r2.cnpmjs.org/on-finished/-/on-finished-2.3.0.tgz",
"integrity": "sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==",
"dev": true,
"dependencies": {
"ee-first": "1.1.1"
},
"engines": {
"node": ">= 0.8"
}
},
"node_modules/connect/node_modules/statuses": {
"version": "1.5.0",
"resolved": "https://r2.cnpmjs.org/statuses/-/statuses-1.5.0.tgz",
"integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==",
"dev": true,
"engines": {
"node": ">= 0.6"
}
},
"node_modules/content-disposition": {
"version": "0.5.4",
"resolved": "https://r2.cnpmjs.org/content-disposition/-/content-disposition-0.5.4.tgz",
@ -10392,6 +10484,15 @@
"node": ">=4"
}
},
"node_modules/load-tsconfig": {
"version": "0.2.5",
"resolved": "https://r.cnpmjs.org/load-tsconfig/-/load-tsconfig-0.2.5.tgz",
"integrity": "sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg==",
"dev": true,
"engines": {
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
}
},
"node_modules/loader-utils": {
"version": "3.2.1",
"resolved": "https://r.cnpmjs.org/loader-utils/-/loader-utils-3.2.1.tgz",
@ -10717,6 +10818,18 @@
"mkdirp": "bin/cmd.js"
}
},
"node_modules/mockjs": {
"version": "1.1.0",
"resolved": "https://r2.cnpmjs.org/mockjs/-/mockjs-1.1.0.tgz",
"integrity": "sha512-eQsKcWzIaZzEZ07NuEyO4Nw65g0hdWAyurVol1IPl1gahRwY+svqzfgfey8U8dahLwG44d6/RwEzuK52rSa/JQ==",
"dev": true,
"dependencies": {
"commander": "*"
},
"bin": {
"random": "bin/random"
}
},
"node_modules/module-alias": {
"version": "2.2.3",
"resolved": "https://r.cnpmjs.org/module-alias/-/module-alias-2.2.3.tgz",
@ -12831,6 +12944,35 @@
}
}
},
"node_modules/vite-plugin-mock": {
"version": "3.0.1",
"resolved": "https://r.cnpmjs.org/vite-plugin-mock/-/vite-plugin-mock-3.0.1.tgz",
"integrity": "sha512-jEqRkX6Ts6z9e3sPrktcmujLGTIjxMwMZUhcgoo1q0dEMcljMBkZgJK1vMaetTm+GfOy2NkGVQOwVqLS/Vy6Uw==",
"dev": true,
"dependencies": {
"@types/mockjs": "^1.0.7",
"bundle-require": "^4.0.1",
"chokidar": "^3.5.3",
"connect": "^3.7.0",
"debug": "^4.3.4",
"fast-glob": "^3.2.12",
"path-to-regexp": "^6.2.1",
"picocolors": "^1.0.0"
},
"engines": {
"node": ">=16.0.0"
},
"peerDependencies": {
"mockjs": ">=1.1.0",
"vite": ">=4.0.0"
}
},
"node_modules/vite-plugin-mock/node_modules/path-to-regexp": {
"version": "6.2.1",
"resolved": "https://r.cnpmjs.org/path-to-regexp/-/path-to-regexp-6.2.1.tgz",
"integrity": "sha512-JLyh7xT1kizaEvcaXOQwOc2/Yhw6KZOvPf1S8401UyLk86CU79LN3vl7ztXGm/pZ+YjoyAJ4rxmHwbkBXJX+yw==",
"dev": true
},
"node_modules/vite/node_modules/@esbuild/android-arm": {
"version": "0.18.20",
"resolved": "https://r.cnpmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz",

@ -1,5 +1,5 @@
{
"appid": "wx8481e8716cf8d9e9",
"appid": "wxf82bcc798891a29d",
"compileType": "miniprogram",
"libVersion": "3.3.0",
"packOptions": {

2
src/env.d.ts vendored

@ -1,6 +1,6 @@
/// <reference types="vite/client" />
declare module '*.vue' {
//@ts-ignore
import { DefineComponent } from 'vue'
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/ban-types
const component: DefineComponent<{}, {}, any>

@ -0,0 +1,923 @@
/*
* @Author: 王文杰
* @Date: 2019-03-05 14:39:24
* @LastEditors: 王文杰
* @LastEditTime: 2024-01-30 16:59:47
* @FilePath: /app-nx-recycle/src/libs/qqmap-wx-jssdk1.2/qqmap-wx-jssdk.min.js
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
var ERROR_CONF = {
KEY_ERR: 311,
KEY_ERR_MSG: 'key格式错误',
PARAM_ERR: 310,
PARAM_ERR_MSG: '请求参数信息有误',
SYSTEM_ERR: 600,
SYSTEM_ERR_MSG: '系统错误',
WX_ERR_CODE: 1000,
WX_OK_CODE: 200,
}
var BASE_URL = 'https://apis.map.qq.com/ws/'
var URL_SEARCH = BASE_URL + 'place/v1/search'
var URL_SUGGESTION = BASE_URL + 'place/v1/suggestion'
var URL_GET_GEOCODER = BASE_URL + 'geocoder/v1/'
var URL_CITY_LIST = BASE_URL + 'district/v1/list'
var URL_AREA_LIST = BASE_URL + 'district/v1/getchildren'
var URL_DISTANCE = BASE_URL + 'distance/v1/'
var URL_DIRECTION = BASE_URL + 'direction/v1/'
var MODE = { driving: 'driving', transit: 'transit' }
var EARTH_RADIUS = 6378136.49
var Utils = {
safeAdd(x, y) {
var lsw = (x & 0xffff) + (y & 0xffff)
var msw = (x >> 16) + (y >> 16) + (lsw >> 16)
return (msw << 16) | (lsw & 0xffff)
},
bitRotateLeft(num, cnt) {
return (num << cnt) | (num >>> (32 - cnt))
},
md5cmn(q, a, b, x, s, t) {
return this.safeAdd(
this.bitRotateLeft(this.safeAdd(this.safeAdd(a, q), this.safeAdd(x, t)), s),
b,
)
},
md5ff(a, b, c, d, x, s, t) {
return this.md5cmn((b & c) | (~b & d), a, b, x, s, t)
},
md5gg(a, b, c, d, x, s, t) {
return this.md5cmn((b & d) | (c & ~d), a, b, x, s, t)
},
md5hh(a, b, c, d, x, s, t) {
return this.md5cmn(b ^ c ^ d, a, b, x, s, t)
},
md5ii(a, b, c, d, x, s, t) {
return this.md5cmn(c ^ (b | ~d), a, b, x, s, t)
},
binlMD5(x, len) {
x[len >> 5] |= 0x80 << len % 32
x[(((len + 64) >>> 9) << 4) + 14] = len
var i
var olda
var oldb
var oldc
var oldd
var a = 1732584193
var b = -271733879
var c = -1732584194
var d = 271733878
for (i = 0; i < x.length; i += 16) {
olda = a
oldb = b
oldc = c
oldd = d
a = this.md5ff(a, b, c, d, x[i], 7, -680876936)
d = this.md5ff(d, a, b, c, x[i + 1], 12, -389564586)
c = this.md5ff(c, d, a, b, x[i + 2], 17, 606105819)
b = this.md5ff(b, c, d, a, x[i + 3], 22, -1044525330)
a = this.md5ff(a, b, c, d, x[i + 4], 7, -176418897)
d = this.md5ff(d, a, b, c, x[i + 5], 12, 1200080426)
c = this.md5ff(c, d, a, b, x[i + 6], 17, -1473231341)
b = this.md5ff(b, c, d, a, x[i + 7], 22, -45705983)
a = this.md5ff(a, b, c, d, x[i + 8], 7, 1770035416)
d = this.md5ff(d, a, b, c, x[i + 9], 12, -1958414417)
c = this.md5ff(c, d, a, b, x[i + 10], 17, -42063)
b = this.md5ff(b, c, d, a, x[i + 11], 22, -1990404162)
a = this.md5ff(a, b, c, d, x[i + 12], 7, 1804603682)
d = this.md5ff(d, a, b, c, x[i + 13], 12, -40341101)
c = this.md5ff(c, d, a, b, x[i + 14], 17, -1502002290)
b = this.md5ff(b, c, d, a, x[i + 15], 22, 1236535329)
a = this.md5gg(a, b, c, d, x[i + 1], 5, -165796510)
d = this.md5gg(d, a, b, c, x[i + 6], 9, -1069501632)
c = this.md5gg(c, d, a, b, x[i + 11], 14, 643717713)
b = this.md5gg(b, c, d, a, x[i], 20, -373897302)
a = this.md5gg(a, b, c, d, x[i + 5], 5, -701558691)
d = this.md5gg(d, a, b, c, x[i + 10], 9, 38016083)
c = this.md5gg(c, d, a, b, x[i + 15], 14, -660478335)
b = this.md5gg(b, c, d, a, x[i + 4], 20, -405537848)
a = this.md5gg(a, b, c, d, x[i + 9], 5, 568446438)
d = this.md5gg(d, a, b, c, x[i + 14], 9, -1019803690)
c = this.md5gg(c, d, a, b, x[i + 3], 14, -187363961)
b = this.md5gg(b, c, d, a, x[i + 8], 20, 1163531501)
a = this.md5gg(a, b, c, d, x[i + 13], 5, -1444681467)
d = this.md5gg(d, a, b, c, x[i + 2], 9, -51403784)
c = this.md5gg(c, d, a, b, x[i + 7], 14, 1735328473)
b = this.md5gg(b, c, d, a, x[i + 12], 20, -1926607734)
a = this.md5hh(a, b, c, d, x[i + 5], 4, -378558)
d = this.md5hh(d, a, b, c, x[i + 8], 11, -2022574463)
c = this.md5hh(c, d, a, b, x[i + 11], 16, 1839030562)
b = this.md5hh(b, c, d, a, x[i + 14], 23, -35309556)
a = this.md5hh(a, b, c, d, x[i + 1], 4, -1530992060)
d = this.md5hh(d, a, b, c, x[i + 4], 11, 1272893353)
c = this.md5hh(c, d, a, b, x[i + 7], 16, -155497632)
b = this.md5hh(b, c, d, a, x[i + 10], 23, -1094730640)
a = this.md5hh(a, b, c, d, x[i + 13], 4, 681279174)
d = this.md5hh(d, a, b, c, x[i], 11, -358537222)
c = this.md5hh(c, d, a, b, x[i + 3], 16, -722521979)
b = this.md5hh(b, c, d, a, x[i + 6], 23, 76029189)
a = this.md5hh(a, b, c, d, x[i + 9], 4, -640364487)
d = this.md5hh(d, a, b, c, x[i + 12], 11, -421815835)
c = this.md5hh(c, d, a, b, x[i + 15], 16, 530742520)
b = this.md5hh(b, c, d, a, x[i + 2], 23, -995338651)
a = this.md5ii(a, b, c, d, x[i], 6, -198630844)
d = this.md5ii(d, a, b, c, x[i + 7], 10, 1126891415)
c = this.md5ii(c, d, a, b, x[i + 14], 15, -1416354905)
b = this.md5ii(b, c, d, a, x[i + 5], 21, -57434055)
a = this.md5ii(a, b, c, d, x[i + 12], 6, 1700485571)
d = this.md5ii(d, a, b, c, x[i + 3], 10, -1894986606)
c = this.md5ii(c, d, a, b, x[i + 10], 15, -1051523)
b = this.md5ii(b, c, d, a, x[i + 1], 21, -2054922799)
a = this.md5ii(a, b, c, d, x[i + 8], 6, 1873313359)
d = this.md5ii(d, a, b, c, x[i + 15], 10, -30611744)
c = this.md5ii(c, d, a, b, x[i + 6], 15, -1560198380)
b = this.md5ii(b, c, d, a, x[i + 13], 21, 1309151649)
a = this.md5ii(a, b, c, d, x[i + 4], 6, -145523070)
d = this.md5ii(d, a, b, c, x[i + 11], 10, -1120210379)
c = this.md5ii(c, d, a, b, x[i + 2], 15, 718787259)
b = this.md5ii(b, c, d, a, x[i + 9], 21, -343485551)
a = this.safeAdd(a, olda)
b = this.safeAdd(b, oldb)
c = this.safeAdd(c, oldc)
d = this.safeAdd(d, oldd)
}
return [a, b, c, d]
},
binl2rstr(input) {
var i
var output = ''
var length32 = input.length * 32
for (i = 0; i < length32; i += 8) {
output += String.fromCharCode((input[i >> 5] >>> i % 32) & 0xff)
}
return output
},
rstr2binl(input) {
var i
var output = []
output[(input.length >> 2) - 1] = undefined
for (i = 0; i < output.length; i += 1) {
output[i] = 0
}
var length8 = input.length * 8
for (i = 0; i < length8; i += 8) {
output[i >> 5] |= (input.charCodeAt(i / 8) & 0xff) << i % 32
}
return output
},
rstrMD5(s) {
return this.binl2rstr(this.binlMD5(this.rstr2binl(s), s.length * 8))
},
rstrHMACMD5(key, data) {
var i
var bkey = this.rstr2binl(key)
var ipad = []
var opad = []
var hash
ipad[15] = opad[15] = undefined
if (bkey.length > 16) {
bkey = this.binlMD5(bkey, key.length * 8)
}
for (i = 0; i < 16; i += 1) {
ipad[i] = bkey[i] ^ 0x36363636
opad[i] = bkey[i] ^ 0x5c5c5c5c
}
hash = this.binlMD5(ipad.concat(this.rstr2binl(data)), 512 + data.length * 8)
return this.binl2rstr(this.binlMD5(opad.concat(hash), 512 + 128))
},
rstr2hex(input) {
var hexTab = '0123456789abcdef'
var output = ''
var x
var i
for (i = 0; i < input.length; i += 1) {
x = input.charCodeAt(i)
output += hexTab.charAt((x >>> 4) & 0x0f) + hexTab.charAt(x & 0x0f)
}
return output
},
str2rstrUTF8(input) {
return unescape(encodeURIComponent(input))
},
rawMD5(s) {
return this.rstrMD5(this.str2rstrUTF8(s))
},
hexMD5(s) {
return this.rstr2hex(this.rawMD5(s))
},
rawHMACMD5(k, d) {
return this.rstrHMACMD5(this.str2rstrUTF8(k), str2rstrUTF8(d))
},
hexHMACMD5(k, d) {
return this.rstr2hex(this.rawHMACMD5(k, d))
},
md5(string, key, raw) {
if (!key) {
if (!raw) {
return this.hexMD5(string)
}
return this.rawMD5(string)
}
if (!raw) {
return this.hexHMACMD5(key, string)
}
return this.rawHMACMD5(key, string)
},
getSig(requestParam, sk, feature, mode) {
var sig = null
var requestArr = []
Object.keys(requestParam)
.sort()
.forEach(function (key) {
requestArr.push(key + '=' + requestParam[key])
})
if (feature == 'search') {
sig = '/ws/place/v1/search?' + requestArr.join('&') + sk
}
if (feature == 'suggest') {
sig = '/ws/place/v1/suggestion?' + requestArr.join('&') + sk
}
if (feature == 'reverseGeocoder') {
sig = '/ws/geocoder/v1/?' + requestArr.join('&') + sk
}
if (feature == 'geocoder') {
sig = '/ws/geocoder/v1/?' + requestArr.join('&') + sk
}
if (feature == 'getCityList') {
sig = '/ws/district/v1/list?' + requestArr.join('&') + sk
}
if (feature == 'getDistrictByCityId') {
sig = '/ws/district/v1/getchildren?' + requestArr.join('&') + sk
}
if (feature == 'calculateDistance') {
sig = '/ws/distance/v1/?' + requestArr.join('&') + sk
}
if (feature == 'direction') {
sig = '/ws/direction/v1/' + mode + '?' + requestArr.join('&') + sk
}
sig = this.md5(sig)
return sig
},
location2query(data) {
if (typeof data == 'string') {
return data
}
var query = ''
for (var i = 0; i < data.length; i++) {
var d = data[i]
if (query) {
query += ';'
}
if (d.location) {
query = query + d.location.lat + ',' + d.location.lng
}
if (d.latitude && d.longitude) {
query = query + d.latitude + ',' + d.longitude
}
}
return query
},
rad(d) {
return (d * Math.PI) / 180.0
},
getEndLocation(location) {
var to = location.split(';')
var endLocation = []
for (var i = 0; i < to.length; i++) {
endLocation.push({
lat: parseFloat(to[i].split(',')[0]),
lng: parseFloat(to[i].split(',')[1]),
})
}
return endLocation
},
getDistance(latFrom, lngFrom, latTo, lngTo) {
var radLatFrom = this.rad(latFrom)
var radLatTo = this.rad(latTo)
var a = radLatFrom - radLatTo
var b = this.rad(lngFrom) - this.rad(lngTo)
var distance =
2 *
Math.asin(
Math.sqrt(
Math.pow(Math.sin(a / 2), 2) +
Math.cos(radLatFrom) * Math.cos(radLatTo) * Math.pow(Math.sin(b / 2), 2),
),
)
distance = distance * EARTH_RADIUS
distance = Math.round(distance * 10000) / 10000
return parseFloat(distance.toFixed(0))
},
getWXLocation(success, fail, complete) {
wx.getLocation({ type: 'gcj02', success: success, fail: fail, complete: complete })
},
getLocationParam(location) {
if (typeof location == 'string') {
var locationArr = location.split(',')
if (locationArr.length === 2) {
location = { latitude: location.split(',')[0], longitude: location.split(',')[1] }
} else {
location = {}
}
}
return location
},
polyfillParam(param) {
param.success = param.success || function () {}
param.fail = param.fail || function () {}
param.complete = param.complete || function () {}
},
checkParamKeyEmpty(param, key) {
if (!param[key]) {
var errconf = this.buildErrorConfig(
ERROR_CONF.PARAM_ERR,
ERROR_CONF.PARAM_ERR_MSG + key + '参数格式有误',
)
param.fail(errconf)
param.complete(errconf)
return true
}
return false
},
checkKeyword(param) {
return !this.checkParamKeyEmpty(param, 'keyword')
},
checkLocation(param) {
var location = this.getLocationParam(param.location)
if (!location || !location.latitude || !location.longitude) {
var errconf = this.buildErrorConfig(
ERROR_CONF.PARAM_ERR,
ERROR_CONF.PARAM_ERR_MSG + ' location参数格式有误',
)
param.fail(errconf)
param.complete(errconf)
return false
}
return true
},
buildErrorConfig(errCode, errMsg) {
return { status: errCode, message: errMsg }
},
handleData(param, data, feature) {
if (feature == 'search') {
var searchResult = data.data
var searchSimplify = []
for (var i = 0; i < searchResult.length; i++) {
searchSimplify.push({
id: searchResult[i].id || null,
title: searchResult[i].title || null,
latitude: (searchResult[i].location && searchResult[i].location.lat) || null,
longitude: (searchResult[i].location && searchResult[i].location.lng) || null,
address: searchResult[i].address || null,
category: searchResult[i].category || null,
tel: searchResult[i].tel || null,
adcode: (searchResult[i].ad_info && searchResult[i].ad_info.adcode) || null,
city: (searchResult[i].ad_info && searchResult[i].ad_info.city) || null,
district: (searchResult[i].ad_info && searchResult[i].ad_info.district) || null,
province: (searchResult[i].ad_info && searchResult[i].ad_info.province) || null,
})
}
param.success(data, { searchResult: searchResult, searchSimplify: searchSimplify })
} else if (feature == 'suggest') {
var suggestResult = data.data
var suggestSimplify = []
for (var i = 0; i < suggestResult.length; i++) {
suggestSimplify.push({
adcode: suggestResult[i].adcode || null,
address: suggestResult[i].address || null,
category: suggestResult[i].category || null,
city: suggestResult[i].city || null,
district: suggestResult[i].district || null,
id: suggestResult[i].id || null,
latitude: (suggestResult[i].location && suggestResult[i].location.lat) || null,
longitude: (suggestResult[i].location && suggestResult[i].location.lng) || null,
province: suggestResult[i].province || null,
title: suggestResult[i].title || null,
type: suggestResult[i].type || null,
})
}
param.success(data, { suggestResult: suggestResult, suggestSimplify: suggestSimplify })
} else if (feature == 'reverseGeocoder') {
var reverseGeocoderResult = data.result
var reverseGeocoderSimplify = {
address: reverseGeocoderResult.address || null,
latitude: (reverseGeocoderResult.location && reverseGeocoderResult.location.lat) || null,
longitude: (reverseGeocoderResult.location && reverseGeocoderResult.location.lng) || null,
adcode: (reverseGeocoderResult.ad_info && reverseGeocoderResult.ad_info.adcode) || null,
city:
(reverseGeocoderResult.address_component &&
reverseGeocoderResult.address_component.city) ||
null,
district:
(reverseGeocoderResult.address_component &&
reverseGeocoderResult.address_component.district) ||
null,
nation:
(reverseGeocoderResult.address_component &&
reverseGeocoderResult.address_component.nation) ||
null,
province:
(reverseGeocoderResult.address_component &&
reverseGeocoderResult.address_component.province) ||
null,
street:
(reverseGeocoderResult.address_component &&
reverseGeocoderResult.address_component.street) ||
null,
street_number:
(reverseGeocoderResult.address_component &&
reverseGeocoderResult.address_component.street_number) ||
null,
recommend:
(reverseGeocoderResult.formatted_addresses &&
reverseGeocoderResult.formatted_addresses.recommend) ||
null,
rough:
(reverseGeocoderResult.formatted_addresses &&
reverseGeocoderResult.formatted_addresses.rough) ||
null,
}
if (reverseGeocoderResult.pois) {
var pois = reverseGeocoderResult.pois
var poisSimplify = []
for (var i = 0; i < pois.length; i++) {
poisSimplify.push({
id: pois[i].id || null,
title: pois[i].title || null,
latitude: (pois[i].location && pois[i].location.lat) || null,
longitude: (pois[i].location && pois[i].location.lng) || null,
address: pois[i].address || null,
category: pois[i].category || null,
adcode: (pois[i].ad_info && pois[i].ad_info.adcode) || null,
city: (pois[i].ad_info && pois[i].ad_info.city) || null,
district: (pois[i].ad_info && pois[i].ad_info.district) || null,
province: (pois[i].ad_info && pois[i].ad_info.province) || null,
})
}
param.success(data, {
reverseGeocoderResult: reverseGeocoderResult,
reverseGeocoderSimplify: reverseGeocoderSimplify,
pois: pois,
poisSimplify: poisSimplify,
})
} else {
param.success(data, {
reverseGeocoderResult: reverseGeocoderResult,
reverseGeocoderSimplify: reverseGeocoderSimplify,
})
}
} else if (feature == 'geocoder') {
var geocoderResult = data.result
var geocoderSimplify = {
title: geocoderResult.title || null,
latitude: (geocoderResult.location && geocoderResult.location.lat) || null,
longitude: (geocoderResult.location && geocoderResult.location.lng) || null,
adcode: (geocoderResult.ad_info && geocoderResult.ad_info.adcode) || null,
province:
(geocoderResult.address_components && geocoderResult.address_components.province) || null,
city: (geocoderResult.address_components && geocoderResult.address_components.city) || null,
district:
(geocoderResult.address_components && geocoderResult.address_components.district) || null,
street:
(geocoderResult.address_components && geocoderResult.address_components.street) || null,
street_number:
(geocoderResult.address_components && geocoderResult.address_components.street_number) ||
null,
level: geocoderResult.level || null,
}
param.success(data, { geocoderResult: geocoderResult, geocoderSimplify: geocoderSimplify })
} else if (feature == 'getCityList') {
var provinceResult = data.result[0]
var cityResult = data.result[1]
var districtResult = data.result[2]
param.success(data, {
provinceResult: provinceResult,
cityResult: cityResult,
districtResult: districtResult,
})
} else if (feature == 'getDistrictByCityId') {
var districtByCity = data.result[0]
param.success(data, districtByCity)
} else if (feature == 'calculateDistance') {
var calculateDistanceResult = data.result.elements
var distance = []
for (var i = 0; i < calculateDistanceResult.length; i++) {
distance.push(calculateDistanceResult[i].distance)
}
param.success(data, { calculateDistanceResult: calculateDistanceResult, distance: distance })
} else if (feature == 'direction') {
var direction = data.result.routes
param.success(data, direction)
} else {
param.success(data)
}
},
buildWxRequestConfig(param, options, feature) {
var that = this
options.header = { 'content-type': 'application/json' }
options.method = 'GET'
options.success = function (res) {
var data = res.data
if (data.status === 0) {
that.handleData(param, data, feature)
} else {
param.fail(data)
}
}
options.fail = function (res) {
res.statusCode = ERROR_CONF.WX_ERR_CODE
param.fail(that.buildErrorConfig(ERROR_CONF.WX_ERR_CODE, res.errMsg))
}
options.complete = function (res) {
var statusCode = +res.statusCode
switch (statusCode) {
case ERROR_CONF.WX_ERR_CODE: {
param.complete(that.buildErrorConfig(ERROR_CONF.WX_ERR_CODE, res.errMsg))
break
}
case ERROR_CONF.WX_OK_CODE: {
var data = res.data
if (data.status === 0) {
param.complete(data)
} else {
param.complete(that.buildErrorConfig(data.status, data.message))
}
break
}
default: {
param.complete(that.buildErrorConfig(ERROR_CONF.SYSTEM_ERR, ERROR_CONF.SYSTEM_ERR_MSG))
}
}
}
return options
},
locationProcess(param, locationsuccess, locationfail, locationcomplete) {
var that = this
locationfail =
locationfail ||
function (res) {
res.statusCode = ERROR_CONF.WX_ERR_CODE
param.fail(that.buildErrorConfig(ERROR_CONF.WX_ERR_CODE, res.errMsg))
}
locationcomplete =
locationcomplete ||
function (res) {
if (res.statusCode == ERROR_CONF.WX_ERR_CODE) {
param.complete(that.buildErrorConfig(ERROR_CONF.WX_ERR_CODE, res.errMsg))
}
}
if (!param.location) {
that.getWXLocation(locationsuccess, locationfail, locationcomplete)
} else if (that.checkLocation(param)) {
var location = Utils.getLocationParam(param.location)
locationsuccess(location)
}
},
}
class QQMapWX {
constructor(options) {
if (!options.key) {
throw Error('key值不能为空')
}
this.key = options.key
}
search(options) {
var that = this
options = options || {}
Utils.polyfillParam(options)
if (!Utils.checkKeyword(options)) {
return
}
var requestParam = {
keyword: options.keyword,
orderby: options.orderby || '_distance',
page_size: options.page_size || 10,
page_index: options.page_index || 1,
output: 'json',
key: that.key,
}
if (options.address_format) {
requestParam.address_format = options.address_format
}
if (options.filter) {
requestParam.filter = options.filter
}
var distance = options.distance || '1000'
var auto_extend = options.auto_extend || 1
var region = null
var rectangle = null
if (options.region) {
region = options.region
}
if (options.rectangle) {
rectangle = options.rectangle
}
var locationsuccess = function (result) {
if (region && !rectangle) {
requestParam.boundary =
'region(' +
region +
',' +
auto_extend +
',' +
result.latitude +
',' +
result.longitude +
')'
if (options.sig) {
requestParam.sig = Utils.getSig(requestParam, options.sig, 'search')
}
} else if (rectangle && !region) {
requestParam.boundary = 'rectangle(' + rectangle + ')'
if (options.sig) {
requestParam.sig = Utils.getSig(requestParam, options.sig, 'search')
}
} else {
requestParam.boundary =
'nearby(' +
result.latitude +
',' +
result.longitude +
',' +
distance +
',' +
auto_extend +
')'
if (options.sig) {
requestParam.sig = Utils.getSig(requestParam, options.sig, 'search')
}
}
wx.request(
Utils.buildWxRequestConfig(options, { url: URL_SEARCH, data: requestParam }, 'search'),
)
}
Utils.locationProcess(options, locationsuccess)
}
getSuggestion(options) {
var that = this
options = options || {}
Utils.polyfillParam(options)
if (!Utils.checkKeyword(options)) {
return
}
var requestParam = {
keyword: options.keyword,
region: options.region || '全国',
region_fix: options.region_fix || 0,
policy: options.policy || 0,
page_size: options.page_size || 10,
page_index: options.page_index || 1,
get_subpois: options.get_subpois || 0,
output: 'json',
key: that.key,
}
if (options.address_format) {
requestParam.address_format = options.address_format
}
if (options.filter) {
requestParam.filter = options.filter
}
if (options.location) {
var locationsuccess = function (result) {
requestParam.location = result.latitude + ',' + result.longitude
if (options.sig) {
requestParam.sig = Utils.getSig(requestParam, options.sig, 'suggest')
}
wx.request(
Utils.buildWxRequestConfig(
options,
{ url: URL_SUGGESTION, data: requestParam },
'suggest',
),
)
}
Utils.locationProcess(options, locationsuccess)
} else {
if (options.sig) {
requestParam.sig = Utils.getSig(requestParam, options.sig, 'suggest')
}
wx.request(
Utils.buildWxRequestConfig(options, { url: URL_SUGGESTION, data: requestParam }, 'suggest'),
)
}
}
reverseGeocoder(options) {
var that = this
options = options || {}
Utils.polyfillParam(options)
var requestParam = {
coord_type: options.coord_type || 5,
get_poi: options.get_poi || 0,
output: 'json',
key: that.key,
}
if (options.poi_options) {
requestParam.poi_options = options.poi_options
}
var locationsuccess = function (result) {
requestParam.location = result.latitude + ',' + result.longitude
if (options.sig) {
requestParam.sig = Utils.getSig(requestParam, options.sig, 'reverseGeocoder')
}
wx.request(
Utils.buildWxRequestConfig(
options,
{ url: URL_GET_GEOCODER, data: requestParam },
'reverseGeocoder',
),
)
}
Utils.locationProcess(options, locationsuccess)
}
geocoder(options) {
var that = this
options = options || {}
Utils.polyfillParam(options)
if (Utils.checkParamKeyEmpty(options, 'address')) {
return
}
var requestParam = { address: options.address, output: 'json', key: that.key }
if (options.region) {
requestParam.region = options.region
}
if (options.sig) {
requestParam.sig = Utils.getSig(requestParam, options.sig, 'geocoder')
}
wx.request(
Utils.buildWxRequestConfig(
options,
{ url: URL_GET_GEOCODER, data: requestParam },
'geocoder',
),
)
}
getCityList(options) {
var that = this
options = options || {}
Utils.polyfillParam(options)
var requestParam = { output: 'json', key: that.key }
if (options.sig) {
requestParam.sig = Utils.getSig(requestParam, options.sig, 'getCityList')
}
wx.request(
Utils.buildWxRequestConfig(
options,
{ url: URL_CITY_LIST, data: requestParam },
'getCityList',
),
)
}
getDistrictByCityId(options) {
var that = this
options = options || {}
Utils.polyfillParam(options)
if (Utils.checkParamKeyEmpty(options, 'id')) {
return
}
var requestParam = { id: options.id || '', output: 'json', key: that.key }
if (options.sig) {
requestParam.sig = Utils.getSig(requestParam, options.sig, 'getDistrictByCityId')
}
wx.request(
Utils.buildWxRequestConfig(
options,
{ url: URL_AREA_LIST, data: requestParam },
'getDistrictByCityId',
),
)
}
calculateDistance(options) {
var that = this
options = options || {}
Utils.polyfillParam(options)
if (Utils.checkParamKeyEmpty(options, 'to')) {
return
}
var requestParam = {
mode: options.mode || 'walking',
to: Utils.location2query(options.to),
output: 'json',
key: that.key,
}
if (options.from) {
options.location = options.from
}
if (requestParam.mode == 'straight') {
var locationsuccess = function (result) {
var locationTo = Utils.getEndLocation(requestParam.to)
var data = { message: 'query ok', result: { elements: [] }, status: 0 }
for (var i = 0; i < locationTo.length; i++) {
data.result.elements.push({
distance: Utils.getDistance(
result.latitude,
result.longitude,
locationTo[i].lat,
locationTo[i].lng,
),
duration: 0,
from: { lat: result.latitude, lng: result.longitude },
to: { lat: locationTo[i].lat, lng: locationTo[i].lng },
})
}
var calculateResult = data.result.elements
var distanceResult = []
for (var i = 0; i < calculateResult.length; i++) {
distanceResult.push(calculateResult[i].distance)
}
return options.success(data, {
calculateResult: calculateResult,
distanceResult: distanceResult,
})
}
Utils.locationProcess(options, locationsuccess)
} else {
var locationsuccess = function (result) {
requestParam.from = result.latitude + ',' + result.longitude
if (options.sig) {
requestParam.sig = Utils.getSig(requestParam, options.sig, 'calculateDistance')
}
wx.request(
Utils.buildWxRequestConfig(
options,
{ url: URL_DISTANCE, data: requestParam },
'calculateDistance',
),
)
}
Utils.locationProcess(options, locationsuccess)
}
}
direction(options) {
var that = this
options = options || {}
Utils.polyfillParam(options)
if (Utils.checkParamKeyEmpty(options, 'to')) {
return
}
var requestParam = { output: 'json', key: that.key }
if (typeof options.to == 'string') {
requestParam.to = options.to
} else {
requestParam.to = options.to.latitude + ',' + options.to.longitude
}
var SET_URL_DIRECTION = null
options.mode = options.mode || MODE.driving
SET_URL_DIRECTION = URL_DIRECTION + options.mode
if (options.from) {
options.location = options.from
}
if (options.mode == MODE.driving) {
if (options.from_poi) {
requestParam.from_poi = options.from_poi
}
if (options.heading) {
requestParam.heading = options.heading
}
if (options.speed) {
requestParam.speed = options.speed
}
if (options.accuracy) {
requestParam.accuracy = options.accuracy
}
if (options.road_type) {
requestParam.road_type = options.road_type
}
if (options.to_poi) {
requestParam.to_poi = options.to_poi
}
if (options.from_track) {
requestParam.from_track = options.from_track
}
if (options.waypoints) {
requestParam.waypoints = options.waypoints
}
if (options.policy) {
requestParam.policy = options.policy
}
if (options.plate_number) {
requestParam.plate_number = options.plate_number
}
}
if (options.mode == MODE.transit) {
if (options.departure_time) {
requestParam.departure_time = options.departure_time
}
if (options.policy) {
requestParam.policy = options.policy
}
}
var locationsuccess = function (result) {
requestParam.from = result.latitude + ',' + result.longitude
if (options.sig) {
requestParam.sig = Utils.getSig(requestParam, options.sig, 'direction', options.mode)
}
wx.request(
Utils.buildWxRequestConfig(
options,
{ url: SET_URL_DIRECTION, data: requestParam },
'direction',
),
)
}
Utils.locationProcess(options, locationsuccess)
}
}
export default QQMapWX

@ -1,122 +1,135 @@
{
"name": "",
"appid": "__UNI__265C604",
"description": "",
"versionName": "1.0.0",
"versionCode": "100",
"transformPx": false,
/* 5+App */
"app-plus": {
//
"compatible": {
"ignoreVersion": true
"name" : "",
"appid" : "__UNI__265C604",
"description" : "",
"versionName" : "1.0.0",
"versionCode" : "100",
"transformPx" : false,
/* 5+App */
"app-plus" : {
//
"compatible" : {
"ignoreVersion" : true
},
"usingComponents" : true,
"nvueStyleCompiler" : "uni-app",
"compilerVersion" : 3,
"splashscreen" : {
"alwaysShowBeforeRender" : true,
"waiting" : true,
"autoclose" : true,
"delay" : 0
},
/* */
"modules" : {},
/* */
"distribute" : {
/* android */
"android" : {
"permissions" : [
"<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
"<uses-permission android:name=\"android.permission.VIBRATE\"/>",
"<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
"<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.CAMERA\"/>",
"<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
"<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
"<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
"<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
"<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
"<uses-feature android:name=\"android.hardware.camera\"/>",
"<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
]
},
/* ios */
"ios" : {
"dSYMs" : false
},
/* SDK */
"sdkConfigs" : {
"ad" : {}
},
"icons" : {
"android" : {
"hdpi" : "unpackage/res/icons/72x72.png",
"xhdpi" : "unpackage/res/icons/96x96.png",
"xxhdpi" : "unpackage/res/icons/144x144.png",
"xxxhdpi" : "unpackage/res/icons/192x192.png"
},
"ios" : {
"appstore" : "unpackage/res/icons/1024x1024.png",
"ipad" : {
"app" : "unpackage/res/icons/76x76.png",
"app@2x" : "unpackage/res/icons/152x152.png",
"notification" : "unpackage/res/icons/20x20.png",
"notification@2x" : "unpackage/res/icons/40x40.png",
"proapp@2x" : "unpackage/res/icons/167x167.png",
"settings" : "unpackage/res/icons/29x29.png",
"settings@2x" : "unpackage/res/icons/58x58.png",
"spotlight" : "unpackage/res/icons/40x40.png",
"spotlight@2x" : "unpackage/res/icons/80x80.png"
},
"iphone" : {
"app@2x" : "unpackage/res/icons/120x120.png",
"app@3x" : "unpackage/res/icons/180x180.png",
"notification@2x" : "unpackage/res/icons/40x40.png",
"notification@3x" : "unpackage/res/icons/60x60.png",
"settings@2x" : "unpackage/res/icons/58x58.png",
"settings@3x" : "unpackage/res/icons/87x87.png",
"spotlight@2x" : "unpackage/res/icons/80x80.png",
"spotlight@3x" : "unpackage/res/icons/120x120.png"
}
}
}
}
},
"usingComponents": true,
"nvueStyleCompiler": "uni-app",
"compilerVersion": 3,
"splashscreen": {
"alwaysShowBeforeRender": true,
"waiting": true,
"autoclose": true,
"delay": 0
/* */
"quickapp" : {},
/* */
"h5" : {
"router" : {
// /
"base" : "./"
}
},
/* */
"modules": {},
/* */
"distribute": {
/* android */
"android": {
"permissions": [
"<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
"<uses-permission android:name=\"android.permission.VIBRATE\"/>",
"<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
"<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.CAMERA\"/>",
"<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
"<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
"<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
"<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
"<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
"<uses-feature android:name=\"android.hardware.camera\"/>",
"<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
]
},
/* ios */
"ios": {
"dSYMs": false
},
/* SDK */
"sdkConfigs": {
"ad": {}
},
"icons": {
"android": {
"hdpi": "unpackage/res/icons/72x72.png",
"xhdpi": "unpackage/res/icons/96x96.png",
"xxhdpi": "unpackage/res/icons/144x144.png",
"xxxhdpi": "unpackage/res/icons/192x192.png"
/* */
"mp-weixin" : {
"appid" : "wxf82bcc798891a29d",
"setting" : {
"minified" : true,
"urlCheck" : false,
"es6" : true,
"postcss" : true
},
//
"lazyCodeLoading" : "requiredComponents",
"usingComponents" : true,
"permission" : {
"scope.userLocation" : {
"desc" : "你的位置信息将用于小程序位置接口的效果展示"
}
},
"ios": {
"appstore": "unpackage/res/icons/1024x1024.png",
"ipad": {
"app": "unpackage/res/icons/76x76.png",
"app@2x": "unpackage/res/icons/152x152.png",
"notification": "unpackage/res/icons/20x20.png",
"notification@2x": "unpackage/res/icons/40x40.png",
"proapp@2x": "unpackage/res/icons/167x167.png",
"settings": "unpackage/res/icons/29x29.png",
"settings@2x": "unpackage/res/icons/58x58.png",
"spotlight": "unpackage/res/icons/40x40.png",
"spotlight@2x": "unpackage/res/icons/80x80.png"
},
"iphone": {
"app@2x": "unpackage/res/icons/120x120.png",
"app@3x": "unpackage/res/icons/180x180.png",
"notification@2x": "unpackage/res/icons/40x40.png",
"notification@3x": "unpackage/res/icons/60x60.png",
"settings@2x": "unpackage/res/icons/58x58.png",
"settings@3x": "unpackage/res/icons/87x87.png",
"spotlight@2x": "unpackage/res/icons/80x80.png",
"spotlight@3x": "unpackage/res/icons/120x120.png"
}
"requiredPrivateInfos": [
"getLocation"
],
"uniStatistics" : {
"enable" : true
}
}
}
},
/* */
"quickapp": {},
/* */
"h5": {
"router": {
// /
"base": "./"
}
},
/* */
"mp-weixin": {
"appid": "wx26729f20b9efae3a",
"setting": {
"minified": true,
"urlCheck": true
},
//
"lazyCodeLoading": "requiredComponents",
"usingComponents": true
},
"mp-alipay": {
"usingComponents": true
},
"mp-baidu": {
"usingComponents": true
},
"mp-toutiao": {
"usingComponents": true
},
"uniStatistics": {
"enable": false
},
"vueVersion": "3"
"mp-alipay" : {
"usingComponents" : true
},
"mp-baidu" : {
"usingComponents" : true
},
"mp-toutiao" : {
"usingComponents" : true
},
"uniStatistics" : {
"enable" : false
},
"vueVersion" : "3"
}

@ -16,27 +16,20 @@
{
"path": "pages/index/index",
"style": {
"navigationStyle": "custom",
"navigationBarTextStyle": "white",
"navigationBarTitleText": "首页"
}
},
{
"path": "pages/serviceSite/serviceSite",
"style": {
"navigationBarTitleText": "服务站列表"
"navigationBarTitleText": "首页",
"navigationStyle": "custom"
}
},
{
"path": "pages/siteDetail/siteDetail",
"path": "pages/orerdList/orerdList",
"style": {
"navigationBarTitleText": "服务站详情"
"navigationBarTitleText": "订单列表"
}
},
{
"path": "pages/booking/booking",
"path": "pages/orderDetail/orderDetail",
"style": {
"navigationBarTitleText": "一键预约"
"navigationBarTitleText": "订单详情"
}
},
{
@ -46,21 +39,16 @@
}
},
{
"path": "pages/orerdList/orerdList",
"path": "pages/newsList/newsList",
"style": {
"navigationBarTitleText": "订单列表"
"navigationBarTitleText": "消息列表",
"navigationStyle": "custom"
}
},
{
"path": "pages/cart/cart",
"path": "pages/orderAuto/orderAuto",
"style": {
"navigationBarTitleText": "购物车"
}
},
{
"path": "pages/cart/cart2",
"style": {
"navigationBarTitleText": "购物车"
"navigationBarTitleText": "自动接单"
}
},
{
@ -97,39 +85,21 @@
}
],
"globalStyle": {
"navigationBarTextStyle": "black",
"navigationBarTextStyle": "white",
"navigationBarTitleText": "",
"navigationBarBackgroundColor": "#F8F8F8",
"backgroundColor": "#F8F8F8"
"navigationBarBackgroundColor": "#3775F6",
"backgroundColor": "#3775F6"
},
// TabBar
"tabBar": {
"color": "#333",
"selectedColor": "#27ba9b",
"color": "#999A9F",
"selectedColor": "#3775F6",
"backgroundColor": "#fff",
"borderStyle": "white",
"list": [
{
"text": "首页",
"pagePath": "pages/index/index",
"iconPath": "static/tabs/home_default.png",
"selectedIconPath": "static/tabs/home_selected.png"
},
{
"text": "服务站",
"pagePath": "pages/serviceSite/serviceSite",
"iconPath": "static/tabs/category_default.png",
"selectedIconPath": "static/tabs/category_selected.png"
},
{
"text": "一键预约",
"pagePath": "pages/booking/booking",
"iconPath": "static/tabs/cart_default.png",
"selectedIconPath": "static/tabs/cart_selected.png"
},
{
"text": "订单",
"pagePath": "pages/orerdList/orerdList",
"pagePath": "pages/index/index",
"iconPath": "static/tabs/cart_default.png",
"selectedIconPath": "static/tabs/cart_selected.png"
},
@ -143,6 +113,31 @@
},
//
"subPackages": [
{
//
"root": "payment",
//
"pages": [
{
"path": "detail/detail",
"style": {
"navigationBarTitleText": "结算详情"
}
},
{
"path": "success/success",
"style": {
"navigationBarTitleText": "结算成功"
}
},
{
"path": "fail/fail",
"style": {
"navigationBarTitleText": "结算失败"
}
}
]
},
{
//
"root": "pagesMember",
@ -188,8 +183,7 @@
{
"path": "detail/detail",
"style": {
"navigationBarTitleText": "订单详情",
"navigationStyle": "custom"
"navigationBarTitleText": "订单详情"
}
},
{

@ -1,261 +0,0 @@
<script setup lang="ts">
import { onMounted, ref } from 'vue'
const menuList = [
{
id: 1,
name: '地区',
},
{
id: 2,
name: '回收品类',
},
{
id: 3,
name: '服务',
},
{
id: 4,
name: '筛选',
},
]
type siteParams = {
page: Number
pageSize: Number
menuState: String
}
const activeMenuKey = ref(0)
const activeWeightKey = ref(0)
//
const leiList = [
{
id: 1,
name: '旧衣服',
},
{
id: 2,
name: '家用电器',
},
{
id: 2,
name: '废纸废书',
},
{
id: 3,
name: '废金属',
},
{
id: 4,
name: '废塑料',
},
]
const weightMenuList = [
{
id: 1,
name: '5-10kg',
},
{
id: 2,
name: '10-15kg',
},
{
id: 3,
name: '15-20kg',
},
{
id: 4,
name: '20-50kg',
},
]
const handleMenuChange = (val) => {
activeMenuKey.value = val
}
const handleWeightChange = (val) => {
activeWeightKey.value = val
}
const handleToto = () => {
uni.showToast({
title: 'todo...',
icon: 'none',
duration: 1000,
})
}
onMounted(() => {})
</script>
<template>
<view class="booking">
<view class="module lei">
<view class="module-title">回收品类</view>
<view class="module-menu">
<view
class="item"
@click="handleMenuChange(index)"
:class="{ active: activeMenuKey == index }"
v-for="(item, index) in leiList"
:key="item.id"
>{{ item.name }}</view
>
</view>
</view>
<view class="module info">
<view class="module-title">取件信息</view>
<view class="list">
<button hover-class="none" class="item arrow">取件时间</button>
<button hover-class="none" class="item arrow">取件地址</button>
</view>
<view class="weight">
<view class="weight-title"
>请选择预估重量<span class="desc">预估仅供参考以实际重量为准</span></view
>
<view class="weight-menu">
<view
class="item"
@click="handleWeightChange(index)"
:class="{ active: activeWeightKey == index }"
v-for="(item, index) in weightMenuList"
:key="item.id"
>{{ item.name }}</view
>
</view>
</view>
</view>
<view class="submit" @click="handleToto"></view>
<!-- 底部占位空盒子 -->
<view class="toolbar-height" safe-area-inset-bottom></view>
</view>
</template>
<style lang="scss">
page {
height: 100%;
background-color: #f2f2fa;
}
.booking {
height: 100%;
padding: 32rpx;
.lei {
margin: 20rpx 0;
padding: 32rpx;
border-radius: 12rpx;
background-color: #fff;
.module-title {
font-size: 30rpx;
color: #0d0d26;
padding-bottom: 20rpx;
border-bottom: 2rpx solid #f2f2f2;
}
.module-menu {
display: flex;
padding: 36rpx 0rpx;
.item {
flex: 1;
color: #95969d;
padding: 10rpx 0;
border-radius: 10rpx;
text-align: center;
&.active {
background: #fff7e8;
}
}
}
}
.info {
margin: 20rpx 0 30rpx;
padding: 32rpx;
border-radius: 12rpx;
background-color: #fff;
.module-title {
font-size: 36rpx;
color: #5386e4;
padding-bottom: 20rpx;
border-bottom: 2rpx solid #f2f2f2;
}
.list {
padding: 0 20rpx;
background-color: #fff;
margin-bottom: 20rpx;
border-radius: 10rpx;
.item {
line-height: 90rpx;
padding-left: 10rpx;
font-size: 30rpx;
color: #333;
border-top: 1rpx solid #ddd;
position: relative;
text-align: left;
border-radius: 0;
background-color: #fff;
&::after {
width: auto;
height: auto;
left: auto;
border: none;
}
&:first-child {
border: none;
}
&::after {
right: 5rpx;
}
}
.arrow::after {
content: '\e6c2';
position: absolute;
top: 50%;
color: #ccc;
font-family: 'erabbit' !important;
font-size: 32rpx;
transform: translateY(-50%);
}
}
.weight {
.weight-title {
color: #3d3d3d;
font-size: 28rpx;
margin: 20rpx 0;
.desc {
margin-left: 10rpx;
font-size: 24rpx;
color: #95969d;
}
}
.weight-menu {
display: flex;
flex-direction: row;
.item {
flex: 1;
text-align: center;
margin: 0 10rpx;
font-size: 28rpx;
border-radius: 8rpx;
padding: 30rpx 10rpx;
background: #f2f2fa;
&.active {
background: #fff7e8;
}
}
}
}
}
.submit {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
width: 448rpx;
margin: 40rpx auto 0;
padding: 20rpx 20rpx;
border-radius: 16rpx;
font-size: 32rpx;
color: #fff;
background: linear-gradient(119deg, #fd815f 7%, #f1484a 95%);
}
}
//
.toolbar-height {
height: 100rpx;
}
</style>

@ -1,13 +0,0 @@
<script setup lang="ts">
import CartMain from './components/CartMain.vue'
</script>
<template>
<CartMain />
</template>
<style lang="scss">
page {
height: 100%;
}
</style>

@ -1,14 +0,0 @@
<script setup lang="ts">
import CartMain from './components/CartMain.vue'
</script>
<template>
<!-- 适配底部安全区 -->
<CartMain safe-area-inset-bottom />
</template>
<style lang="scss">
page {
height: 100%;
}
</style>

@ -1,36 +0,0 @@
<script setup lang="ts">
import type { CategoryItem } from '@/types/home'
// props
defineProps<{
list: CategoryItem[]
}>()
</script>
<template>
<view class="category">
<view class="module-title"> 预约上门回收 </view>
<view class="cont">
<navigator
class="category-item"
hover-class="none"
url="/pages/index/index"
v-for="item in list"
:key="item.id"
>
<view class="left">
<view class="title">{{ item.name }}</view>
<view class="desc">{{ item.desc }}</view>
</view>
<view class="right">
<image class="icon" :src="item.icon"></image>
</view>
</navigator>
</view>
</view>
</template>
<style lang="scss">
@import '../styles/category.scss';
</style>

@ -1,63 +0,0 @@
<script setup lang="ts">
type item = { desc: string; name: string; id: Number }
const dataList: item[] = [
{
id: 1,
name: '',
desc: '公司风采一标题占用两行',
},
{
id: 11,
name: '',
desc: '公司风采一标题占用两行',
},
{
id: 122,
name: '',
desc: '公司风采一标题占用两行',
},
]
const handleMore = () => {}
const actionsClick = (type) => {}
</script>
<template>
<view class="class">
<view class="hd">
<view class="module-title">知识大课堂</view>
<view class="module-more" @tab="handleMore"> > </view>
</view>
<view class="module-cont">
<view class="section" v-for="item in dataList" :key="item.id">
<image
class="left"
src="https://yanxuan-item.nosdn.127.net/ef56a7139fffe2650a7cd74deafd08da.png"
></image>
<view class="right">
<view class="desc">{{ item.desc }}</view>
<view class="footer">
<view class="num">4.2w人浏览</view>
<view class="action">
<view class="item">
<uni-icons type="redo" size="18" color="#999"></uni-icons>
<text class="text">分享</text>
</view>
<view class="item">
<uni-icons type="hand-up-filled" size="18" color="#999"></uni-icons>
<text class="text">点赞</text>
</view>
<view class="item">
<uni-icons type="chat" size="18" color="#999"></uni-icons>
<text class="text">评论</text>
</view>
</view>
</view>
</view>
</view>
</view>
</view>
</template>
<style lang="scss" scoped>
@import '../styles/class.scss';
</style>

@ -1,59 +0,0 @@
<script setup lang="ts">
type item = { desc: string; name: string; id: Number }
const dataList: item[] = [
{
id: 1,
name: '',
desc: '公司风采一标题占用两行',
},
{
id: 11,
name: '',
desc: '公司风采一标题占用两行',
},
{
id: 122,
name: '',
desc: '公司风采一标题占用两行',
},
]
const handleMore = () => {}
const actionsClick = (type) => {}
</script>
<template>
<view class="community">
<view class="hd">
<view class="module-title">精彩社区</view>
<view class="module-more" @tab="handleMore"> > </view>
</view>
<view class="module-cont">
<view class="section" v-for="item in dataList" :key="item.id">
<image
class="img"
src="https://yanxuan-item.nosdn.127.net/ef56a7139fffe2650a7cd74deafd08da.png"
></image>
<view class="desc">{{ item.desc }}</view>
<view class="action">
<view class="item">
<uni-icons type="redo" size="18" color="#999"></uni-icons>
<text class="text">分享</text>
</view>
<view class="item">
<uni-icons type="hand-up-filled" size="18" color="#999"></uni-icons>
<text class="text">点赞</text>
</view>
<view class="item">
<uni-icons type="chat" size="18" color="#999"></uni-icons>
<text class="text">评论</text>
</view>
</view>
</view>
</view>
</view>
</template>
<style lang="scss" scoped>
@import '../styles/community.scss';
</style>

@ -1,71 +0,0 @@
<script setup lang="ts">
//
const { safeAreaInsets } = uni.getSystemInfoSync()
</script>
<template>
<view class="navbar" :style="{ paddingTop: safeAreaInsets!.top + 10 + 'px' }">
<!-- logo文字 -->
<view class="logo">
<image class="logo-image" src="@/static/images/logo.png"></image>
<!-- <text class="logo-text">新鲜 · 亲民 · 快捷</text> -->
</view>
<!-- 搜索条 -->
<view class="search">
<text class="icon-search">搜索商品</text>
<text class="icon-scan"></text>
</view>
</view>
</template>
<style lang="scss" scoped>
/* 自定义导航条 */
.navbar {
background-image: url(@/static/images/navigator_bg.png);
background-size: cover;
position: relative;
display: flex;
flex-direction: column;
padding-top: 20px;
.logo {
display: flex;
align-items: center;
height: 64rpx;
padding-left: 30rpx;
.logo-image {
width: 166rpx;
height: 39rpx;
}
.logo-text {
flex: 1;
line-height: 28rpx;
color: #fff;
margin: 2rpx 0 0 20rpx;
padding-left: 20rpx;
border-left: 1rpx solid #fff;
font-size: 26rpx;
}
}
.search {
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 10rpx 0 26rpx;
height: 64rpx;
margin: 16rpx 20rpx;
color: #fff;
font-size: 28rpx;
border-radius: 32rpx;
background-color: rgba(255, 255, 255, 0.5);
}
.icon-search {
&::before {
margin-right: 10rpx;
}
}
.icon-scan {
font-size: 30rpx;
padding: 15rpx;
}
}
</style>

@ -0,0 +1,412 @@
<script setup lang="ts">
import { OrderState } from '@/services/constants'
import { orderStateList } from '@/services/constants'
import { putMemberOrderReceiptByIdAPI } from '@/services/order'
import { deleteMemberOrderAPI } from '@/services/order'
import { getListOrderAPI } from '@/services/order'
import { getPayMockAPI, getPayWxPayMiniPayAPI } from '@/services/pay'
import type { OrderItem } from '@/types/order'
import type { OrderListParams } from '@/types/order'
import { onMounted, ref, reactive, watch } from 'vue'
import { useMemberStore } from '@/stores'
import { formatDate } from '@/utils/index'
//
const { safeAreaInsets } = uni.getSystemInfoSync()
// porps
const props = defineProps<{
statusId: String
}>()
const memberStore = useMemberStore()
const userInfo = memberStore.profile?.userInfo
//
const queryParams: Required<OrderListParams> = {
currentPage: 1,
pageSize: 10,
staffId: userInfo.id,
orderStafstatusId: props.statusId,
}
interface order {
id: string
timeupSecond: number
unAccept: boolean
locationNum: string
loction: string
people: string
state: string
time: string
}
let orderList: any[] = reactive([])
//
const isLoading = ref(false)
const getMemberOrderData = async () => {
// 退
if (isLoading.value) return
// 退
if (isFinish.value === true) {
return uni.showToast({ icon: 'none', title: '没有更多数据~' })
}
//
isLoading.value = true
//
const res = await getListOrderAPI(queryParams)
//
isLoading.value = false
res.data.list.forEach(e => {
e.time = e.appointmentTimeStart + ' - ' + e.appointmentTimeEnd?.substring(11)
})
//
orderList.push(...res.data.list)
//
if (queryParams.currentPage < res.data.pages) {
//
queryParams.currentPage++
} else {
//
isFinish.value = true
}
}
onMounted(() => {
getSettingInfo()
// getMemberOrderData()
})
const handleTimeup = async (item: Object) => {
console.log(item, orderList)
// const order = orderList.value.find((v) => v.id === item.id)
// order!.unAccept = true
// console.log(orderList)
// await updateOrderAPI({ ids: [id] })
}
const onOrderPay = (item: Object) => {
uni.navigateTo({ url: '/payment/detail/detail' })
}
//
const onOrderConfirm = (item: Object) => {
emit('orderAccept', item)
}
//
const isFinish = ref(false)
//
const isTriggered = ref(false)
//
const onRefresherrefresh = async () => {
//
isTriggered.value = true
//
queryParams.currentPage = 1
orderList.value = []
isFinish.value = false
//
await getMemberOrderData()
//
isTriggered.value = false
}
const emit = defineEmits('orderAccept')
// -
const getSettingInfo = () => {
uni.getSetting({
success(res) {
if (res.authSetting['scope.userLocation']) {
getLocationInfo()
} else {
getAuthorizeInfo()
}
},
})
}
// -
const getLocationInfo = () => {
uni.getLocation({
type: 'gcj02',
// isHighAccuracy: true,
// highAccuracyExpireTime: 5000,
success(res) {
console.log(res)
const longitude = res.longitude
const latitude = res.latitude
getMemberOrderData()
},
fail(err) {
uni.showModal({
content: '检测到您没打开获取定位功能权限,是否去设置打开?',
confirmText: '确认',
cancelText: '取消',
success: function (res) {
if (res.confirm) {
uni.openSetting({
success() {
getLocationInfo()
},
})
}
}
})
},
})
}
const getAuthorizeInfo = () => {
uni.authorize({
scope: 'scope.userLocation',
success(res) {
getLocationInfo()
},
fail(err) {
uni.showModal({
content: '检测到您没打开获取定位功能权限,是否去设置打开?',
confirmText: '确认',
cancelText: '取消',
success: function (res) {
if (res.confirm) {
uni.openSetting({
success() {
getLocationInfo()
},
})
} else {
getAuthorizeInfo()
}
}
})
},
})
}
</script>
<template>
<scroll-view
enable-back-to-top
scroll-y
class="orders"
refresher-enabled
:refresher-triggered="isTriggered"
@refresherrefresh="onRefresherrefresh"
@scrolltolower="getMemberOrderData"
>
<view class="card" v-for="item in orderList" :key="item.id">
<!-- 订单信息 -->
<view class="hd">
<text class="locationNum">距离{{ item.locationNum }}</text>
</view>
<!-- 商品信息点击商品跳转到订单详情不是商品详情 -->
<navigator
class="order"
:url="`/pages/orderDetail/orderDetail?id=${item.id}&state=${item.state}`"
hover-class="none"
>
<view class="meta">
<view class="loction">
<image class="img" src="/static/images/loction_home.png" mode="aspectFit" />
<view class="text ellipsis">{{ item.recycleAddress }}</view>
</view>
<view class="time ellipsis">
<image class="img" src="/static/images/time_home.png" mode="aspectFit" />
<view class="text">上门时间起止{{ item.time }}</view>
</view>
<view class="people ellipsis">
<image class="img" src="/static/images/iphone_home.png" mode="aspectFit" />
<view class="text">{{ item.clientName }} <text class="iphone">{{ item.clientMobile }}</text></view>
</view>
</view>
</navigator>
<!-- 订单操作按钮 -->
<view class="action" v-if="props.statusId == '520192817293693253'">
<view class="left">
<text class="label">剩余接单时间</text>
<uni-countdown
:show-day="false"
:minute="30"
:second="0"
color="#E30000"
@timeup="handleTimeup(item)"
/>
</view>
<view :class="[item.unAccept ? 'disabled' : '', 'button']" @tap="onOrderConfirm(item)"
>接单</view
>
</view>
<view class="action" v-else>
<view class="left">
<text class="label">剩余接单时间</text>
<uni-countdown
:show-day="false"
:minute="30"
:second="0"
color="#E30000"
@timeup="handleTimeup(item)"
/>
</view>
<view :class="[item.unAccept ? 'disabled' : '', 'button']" @tap="onOrderPay(item)"
>结算</view
>
</view>
</view>
<view class="loading-text" :style="{ paddingBottom: safeAreaInsets?.bottom + 'px' }">
{{ isFinish ? '没有更多数据~' : '正在加载...' }}
</view>
</scroll-view>
</template>
<style lang="scss">
//
.orders {
position: relative;
.card {
min-height: 100rpx;
padding: 20rpx;
margin: 20rpx 20rpx 0;
border-radius: 10rpx;
background-color: #fff;
&:last-child {
padding-bottom: 40rpx;
}
}
.hd {
display: flex;
align-items: center;
justify-content: space-between;
font-size: 28rpx;
color: #999;
.locationNum {
color: #3d3d3d;
font-size: 32rpx;
font-weight: 500;
flex: 1;
}
}
.order {
display: flex;
margin-bottom: 20rpx;
border-top: 2rpx solid #f2f2f2;
border-bottom: 2rpx solid #f2f2f2;
margin: 20rpx 0;
.meta {
flex: 1;
display: flex;
flex-direction: column;
justify-content: center;
.loction {
margin-top: 20rpx;
display: flex;
align-items: center;
.img {
width: 40rpx;
height: 40rpx;
margin-right: 20rpx;
}
.text {
font-size: 32rpx;
color: #3d3d3d;
}
}
.time {
display: flex;
align-items: center;
margin: 20rpx 0;
.img {
width: 40rpx;
height: 40rpx;
margin-right: 20rpx;
}
.text {
font-size: 32rpx;
color: #3d3d3d;
}
}
.people {
display: flex;
align-items: center;
margin-bottom: 20rpx;
.img {
width: 36rpx;
height: 36rpx;
margin-right: 26rpx;
}
.text {
font-size: 32rpx;
color: #3d3d3d;
.iphone {
color: #3775f6;
margin-left: 10rpx;
}
}
}
}
}
.action {
display: flex;
justify-content: space-between;
align-items: center;
.left {
display: flex;
.label {
align-items: center;
color: #3d3d3d;
font-size: 32rpx;
}
}
.button {
width: 180rpx;
height: 60rpx;
display: flex;
justify-content: center;
align-items: center;
margin-left: 20rpx;
border-radius: 60rpx;
border: 1rpx solid #ccc;
font-size: 26rpx;
background: linear-gradient(171deg, #51b6ff -5%, #3775f6 129%);
color: #fff;
&.disabled {
border: none;
background: none;
background-color: #f1f1f1;
color: #c3b4b4;
}
}
}
.loading-text {
text-align: center;
font-size: 28rpx;
color: #666;
padding: 20rpx 0;
}
}
</style>

@ -1,33 +0,0 @@
<script setup lang="ts">
import type { HotItem } from '@/types/home'
// props
defineProps<{
list: HotItem[]
}>()
</script>
<template>
<!-- 推荐专区 -->
<view class="panel hot">
<view class="item" v-for="item in list" :key="item.id">
<view class="title">
<text class="title-text">{{ item.title }}</text>
<text class="title-desc">{{ item.alt }}</text>
</view>
<navigator hover-class="none" :url="`/pages/hot/hot?type=${item.type}`" class="cards">
<image
v-for="src in item.pictures"
:key="src"
class="image"
mode="aspectFit"
:src="src"
></image>
</navigator>
</view>
</view>
</template>
<style lang="scss">
@import '../styles/hot.scss';
</style>

@ -1,44 +0,0 @@
<script setup lang="ts">
// const handlePhone = () => {
// uni.makePhoneCall({
// phoneNumber: '400-123-000', //
// })
// }
const handleToto = () => {
uni.navigateTo({ url: '/pages/siteDetail/siteDetail' })
}
</script>
<template>
<view class="neighborhood-site" @tap="handleToto">
<view class="module-title">附近回收站</view>
<view class="module-cont">
<image
class="left"
src="https://img.36krcdn.com/20200410/v2_41365a0f26a244fdab8e3f5be081ed2b_img_000"
/>
<view class="md">
<view class="name"> <span class="zuijin"> 最近 </span>上海市松江区佘山镇 </view>
<view class="time">营业时间09-18:00</view>
<view class="loction">上海市松江区新松江路92弄开元地中海园区</view>
</view>
<view class="right">
<view class="num">1.03km</view>
<image
class="img"
src="https://img.36krcdn.com/20200410/v2_41365a0f26a244fdab8e3f5be081ed2b_img_000"
/>
</view>
</view>
<view class="md-tag"
><span class="tag-before">回收品类</span>旧衣·纸品·金属·家电·塑料·玻璃</view
>
<view class="foot-desc">
<view class="item">特色服务上门服务家电维修</view>
<view class="item">优惠活动预约回收立享双倍积分</view>
</view>
</view>
</template>
<style lang="scss" scoped>
@import '../styles/neighborhoodSite.scss';
</style>

@ -1,376 +0,0 @@
<template name="skeleton">
<view class="sk-container">
<view class="viewport viewport">
<view is="pages/index/components/CustomNavbar">
<view
class="navbar CustomNavbar--navbar data-v-ff0d84a2 CustomNavbar--data-v-ff0d84a2"
style="padding-top: 30px"
>
<view class="logo CustomNavbar--logo data-v-ff0d84a2 CustomNavbar--data-v-ff0d84a2">
<image
class="logo-image CustomNavbar--logo-image data-v-ff0d84a2 CustomNavbar--data-v-ff0d84a2 sk-image"
></image>
</view>
<view class="search CustomNavbar--search data-v-ff0d84a2 CustomNavbar--data-v-ff0d84a2">
<text
class="icon-search CustomNavbar--icon-search data-v-ff0d84a2 CustomNavbar--data-v-ff0d84a2 sk-transparent sk-text-14-2857-875 sk-text sk-pseudo sk-pseudo-circle"
>搜索商品</text
>
<text
class="icon-scan CustomNavbar--icon-scan data-v-ff0d84a2 CustomNavbar--data-v-ff0d84a2 sk-pseudo sk-pseudo-circle"
></text>
</view>
</view>
</view>
<scroll-view
enable-back-to-top="true"
refresher-enabled="true"
scroll-y="true"
class="scroll-view scroll-view"
>
<view is="components/XtxSwiper">
<view class="carousel XtxSwiper--carousel">
<swiper circular="true" interval="3000" current="0" autoplay="false">
<swiper-item
style="
position: absolute;
width: 100%;
height: 100%;
transform: translate(0%, 0px) translateZ(0px);
"
>
<navigator class="navigator XtxSwiper--navigator" hover-class="none">
<image class="image XtxSwiper--image sk-image" mode="aspectFill"></image>
</navigator>
</swiper-item>
</swiper>
<view class="indicator XtxSwiper--indicator">
<text class="dot XtxSwiper--dot active XtxSwiper--active"></text>
<text class="dot XtxSwiper--dot"></text>
<text class="dot XtxSwiper--dot"></text>
<text class="dot XtxSwiper--dot"></text>
<text class="dot XtxSwiper--dot"></text>
</view>
</view>
</view>
<view is="pages/index/components/CategoryPanel">
<view class="category CategoryPanel--category">
<view
class="module-title CategoryPanel--module-title sk-transparent sk-text-14-2857-989 sk-text"
>
预约上门回收
</view>
<view class="cont CategoryPanel--cont">
<navigator class="category-item CategoryPanel--category-item" hover-class="none">
<view class="left CategoryPanel--left">
<view
class="title CategoryPanel--title sk-transparent sk-text-14-2857-831 sk-text"
>旧衣服</view
>
<view class="desc CategoryPanel--desc sk-transparent sk-text-14-2857-227 sk-text"
>旧衣服回收不浪费</view
>
</view>
<view class="right CategoryPanel--right">
<image class="icon CategoryPanel--icon sk-image"></image>
</view>
</navigator>
<navigator class="category-item CategoryPanel--category-item" hover-class="none">
<view class="left CategoryPanel--left">
<view
class="title CategoryPanel--title sk-transparent sk-text-14-2857-147 sk-text"
>家用电器</view
>
<view class="desc CategoryPanel--desc sk-transparent sk-text-14-2857-444 sk-text"
>旧衣服回收不浪费</view
>
</view>
<view class="right CategoryPanel--right">
<image class="icon CategoryPanel--icon sk-image"></image>
</view>
</navigator>
<navigator class="category-item CategoryPanel--category-item" hover-class="none">
<view class="left CategoryPanel--left">
<view
class="title CategoryPanel--title sk-transparent sk-text-14-2857-139 sk-text"
>废纸废书</view
>
<view class="desc CategoryPanel--desc sk-transparent sk-text-14-2857-520 sk-text"
>旧衣服回收不浪费</view
>
</view>
<view class="right CategoryPanel--right">
<image class="icon CategoryPanel--icon sk-image"></image>
</view>
</navigator>
<navigator class="category-item CategoryPanel--category-item" hover-class="none">
<view class="left CategoryPanel--left">
<view
class="title CategoryPanel--title sk-transparent sk-text-14-2857-471 sk-text"
>废金属</view
>
<view class="desc CategoryPanel--desc sk-transparent sk-text-14-2857-372 sk-text"
>旧衣服回收不浪费</view
>
</view>
<view class="right CategoryPanel--right">
<image class="icon CategoryPanel--icon sk-image"></image>
</view>
</navigator>
<navigator class="category-item CategoryPanel--category-item" hover-class="none">
<view class="left CategoryPanel--left">
<view
class="title CategoryPanel--title sk-transparent sk-text-14-2857-575 sk-text"
>废玻璃</view
>
<view class="desc CategoryPanel--desc sk-transparent sk-text-14-2857-572 sk-text"
>旧衣服回收不浪费</view
>
</view>
<view class="right CategoryPanel--right">
<image class="icon CategoryPanel--icon sk-image"></image>
</view>
</navigator>
<navigator class="category-item CategoryPanel--category-item" hover-class="none">
<view class="left CategoryPanel--left">
<view
class="title CategoryPanel--title sk-transparent sk-text-14-2857-961 sk-text"
>废塑料</view
>
<view class="desc CategoryPanel--desc sk-transparent sk-text-14-2857-400 sk-text"
>旧衣服回收不浪费</view
>
</view>
<view class="right CategoryPanel--right">
<image class="icon CategoryPanel--icon sk-image"></image>
</view>
</navigator>
</view>
</view>
</view>
<view is="pages/index/components/PhoneContact">
<view
class="phone-contact PhoneContact--phone-contact data-v-47ea6ab4 PhoneContact--data-v-47ea6ab4"
>
<view
class="module-title PhoneContact--module-title data-v-47ea6ab4 PhoneContact--data-v-47ea6ab4 sk-transparent sk-text-14-2857-52 sk-text"
>电话预约回收</view
>
<view
class="module-action PhoneContact--module-action data-v-47ea6ab4 PhoneContact--data-v-47ea6ab4 sk-transparent sk-text-14-2857-16 sk-text"
>400-123-000</view
>
</view>
</view>
</scroll-view>
</view>
</view>
</template>
<style lang="scss">
/* #ifdef H5 || APP-PLUS */
/* 修复 H5 端骨架屏样式异常 */
/* 原因H5 端样式自动开启 scoped 隔离,导致骨架屏的基础样式被隔离 */
@import '../styles/category.scss';
@import '../styles/hot.scss';
@import '@/components/styles/XtxSwiper.scss';
/* #endif */
.sk-transparent {
color: transparent !important;
}
.sk-text-14-2857-875 {
background-image: linear-gradient(
transparent 14.2857%,
#eeeeee 0%,
#eeeeee 85.7143%,
transparent 0%
) !important;
background-size: 100% 38.0435rpx;
position: relative !important;
}
.sk-text {
background-origin: content-box !important;
background-clip: content-box !important;
background-color: transparent !important;
color: transparent !important;
background-repeat: repeat-y !important;
}
.sk-text-14-2857-989 {
background-image: linear-gradient(
transparent 14.2857%,
#eeeeee 0%,
#eeeeee 85.7143%,
transparent 0%
) !important;
background-size: 100% 40.5797rpx;
position: relative !important;
}
.sk-text-14-2857-831 {
background-image: linear-gradient(
transparent 14.2857%,
#eeeeee 0%,
#eeeeee 85.7143%,
transparent 0%
) !important;
background-size: 100% 35.5072rpx;
position: relative !important;
}
.sk-text-14-2857-227 {
background-image: linear-gradient(
transparent 14.2857%,
#eeeeee 0%,
#eeeeee 85.7143%,
transparent 0%
) !important;
background-size: 100% 32.971rpx;
position: relative !important;
}
.sk-text-14-2857-147 {
background-image: linear-gradient(
transparent 14.2857%,
#eeeeee 0%,
#eeeeee 85.7143%,
transparent 0%
) !important;
background-size: 100% 35.5072rpx;
position: relative !important;
}
.sk-text-14-2857-444 {
background-image: linear-gradient(
transparent 14.2857%,
#eeeeee 0%,
#eeeeee 85.7143%,
transparent 0%
) !important;
background-size: 100% 32.971rpx;
position: relative !important;
}
.sk-text-14-2857-139 {
background-image: linear-gradient(
transparent 14.2857%,
#eeeeee 0%,
#eeeeee 85.7143%,
transparent 0%
) !important;
background-size: 100% 35.5072rpx;
position: relative !important;
}
.sk-text-14-2857-520 {
background-image: linear-gradient(
transparent 14.2857%,
#eeeeee 0%,
#eeeeee 85.7143%,
transparent 0%
) !important;
background-size: 100% 32.971rpx;
position: relative !important;
}
.sk-text-14-2857-471 {
background-image: linear-gradient(
transparent 14.2857%,
#eeeeee 0%,
#eeeeee 85.7143%,
transparent 0%
) !important;
background-size: 100% 35.5072rpx;
position: relative !important;
}
.sk-text-14-2857-372 {
background-image: linear-gradient(
transparent 14.2857%,
#eeeeee 0%,
#eeeeee 85.7143%,
transparent 0%
) !important;
background-size: 100% 32.971rpx;
position: relative !important;
}
.sk-text-14-2857-575 {
background-image: linear-gradient(
transparent 14.2857%,
#eeeeee 0%,
#eeeeee 85.7143%,
transparent 0%
) !important;
background-size: 100% 35.5072rpx;
position: relative !important;
}
.sk-text-14-2857-572 {
background-image: linear-gradient(
transparent 14.2857%,
#eeeeee 0%,
#eeeeee 85.7143%,
transparent 0%
) !important;
background-size: 100% 32.971rpx;
position: relative !important;
}
.sk-text-14-2857-961 {
background-image: linear-gradient(
transparent 14.2857%,
#eeeeee 0%,
#eeeeee 85.7143%,
transparent 0%
) !important;
background-size: 100% 35.5072rpx;
position: relative !important;
}
.sk-text-14-2857-400 {
background-image: linear-gradient(
transparent 14.2857%,
#eeeeee 0%,
#eeeeee 85.7143%,
transparent 0%
) !important;
background-size: 100% 32.971rpx;
position: relative !important;
}
.sk-text-14-2857-52 {
background-image: linear-gradient(
transparent 14.2857%,
#eeeeee 0%,
#eeeeee 85.7143%,
transparent 0%
) !important;
background-size: 100% 40.5797rpx;
position: relative !important;
}
.sk-text-14-2857-16 {
background-image: linear-gradient(
transparent 14.2857%,
#eeeeee 0%,
#eeeeee 85.7143%,
transparent 0%
) !important;
background-size: 100% 43.1159rpx;
position: relative !important;
}
.sk-image {
background: #efefef !important;
}
.sk-pseudo::before,
.sk-pseudo::after {
background: #efefef !important;
background-image: none !important;
color: transparent !important;
border-color: transparent !important;
}
.sk-pseudo-rect::before,
.sk-pseudo-rect::after {
border-radius: 0 !important;
}
.sk-pseudo-circle::before,
.sk-pseudo-circle::after {
border-radius: 50% !important;
}
.sk-container {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
overflow: hidden;
background-color: transparent;
}
</style>

@ -1,17 +0,0 @@
<script setup lang="ts">
const handlePhone = () => {
uni.makePhoneCall({
phoneNumber: '400-123-000', //
})
}
</script>
<template>
<view class="phone-contact">
<view class="module-title">电话预约回收</view>
<view class="module-action" @tap="handlePhone">400-123-000</view>
</view>
</template>
<style lang="scss" scoped>
@import '../styles/phoneContact.scss';
</style>

@ -1,169 +1,318 @@
<script setup lang="ts">
import { getHomeBannerAPI, getHomeCategoryAPI, getHomeHotAPI } from '@/services/home'
import type { BannerItem, CategoryItem, HotItem } from '@/types/home'
import { onLoad } from '@dcloudio/uni-app'
import { ref } from 'vue'
import CustomNavbar from './components/CustomNavbar.vue'
import CategoryPanel from './components/CategoryPanel.vue'
import HotPanel from './components/HotPanel.vue'
import PageSkeleton from './components/PageSkeleton.vue'
import PhoneContact from './components/PhoneContact.vue'
import NeighborhoodSite from './components/NeighborhoodSite.vue'
import Community from './components/Community.vue'
import Class from './components/Class.vue'
import { useGuessList } from '@/composables'
//
const bannerList = ref<BannerItem[]>([])
const getHomeBannerData = async () => {
const res = await getHomeBannerAPI()
bannerList.value = res.result
}
import { useMemberStore } from '@/stores'
import DataList from './components/DataList.vue'
import { onReady } from '@dcloudio/uni-app'
//
const categoryList = ref<CategoryItem[]>([])
const getHomeCategoryData = async () => {
// const res = await getHomeCategoryAPI()
// console.log(JSON.stringify(res.result,null, 4))
// debugger
// categoryList.value = res.result
const data = [
{
id: '1019000',
name: '旧衣服',
desc: '旧衣服回收不浪费',
icon: 'http://yjy-xiaotuxian-dev.oss-cn-beijing.aliyuncs.com/picture/2021-05-06/4b02f01f-a365-4b6c-9f7a-8b0f591dda02.png?quality=95&imageView',
},
{
id: '1043000',
name: '家用电器',
desc: '旧衣服回收不浪费',
icon: 'http://yjy-xiaotuxian-dev.oss-cn-beijing.aliyuncs.com/picture/2021-05-06/9660870d-6a59-4624-8064-b3a8cbf50d5c.png?quality=95&imageView',
},
{
id: '109243029',
name: '废纸废书',
desc: '旧衣服回收不浪费',
icon: 'http://yjy-xiaotuxian-dev.oss-cn-beijing.aliyuncs.com/picture/2021-05-06/7d19752c-baff-49b6-bd02-5ece1d729214.png?quality=95&imageView',
},
{
id: '19999999',
name: '废金属',
desc: '旧衣服回收不浪费',
icon: 'http://yjy-xiaotuxian-dev.oss-cn-beijing.aliyuncs.com/picture/2021-05-06/4ff20b9e-8150-4bd3-87a3-0cd6766938dd.png?quality=95&imageView',
},
{
id: '999999',
name: '废玻璃',
desc: '旧衣服回收不浪费',
icon: 'http://yjy-xiaotuxian-dev.oss-cn-beijing.aliyuncs.com/picture/2021-05-06/d9ee4919-0d2c-4383-9916-2dd25f12610c.png?quality=95&imageView',
},
{
id: '999999',
name: '废塑料',
desc: '旧衣服回收不浪费',
icon: 'http://yjy-xiaotuxian-dev.oss-cn-beijing.aliyuncs.com/picture/2021-05-06/d9ee4919-0d2c-4383-9916-2dd25f12610c.png?quality=95&imageView',
},
]
categoryList.value = data
}
//
const orderAcceptPopup = ref<UniHelper.UniPopupInstance>()
const memberStore = useMemberStore()
// tabs
const orderTabs = ref([
{ orderState: 0, title: '待接单', isRender: false, statusId: '520192817293693253' },
{ orderState: 1, title: '进行中', isRender: false, statusId: '520192993311854917' },
])
//
const activeIndex = ref(orderTabs.value.findIndex((v) => v.orderState === 0))
orderTabs.value[activeIndex.value].isRender = true
//
// //
// onReady(() => {
// debugger
// if (memberStore.profile?.token) {
// getSettingInfo()
// } else {
// }
// })
//
const hotList = ref<HotItem[]>([])
const getHomeHotData = async () => {
const res = await getHomeHotAPI()
hotList.value = res.result
}
//
const isLoading = ref(false)
//
onLoad(async () => {
isLoading.value = true
await Promise.all([getHomeBannerData(), getHomeCategoryData(), getHomeHotData()])
isLoading.value = false
})
//
const { guessRef, onScrolltolower } = useGuessList()
//
const isTriggered = ref(false)
//
const onRefresherrefresh = async () => {
//
isTriggered.value = true
//
// await getHomeBannerData()
// await getHomeCategoryData()
// await getHomeHotData()
//
guessRef.value?.resetData()
await Promise.all([
getHomeBannerData(),
getHomeCategoryData(),
getHomeHotData(),
guessRef.value?.getMore(),
])
//
isTriggered.value = false
const datetimesingle = ref('')
const activeId = ref('')
const handleOrderAccept = (item: any) => {
activeId.value = item.id
datetimesingle.value = item.time
orderAcceptPopup?.value?.open()
}
const changeTime = (e) => {
console.log('change事件:', e)
}
const handleAccept = () => {
const url = `/pages/orderDetail/orderDetail?state=${props.state}&id=${activeId.value}`
uni.navigateTo({ url })
}
const handleLogin = () => {
const url = `/pages/login/login`
uni.navigateTo({ url })
}
const handleIndexChange = (index: any) => {
orderTabs.value.forEach(e => {
e.isRender = false
})
activeIndex.value = index
orderTabs.value[index].isRender = true
}
</script>
<template>
<view class="viewport">
<!-- 自定义导航栏 -->
<CustomNavbar />
<!-- 滚动容器 -->
<scroll-view
enable-back-to-top
refresher-enabled
@refresherrefresh="onRefresherrefresh"
:refresher-triggered="isTriggered"
@scrolltolower="onScrolltolower"
class="scroll-view"
scroll-y
>
<PageSkeleton v-if="isLoading" />
<template v-else>
<!-- 自定义轮播图 -->
<XtxSwiper :list="bannerList" />
<!-- 分类面板 -->
<CategoryPanel :list="categoryList" />
<!-- 电话联系> -->
<PhoneContact />
<!-- 附近回收站> -->
<NeighborhoodSite />
<!-- 社区服务中心 -->
<Community />
<!-- 课堂 -->
<Class />
<!-- 热门推荐 -->
<!-- <HotPanel :list="hotList" /> -->
<!-- 猜你喜欢 -->
<!-- <XtxGuess ref="guessRef" /> -->
</template>
</scroll-view>
<template v-if="memberStore.profile?.token">
<view class="cont">
<view class="tabs">
<text
class="item"
:class="{ active: activeIndex == index }"
v-for="(item, index) in orderTabs"
:key="item.title"
@click="handleIndexChange(index)"
>{{ item.title }}
</text>
<!-- 游标 -->
<view class="cursor" :style="{ left: activeIndex ? '65%' : '14%' }"></view>
</view>
<!-- 滑动容器 -->
<swiper class="swiper" :current="activeIndex" @change="activeIndex = $event.detail.current">
<!-- 滑动项 -->
<swiper-item v-for="item in orderTabs" :key="item.title">
<!-- 订单列表 -->
<DataList v-if="item.isRender" :status-id="item.statusId" @orderAccept="handleOrderAccept" />
</swiper-item>
</swiper>
<uni-popup ref="orderAcceptPopup" type="center" background-color="#fff">
<view class="popup-root">
<view class="title">请确保上门时间有效</view>
<view class="description">
<view class="tips">1请和客户确认如下上门时间</view>
<view class="date">
<uni-datetime-picker type="datetime" v-model="datetimesingle" @change="changeTime" />
</view>
</view>
<view class="footer">
<view class="button" @tap="orderAcceptPopup?.close?.()"></view>
<view class="button primary" @tap="handleAccept"></view>
</view>
</view>
</uni-popup>
</view>
</template>
<view class="noLogin" v-else>
<image
class="img"
src="@/static/images/warn_home.png"
mode="scaleToFill"
/>
<view class="title">未登录</view>
<view class="desc">您目前还未登录账号无法加载任何信息请先去登录账号</view>
<view class="button" @click="handleLogin"></view>
</view>
</view>
</template>
<style lang="scss">
page {
background-color: #f7f7f7;
height: 100%;
overflow: hidden;
}
.viewport {
height: 100%;
display: flex;
flex-direction: column;
}
width: 100vw;
height: 100vh;
.scroll-view {
flex: 1;
overflow: hidden;
.cont {
height: 100%;
background-color: #3775f6;
display: flex;
flex-direction: column;
.navbar {
width: 750rpx;
color: #000;
position: fixed;
top: 0;
left: 0;
z-index: 9;
/* background-color: #f8f8f8; */
background-color: #3775f6;
.wrap {
position: relative;
background-color: #3775f6;
.title {
height: 44px;
display: flex;
justify-content: center;
align-items: center;
font-size: 32rpx;
/* color: #000; */
color: #fff;
}
.back {
position: absolute;
left: 0;
height: 44px;
width: 44px;
font-size: 44rpx;
display: flex;
align-items: center;
justify-content: center;
/* color: #000; */
color: #fff;
}
}
}
.popup-root {
padding: 30rpx 30rpx 0rpx;
border-radius: 10rpx 10rpx 0 0;
overflow: hidden;
background: linear-gradient(180deg, #d2eeff -7%, rgba(255, 255, 255, 0) 38%), #ffffff;
box-shadow: 0px -2px 8px 0px rgba(133, 155, 180, 0.4);
position: relative;
.title {
text-align: left;
margin-bottom: 30rpx;
padding-bottom: 20rpx;
border-bottom: 2rpx solid #e1e7f2;
.text {
font-size: 30rpx;
}
.close {
position: absolute;
right: 0;
top: 0;
padding: 23rpx 50rpx;
color: #333;
font-size: 30rpx;
text-align: center;
}
}
.description {
min-height: 400rpx;
.tips {
margin: 20rpx 0;
}
.date {
margin: 60rpx 0;
}
}
.footer {
display: flex;
justify-content: space-between;
padding: 30rpx 0 20rpx;
font-size: 28rpx;
color: #444;
.button {
flex: 1;
height: 72rpx;
text-align: center;
line-height: 72rpx;
margin: 0 20rpx;
color: #444;
border-radius: 72rpx;
border: 1rpx solid #ccc;
}
.primary {
color: #fff;
background-color: #27ba9b;
border: none;
}
}
}
// tabs
.tabs {
display: flex;
justify-content: space-around;
line-height: 60rpx;
margin: 0 10rpx;
background-color: #3775f6;
box-shadow: 0 4rpx 6rpx rgba(240, 240, 240, 0.6);
position: relative;
z-index: 9;
margin-top: 128rpx;
.item {
flex: 1;
text-align: center;
padding: 20rpx;
font-size: 28rpx;
color: #fff;
}
.cursor {
position: absolute;
left: 13%;
bottom: 0;
width: 20%;
height: 6rpx;
padding: 0 50rpx;
background-color: #fff;
/* 过渡效果 */
transition: all 0.4s;
}
}
// swiper
.swiper {
background-color: #f7f7f8;
}
}
.noLogin {
position: absolute;
color: #333;
top: 50%;
left: 50%;
margin: 0 auto;
transform: translate(-50%, -50%);
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
.img {
width: 96rpx;
height: 96rpx;
}
.title {
color: #0D0D26;
font-size: 36rpx;
margin: 20rpx 0;
}
.desc {
color: #999A9F;
font-size: 28rpx;
margin: 20rpx 0;
}
.button {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
border-radius: 100rpx;
padding: 30rpx 120rpx;
margin: 60rpx 0;
color: #fff;
background: linear-gradient(149deg, #51B6FF 19%, #3775F6 82%);
}
}
}
</style>

@ -1,49 +0,0 @@
/* 前台类目 */
.category {
padding: 32rpx 20rpx;
margin: 16rpx;
background-color: #fff;
border-radius: 4rpx;
.module-title {
font-size: 30rpx;
color: #0D0D26;
padding-bottom: 20rpx;
border-bottom: 2rpx solid #F2F2F2;
}
.cont {
// margin: 20rpx 0 0;
padding: 10rpx 0;
display: flex;
justify-content: center;
flex-wrap: wrap;
min-height: 328rpx;
.category-item {
width: 46%;
border-radius: 16rpx;
margin: 8rpx;
padding: 16rpx 0;
display: flex;
justify-content: center; // flex-direction: row;
align-items: center;
box-sizing: border-box;
background: #FCF4FB;
.left {
.title {
font-size: 26rpx;
color: #666;
}
.desc {
font-size: 24rpx;
color: #7BAFBD;
}
}
.right {
.icon {
width: 100rpx;
height: 100rpx;
}
}
}
}
}

@ -1,50 +0,0 @@
@charset "UTF-8";
/* 前台类目 */
.category {
padding: 32rpx 20rpx;
margin: 16rpx;
background-color: #fff;
border-radius: 4rpx;
}
.category .module-title {
font-size: 30rpx;
color: #0D0D26;
padding-bottom: 20rpx;
border-bottom: 2rpx solid #F2F2F2;
}
.category .cont {
padding: 10rpx 0;
display: flex;
justify-content: center;
flex-wrap: wrap;
min-height: 328rpx;
}
.category .cont .category-item {
width: 46%;
border-radius: 16rpx;
margin: 8rpx;
padding: 16rpx 0;
display: flex;
justify-content: center;
align-items: center;
box-sizing: border-box;
background: #FCF4FB;
}
.category .cont .category-item .left .title {
font-size: 26rpx;
color: #666;
}
.category .cont .category-item .left .desc {
font-size: 24rpx;
color: #7BAFBD;
}
.category .cont .category-item .right .icon {
width: 100rpx;
height: 100rpx;
}

@ -1,71 +0,0 @@
/* 前台类目 */
.class {
padding: 32rpx 20rpx;
margin: 16rpx;
border-radius: 4rpx;
.hd {
display: flex;
justify-content: space-between;
align-items: center;
.module-title {
font-size: 32rpx;
font-weight: 500;
color: #0D0D26;
padding-bottom: 20rpx;
}
.module-more {
color: #95969D;
font-size: 24rpx;
}
}
.module-cont {
// margin: 20rpx 0 0;
padding: 10rpx 0;
display: flex;
justify-content: space-around;
flex-wrap: wrap;
min-height: 328rpx;
.section {
width: 100%;
border-radius: 16rpx;
margin: 8rpx;
padding: 16rpx 0;
display: flex;
justify-content: center; // flex-direction: row;
align-items: center;
box-sizing: border-box;
background: #fff;
.left {
width: 240rpx;
height: 216rpx;
}
.right {
flex: 1;
position: relative;
.desc {
font-size: 24rpx;
}
.footer {
margin: 80rpx 0 0;
display: flex;
flex-direction: row;
.num {
font-size: 24rpx;
}
.action {
display: flex;
flex-direction: row;
margin-left: 10rpx;
font-size: 24rpx;
.item {
margin: 0 4rpx;
display: flex;
align-items: center;
}
}
}
}
}
}
}

@ -1,82 +0,0 @@
@charset "UTF-8";
/* 前台类目 */
.class {
padding: 32rpx 20rpx;
margin: 16rpx;
border-radius: 4rpx;
}
.class .hd {
display: flex;
justify-content: space-between;
align-items: center;
}
.class .hd .module-title {
font-size: 32rpx;
font-weight: 500;
color: #0D0D26;
padding-bottom: 20rpx;
}
.class .hd .module-more {
color: #95969D;
font-size: 24rpx;
}
.class .module-cont {
padding: 10rpx 0;
display: flex;
justify-content: space-around;
flex-wrap: wrap;
min-height: 328rpx;
}
.class .module-cont .section {
width: 100%;
border-radius: 16rpx;
margin: 8rpx;
padding: 16rpx 0;
display: flex;
justify-content: center;
align-items: center;
box-sizing: border-box;
background: #fff;
}
.class .module-cont .section .left {
width: 240rpx;
height: 216rpx;
}
.class .module-cont .section .right {
flex: 1;
position: relative;
}
.class .module-cont .section .right .desc {
font-size: 24rpx;
}
.class .module-cont .section .right .footer {
margin: 80rpx 0 0;
display: flex;
flex-direction: row;
}
.class .module-cont .section .right .footer .num {
font-size: 24rpx;
}
.class .module-cont .section .right .footer .action {
display: flex;
flex-direction: row;
margin-left: 10rpx;
font-size: 24rpx;
}
.class .module-cont .section .right .footer .action .item {
margin: 0 4rpx;
display: flex;
align-items: center;
}

@ -1,48 +0,0 @@
.community {
padding: 32rpx 20rpx;
margin: 16rpx;
border-radius: 4rpx;
.hd {
display: flex;
justify-content: space-between;
align-items: center;
.module-title {
font-size: 32rpx;
font-weight: 500;
color: #0D0D26;
padding-bottom: 20rpx;
}
.module-more {
color: #95969D;
font-size: 24rpx;
}
}
.module-cont {
display: flex;
flex-direction: row;
flex-wrap: wrap;
.section {
width: 47%;
height: auto;
margin: 10rpx 10rpx;
border-radius: 10rpx;
padding: 4rpx 10rpx;
background-color: #fff;
.img {
height: 200rpx;
}
.desc {
color: #0D0D26;
}
.action {
margin: 20rpx 0;
display: flex;
flex-direction: row;
.item {
flex: 1;
color: #95969D;
}
}
}
}
}

@ -1,57 +0,0 @@
.community {
padding: 32rpx 20rpx;
margin: 16rpx;
border-radius: 4rpx;
}
.community .hd {
display: flex;
justify-content: space-between;
align-items: center;
}
.community .hd .module-title {
font-size: 32rpx;
font-weight: 500;
color: #0D0D26;
padding-bottom: 20rpx;
}
.community .hd .module-more {
color: #95969D;
font-size: 24rpx;
}
.community .module-cont {
display: flex;
flex-direction: row;
flex-wrap: wrap;
}
.community .module-cont .section {
width: 47%;
height: auto;
margin: 10rpx 10rpx;
border-radius: 10rpx;
padding: 4rpx 10rpx;
background-color: #fff;
}
.community .module-cont .section .img {
height: 200rpx;
}
.community .module-cont .section .desc {
color: #0D0D26;
}
.community .module-cont .section .action {
margin: 20rpx 0;
display: flex;
flex-direction: row;
}
.community .module-cont .section .action .item {
flex: 1;
color: #95969D;
}

@ -1,51 +0,0 @@
/* 热门推荐 */
.hot {
display: flex;
flex-wrap: wrap;
min-height: 508rpx;
margin: 20rpx 20rpx 0;
border-radius: 10rpx;
background-color: #fff;
.title {
display: flex;
align-items: center;
padding: 24rpx 24rpx 0;
font-size: 32rpx;
color: #262626;
position: relative;
.title-desc {
font-size: 24rpx;
color: #7f7f7f;
margin-left: 18rpx;
}
}
.item {
display: flex;
flex-direction: column;
width: 50%;
height: 254rpx;
border-right: 1rpx solid #eee;
border-top: 1rpx solid #eee;
.title {
justify-content: start;
}
&:nth-child(2n) {
border-right: 0 none;
}
&:nth-child(-n + 2) {
border-top: 0 none;
}
.image {
width: 150rpx;
height: 150rpx;
}
}
.cards {
flex: 1;
padding: 15rpx 20rpx;
display: flex;
justify-content: space-between;
align-items: center;
}
}

@ -1,59 +0,0 @@
@charset "UTF-8";
/* 热门推荐 */
.hot {
display: flex;
flex-wrap: wrap;
min-height: 508rpx;
margin: 20rpx 20rpx 0;
border-radius: 10rpx;
background-color: #fff;
}
.hot .title {
display: flex;
align-items: center;
padding: 24rpx 24rpx 0;
font-size: 32rpx;
color: #262626;
position: relative;
}
.hot .title .title-desc {
font-size: 24rpx;
color: #7f7f7f;
margin-left: 18rpx;
}
.hot .item {
display: flex;
flex-direction: column;
width: 50%;
height: 254rpx;
border-right: 1rpx solid #eee;
border-top: 1rpx solid #eee;
}
.hot .item .title {
justify-content: start;
}
.hot .item:nth-child(2n) {
border-right: 0 none;
}
.hot .item:nth-child(-n + 2) {
border-top: 0 none;
}
.hot .item .image {
width: 150rpx;
height: 150rpx;
}
.hot .cards {
flex: 1;
padding: 15rpx 20rpx;
display: flex;
justify-content: space-between;
align-items: center;
}

@ -1,82 +0,0 @@
.neighborhood-site {
padding: 32rpx 20rpx;
margin: 16rpx;
background-color: #fff;
border-radius: 4rpx;
.module-title {
font-size: 30rpx;
color: #0D0D26;
padding-bottom: 20rpx;
border-bottom: 2rpx solid #F2F2F2;
}
.module-cont {
padding: 20rpx 0;
display: flex;
flex-direction: row;
.left {
width: 140rpx;
height: 140rpx;
border-radius: 12rpx;
}
.md {
flex: 1;
margin: 0 10rpx;
font-size: 24rpx;
color: #0D0D26;
.name {
font-size: 30rpx;
.zuijin {
font-size: 24rpx;
color: #FF7D00;
background: #FFF7E8;
padding: 4rpx 4rpx;
margin-right: 6rpx;
border-radius: 4rpx;
}
}
.time {
color: #95969D;
margin: 8rpx 0;
}
.loction {
color: #0D0D26;
}
}
.right {
.num {
font-size: 28rpx;
color: #95969D
}
.img {
width: 72rpx;
height: 72rpx;
margin-top: 20rpx;
border-radius: 10rpx;
}
}
}
.md-tag {
background: #E8FFFB;
color: #0FC6C2;
margin: 10rpx 0;
font-weight: 400;
font-size: 24rpx;
padding: 6rpx 0rpx;
.tag-before {
background: #0FC6C2;
color: #fff;
font-size: 24rpx;
font-weight: 500;
padding: 4rpx 8rpx;
border-radius: 4rpx;
margin-right: 10rpx;
}
}
.foot-desc {
.item {
font-size: 24rpx;
color: #95969D;
margin: 10rpx 0;
}
}
}

@ -1,91 +0,0 @@
.neighborhood-site {
padding: 32rpx 20rpx;
margin: 16rpx;
background-color: #fff;
border-radius: 4rpx;
}
.neighborhood-site .module-title {
font-size: 30rpx;
color: #0D0D26;
padding-bottom: 20rpx;
border-bottom: 2rpx solid #F2F2F2;
}
.neighborhood-site .module-cont {
padding: 20rpx 0;
display: flex;
flex-direction: row;
}
.neighborhood-site .module-cont .left {
width: 140rpx;
height: 140rpx;
border-radius: 12rpx;
}
.neighborhood-site .module-cont .md {
flex: 1;
margin: 0 10rpx;
font-size: 24rpx;
color: #0D0D26;
}
.neighborhood-site .module-cont .md .name {
font-size: 30rpx;
}
.neighborhood-site .module-cont .md .name .zuijin {
font-size: 24rpx;
color: #FF7D00;
background: #FFF7E8;
padding: 4rpx 4rpx;
margin-right: 6rpx;
border-radius: 4rpx;
}
.neighborhood-site .module-cont .md .time {
color: #95969D;
margin: 8rpx 0;
}
.neighborhood-site .module-cont .md .loction {
color: #0D0D26;
}
.neighborhood-site .module-cont .right .num {
font-size: 28rpx;
color: #95969D;
}
.neighborhood-site .module-cont .right .img {
width: 72rpx;
height: 72rpx;
margin-top: 20rpx;
border-radius: 10rpx;
}
.neighborhood-site .md-tag {
background: #E8FFFB;
color: #0FC6C2;
margin: 10rpx 0;
font-weight: 400;
font-size: 24rpx;
padding: 6rpx 0rpx;
}
.neighborhood-site .md-tag .tag-before {
background: #0FC6C2;
color: #fff;
font-size: 24rpx;
font-weight: 500;
padding: 4rpx 8rpx;
border-radius: 4rpx;
margin-right: 10rpx;
}
.neighborhood-site .foot-desc .item {
font-size: 24rpx;
color: #95969D;
margin: 10rpx 0;
}

@ -1,26 +0,0 @@
/* 热门推荐 */
.phone-contact {
padding: 32rpx 20rpx;
margin: 16rpx;
background-color: #fff;
border-radius: 4rpx;
.module-title {
font-size: 30rpx;
color: #0D0D26;
padding-bottom: 20rpx;
border-bottom: 2rpx solid #F2F2F2;
}
.module-action {
width: 486rpx;
margin: 40rpx auto 0;
border-radius: 50px;
background: #5386E4;
color: #fff;
display: flex;
font-size: 32rpx;
justify-content: center;
align-items: center;
padding: 20rpx 100rpx;
}
}

@ -1,28 +0,0 @@
@charset "UTF-8";
/* 热门推荐 */
.phone-contact {
padding: 32rpx 20rpx;
margin: 16rpx;
background-color: #fff;
border-radius: 4rpx;
}
.phone-contact .module-title {
font-size: 30rpx;
color: #0D0D26;
padding-bottom: 20rpx;
border-bottom: 2rpx solid #F2F2F2;
}
.phone-contact .module-action {
width: 486rpx;
margin: 40rpx auto 0;
border-radius: 50px;
background: #5386E4;
color: #fff;
display: flex;
font-size: 32rpx;
justify-content: center;
align-items: center;
padding: 20rpx 100rpx;
}

@ -1,11 +1,10 @@
<script setup lang="ts">
import { postLoginAPI, postLoginWxMinAPI, postLoginWxMinSimpleAPI } from '@/services/login'
import { postLoginWxMinAPI } from '@/services/login'
import { useMemberStore } from '@/stores'
import type { LoginResult } from '@/types/member'
import { onLoad } from '@dcloudio/uni-app'
import { ref } from 'vue'
// #ifdef MP-WEIXIN
// code
let code = ''
onLoad(async () => {
@ -17,16 +16,12 @@ onLoad(async () => {
const onGetphonenumber: UniHelper.ButtonOnGetphonenumber = async (ev) => {
await checkedAgreePrivacy()
const { encryptedData, iv } = ev.detail
const res = await postLoginWxMinAPI({ code, encryptedData, iv })
loginSuccess(res.result)
}
// #endif
//
const onGetphonenumberSimple = async () => {
await checkedAgreePrivacy()
const res = await postLoginWxMinSimpleAPI('13123456789')
loginSuccess(res.result)
if (encryptedData) {
const res = await postLoginWxMinAPI({ code, encryptedData, iv })
loginSuccess(res.data)
} else {
uni.showToast({ icon: 'none', title: '请授权手机号' })
}
}
const loginSuccess = (profile: LoginResult) => {
@ -37,28 +32,13 @@ const loginSuccess = (profile: LoginResult) => {
uni.showToast({ icon: 'success', title: '登录成功' })
setTimeout(() => {
//
// uni.switchTab({ url: '/pages/my/my' })
uni.switchTab({ url: '/pages/index/index' })
uni.navigateBack()
}, 500)
}
// #ifdef H5
// 13123456789 123456使
const form = ref({
account: '13123456789',
password: '',
})
//
const onSubmit = async () => {
await checkedAgreePrivacy()
const res = await postLoginAPI(form.value)
loginSuccess(res.result)
}
// #endif
//
const isAgreePrivacy = ref(false)
const isAgreePrivacy = ref(true)
const isAgreePrivacyShakeY = ref(false)
const checkedAgreePrivacy = async () => {
if (!isAgreePrivacy.value) {
@ -75,30 +55,17 @@ const checkedAgreePrivacy = async () => {
return Promise.reject(new Error('请先阅读并勾选协议'))
}
}
const onOpenPrivacyContract = () => {
// #ifdef MP-WEIXIN
//
wx.openPrivacyContract({})
// #endif
}
</script>
<template>
<view class="viewport">
<view class="logo">
<image src="/static/images/logo.png"></image>
</view>
<view class="login">
<!-- 网页端表单登录 -->
<!-- #ifdef H5 -->
<input v-model="form.account" class="input" type="text" placeholder="请输入用户名/手机号码" />
<input v-model="form.password" class="input" type="text" password placeholder="请输入密码" />
<button @tap="onSubmit" class="button phone">登录</button>
<!-- #endif -->
<!-- 小程序端授权登录 -->
<!-- #ifdef MP-WEIXIN -->
<view class="button-privacy-wrap">
<button
:hidden="isAgreePrivacy"
@ -112,21 +79,9 @@ const onOpenPrivacyContract = () => {
手机号快捷登录
</button>
</view>
<!-- #endif -->
<view class="extra">
<view class="caption">
<text>其他登录方式</text>
</view>
<view class="options">
<!-- 通用模拟登录 -->
<button @tap="onGetphonenumberSimple">
<text class="icon icon-phone">模拟快捷登录</text>
</button>
</view>
</view>
<view class="tips" :class="{ animate__shakeY: isAgreePrivacyShakeY }">
<label class="label" @tap="isAgreePrivacy = !isAgreePrivacy">
<radio class="radio" color="#28bb9c" :checked="isAgreePrivacy" />
<radio class="radio" color="#3775F6" :checked="isAgreePrivacy" />
<text>登录/注册即视为你同意</text>
</label>
<navigator class="link" hover-class="none" url="./protocal">服务条款</navigator>
@ -152,6 +107,7 @@ page {
.logo {
flex: 1;
text-align: center;
image {
width: 220rpx;
height: 220rpx;
@ -184,6 +140,7 @@ page {
font-size: 28rpx;
border-radius: 72rpx;
color: #fff;
.icon {
font-size: 40rpx;
margin-right: 6rpx;
@ -191,16 +148,17 @@ page {
}
.phone {
background-color: #28bb9c;
background-color: #3775F6;
}
.wechat {
background-color: #06c05f;
background-color: #3775F6;
}
.extra {
flex: 1;
padding: 70rpx 70rpx 0;
.caption {
width: 440rpx;
line-height: 1;
@ -208,6 +166,7 @@ page {
font-size: 26rpx;
color: #999;
position: relative;
text {
transform: translate(-40%);
background-color: #fff;
@ -222,9 +181,11 @@ page {
justify-content: center;
align-items: center;
margin-top: 70rpx;
button {
padding: 0;
background-color: transparent;
&::after {
border: none;
}
@ -250,9 +211,10 @@ page {
border-radius: 50%;
}
}
.icon-weixin::before {
border-color: #06c05f;
color: #06c05f;
border-color: #3775F6;
color: #3775F6;
}
}
}
@ -261,9 +223,11 @@ page {
0% {
transform: translate(0, 0);
}
50% {
transform: translate(0, -5rpx);
}
100% {
transform: translate(0, 0);
}
@ -275,6 +239,7 @@ page {
.button-privacy-wrap {
position: relative;
.button-opacity {
opacity: 0;
position: absolute;
@ -300,7 +265,7 @@ page {
.link {
display: inline;
color: #28bb9c;
color: #3775F6;
}
}
</style>

@ -1,16 +1,16 @@
<template>
<article class="article">
<h1 class="h1 tac">小兔鲜儿用户服务协议</h1>
<h1 class="h1 tac">xxxx用户服务协议</h1>
<p class="p tac">版本生效日期2023年11月6日</p>
<h2 class="h2">服务条款的确认及接受</h2>
<p class="p">
() 小兔鲜儿 网站各项电子服务的所有权和运作权归属于传智教育所有<strong class="strong"
() xxxx 网站各项电子服务的所有权和运作权归属于传智教育所有<strong class="strong"
>仅用于IT培训教学使用为保障您的个人信息安全请勿向平台录入任何个人敏感信息如手机号身份证号等</strong
>本网站提供的服务将完全按照其发布的服务条款和操作规则严格执行您确认所有服务条款并完成注册程序时本协议在您与本网站间成立并发生法律效力同时您成为本网站正式用户
</p>
<p class="p">
()
小兔鲜儿隐私政策平台规则单独协议均为本协议的补充协议与本协议不可分割且具有同等法律效力如您使用小兔鲜儿平台服务视为您同意上述补充协议
xxxx隐私政策平台规则单独协议均为本协议的补充协议与本协议不可分割且具有同等法律效力如您使用xxxx平台服务视为您同意上述补充协议
</p>
<p class="p">
()
@ -22,7 +22,7 @@
</p>
<p class="p">
()
除非另有明确的书面说明,小兔鲜儿不对本网站的运营及其包含在本网站上的信息内容材料产品包括软件或服务作任何形式的明示或默示的声明或担保根据中华人民共和国法律另有规定的以外
除非另有明确的书面说明,xxxx不对本网站的运营及其包含在本网站上的信息内容材料产品包括软件或服务作任何形式的明示或默示的声明或担保根据中华人民共和国法律另有规定的以外
</p>
<p class="p">
()
@ -31,88 +31,88 @@
<h2 class="h2">账户注册管理及使用</h2>
<h4 class="h4">() 用户资格</h4>
<p class="p">
您确认在您开始注册程序使用小兔鲜儿平台服务前您应当具备中华人民共和国法律规定的与您行为相适应的民事行为能力若您不具备前述与您行为相适应的民事行为能力需要在监护人的监护参与下才能注册并使用本网站您及您的监护人应依照法律规定承担因此而导致的一切后果
此外您还需确保您不是任何国家地区或国际组织实施的贸易限制经济制裁或其他法律法规限制的对象也未直接或间接为前述对象提供资金商品或服务否则您应当停止使用小兔鲜儿平台服务同时您理解违反前述要求可能会造成您无法正常注册及使用小兔鲜儿平台服务
您确认在您开始注册程序使用xxxx平台服务前您应当具备中华人民共和国法律规定的与您行为相适应的民事行为能力若您不具备前述与您行为相适应的民事行为能力需要在监护人的监护参与下才能注册并使用本网站您及您的监护人应依照法律规定承担因此而导致的一切后果
此外您还需确保您不是任何国家地区或国际组织实施的贸易限制经济制裁或其他法律法规限制的对象也未直接或间接为前述对象提供资金商品或服务否则您应当停止使用xxxx平台服务同时您理解违反前述要求可能会造成您无法正常注册及使用xxxx平台服务
</p>
<h4 class="h4">() 账户注册</h4>
<p class="p">
1
您按照注册页面提示填写信息阅读并同意本协议且完成全部注册程序后您可获得小兔鲜儿平台账户并成为小兔鲜儿平台用户您设置的小兔鲜儿账号名/昵称/头像等不得违反国家法律法规及小兔鲜儿平台相关规则关于账号注册的管理规定未经他人许可不得用他人名义包括但不限于冒用他人姓名名称字号头像等或采取其他足以让人引起混淆的方式开设账号不得恶意注册小兔鲜儿账号否则小兔鲜儿平台经营者有权拒绝设置或收回您的账号名/昵称账号名的回收不影响您以邮箱手机号码登录小兔鲜儿平台并使用小兔鲜儿平台服务
您按照注册页面提示填写信息阅读并同意本协议且完成全部注册程序后您可获得xxxx平台账户并成为xxxx平台用户您设置的xxxx账号名/昵称/头像等不得违反国家法律法规及xxxx平台相关规则关于账号注册的管理规定未经他人许可不得用他人名义包括但不限于冒用他人姓名名称字号头像等或采取其他足以让人引起混淆的方式开设账号不得恶意注册xxxx账号否则xxxx平台经营者有权拒绝设置或收回您的账号名/昵称账号名的回收不影响您以邮箱手机号码登录xxxx平台并使用xxxx平台服务
</p>
<p class="p">
2
小兔鲜儿平台原则上只允许每位用户使用一个小兔鲜儿平台账户如有证据证明或小兔鲜儿根据小兔鲜儿平台规则判断您存在不当注册或不当使用多个小兔鲜儿平台账户的情形小兔鲜儿平台可采取冻结或关闭账户取消订单拒绝提供服务等措施如给小兔鲜儿平台及相关方造成损失的您还应承担赔偿责任
xxxx平台原则上只允许每位用户使用一个xxxx平台账户如有证据证明或xxxx根据xxxx平台规则判断您存在不当注册或不当使用多个xxxx平台账户的情形xxxx平台可采取冻结或关闭账户取消订单拒绝提供服务等措施如给xxxx平台及相关方造成损失的您还应承担赔偿责任
</p>
<p class="p">
3
在使用小兔鲜儿平台服务时您应当按小兔鲜儿平台页面的提示准确完整地提供您的信息包括您的姓名及电子邮件地址联系电话联系地址等以便小兔鲜儿或其他服务方与您联系您了解并同意您有义务保持您提供信息的真实性及有效性
在使用xxxx平台服务时您应当按xxxx平台页面的提示准确完整地提供您的信息包括您的姓名及电子邮件地址联系电话联系地址等以便xxxx或其他服务方与您联系您了解并同意您有义务保持您提供信息的真实性及有效性
</p>
<h4 class="h4">() 账户登录</h4>
<p class="p">
您有权使用您设置或确认的小兔鲜儿用户名手机号码以下简称账户名称及您设置的密码账户名称及密码合称账户或通过授权使用您合法拥有的第三方软件或平台用户账号如微信账号QQ账号等登录小兔鲜儿平台但第三方软件或平台对此有限制或禁止的除外当您以前述已有账号登录使用的同样适用本协议中的相关条款
您有权使用您设置或确认的xxxx用户名手机号码以下简称账户名称及您设置的密码账户名称及密码合称账户或通过授权使用您合法拥有的第三方软件或平台用户账号如微信账号QQ账号等登录xxxx平台但第三方软件或平台对此有限制或禁止的除外当您以前述已有账号登录使用的同样适用本协议中的相关条款
</p>
<p class="p">
您理解并同意除您登录小兔鲜儿平台以外您还可以使用小兔鲜儿账号登录小兔鲜儿及其关联方或其他合作方提供的其他软件服务您以小兔鲜儿账号登录前述服务的同样应受其他软件服务实际提供方的用户协议及其他协议条款约束
您理解并同意除您登录xxxx平台以外您还可以使用xxxx账号登录xxxx及其关联方或其他合作方提供的其他软件服务您以xxxx账号登录前述服务的同样应受其他软件服务实际提供方的用户协议及其他协议条款约束
</p>
<h4 class="h4">() 实名认证</h4>
<p class="p">
作为小兔鲜儿平台经营者为使您更好地使用小兔鲜儿平台的各项服务保障您的账户安全小兔鲜儿可要求您按照相关法律法规规定完成实名认证
作为xxxx平台经营者为使您更好地使用xxxx平台的各项服务保障您的账户安全xxxx可要求您按照相关法律法规规定完成实名认证
</p>
<h4 class="h4">() 更新维护</h4>
<p class="p">
您应当及时更新您提供的信息在法律有明确规定要求小兔鲜儿作为平台服务提供者必须对部分用户的信息进行核实的情况下小兔鲜儿将依法不时地对您的信息进行检查核实您应当配合提供最新真实完整有效的信息
您应当及时更新您提供的信息在法律有明确规定要求xxxx作为平台服务提供者必须对部分用户的信息进行核实的情况下xxxx将依法不时地对您的信息进行检查核实您应当配合提供最新真实完整有效的信息
</p>
<p class="p">
小兔鲜儿按您最后一次提供的信息与您联系未果您未按小兔鲜儿的要求及时提供信息您提供的信息存在明显不实或行政司法机关核实您提供的信息无效的您将承担因此对您自身他人及小兔鲜儿造成的全部损失与不利后果小兔鲜儿可向您发出询问或要求整改的通知并要求您进行重新认证直至中止终止对您提供部分或全部小兔鲜儿平台服务小兔鲜儿对此不承担责任
xxxx按您最后一次提供的信息与您联系未果您未按xxxx的要求及时提供信息您提供的信息存在明显不实或行政司法机关核实您提供的信息无效的您将承担因此对您自身他人及xxxx造成的全部损失与不利后果xxxx可向您发出询问或要求整改的通知并要求您进行重新认证直至中止终止对您提供部分或全部xxxx平台服务xxxx对此不承担责任
</p>
<h4 class="h4">() 账户管理</h4>
<p class="p">
1
由于您的小兔鲜儿平台账户关联您的个人信息及小兔鲜儿平台商业信息您的小兔鲜儿平台账户仅限您本人使用您应对您账户下的所有行为结果负责不得以任何方式转让否则小兔鲜儿平台有权追究您的违约责任且由此产生的责任及后果均由您自行承担您直接或间接授权第三方使用您小兔鲜儿平台账户或获取您账户项下信息的行为后果亦由您自行承担小兔鲜儿根据小兔鲜儿平台规则中约定的违约认定程序及标准判断您小兔鲜儿平台账户的使用可能危及您的账户安全及/或小兔鲜儿平台信息安全的小兔鲜儿平台可拒绝提供相应服务或终止本协议
由于您的xxxx平台账户关联您的个人信息及xxxx平台商业信息您的xxxx平台账户仅限您本人使用您应对您账户下的所有行为结果负责不得以任何方式转让否则xxxx平台有权追究您的违约责任且由此产生的责任及后果均由您自行承担您直接或间接授权第三方使用您xxxx平台账户或获取您账户项下信息的行为后果亦由您自行承担xxxx根据xxxx平台规则中约定的违约认定程序及标准判断您xxxx平台账户的使用可能危及您的账户安全及/或xxxx平台信息安全的xxxx平台可拒绝提供相应服务或终止本协议
</p>
<p class="p">
2
您的账户为您自行设置并由您保管小兔鲜儿任何时候均不会主动要求您提供您的账户密码因此建议您务必保管好您的账户并确保您在每个上网时段结束时退出登录并以正确步骤离开小兔鲜儿平台
您的账户为您自行设置并由您保管xxxx任何时候均不会主动要求您提供您的账户密码因此建议您务必保管好您的账户并确保您在每个上网时段结束时退出登录并以正确步骤离开xxxx平台
</p>
<p class="p">
3
账户因您主动泄露或因您遭受他人攻击诈骗等行为导致的损失及后果小兔鲜儿并不承担责任您应通过司法行政等救济途径向侵权行为人追偿如发现任何未经授权使用您账户登录小兔鲜儿平台或其他可能导致您账户遭窃遗失的情况建议您立即通知小兔鲜儿您理解小兔鲜儿对您的任何请求采取行动均需要合理时间且小兔鲜儿应您请求而采取的行动可能无法避免或阻止侵害后果的形成或扩大小兔鲜儿存在法定过错外小兔鲜儿不承担责任
账户因您主动泄露或因您遭受他人攻击诈骗等行为导致的损失及后果xxxx并不承担责任您应通过司法行政等救济途径向侵权行为人追偿如发现任何未经授权使用您账户登录xxxx平台或其他可能导致您账户遭窃遗失的情况建议您立即通知xxxx您理解xxxx对您的任何请求采取行动均需要合理时间且xxxx应您请求而采取的行动可能无法避免或阻止侵害后果的形成或扩大xxxx存在法定过错外xxxx不承担责任
</p>
<p class="p">
4
您理解并同意为充分使用账号资源如您在注册后未及时进行初次登录使用或连续12个月未登录任一小兔鲜儿平台且不存在未到期的有效业务的小兔鲜儿有权收回您的账号您可能无法通过您此前持有的账号登录小兔鲜儿平台您该账号下任何个性化设置如头像/昵称即将无法恢复在收回您的账号之前小兔鲜儿将以适当方式做出提示如您在收到相关提示后一定期限内仍未登录使用账号小兔鲜儿将收回账号
您理解并同意为充分使用账号资源如您在注册后未及时进行初次登录使用或连续12个月未登录任一xxxx平台且不存在未到期的有效业务的xxxx有权收回您的账号您可能无法通过您此前持有的账号登录xxxx平台您该账号下任何个性化设置如头像/昵称即将无法恢复在收回您的账号之前xxxx将以适当方式做出提示如您在收到相关提示后一定期限内仍未登录使用账号xxxx将收回账号
</p>
<h4 class="h4">() 账号注销</h4>
<p class="p">
如您需要终止使用小兔鲜儿账号服务符合以下条件的您可以申请注销您的账号1您仅能申请注销您本人的账号并依照小兔鲜儿账号注销须知进行注销2您仍应对您在注销账号前使用小兔鲜儿账号服务期间的行为承担责任特别提示您您申请同意注销账户的视为您放弃账户信息以及该账户在平台的资产虚拟权益等小兔鲜儿无法为您恢复前述服务这可能对您主张售后服务带来不便
如您需要终止使用xxxx账号服务符合以下条件的您可以申请注销您的账号1您仅能申请注销您本人的账号并依照xxxx账号注销须知进行注销2您仍应对您在注销账号前使用xxxx账号服务期间的行为承担责任特别提示您您申请同意注销账户的视为您放弃账户信息以及该账户在平台的资产虚拟权益等xxxx无法为您恢复前述服务这可能对您主张售后服务带来不便
</p>
<p class="p"></p>
<h3 class="h3">小兔鲜儿平台服务</h3>
<h3 class="h3">xxxx平台服务</h3>
<p class="p">
您有权在小兔鲜儿平台上享受商品及/或服务的浏览收藏购买与评价配送和交付平台活动交易争议处理信息交流及分享等服务详情您可登录小兔鲜儿平台查看
您有权在xxxx平台上享受商品及/或服务的浏览收藏购买与评价配送和交付平台活动交易争议处理信息交流及分享等服务详情您可登录xxxx平台查看
</p>
<h4 class="h4">() 商品及/或服务的浏览收藏</h4>
<p class="p">
在您浏览我们网站或客户端的过程中小兔鲜儿为您提供了信息分类关键词检索筛选收藏及关注等功能以更好地匹配您的需求您可以对您感兴趣的商品及/或服务进行收藏添加至购物车关注您所感兴趣的店铺/品牌等
在您浏览我们网站或客户端的过程中xxxx为您提供了信息分类关键词检索筛选收藏及关注等功能以更好地匹配您的需求您可以对您感兴趣的商品及/或服务进行收藏添加至购物车关注您所感兴趣的店铺/品牌等
</p>
<h4 class="h4">() 商品及/或服务的购买</h4>
<p class="p">
1
当您在小兔鲜儿平台购买商品及/或服务时请您仔细确认所购商品的名称价格数量型号规格尺寸联系地址电话收货人等信息收货人与您本人不一致的收货人的行为和意思表示视为您的行为和意思表示您应对收货人的行为及意思表示的法律后果承担连带责任
当您在xxxx平台购买商品及/或服务时请您仔细确认所购商品的名称价格数量型号规格尺寸联系地址电话收货人等信息收货人与您本人不一致的收货人的行为和意思表示视为您的行为和意思表示您应对收货人的行为及意思表示的法律后果承担连带责任
</p>
<p class="p">
2
您的购买行为应当符合法律规定为生活消费需要购买使用商品或者接受服务不得存在对商品及/或服务实施恶意购买恶意维权等扰乱小兔鲜儿平台正常交易秩序的行为基于维护小兔鲜儿平台交易秩序及交易安全的需要小兔鲜儿发现上述情形时可主动执行包括但不限于暂停或停止服务取消订单等小兔鲜儿认为有必要的管控措施等操作
您的购买行为应当符合法律规定为生活消费需要购买使用商品或者接受服务不得存在对商品及/或服务实施恶意购买恶意维权等扰乱xxxx平台正常交易秩序的行为基于维护xxxx平台交易秩序及交易安全的需要xxxx发现上述情形时可主动执行包括但不限于暂停或停止服务取消订单等xxxx认为有必要的管控措施等操作
</p>
<p class="p">
3 您理解并同意本网站上销售商展示的商品和价格等信息<strong class="strong"
>仅用于教学展示使用</strong
>如果您下单购买商品或服务并完成支付不会产生实际购买商品或服务的合同关系小兔鲜儿平台无需发货该购买行为仅视为教学测试使用
>如果您下单购买商品或服务并完成支付不会产生实际购买商品或服务的合同关系xxxx平台无需发货该购买行为仅视为教学测试使用
</p>
<h4 class="h4">() 配送和交付</h4>
<p class="p">
您在本网站购买的商品<strong class="strong">仅为教学测试使用</strong
>并未实际产生交易金额因此小兔鲜儿平台不会根据您填写的物流信息进行实际配送服务
>并未实际产生交易金额因此xxxx平台不会根据您填写的物流信息进行实际配送服务
</p>
<p class="p"></p>
<h3 class="h3">用户个人信息保护及授权</h3>
@ -120,24 +120,24 @@
() 您知悉并同意为方便您使用本网站相关服务本网站将存储您在使用时的必要信息
</h4>
<p class="p">
包括但不限于您的真实姓名性别生日配送地址联系方式通讯录相册日历定位信息等除法律法规规定的情形外未经您的许可小兔鲜儿不会向第三方公开透露您的个人信息小兔鲜儿对相关信息采取专业加密存储与传输方式利用合理措施保障用户个人信息的安全小兔鲜儿平台网站或客户端未设置独立隐私政策但使用了小兔鲜儿平台账号登陆相应网站或客户端的为保护您的隐私权我们将参照适用小兔鲜儿隐私政策的要求对您的个人信息进行收集存储使用披露和保护小兔鲜儿希望通过隐私政策向您清楚地介绍小兔鲜儿对您个人信息的处理方式因此小兔鲜儿建议您完整地阅读隐私政策以帮助您更好地保护您的隐私权
包括但不限于您的真实姓名性别生日配送地址联系方式通讯录相册日历定位信息等除法律法规规定的情形外未经您的许可xxxx不会向第三方公开透露您的个人信息xxxx对相关信息采取专业加密存储与传输方式利用合理措施保障用户个人信息的安全xxxx平台网站或客户端未设置独立隐私政策但使用了xxxx平台账号登陆相应网站或客户端的为保护您的隐私权我们将参照适用xxxx隐私政策的要求对您的个人信息进行收集存储使用披露和保护xxxx希望通过隐私政策向您清楚地介绍xxxx对您个人信息的处理方式因此xxxx建议您完整地阅读隐私政策以帮助您更好地保护您的隐私权
</p>
<h4 class="h4">() 您充分理解并同意</h4>
<p class="p">
1
您理解并同意通过邮件短信电话消息等平台渠道形式接收相关订单信息促销活动商品推荐等内容您有权通过您注册时填写的手机号码或者电子邮箱获取您感兴趣的商品广告信息促销优惠等商业性信息推广或信息包括商业或非商业信息您如果不愿意接收此类信息您有权通过小兔鲜儿提供的相应的退订功能进行退订
您理解并同意通过邮件短信电话消息等平台渠道形式接收相关订单信息促销活动商品推荐等内容您有权通过您注册时填写的手机号码或者电子邮箱获取您感兴趣的商品广告信息促销优惠等商业性信息推广或信息包括商业或非商业信息您如果不愿意接收此类信息您有权通过xxxx提供的相应的退订功能进行退订
</p>
<p class="p">
2
为配合行政监管机关司法机关执行工作在法律规定范围内小兔鲜儿有权向上述行政司法机关提供您在使用本网站时所储存的相关信息包括但不限于您的注册信息等或使用相关信息进行证据保全包括但不限于公证见证等
为配合行政监管机关司法机关执行工作在法律规定范围内xxxx有权向上述行政司法机关提供您在使用本网站时所储存的相关信息包括但不限于您的注册信息等或使用相关信息进行证据保全包括但不限于公证见证等
</p>
<p class="p">
3
小兔鲜儿依法保障您在安装或使用过程中的知情权和选择权在您使用本网站服务过程中涉及您设备自带功能的服务会提前征得您同意您一经确认小兔鲜儿有权开启包括但不限于收集地理位置读取通讯录使用摄像头启用录音等提供服务必要的辅助功能
xxxx依法保障您在安装或使用过程中的知情权和选择权在您使用本网站服务过程中涉及您设备自带功能的服务会提前征得您同意您一经确认xxxx有权开启包括但不限于收集地理位置读取通讯录使用摄像头启用录音等提供服务必要的辅助功能
</p>
<p class="p">
4
小兔鲜儿有权根据实际情况在法律规定范围内自行决定单个用户在本网站及服务中数据的最长储存期限以及用户日志的储存期限并在服务器上为其分配数据最大存储空间等
xxxx有权根据实际情况在法律规定范围内自行决定单个用户在本网站及服务中数据的最长储存期限以及用户日志的储存期限并在服务器上为其分配数据最大存储空间等
</p>
<p class="p"></p>
<h3 class="h3">用户行为规范</h3>
@ -155,7 +155,7 @@
<p class="p">2 不得利用本网站从事洗钱窃取商业秘密窃取个人信息等违法犯罪活动</p>
<p class="p">
3
不得企图干扰破坏小兔鲜儿系统或网站的正常运转故意传播恶意程序或病毒以及其他破坏干扰正常网络信息服务的行为
不得企图干扰破坏xxxx系统或网站的正常运转故意传播恶意程序或病毒以及其他破坏干扰正常网络信息服务的行为
</p>
<p class="p">
4
@ -169,30 +169,30 @@
<p class="p">7 不得发布任何侵犯他人个人信息著作权商标权等知识产权或合法权利的内容</p>
<p class="p">
8
不得冒充他人或利用他人的名义使用小兔鲜儿软件服务或传播任何信息恶意使用注册账号导致其他用户误认的
不得冒充他人或利用他人的名义使用xxxx软件服务或传播任何信息恶意使用注册账号导致其他用户误认的
</p>
<p class="p">
9
不得存在可能破坏篡改删除影响小兔鲜儿平台任何系统正常运行或未经授权秘密获取小兔鲜儿平台及其他用户的数据个人资料的病毒木马爬虫等恶意软件程序代码的
不得存在可能破坏篡改删除影响xxxx平台任何系统正常运行或未经授权秘密获取xxxx平台及其他用户的数据个人资料的病毒木马爬虫等恶意软件程序代码的
</p>
<p class="p">10不得恶意注册小兔鲜儿账号包括但不限于频繁批量注册账号注销账号</p>
<p class="p">10不得恶意注册xxxx账号包括但不限于频繁批量注册账号注销账号</p>
<p class="p">11不得发布其他对网络生态造成不良影响的内容及法律行政法规禁止的其他内容</p>
<h4 class="h4">()您须对自己在网上的言论和行为承担法律责任</h4>
<p class="p">
您若在本网站上散布和传播反动色情或其它违反国家法律的信息本网站的系统记录有可能作为您违反法律的证据小兔鲜儿可对您发布的信息依法或依本协议进行删除或屏蔽
您若在本网站上散布和传播反动色情或其它违反国家法律的信息本网站的系统记录有可能作为您违反法律的证据xxxx可对您发布的信息依法或依本协议进行删除或屏蔽
</p>
<h4 class="h4">() 除非法律允许或小兔鲜儿书面许可您使用本网站过程中不得从事下列行为</h4>
<h4 class="h4">() 除非法律允许或xxxx书面许可您使用本网站过程中不得从事下列行为</h4>
<p class="p">1 删除本网站及其副本上关于著作权的信息</p>
<p class="p">
2 对本网站进行反向工程反向汇编反向编译或者以其他方式尝试发现本网站的源代码
</p>
<p class="p">
3
小兔鲜儿拥有知识产权的内容进行使用出租出借复制修改链接转载汇编发表出版建立镜像站点等
xxxx拥有知识产权的内容进行使用出租出借复制修改链接转载汇编发表出版建立镜像站点等
</p>
<p class="p">
4
对本网站或者本网站运行过程中释放到任何终端内存中的数据网站运行过程中客户端与服务器端的交互数据以及本网站运行所必需的系统数据进行复制修改增加删除挂接运行或创作任何衍生作品形式包括但不限于使用插件外挂或非经小兔鲜儿授权的第三方工具/服务接入本网站和相关系统
对本网站或者本网站运行过程中释放到任何终端内存中的数据网站运行过程中客户端与服务器端的交互数据以及本网站运行所必需的系统数据进行复制修改增加删除挂接运行或创作任何衍生作品形式包括但不限于使用插件外挂或非经xxxx授权的第三方工具/服务接入本网站和相关系统
</p>
<p class="p">
5
@ -200,7 +200,7 @@
</p>
<p class="p">
6
通过非小兔鲜儿开发授权的第三方软件插件外挂系统登录或使用本网站及服务或制作发布传播上述工具
通过非xxxx开发授权的第三方软件插件外挂系统登录或使用本网站及服务或制作发布传播上述工具
</p>
<p class="p">7 自行或者授权他人第三方软件对本网站及其组件模块数据进行干扰</p>
<h3 class="h3">不可抗力或其他免责事由</h3>
@ -209,16 +209,16 @@
您理解并同意在使用本服务的过程中可能会遇到不可抗力等风险因素使本服务协议下的服务发生中断或终止
</h4>
<p class="p">
不可抗力是指不能预见不能克服并不能避免且对一方或双方造成重大影响的客观事件包括但不限于信息网络设备维护信息网络连接故障电脑通讯或其他系统的故障电力故障罢工劳动争议暴乱起义骚乱生产力或生产资料不足火灾洪水风暴爆炸战争政府行为法律法规变动司法行政机关的命令其他不可抗力或第三方的不作为而造成的不能服务或延迟服务等行为出现上述情况时小兔鲜儿将努力在第一时间与相关部门配合及时进行修复但是由此给您造成的损失小兔鲜儿在法律允许的范围内免责
不可抗力是指不能预见不能克服并不能避免且对一方或双方造成重大影响的客观事件包括但不限于信息网络设备维护信息网络连接故障电脑通讯或其他系统的故障电力故障罢工劳动争议暴乱起义骚乱生产力或生产资料不足火灾洪水风暴爆炸战争政府行为法律法规变动司法行政机关的命令其他不可抗力或第三方的不作为而造成的不能服务或延迟服务等行为出现上述情况时xxxx将努力在第一时间与相关部门配合及时进行修复但是由此给您造成的损失xxxx在法律允许的范围内免责
</p>
<h4 class="h4">
() 您理解并同意在法律允许的范围内小兔鲜儿对以下事由所导致的服务中断或终止不承担责任
() 您理解并同意在法律允许的范围内xxxx对以下事由所导致的服务中断或终止不承担责任
</h4>
<p class="p">1 受到计算机病毒木马或其他恶意程序黑客攻击的破坏</p>
<p class="p">2 用户或小兔鲜儿的电脑软件系统硬件和通信线路出现故障</p>
<p class="p">2 用户或xxxx的电脑软件系统硬件和通信线路出现故障</p>
<p class="p">3 用户操作不当</p>
<p class="p">4 用户通过非小兔鲜儿授权的方式使用本服务</p>
<p class="p">5 其他小兔鲜儿无法控制或合理预见的情形</p>
<p class="p">4 用户通过非xxxx授权的方式使用本服务</p>
<p class="p">5 其他xxxx无法控制或合理预见的情形</p>
</article>
</template>

@ -1,20 +1,22 @@
<script setup lang="ts">
import { ref } from 'vue'
import { ref, reactive } from 'vue'
import { useGuessList } from '@/composables'
import { useMemberStore } from '@/stores'
//
const { safeAreaInsets } = uni.getSystemInfoSync()
//
const orderTypes = [
{ type: '1', text: '待付款', icon: 'icon-currency' },
{ type: '2', text: '待发货', icon: 'icon-gift' },
{ type: '3', text: '待收货', icon: 'icon-check' },
{ type: '4', text: '待评价', icon: 'icon-comment' },
]
//
const memberStore = useMemberStore()
const { guessRef, onScrolltolower } = useGuessList()
const handleOrderList = () => {
uni.navigateTo({ url: '/pages/orerdList/orerdList' })
}
const handleOrderAuto = () => {
uni.navigateTo({ url: '/pages/orderAuto/orderAuto' })
}
const handleNewsList = () => {
uni.navigateTo({ url: '/pages/newsList/newsList' })
}
</script>
<template>
@ -59,30 +61,55 @@ const { guessRef, onScrolltolower } = useGuessList()
</view>
<!-- 我的订单 -->
<view class="orders">
<view class="title">
我的订单
<navigator class="navigator" url="/pagesOrder/list/list?type=0" hover-class="none">
查看全部订单<text class="icon-right"></text>
</navigator>
</view>
<view class="section">
<!-- 订单 -->
<navigator
v-for="item in orderTypes"
:key="item.type"
:class="item.icon"
:url="`/pagesOrder/list/list?type=${item.type}`"
class="navigator"
hover-class="none"
>
{{ item.text }}
</navigator>
<!-- 客服 -->
<!-- #ifdef MP-WEIXIN -->
<button class="contact icon-handset" open-type="contact">售后</button>
<!-- #endif -->
<view class="card">
<view class="away-all">
<text class="label">回收收货里程</text>
<view class="num">12,365公里</view>
</view>
<view class="order-num">
<text class="label">订单总数</text>
<view class="num">1,243</view>
</view>
</view>
</view>
<view class="list">
<button hover-class="none" class="item arrow" @click="handleOrderList">
<image class="img" src="/static/images/order_my.png" mode="scaleToFill" />
<view class="text"> 已完成订单 </view>
</button>
<!-- <button hover-class="none" class="item arrow" open-type="feedback">问题反馈</button> -->
<button hover-class="none" class="item arrow" open-type="contact">
<image class="img" src="/static/images/kefu_my.png" mode="scaleToFill" />
<view class="text"> 联系我们 </view>
</button>
<button hover-class="none" class="item arrow" @click="handleOrderAuto">
<image class="img" src="/static/images/order_auto_my.png" mode="scaleToFill" />
<view class="text"> 自动接单 </view>
</button>
<navigator
class="settings item arrow"
url="/pagesMember/settings/settings"
hover-class="none"
>
<image class="img" src="/static/images/lock_my.png" mode="scaleToFill" />
<view class="text"> 设置 </view>
</navigator>
<!-- <button hover-class="none" class="item arrow" open-type="contact">
<image
class="img"
src="/static/images/seting_my.png"
mode="scaleToFill"
/>
<view class="text">
检查更新
</view>
</button> -->
<button hover-class="none" class="item arrow" @click="handleNewsList">
<image class="img" src="/static/images/detail_concat.png" mode="scaleToFill" />
<view class="text"> 消息列表 </view>
</button>
</view>
<!-- 猜你喜欢 -->
<!-- <view class="guess">
<XtxGuess ref="guessRef" />
@ -100,7 +127,8 @@ page {
.viewport {
height: 100%;
background-repeat: no-repeat;
background-image: url(https://pcapi-xiaotuxian-front-devtest.itheima.net/miniapp/images/center_bg.png);
background-image: url('http://174.137.59.38/static/bg.png');
// background-color: #3775F6;
background-size: 100% auto;
}
@ -183,46 +211,138 @@ page {
border-radius: 10rpx;
box-shadow: 0 4rpx 6rpx rgba(240, 240, 240, 0.6);
.title {
height: 40rpx;
line-height: 40rpx;
font-size: 28rpx;
color: #1e1e1e;
.navigator {
font-size: 24rpx;
color: #939393;
float: right;
}
}
.section {
width: 100%;
.card {
display: flex;
flex-direction: row;
justify-content: space-between;
padding: 40rpx 20rpx 10rpx;
.navigator,
.contact {
.away-all {
flex: 1;
text-align: center;
.label {
font-size: 32rpx;
color: #0d0d26;
}
.num {
color: #999a9f;
font-size: 28rpx;
margin-top: 20rpx;
}
border-right: 2rpx solid #f2f2f2;
}
.order-num {
flex: 1;
text-align: center;
font-size: 24rpx;
color: #333;
&::before {
display: block;
font-size: 60rpx;
color: #ff9545;
.label {
font-size: 32rpx;
color: #0d0d26;
}
&::after {
border: none;
.num {
color: #999a9f;
font-size: 28rpx;
margin-top: 20rpx;
}
}
.contact {
padding: 0;
margin: 0;
border: 0;
background-color: transparent;
line-height: inherit;
}
// .title {
// height: 40rpx;
// line-height: 40rpx;
// font-size: 28rpx;
// color: #1e1e1e;
// .navigator {
// font-size: 24rpx;
// color: #939393;
// float: right;
// }
// }
// .section {
// width: 100%;
// display: flex;
// justify-content: space-between;
// padding: 40rpx 20rpx 10rpx;
// .navigator,
// .contact {
// text-align: center;
// font-size: 24rpx;
// color: #333;
// &::before {
// display: block;
// font-size: 60rpx;
// color: #ff9545;
// }
// &::after {
// border: none;
// }
// }
// .contact {
// padding: 0;
// margin: 0;
// border: 0;
// background-color: transparent;
// line-height: inherit;
// }
// }
}
/* 列表 */
.list {
padding: 0 20rpx;
margin-bottom: 20rpx;
border-radius: 10rpx;
margin: 40rpx 20rpx 0;
.item {
line-height: 90rpx;
padding-left: 10rpx;
font-size: 30rpx;
color: #333;
border-top: 1rpx solid #ddd;
position: relative;
text-align: left;
border-radius: 0;
display: flex;
align-items: center;
&::after {
width: auto;
height: auto;
left: auto;
border: none;
}
&:first-child {
border: none;
}
&::after {
right: 5rpx;
}
}
.arrow::after {
content: '\e6c2';
position: absolute;
top: 50%;
color: #ccc;
font-family: 'erabbit' !important;
font-size: 32rpx;
transform: translateY(-50%);
}
.img {
width: 40rpx;
height: 40rpx;
margin-right: 20rpx;
}
}
/* 猜你喜欢 */

@ -0,0 +1,161 @@
<script setup lang="ts">
import { onMounted, ref, defineEmits } from 'vue'
import type { OrderListParams } from '@/types/order'
//
const isFinish = ref(false)
//
const isTriggered = ref(false)
// porps
const props = defineProps<{
orderState: number
}>()
//
const isLoading = ref(false)
//
const queryParams: Required<OrderListParams> = {
page: 1,
pageSize: 5,
orderState: props.orderState,
}
const dataList = ref([
{
id: 1,
name: 'dd',
},
{
id: 2,
name: 'dd',
},
{
id: 3,
name: 'dd',
},
{
id: 4,
name: 'dd',
},
{
id: 5,
name: 'dd',
},
])
const getMemberOrderData = async () => {
// 退
if (isLoading.value) return
// 退
if (isFinish.value === true) {
return uni.showToast({ icon: 'none', title: '没有更多数据~' })
}
//
isLoading.value = true
//
const res = await getMemberOrderAPI(queryParams)
// debugger
//
isLoading.value = false
//
orderList.value.push(...res.result.items)
//
if (queryParams.page < res.result.pages) {
//
queryParams.page++
} else {
//
isFinish.value = true
}
}
onMounted(() => {
// getMemberOrderData()
// const arr: object[] = [
// {
// id: 1,
// name: '233'
// }
// ]
// orderList.value.push(...arr)
})
//
const onRefresherrefresh = async () => {
//
isTriggered.value = true
//
queryParams.page = 1
orderList.value = []
isFinish.value = false
//
await getMemberOrderData()
//
isTriggered.value = false
}
</script>
<template>
<scroll-view
enable-back-to-top
scroll-y
class="orders"
refresher-enabled
:refresher-triggered="isTriggered"
@refresherrefresh="onRefresherrefresh"
@scrolltolower="getMemberOrderData"
>
<view class="dataList">
<view class="item" v-for="item in dataList" :key="item.id">
<image src="/static/images/news_icon.png" mode="aspectFit" class="img"></image>
<view class="right">
<view class="hd">
<view class="title">13277590688</view>
<view class="time">4分钟前</view>
</view>
<view class="info">什么时间到</view>
</view>
</view>
</view>
</scroll-view>
</template>
<style lang="scss">
.dataList {
padding: 20rpx 20rpx;
.item {
display: flex;
justify-content: flex-start;
align-items: center;
margin: 20rpx 0;
padding: 20rpx 10rpx;
border-radius: 16rpx;
box-shadow: 0px 0px 8px 0px rgba(164, 182, 203, 0.33);
.img {
width: 72rpx;
height: 72rpx;
margin-right: 20rpx;
}
.right {
flex: 1;
margin-right: 10rpx;
.hd {
display: flex;
flex-direction: row;
justify-content: space-between;
.title {
color: #3d3d3d;
font-size: 32rpx;
}
.time {
color: #afb0b6;
font-size: 28rpx;
}
}
.info {
color: #868891;
margin: 20rpx 0;
font-size: 30rpx;
}
}
}
}
</style>

@ -0,0 +1,161 @@
<script setup lang="ts">
import { onMounted, ref, defineEmits } from 'vue'
import type { OrderListParams } from '@/types/order'
//
const isFinish = ref(false)
//
const isTriggered = ref(false)
// porps
const props = defineProps<{
orderState: number
}>()
//
const isLoading = ref(false)
//
const queryParams: Required<OrderListParams> = {
page: 1,
pageSize: 5,
orderState: props.orderState,
}
const dataList = ref([
{
id: 1,
name: 'dd',
},
{
id: 2,
name: 'dd',
},
{
id: 3,
name: 'dd',
},
{
id: 4,
name: 'dd',
},
{
id: 5,
name: 'dd',
},
])
const getMemberOrderData = async () => {
// 退
if (isLoading.value) return
// 退
if (isFinish.value === true) {
return uni.showToast({ icon: 'none', title: '没有更多数据~' })
}
//
isLoading.value = true
//
const res = await getMemberOrderAPI(queryParams)
// debugger
//
isLoading.value = false
//
orderList.value.push(...res.result.items)
//
if (queryParams.page < res.result.pages) {
//
queryParams.page++
} else {
//
isFinish.value = true
}
}
onMounted(() => {
// getMemberOrderData()
// const arr: object[] = [
// {
// id: 1,
// name: '233'
// }
// ]
// orderList.value.push(...arr)
})
//
const onRefresherrefresh = async () => {
//
isTriggered.value = true
//
queryParams.page = 1
orderList.value = []
isFinish.value = false
//
await getMemberOrderData()
//
isTriggered.value = false
}
</script>
<template>
<scroll-view
enable-back-to-top
scroll-y
class="orders"
refresher-enabled
:refresher-triggered="isTriggered"
@refresherrefresh="onRefresherrefresh"
@scrolltolower="getMemberOrderData"
>
<view class="dataList">
<view class="item" v-for="item in dataList" :key="item.id">
<image src="/static/images/news_icon.png" mode="aspectFit" class="img"></image>
<view class="right">
<view class="hd">
<view class="title">平台运营中心</view>
<view class="time">4分钟前</view>
</view>
<view class="info">派送给您编号HS21545455244...</view>
</view>
</view>
</view>
</scroll-view>
</template>
<style lang="scss">
.dataList {
padding: 20rpx 20rpx;
.item {
display: flex;
justify-content: flex-start;
align-items: center;
margin: 20rpx 0;
padding: 20rpx 10rpx;
border-radius: 16rpx;
box-shadow: 0px 0px 8px 0px rgba(164, 182, 203, 0.33);
.img {
width: 72rpx;
height: 72rpx;
margin-right: 20rpx;
}
.right {
flex: 1;
margin-right: 10rpx;
.hd {
display: flex;
flex-direction: row;
justify-content: space-between;
.title {
color: #3d3d3d;
font-size: 32rpx;
}
.time {
color: #afb0b6;
font-size: 28rpx;
}
}
.info {
color: #868891;
margin: 20rpx 0;
font-size: 30rpx;
}
}
}
}
</style>

@ -0,0 +1,141 @@
<script setup lang="ts">
import { ref } from 'vue'
import newsItem from './components/newsItem.vue'
import noticeItem from './components/noticeItem.vue'
//
const { safeAreaInsets } = uni.getSystemInfoSync()
// tabs
const orderTabs = ref([
{ orderState: 0, title: '通知', isRender: false },
{ orderState: 1, title: '私信', isRender: false },
])
//
const activeIndex = ref(orderTabs.value.findIndex((v) => v.orderState === Number(0)))
//
orderTabs.value[activeIndex.value].isRender = true
</script>
<template>
<!-- <CartMain /> -->
<view class="viewport">
<!-- 自定义导航栏: 默认透明不可见, scroll-view 滚动到 50 时展示 -->
<view class="navbar" :style="{ paddingTop: safeAreaInsets?.top + 'px' }">
<view class="wrap">
<navigator open-type="navigateBack" class="back icon-left"></navigator>
<view class="title"></view>
</view>
</view>
<view class="tabs">
<text
class="item"
:class="{ active: activeIndex == index }"
v-for="(item, index) in orderTabs"
:key="item.title"
@tap="
() => {
activeIndex = index
item.isRender = true
}
"
>
{{ item.title }}
</text>
<!-- 游标 -->
<view class="cursor" :style="{ left: activeIndex ? '65%' : '14%' }"></view>
</view>
<!-- 滑动容器 -->
<swiper class="swiper" :current="activeIndex" @change="activeIndex = $event.detail.current">
<!-- 滑动项 -->
<swiper-item v-for="item in orderTabs" :key="item.title">
<newsItem v-if="activeIndex" />
<noticeItem v-else />
</swiper-item>
</swiper>
</view>
</template>
<style lang="scss">
page {
height: 100%;
}
.viewport {
height: 100%;
display: flex;
flex-direction: column;
// background-color: #3775F6;
.navbar {
width: 750rpx;
color: #000;
position: fixed;
top: 0;
left: 0;
z-index: 9;
/* background-color: #f8f8f8; */
background-color: #3775f6;
.wrap {
position: relative;
background-color: #3775f6;
.title {
height: 44px;
display: flex;
justify-content: center;
align-items: center;
font-size: 32rpx;
/* color: #000; */
color: #fff;
}
.back {
position: absolute;
left: 0;
height: 44px;
width: 44px;
font-size: 44rpx;
display: flex;
align-items: center;
justify-content: center;
/* color: #000; */
color: #fff;
}
}
}
.tabs {
display: flex;
justify-content: space-around;
line-height: 60rpx;
background-color: #3775f6;
position: relative;
z-index: 9;
margin-top: 128rpx;
width: 100%;
.item {
flex: 1;
text-align: center;
padding: 20rpx;
font-size: 28rpx;
color: #fff;
// &.active {
// border-bottom: 2rpx solid #5386e4;
// }
}
.cursor {
position: absolute;
left: 13%;
bottom: 0;
width: 20%;
height: 6rpx;
padding: 0 50rpx;
background-color: #fff;
/* 过渡效果 */
transition: all 0.4s;
}
}
// swiper
.swiper {
background-color: #f7f7f8;
}
}
</style>

@ -44,7 +44,7 @@ onShow(() => {
const onDeleteCart = (skuId: string) => {
//
uni.showModal({
content: "是否删除",
content: '是否删除',
confirmColor: '#27BA9B',
success: async (res) => {
if (res.confirm) {

@ -0,0 +1,121 @@
<script setup lang="ts">
import { ref } from 'vue'
const handleSubmit = async () => {}
</script>
<template>
<view class="viewport">
<view class="section-auto">
<view class="left">
<view class="title">自动接单</view>
<view class="desc">开启后将根据配置情况自动接单</view>
</view>
<view class="switch">
<switch checked color="#3775F6" style="transform: scale(0.7)" />
</view>
</view>
<view class="section-time">
<view class="start-time item">
<view class="left">
<view class="title">开始接单时间</view>
<view class="val">2024-01-16 13:25:22</view>
</view>
<view class="edit">修改</view>
</view>
<view class="end-time item">
<view class="left">
<view class="title">结束接单时间</view>
<view class="val">2024-01-16 13:25:22</view>
</view>
<view class="edit">修改</view>
</view>
<view class="auto-num item">
<view class="left">
<view class="title">自动接单范围</view>
<view class="val">4km</view>
</view>
<view class="edit">修改</view>
</view>
</view>
<view class="action" @click="handleSubmit"> </view>
</view>
</template>
<style lang="scss">
page {
height: 100%;
background-color: #fafafd;
}
.viewport {
padding: 10rpx;
.section-auto {
display: flex;
justify-content: space-between;
padding: 30rpx 0rpx;
margin: 20rpx 0;
border-radius: 16rpx;
background: #ffffff;
box-shadow: 0px 0px 8px 0px rgba(164, 182, 203, 0.33);
.left {
margin-left: 30rpx;
.title {
color: #3d3d3d;
font-size: 34rpx;
margin-bottom: 20rpx;
}
.desc {
color: #999a9f;
font-size: 32rpx;
}
}
}
.section-time {
padding: 30rpx 30rpx;
margin: 20rpx 0;
background: #ffffff;
border-radius: 16rpx;
box-shadow: 0px 0px 8px 0px rgba(164, 182, 203, 0.33);
.item {
display: flex;
justify-content: space-between;
align-items: center;
margin: 20rpx 0;
padding-bottom: 10rpx;
border-bottom: 2rpx solid #f2f2f2;
.left {
.title {
font-size: 34rpx;
color: #3d3d3d;
margin-bottom: 20rpx;
}
.val {
color: #999a9f;
font-size: 32rpx;
}
}
.edit {
color: #3775f6;
font-size: 40rpx;
text-decoration: underline;
}
&:last-child {
border: none;
}
}
}
.action {
width: 344rpx;
margin: 100rpx auto 0;
border-radius: 100rpx;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
padding: 30rpx 30rpx;
color: #fff;
font-size: 36rpx;
background: linear-gradient(152deg, #51b6ff 16%, #3775f6 86%);
}
}
</style>

@ -0,0 +1,430 @@
<template name="skeleton">
<view class="sk-container">
<scroll-view
:scroll-y="true"
class="viewport sk-transparent"
id="scroller"
:enable-back-to-top="true"
>
<view class="overview sk-image" style="padding-top: 64px">
<view class="status sk-transparent sk-text-0-0000-826 sk-text">待收货</view>
</view>
<view class="shipment">
<navigator class="logistics sk-image sk-pseudo sk-pseudo-circle" hover-class="none">
<view class="message sk-transparent sk-text-14-2857-512 sk-text"
>到了小福家里请签收</view
>
<view class="date sk-transparent sk-text-14-2857-990 sk-text">2023-04-15 23:23:04</view>
</navigator>
<view class="locate sk-image">
<view class="user sk-transparent sk-text-14-2857-630 sk-text">苏东坡 13633336666</view>
<view class="address sk-transparent sk-text-14-2857-606 sk-text"
>广东省 广州市 天河区吉山幼儿园</view
>
</view>
</view>
<view class="goods">
<view class="item">
<navigator class="navigator" hover-class="none">
<image class="cover sk-image"></image>
<view class="meta">
<view class="name ellipsis sk-transparent sk-text-14-2857-474 sk-text"
>厚厚一按就干爽埃及进口长绒棉毛巾</view
>
<view class="type sk-transparent sk-text-22-2222-237 sk-text"
>超值4条装灰蓝色+粉色+银灰+嫩黄</view
>
<view class="price">
<view class="actual">
<text class="symbol sk-transparent sk-opacity">¥</text>
<text class="sk-transparent sk-text-14-2857-102 sk-text">68</text>
</view>
</view>
<view class="quantity sk-transparent sk-opacity">x1</view>
</view>
</navigator>
<navigator class="navigator" hover-class="none">
<image class="cover sk-image"></image>
<view class="meta">
<view class="name ellipsis sk-transparent sk-text-14-2857-969 sk-text"
>KJE金属色系轻量电动车骑行盔男女通用</view
>
<view class="type sk-transparent sk-text-22-2222-510 sk-text">玫瑰金L</view>
<view class="price">
<view class="actual">
<text class="symbol sk-transparent sk-opacity">¥</text>
<text class="sk-transparent sk-text-14-2857-431 sk-text">120</text>
</view>
</view>
<view class="quantity sk-transparent sk-opacity">x1</view>
</view>
</navigator>
<navigator class="navigator" hover-class="none">
<image class="cover sk-image"></image>
<view class="meta">
<view class="name ellipsis sk-transparent sk-text-14-2857-130 sk-text"
>源自澳洲进口羊毛儿童奢暖羊毛被升级款</view
>
<view class="type sk-transparent sk-text-22-2222-110 sk-text"
>春秋款 100%羊毛款150x200cm适合1.2/1.35米床</view
>
<view class="price">
<view class="actual">
<text class="symbol sk-transparent sk-opacity">¥</text>
<text class="sk-transparent sk-text-14-2857-273 sk-text">289</text>
</view>
</view>
<view class="quantity sk-transparent sk-opacity">x1</view>
</view>
</navigator>
</view>
<view class="total">
<view class="row">
<view class="text sk-transparent sk-text-0-0000-302 sk-text">商品总价: </view>
<view
class="symbol sk-transparent sk-text-0-0000-998 sk-text sk-pseudo sk-pseudo-circle"
>477</view
>
</view>
<view class="row">
<view class="text sk-transparent sk-text-0-0000-912 sk-text">运费: </view>
<view
class="symbol sk-transparent sk-text-0-0000-208 sk-text sk-pseudo sk-pseudo-circle"
>2</view
>
</view>
<view class="row">
<view class="text sk-transparent sk-text-0-0000-538 sk-text">应付金额: </view>
<view
class="symbol primary sk-transparent sk-text-0-0000-858 sk-text sk-pseudo sk-pseudo-circle"
>479</view
>
</view>
</view>
</view>
<view class="detail">
<view class="title sk-transparent sk-text-0-0000-66 sk-text">订单信息</view>
<view class="row">
<view class="item sk-transparent">
订单编号: 1645809639951962113
<text class="copy sk-transparent sk-text-0-0000-522 sk-text">复制</text>
</view>
<view class="item sk-transparent sk-text-0-0000-353 sk-text"
>下单时间: 2023-04-11 23:22:50</view
>
</view>
</view>
<view class="toolbar" style="padding-bottom: 34px">
<view
class="button primary sk-transparent sk-text-31-9444-411 sk-text"
style="background-position-x: 50%"
>再次购买</view
>
</view>
</scroll-view>
</view>
</template>
<style>
.sk-transparent {
color: transparent !important;
}
.sk-text-14-2857-107 {
background-image: linear-gradient(
transparent 14.2857%,
#eeeeee 0%,
#eeeeee 85.7143%,
transparent 0%
) !important;
background-size: 100% 44.8rpx;
position: relative !important;
}
.sk-text {
background-origin: content-box !important;
background-clip: content-box !important;
background-color: transparent !important;
color: transparent !important;
background-repeat: repeat-y !important;
}
.sk-text-0-0000-826 {
background-image: linear-gradient(
transparent 0%,
#eeeeee 0%,
#eeeeee 100%,
transparent 0%
) !important;
background-size: 100% 36rpx;
position: relative !important;
}
.sk-text-14-2857-512 {
background-image: linear-gradient(
transparent 14.2857%,
#eeeeee 0%,
#eeeeee 85.7143%,
transparent 0%
) !important;
background-size: 100% 36.4rpx;
position: relative !important;
}
.sk-text-14-2857-990 {
background-image: linear-gradient(
transparent 14.2857%,
#eeeeee 0%,
#eeeeee 85.7143%,
transparent 0%
) !important;
background-size: 100% 33.6rpx;
position: relative !important;
}
.sk-text-14-2857-630 {
background-image: linear-gradient(
transparent 14.2857%,
#eeeeee 0%,
#eeeeee 85.7143%,
transparent 0%
) !important;
background-size: 100% 36.4rpx;
position: relative !important;
}
.sk-text-14-2857-606 {
background-image: linear-gradient(
transparent 14.2857%,
#eeeeee 0%,
#eeeeee 85.7143%,
transparent 0%
) !important;
background-size: 100% 33.6rpx;
position: relative !important;
}
.sk-text-14-2857-474 {
background-image: linear-gradient(
transparent 14.2857%,
#eeeeee 0%,
#eeeeee 85.7143%,
transparent 0%
) !important;
background-size: 100% 36.4rpx;
position: relative !important;
}
.sk-text-22-2222-237 {
background-image: linear-gradient(
transparent 22.2222%,
#eeeeee 0%,
#eeeeee 77.7778%,
transparent 0%
) !important;
background-size: 100% 43.2rpx;
position: relative !important;
}
.sk-opacity {
opacity: 0 !important;
}
.sk-text-14-2857-102 {
background-image: linear-gradient(
transparent 14.2857%,
#eeeeee 0%,
#eeeeee 85.7143%,
transparent 0%
) !important;
background-size: 100% 33.6rpx;
position: relative !important;
}
.sk-text-14-2857-969 {
background-image: linear-gradient(
transparent 14.2857%,
#eeeeee 0%,
#eeeeee 85.7143%,
transparent 0%
) !important;
background-size: 100% 36.4rpx;
position: relative !important;
}
.sk-text-22-2222-510 {
background-image: linear-gradient(
transparent 22.2222%,
#eeeeee 0%,
#eeeeee 77.7778%,
transparent 0%
) !important;
background-size: 100% 43.2rpx;
position: relative !important;
}
.sk-text-14-2857-431 {
background-image: linear-gradient(
transparent 14.2857%,
#eeeeee 0%,
#eeeeee 85.7143%,
transparent 0%
) !important;
background-size: 100% 33.6rpx;
position: relative !important;
}
.sk-text-14-2857-130 {
background-image: linear-gradient(
transparent 14.2857%,
#eeeeee 0%,
#eeeeee 85.7143%,
transparent 0%
) !important;
background-size: 100% 36.4rpx;
position: relative !important;
}
.sk-text-22-2222-110 {
background-image: linear-gradient(
transparent 22.2222%,
#eeeeee 0%,
#eeeeee 77.7778%,
transparent 0%
) !important;
background-size: 100% 43.2rpx;
position: relative !important;
}
.sk-text-14-2857-273 {
background-image: linear-gradient(
transparent 14.2857%,
#eeeeee 0%,
#eeeeee 85.7143%,
transparent 0%
) !important;
background-size: 100% 33.6rpx;
position: relative !important;
}
.sk-text-0-0000-302 {
background-image: linear-gradient(
transparent 0%,
#eeeeee 0%,
#eeeeee 100%,
transparent 0%
) !important;
background-size: 100% 26rpx;
position: relative !important;
}
.sk-text-0-0000-998 {
background-image: linear-gradient(
transparent 0%,
#eeeeee 0%,
#eeeeee 100%,
transparent 0%
) !important;
background-size: 100% 26rpx;
position: relative !important;
}
.sk-text-0-0000-912 {
background-image: linear-gradient(
transparent 0%,
#eeeeee 0%,
#eeeeee 100%,
transparent 0%
) !important;
background-size: 100% 26rpx;
position: relative !important;
}
.sk-text-0-0000-208 {
background-image: linear-gradient(
transparent 0%,
#eeeeee 0%,
#eeeeee 100%,
transparent 0%
) !important;
background-size: 100% 26rpx;
position: relative !important;
}
.sk-text-0-0000-538 {
background-image: linear-gradient(
transparent 0%,
#eeeeee 0%,
#eeeeee 100%,
transparent 0%
) !important;
background-size: 100% 26rpx;
position: relative !important;
}
.sk-text-0-0000-858 {
background-image: linear-gradient(
transparent 0%,
#eeeeee 0%,
#eeeeee 100%,
transparent 0%
) !important;
background-size: 100% 36rpx;
position: relative !important;
}
.sk-text-0-0000-66 {
background-image: linear-gradient(
transparent 0%,
#eeeeee 0%,
#eeeeee 100%,
transparent 0%
) !important;
background-size: 100% 30rpx;
position: relative !important;
}
.sk-text-0-0000-522 {
background-image: linear-gradient(
transparent 0%,
#eeeeee 0%,
#eeeeee 100%,
transparent 0%
) !important;
background-size: 100% 20rpx;
position: relative !important;
}
.sk-text-0-0000-353 {
background-image: linear-gradient(
transparent 0%,
#eeeeee 0%,
#eeeeee 100%,
transparent 0%
) !important;
background-size: 100% 26rpx;
position: relative !important;
}
.sk-text-0-0000-375 {
background-image: linear-gradient(
transparent 0%,
#eeeeee 0%,
#eeeeee 100%,
transparent 0%
) !important;
background-size: 100% 32rpx;
position: relative !important;
}
.sk-text-31-9444-411 {
background-image: linear-gradient(
transparent 31.9444%,
#eeeeee 0%,
#eeeeee 68.0556%,
transparent 0%
) !important;
background-size: 100% 72rpx;
position: relative !important;
}
.sk-image {
background: #efefef !important;
}
.sk-pseudo::before,
.sk-pseudo::after {
background: #efefef !important;
background-image: none !important;
color: transparent !important;
border-color: transparent !important;
}
.sk-pseudo-rect::before,
.sk-pseudo-rect::after {
border-radius: 0 !important;
}
.sk-pseudo-circle::before,
.sk-pseudo-circle::after {
border-radius: 50% !important;
}
.sk-container {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
overflow: hidden;
background-color: transparent;
}
</style>

@ -0,0 +1,587 @@
<script setup lang="ts">
import { OrderState, orderStateList } from '@/services/constants'
import {
deleteMemberOrderAPI,
getMemberOrderByIdAPI,
getMemberOrderCancelByIdAPI,
getMemberOrderLogisticsByIdAPI,
getMemberOrderConsignmentByIdAPI,
putMemberOrderReceiptByIdAPI,
} from '@/services/order'
import type { LogisticItem, OrderResult } from '@/types/order'
import { onLoad, onReady } from '@dcloudio/uni-app'
import { ref, getCurrentInstance, unref } from 'vue'
import PageSkeleton from './components/PageSkeleton.vue'
import { getPayMockAPI, getPayWxPayMiniPayAPI } from '@/services/pay'
import QQMapWX from '@/libs/qqmap-wx-jssdk1.2/qqmap-wx-jssdk.min.js'
//
const { safeAreaInsets } = uni.getSystemInfoSync()
//
const orderDetailPopup = ref<UniHelper.UniPopupInstance>()
const orderConfirmPopup = ref<UniHelper.UniPopupInstance>()
//
const longitude = ref(0)
const latitude = ref(0)
const polyline = ref<any>([])
//
interface Props {
id: string
state: string,
targetLongitude: string,
targetLatitude: string,
}
const props = withDefaults(defineProps<Props>(), {
id: '0',
state: '0',
targetLongitude: '121.197665',
targetLatitude: '31.128418',
})
const tMap = new QQMapWX({
key: 'EAQBZ-BZZCZ-DGUX2-TZI4D-PZRWH-NNFNJ',
})
// -
const getLocationInfo = () => {
uni.getLocation({
type: 'gcj02',
// isHighAccuracy: true,
// highAccuracyExpireTime: 5000,
success(res) {
console.log(res)
tMap.direction({
mode: 'driving',
from: {
// longitude: res.longitude,
// latitude: res.latitude,
longitude: '121.197635',
latitude: '31.128684',
},
to: {
longitude: props.targetLongitude,
latitude: props.targetLatitude,
},
success(res2: any) {
console.log('res2', res2)
const ret = res2
const coors = ret.result.routes[0].polyline,
pl = []
//
const kr = 1000000
for (let i = 2; i < coors.length; i++) {
coors[i] = Number(coors[i - 2]) + Number(coors[i]) / kr
}
//pl
for (let i = 0; i < coors.length; i += 2) {
pl.push({ latitude: coors[i], longitude: coors[i + 1] })
}
console.log(pl)
//polyline线,
latitude.value = pl[0].latitude
longitude.value = pl[0].longitude
polyline.value = [
{
points: pl,
color: '#409eff',
width: 4,
},
]
orderDetailPopup?.value?.open()
},
})
},
fail(err) {
console.log(err)
uni.showModal({
content: '检测到您没打开获取定位功能权限,是否去设置打开?',
confirmText: '确认',
cancelText: '取消',
success: function (res) {
if (res.confirm) {
uni.openSetting({
success() {
getLocationInfo()
},
})
}
},
})
},
})
}
const getAuthorizeInfo = () => {
uni.authorize({
scope: 'scope.userLocation',
success(res) {
getLocationInfo()
},
fail(err) {
uni.showModal({
content: '检测到您没打开获取定位功能权限,是否去设置打开?',
confirmText: '确认',
cancelText: '取消',
success: function (res) {
if (res.confirm) {
uni.openSetting({
success() {
getLocationInfo()
},
})
}
},
})
},
})
}
// -
const getSettingInfo = () => {
uni.getSetting({
success(res) {
if (res.authSetting['scope.userLocation']) {
getLocationInfo()
} else {
getAuthorizeInfo()
}
},
})
}
//
onReady(() => {
getSettingInfo()
console.log(props)
})
const { ctx }: any = getCurrentInstance()
const mapContext = ref<UniApp.MapContext>(null as unknown as UniApp.MapContext)
//
// const order = ref<OrderResult>()
// const getMemberOrderByIdData = async () => {
// const res = await getMemberOrderByIdAPI(query.id)
// order.value = res.result
// if (
// [OrderState.DaiShouHuo, OrderState.DaiPingJia, OrderState.YiWanCheng].includes(
// order.value.orderState,
// )
// ) {
// getMemberOrderLogisticsByIdData()
// }
// }
// //
// const logisticList = ref<LogisticItem[]>([])
// const getMemberOrderLogisticsByIdData = async () => {
// const res = await getMemberOrderLogisticsByIdAPI(query.id)
// logisticList.value = res.result.list
// }
onLoad(() => {
// getMemberOrderByIdData()
// buttonDriving()
})
//
// const onTimeup = () => {
// //
// order.value!.orderState = OrderState.YiQuXiao
// }
const phone = async () => {
uni
.makePhoneCall({
phoneNumber: '13601921745',
})
.catch((e) => {
// console.log(e) //catch(e){makePhoneCall:fail cancel}
})
}
//
// const onOrderConfirm = () => {
// //
// uni.showModal({
// content: '',
// confirmColor: '#27BA9B',
// success: async (success) => {
// if (success.confirm) {
// const res = await putMemberOrderReceiptByIdAPI(query.id)
// //
// order.value = res.result
// }
// },
// })
// }
const handleAction = () => {
if (props.state == '1') {
tMap.direction({
mode: 'walking',
from: {
// longitude: res.longitude,
// latitude: res.latitude,
longitude: '121.197635',
latitude: '31.128684',
},
to: {
longitude: props.targetLongitude,
latitude: props.targetLatitude,
},
success(res: any) {
const ret = res
const distance = ret.result.routes[0].distance
if (distance < 100) {
uni.navigateTo({ url: '/payment/detail/detail' })
} else {
uni.showToast({
icon: 'none',
title: '请先到达订单所在的位置',
})
}
},
})
} else {
orderConfirmPopup.value?.open?.()
}
}
const handleDetailShow = () => {
orderDetailPopup.value?.open?.()
}
const handleDetailPopupClose = () => {
orderDetailPopup.value?.close?.()
}
const handleAcceptConfirm = () => {
uni.navigateTo({ url: '/payment/detail/detail' })
}
</script>
<template>
<view class="viewport">
<template v-if="1">
<view class="section-map">
<map
id="map"
class="map"
:polyline="polyline"
show-location
:latitude="latitude"
:longitude="longitude"
></map>
</view>
<!-- 底部操作栏 -->
<view class="toolbar-height" :style="{ paddingBottom: safeAreaInsets?.bottom + 'px' }"></view>
<view class="toolbar" :style="{ paddingBottom: safeAreaInsets?.bottom + 'px' }">
<view class="button" @tap="phone">
<image
class="concat-img"
src="../../../static/images/detail_iphone.png"
mode="scaleToFill"
/>
</view>
<view class="button">
<image
class="concat-img"
src="../../../static/images/detail_concat.png"
mode="scaleToFill"
/>
</view>
<view class="button primary" @click="handleDetailShow"></view>
<view class="button primary" @click="handleAction">{{
props.state == '1' ? '已经到达' : '立即接单'
}}</view>
</view>
</template>
<template v-else>
<PageSkeleton />
</template>
</view>
<uni-popup ref="orderDetailPopup" type="bottom" background-color="#fff">
<view class="popup-root">
<view class="title">
<view class="text">订单详情</view>
<view class="close" @click="handleDetailPopupClose">X</view>
</view>
<view class="cont">
<view class="info1">
<view class="loction">
<view class="text ellipsis">上海市松江区新松江路92弄开元地中海园区</view>
<view class="num">0.4km</view>
</view>
<view class="coming-time">
<view class="label">上门时间</view>
<view class="val">今天上午 12:00</view>
</view>
<view class="people"> 曾先生 18526235487 </view>
</view>
<view class="info2">
<view class="item">
<view class="label">回收品类</view>
<view class="val">塑料瓶/纸箱</view>
</view>
<view class="item">
<view class="label">预计重量</view>
<view class="val">2kg</view>
</view>
<view class="item">
<view class="label">备注</view>
<view class="val"></view>
</view>
</view>
<view class="time-status">
<text class="label">剩余接单时间</text>
<uni-countdown
:show-day="false"
:minute="30"
:second="0"
color="#E30000"
@timeup="handleTimeup(item)"
/>
</view>
</view>
</view>
</uni-popup>
<uni-popup ref="orderConfirmPopup" type="center" background-color="#fff">
<view class="popup-root">
<view class="title">请确保上门时间有效</view>
<view class="description">
<view class="tips">1请和客户确认如下上门时间</view>
<view class="date">
<uni-datetime-picker type="datetime" v-model="datetimesingle" @change="changeTime" />
</view>
</view>
<view class="footer">
<view class="button" @tap="orderConfirmPopup?.close?.()"></view>
<view class="button primary" @tap="handleAcceptConfirm"></view>
</view>
</view>
</uni-popup>
</template>
<style lang="scss">
page {
display: flex;
flex-direction: column;
height: 100%;
overflow: hidden;
scrollbar-width: none;
}
.viewport {
background-color: #f7f7f8;
margin-bottom: 100rpx;
overflow: auto;
scrollbar-width: none;
.section-map {
width: 100vw;
height: 100vh;
.map {
width: 100%;
height: 100%;
}
}
.toolbar-height {
height: 100rpx;
box-sizing: content-box;
}
.toolbar {
position: fixed;
left: 0;
right: 0;
bottom: calc(var(--window-bottom));
z-index: 1;
height: 100rpx;
display: flex;
align-items: center;
justify-content: space-around;
border-top: 1rpx solid #ededed;
border-bottom: 1rpx solid #ededed;
background-color: #fff;
box-sizing: content-box;
.button {
display: flex;
justify-content: center;
align-items: center;
flex: 1;
height: 100%;
font-size: 26rpx;
border-right: 1rpx solid #ccc;
color: #fff;
.concat {
width: 48rpx;
height: 44rpx;
}
.concat-img {
width: 48rpx;
height: 44rpx;
}
}
.primary {
color: #fff;
background: linear-gradient(158deg, #51b6ff -10%, #3775f6 129%);
}
}
}
.popup-root {
padding: 30rpx 30rpx 50rpx;
border-radius: 10rpx 10rpx 0 0;
overflow: hidden;
background: linear-gradient(180deg, #d2eeff -7%, rgba(255, 255, 255, 0) 38%), #ffffff;
box-shadow: 0px -2px 8px 0px rgba(133, 155, 180, 0.4);
position: relative;
.title {
text-align: left;
margin-bottom: 30rpx;
padding-bottom: 20rpx;
border-bottom: 2rpx solid #e1e7f2;
.text {
font-size: 30rpx;
}
.close {
position: absolute;
right: 0;
top: 0;
padding: 23rpx 50rpx;
color: #333;
font-size: 30rpx;
text-align: center;
}
}
.cont {
.info1 {
padding: 20rpx 0;
min-height: 100rpx;
width: 100%;
border-bottom: 2rpx solid #e1e7f2;
.loction {
display: flex;
flex-direction: row;
width: 100%;
justify-content: space-between;
.text {
color: #3d3d3d;
width: 80%;
-webkit-line-clamp: 1;
}
.num {}
}
.coming-time {
margin: 10rpx 0;
display: flex;
flex-direction: row;
color: #3d3d3d;
.label {}
}
.people {
color: #3d3d3d;
.label {}
}
}
.info2 {
padding: 20rpx 0;
min-height: 100rpx;
border-bottom: 2rpx solid #e1e7f2;
.item {
display: flex;
flex-direction: row;
margin: 20rpx 0;
.label {
color: #999a9f;
}
}
}
.time-status {
margin: 20rpx 0;
display: flex;
flex-direction: row;
.label {
font-size: 32rpx;
}
.time {
color: #e30000;
}
}
}
}
.description {
font-size: 28rpx;
padding: 0 20rpx;
.tips {
color: #444;
margin-bottom: 12rpx;
}
.cell {
display: flex;
justify-content: space-between;
align-items: center;
padding: 15rpx 0;
color: #666;
}
.icon::before {
content: '\e6cd';
font-family: 'erabbit' !important;
font-size: 38rpx;
color: #999;
}
.icon.checked::before {
content: '\e6cc';
font-size: 38rpx;
color: #27ba9b;
}
}
.footer {
display: flex;
justify-content: space-between;
padding: 30rpx 0 40rpx;
font-size: 28rpx;
color: #444;
.button {
flex: 1;
height: 72rpx;
text-align: center;
line-height: 72rpx;
margin: 0 20rpx;
color: #444;
border-radius: 72rpx;
border: 1rpx solid #ccc;
}
.primary {
color: #fff;
background-color: #27ba9b;
border: none;
}
}
</style>

@ -0,0 +1,318 @@
<script setup lang="ts">
import { OrderState } from '@/services/constants'
import { orderStateList } from '@/services/constants'
import { putMemberOrderReceiptByIdAPI } from '@/services/order'
import { deleteMemberOrderAPI } from '@/services/order'
import { getMemberOrderAPI } from '@/services/order'
import { getPayMockAPI, getPayWxPayMiniPayAPI } from '@/services/pay'
import type { OrderItem } from '@/types/order'
import type { OrderListParams } from '@/types/order'
import { onMounted, ref, defineEmits } from 'vue'
//
const { safeAreaInsets } = uni.getSystemInfoSync()
// porps
const props = defineProps<{
orderState: number
}>()
//
const queryParams: Required<OrderListParams> = {
page: 1,
pageSize: 5,
orderState: props.orderState,
}
//
// const orderList = ref<OrderItem[]>([])
const orderList = [
{
id: '1747900788929204226',
createTime: '剩余接单时间',
locationNum: '0.4km',
loction: '上海市松江区新松江路92弄开元地中海园区',
people: '曾先生 18526235487',
payType: 1,
orderState: 2,
time: '2024-01-18 17:06:37',
time2: '17:01:01',
postFee: 8.0,
payMoney: 982.0,
totalMoney: 974.0,
totalNum: 13,
payChannel: 2,
countdown: 1579,
},
{
locationNum: '0.4km',
loction: '上海市松江区新松江路92弄开元地中海园区',
id: '1747899379064246273',
people: '曾先生 18526235487',
createTime: '剩余接单时间',
payType: 1,
orderState: 1,
time: '2024-01-18 17:01:01',
time2: '17:01:01',
postFee: 1.0,
payMoney: 70.0,
totalMoney: 69.0,
totalNum: 1,
payChannel: 2,
countdown: 1243,
},
]
//
const isLoading = ref(false)
const emit = defineEmits('tabChange')
const getMemberOrderData = async () => {
// 退
if (isLoading.value) return
// 退
if (isFinish.value === true) {
return uni.showToast({ icon: 'none', title: '没有更多数据~' })
}
//
isLoading.value = true
//
const res = await getMemberOrderAPI(queryParams)
// debugger
//
isLoading.value = false
//
orderList.value.push(...res.result.items)
//
if (queryParams.page < res.result.pages) {
//
queryParams.page++
} else {
//
isFinish.value = true
}
}
onMounted(() => {
// getMemberOrderData()
// const arr: object[] = [
// {
// id: 1,
// name: '233'
// }
// ]
// orderList.value.push(...arr)
})
//
const onOrderPay = async (id: string) => {
emit('tabChange', {})
// uni.$emit('childEvent');
// if (import.meta.env.DEV) {
// //
// await getPayMockAPI({ orderId: id })
// } else {
// // #ifdef MP-WEIXIN
// // 1.2.API
// // const res = await getPayWxPayMiniPayAPI({ orderId: id })
// // await wx.requestPayment(res.result)
// // 线 0.01
// await getPayMockAPI({ orderId: id })
// // #endif
// }
// //
// uni.showToast({ title: '' })
// //
// setTimeout(() => {
// wx.showModal({
// title: '',
// content: '',
// confirmText: '',
// showCancel: false,
// })
// }, 2000)
// //
// const order = orderList.value.find((v) => v.id === id)
// order!.orderState = OrderState.DaiFaHuo
}
//
const onOrderConfirm = (id: string) => {
uni.showModal({
content: '为保障您的权益,请收到货并确认无误后,再确认收货',
confirmColor: '#27BA9B',
success: async (res) => {
if (res.confirm) {
await putMemberOrderReceiptByIdAPI(id)
uni.showToast({ icon: 'success', title: '确认收货成功' })
//
const order = orderList.value.find((v) => v.id === id)
order!.orderState = OrderState.DaiPingJia
}
},
})
}
//
const onOrderDelete = (id: string) => {
uni.showModal({
content: '你确定要删除该订单?',
confirmColor: '#27BA9B',
success: async (res) => {
if (res.confirm) {
await deleteMemberOrderAPI({ ids: [id] })
//
const index = orderList.value.findIndex((v) => v.id === id)
orderList.value.splice(index, 1)
}
},
})
}
//
const isFinish = ref(false)
//
const isTriggered = ref(false)
//
const onRefresherrefresh = async () => {
//
isTriggered.value = true
//
queryParams.page = 1
orderList.value = []
isFinish.value = false
//
await getMemberOrderData()
//
isTriggered.value = false
}
</script>
<template>
<scroll-view
enable-back-to-top
scroll-y
class="orders"
refresher-enabled
:refresher-triggered="isTriggered"
@refresherrefresh="onRefresherrefresh"
@scrolltolower="getMemberOrderData"
>
<view class="card" v-for="item in orderList" :key="item.id">
<!-- 订单信息 -->
<view class="hd">
<text class="locationNum">订单编号HG201604052233</text>
</view>
<navigator class="goods" :url="`/pagesOrder/detail/detail?id=${item.id}`" hover-class="none">
<view class="meta">
<view class="location ellipsis">
<image src="/static/images/loction.png" mode="aspectFit" class="icon" />
{{ item.loction }}</view
>
<view class="people ellipsis">
<image src="/static/images/iphone.png" mode="aspectFit" class="icon" />
{{ item.people }}</view
>
</view>
</navigator>
<!-- 订单操作按钮 -->
<view class="action">
<text class="label">订单完成时间2024-01-16 13:25:22</text>
</view>
<image src="/static/images/order_completed.png" mode="aspectFit" class="img"></image>
</view>
<!-- 底部提示文字 -->
<view class="loading-text" :style="{ paddingBottom: safeAreaInsets?.bottom + 'px' }">
{{ isFinish ? '没有更多数据~' : '正在加载...' }}
</view>
</scroll-view>
</template>
<style lang="scss">
//
.orders {
.card {
padding: 20rpx;
margin: 20rpx 20rpx 0;
border-radius: 10rpx;
position: relative;
background: linear-gradient(180deg, #d2eeff -14%, rgba(255, 255, 255, 0) 63%), #ffffff;
box-shadow: 0px 0px 8px 0px rgba(164, 182, 203, 0.33);
.hd {
display: flex;
align-items: center;
justify-content: space-between;
font-size: 28rpx;
padding-bottom: 20rpx;
border-bottom: 2rpx solid #f1e8e8;
.locationNum {
color: #3d3d3d;
}
}
.goods {
display: flex;
.meta {
flex: 1;
display: flex;
flex-direction: column;
justify-content: center;
padding: 10rpx 0;
border-bottom: 2rpx solid #f2f2f2;
.location {
font-size: 32rpx;
color: #999a9f;
margin-top: 20rpx;
.icon {
width: 32rpx;
height: 32rpx;
margin-right: 6rpx;
}
}
.people {
font-size: 32rpx;
color: #999a9f;
margin: 20rpx 0;
.icon {
width: 32rpx;
height: 32rpx;
margin-right: 6rpx;
}
}
}
}
.action {
display: flex;
justify-content: space-between;
align-items: center;
padding: 20rpx 0;
.label {
flex: 1;
align-items: center;
color: #999a9f;
font-size: 32rpx;
}
}
.img {
position: absolute;
top: 0;
right: 0;
width: 140rpx;
height: 140rpx;
}
&:last-child {
padding-bottom: 40rpx;
}
}
.loading-text {
text-align: center;
font-size: 28rpx;
color: #666;
padding: 20rpx 0;
}
}
</style>

@ -1,388 +0,0 @@
<script setup lang="ts">
import { OrderState } from '@/services/constants'
import { orderStateList } from '@/services/constants'
import { putMemberOrderReceiptByIdAPI } from '@/services/order'
import { deleteMemberOrderAPI } from '@/services/order'
import { getMemberOrderAPI } from '@/services/order'
import { getPayMockAPI, getPayWxPayMiniPayAPI } from '@/services/pay'
import type { OrderItem } from '@/types/order'
import type { OrderListParams } from '@/types/order'
import { onMounted, ref } from 'vue'
//
const { safeAreaInsets } = uni.getSystemInfoSync()
// porps
const props = defineProps<{
orderState: number
}>()
//
const queryParams: Required<OrderListParams> = {
page: 1,
pageSize: 5,
orderState: props.orderState,
}
//
const orderList = ref<OrderItem[]>([])
//
const isLoading = ref(false)
const getMemberOrderData = async () => {
// 退
if (isLoading.value) return
// 退
if (isFinish.value === true) {
return uni.showToast({ icon: 'none', title: '没有更多数据~' })
}
//
isLoading.value = true
//
const res = await getMemberOrderAPI(queryParams)
//
isLoading.value = false
//
orderList.value.push(...res.result.items)
//
if (queryParams.page < res.result.pages) {
//
queryParams.page++
} else {
//
isFinish.value = true
}
}
onMounted(() => {
getMemberOrderData()
})
//
const onOrderPay = async (id: string) => {
if (import.meta.env.DEV) {
//
await getPayMockAPI({ orderId: id })
} else {
// #ifdef MP-WEIXIN
// 1.2.API
// const res = await getPayWxPayMiniPayAPI({ orderId: id })
// await wx.requestPayment(res.result)
// 线 0.01
await getPayMockAPI({ orderId: id })
// #endif
}
//
uni.showToast({ title: '模拟支付成功' })
//
setTimeout(() => {
wx.showModal({
title: '温馨提示',
content: '此交易是模拟支付,您并未付款,不会导致实际购买商品或服务',
confirmText: '知道了',
showCancel: false,
})
}, 2000)
//
const order = orderList.value.find((v) => v.id === id)
order!.orderState = OrderState.DaiFaHuo
}
//
const onOrderConfirm = (id: string) => {
uni.showModal({
content: '为保障您的权益,请收到货并确认无误后,再确认收货',
confirmColor: '#27BA9B',
success: async (res) => {
if (res.confirm) {
await putMemberOrderReceiptByIdAPI(id)
uni.showToast({ icon: 'success', title: '确认收货成功' })
//
const order = orderList.value.find((v) => v.id === id)
order!.orderState = OrderState.DaiPingJia
}
},
})
}
//
const onOrderDelete = (id: string) => {
uni.showModal({
content: '你确定要删除该订单?',
confirmColor: '#27BA9B',
success: async (res) => {
if (res.confirm) {
await deleteMemberOrderAPI({ ids: [id] })
//
const index = orderList.value.findIndex((v) => v.id === id)
orderList.value.splice(index, 1)
}
},
})
}
//
const isFinish = ref(false)
//
const isTriggered = ref(false)
//
const onRefresherrefresh = async () => {
//
isTriggered.value = true
//
queryParams.page = 1
orderList.value = []
isFinish.value = false
//
await getMemberOrderData()
//
isTriggered.value = false
}
</script>
<template>
<scroll-view
enable-back-to-top
scroll-y
class="orders"
refresher-enabled
:refresher-triggered="isTriggered"
@refresherrefresh="onRefresherrefresh"
@scrolltolower="getMemberOrderData"
>
<view class="card" v-for="order in orderList" :key="order.id">
<!-- 订单信息 -->
<view class="status">
<text class="date">{{ order.createTime }}</text>
<!-- 订单状态文字 -->
<text>{{ orderStateList[order.orderState].text }}</text>
<!-- 待评价/已完成/已取消 状态: 展示删除订单 -->
<text
v-if="order.orderState >= OrderState.DaiPingJia"
class="icon-delete"
@tap="onOrderDelete(order.id)"
></text>
</view>
<!-- 商品信息点击商品跳转到订单详情不是商品详情 -->
<navigator
v-for="item in order.skus"
:key="item.id"
class="goods"
:url="`/pagesOrder/detail/detail?id=${order.id}`"
hover-class="none"
>
<view class="cover">
<image class="image" mode="aspectFit" :src="item.image"></image>
</view>
<view class="meta">
<view class="name ellipsis">{{ item.name }}</view>
<view class="type">{{ item.attrsText }}</view>
</view>
</navigator>
<!-- 支付信息 -->
<view class="payment">
<text class="quantity">{{ order.totalNum }}件商品</text>
<text>实付</text>
<text class="amount"> <text class="symbol">¥</text>{{ order.payMoney }}</text>
</view>
<!-- 订单操作按钮 -->
<view class="action">
<!-- 待付款状态显示去支付按钮 -->
<template v-if="order.orderState === OrderState.DaiFuKuan">
<view class="button primary" @tap="onOrderPay(order.id)"></view>
</template>
<template v-else>
<navigator
class="button secondary"
:url="`/pagesOrder/create/create?orderId=${order.id}`"
hover-class="none"
>
再次购买
</navigator>
<!-- 待收货状态: 展示确认收货 -->
<view
v-if="order.orderState === OrderState.DaiShouHuo"
class="button primary"
@tap="onOrderConfirm(order.id)"
>
确认收货
</view>
</template>
</view>
</view>
<!-- 底部提示文字 -->
<view class="loading-text" :style="{ paddingBottom: safeAreaInsets?.bottom + 'px' }">
{{ isFinish ? '没有更多数据~' : '正在加载...' }}
</view>
</scroll-view>
</template>
<style lang="scss">
//
.orders {
.card {
min-height: 100rpx;
padding: 20rpx;
margin: 20rpx 20rpx 0;
border-radius: 10rpx;
background-color: #fff;
&:last-child {
padding-bottom: 40rpx;
}
}
.status {
display: flex;
align-items: center;
justify-content: space-between;
font-size: 28rpx;
color: #999;
margin-bottom: 15rpx;
.date {
color: #666;
flex: 1;
}
.primary {
color: #ff9240;
}
.icon-delete {
line-height: 1;
margin-left: 10rpx;
padding-left: 10rpx;
border-left: 1rpx solid #e3e3e3;
}
}
.goods {
display: flex;
margin-bottom: 20rpx;
.cover {
width: 170rpx;
height: 170rpx;
margin-right: 20rpx;
border-radius: 10rpx;
overflow: hidden;
position: relative;
.image {
width: 170rpx;
height: 170rpx;
}
}
.quantity {
position: absolute;
bottom: 0;
right: 0;
line-height: 1;
padding: 6rpx 4rpx 6rpx 8rpx;
font-size: 24rpx;
color: #fff;
border-radius: 10rpx 0 0 0;
background-color: rgba(0, 0, 0, 0.6);
}
.meta {
flex: 1;
display: flex;
flex-direction: column;
justify-content: center;
}
.name {
height: 80rpx;
font-size: 26rpx;
color: #444;
}
.type {
line-height: 1.8;
padding: 0 15rpx;
margin-top: 10rpx;
font-size: 24rpx;
align-self: flex-start;
border-radius: 4rpx;
color: #888;
background-color: #f7f7f8;
}
.more {
flex: 1;
display: flex;
align-items: center;
justify-content: center;
font-size: 22rpx;
color: #333;
}
}
.payment {
display: flex;
justify-content: flex-end;
align-items: center;
line-height: 1;
padding: 20rpx 0;
text-align: right;
color: #999;
font-size: 28rpx;
border-bottom: 1rpx solid #eee;
.quantity {
font-size: 24rpx;
margin-right: 16rpx;
}
.amount {
color: #444;
margin-left: 6rpx;
}
.symbol {
font-size: 20rpx;
}
}
.action {
display: flex;
justify-content: flex-end;
align-items: center;
padding-top: 20rpx;
.button {
width: 180rpx;
height: 60rpx;
display: flex;
justify-content: center;
align-items: center;
margin-left: 20rpx;
border-radius: 60rpx;
border: 1rpx solid #ccc;
font-size: 26rpx;
color: #444;
}
.secondary {
color: #27ba9b;
border-color: #27ba9b;
}
.primary {
color: #fff;
background-color: #27ba9b;
border-color: #27ba9b;
}
}
.loading-text {
text-align: center;
font-size: 28rpx;
color: #666;
padding: 20rpx 0;
}
}
</style>

@ -1,6 +1,9 @@
<script setup lang="ts">
import { ref } from 'vue'
import OrderList from './components/OrderList.vue'
import OrderItem from './components/OrderItem.vue'
//
const { safeAreaInsets } = uni.getSystemInfoSync()
//
const query = defineProps<{
@ -9,47 +12,37 @@ const query = defineProps<{
// tabs
const orderTabs = ref([
{ orderState: 0, title: '全部', isRender: false },
{ orderState: 1, title: '待接单', isRender: false },
{ orderState: 2, title: '待回收', isRender: false },
{ orderState: 3, title: '已完成', isRender: false },
{ orderState: 4, title: '已取消', isRender: false },
{ orderState: 0, title: '待接单', isRender: false },
{ orderState: 1, title: '进行中', isRender: false },
])
//
const activeIndex = ref(orderTabs.value.findIndex((v) => v.orderState === Number(query.type)))
//
orderTabs.value[activeIndex.value].isRender = true
const handleTabChange = (type: string) => {
if (!activeIndex.value) {
activeIndex.value = 1
}
}
</script>
<template>
<view class="viewport">
<!-- tabs -->
<view class="tabs">
<text
class="item"
v-for="(item, index) in orderTabs"
:key="item.title"
@tap="
() => {
activeIndex = index
item.isRender = true
}
"
>
{{ item.title }}
</text>
<!-- 游标 -->
<view class="cursor" :style="{ left: activeIndex * 20 + '%' }"></view>
</view>
<!-- 滑动容器 -->
<swiper class="swiper" :current="activeIndex" @change="activeIndex = $event.detail.current">
<view class="cont" :current="activeIndex" @change="activeIndex = $event.detail.current">
<!-- 滑动项 -->
<swiper-item v-for="item in orderTabs" :key="item.title">
<view class="item" v-for="item in orderTabs" :key="item.title">
<!-- 订单列表 -->
<OrderList v-if="item.isRender" :order-state="item.orderState" />
</swiper-item>
</swiper>
<OrderItem
v-if="item.isRender"
:order-state="item.orderState"
@tab-change="handleTabChange"
/>
</view>
</view>
</view>
</template>
@ -63,43 +56,11 @@ page {
height: 100%;
display: flex;
flex-direction: column;
background-color: #fff;
}
// tabs
.tabs {
display: flex;
justify-content: space-around;
line-height: 60rpx;
margin: 0 10rpx;
background-color: #fff;
box-shadow: 0 4rpx 6rpx rgba(240, 240, 240, 0.6);
position: relative;
z-index: 9;
.item {
flex: 1;
text-align: center;
padding: 20rpx;
font-size: 28rpx;
color: #262626;
}
.cursor {
position: absolute;
left: 0;
bottom: 0;
width: 20%;
height: 6rpx;
padding: 0 50rpx;
background-color: #5386e4;
/* 过渡效果 */
transition: all 0.4s;
}
}
// swiper
.swiper {
.cont {
background-color: #f7f7f8;
// margin-top: 128rpx;
}
</style>

@ -1,119 +0,0 @@
<script setup lang="ts">
// const handlePhone = () => {
// uni.makePhoneCall({
// phoneNumber: '400-123-000', //
// })
// }
const handleToto = () => {
uni.navigateTo({ url: '/pages/siteDetail/siteDetail' })
}
</script>
<template>
<view class="item-site" @tap="handleToto">
<view class="module-cont">
<image
class="left"
src="https://img.36krcdn.com/20200410/v2_41365a0f26a244fdab8e3f5be081ed2b_img_000"
/>
<view class="md">
<view class="name"> <span class="zuijin"> 最近 </span>上海市松江区佘山镇 </view>
<view class="time">营业时间09-18:00</view>
<view class="loction">上海市松江区新松江路92弄开元地中海园区</view>
</view>
<view class="right">
<view class="num">1.03km</view>
<image
class="img"
src="https://img.36krcdn.com/20200410/v2_41365a0f26a244fdab8e3f5be081ed2b_img_000"
/>
</view>
</view>
<view class="md-tag"
><span class="tag-before">回收品类</span>旧衣·纸品·金属·家电·塑料·玻璃</view
>
<view class="foot-desc">
<view class="item">特色服务上门服务家电维修</view>
<view class="item">优惠活动预约回收立享双倍积分</view>
</view>
</view>
</template>
<style lang="scss" scoped>
.item-site {
padding: 32rpx 20rpx;
margin: 16rpx;
background-color: #fff;
border-radius: 4rpx;
.module-cont {
padding: 20rpx 0;
display: flex;
flex-direction: row;
.left {
width: 140rpx;
height: 140rpx;
border-radius: 12rpx;
}
.md {
flex: 1;
margin: 0 10rpx;
font-size: 24rpx;
color: #0d0d26;
.name {
font-size: 30rpx;
.zuijin {
font-size: 24rpx;
color: #ff7d00;
background: #fff7e8;
padding: 4rpx 4rpx;
margin-right: 6rpx;
border-radius: 4rpx;
}
}
.time {
color: #95969d;
margin: 8rpx 0;
}
.loction {
color: #0d0d26;
}
}
.right {
.num {
font-size: 28rpx;
color: #95969d;
}
.img {
width: 72rpx;
height: 72rpx;
margin-top: 20rpx;
border-radius: 10rpx;
}
}
}
.md-tag {
background: #e8fffb;
color: #0fc6c2;
margin: 10rpx 0;
font-weight: 400;
font-size: 24rpx;
padding: 6rpx 0rpx;
.tag-before {
background: #0fc6c2;
color: #fff;
font-size: 24rpx;
font-weight: 500;
padding: 4rpx 8rpx;
border-radius: 4rpx;
margin-right: 10rpx;
}
}
.foot-desc {
.item {
font-size: 24rpx;
color: #95969d;
margin: 10rpx 0;
}
}
}
</style>

@ -1,179 +0,0 @@
<script setup lang="ts">
import { onMounted, ref } from 'vue'
import SiteItem from './components/siteItem.vue'
const activeMenuKey = ref(0)
const menuList = [
{
id: 1,
name: '地区',
},
{
id: 2,
name: '回收品类',
},
{
id: 3,
name: '服务',
},
{
id: 4,
name: '筛选',
},
]
type siteParams = {
page: Number
pageSize: Number
menuState: String
}
//
const queryParams: Required<siteParams> = {
page: 1,
pageSize: 5,
menuState: '1',
}
//
const dataList = ref<any[]>([])
//
const isLoading = ref(false)
//
const isFinish = ref(false)
const getDataList = async () => {
// 退
if (isLoading.value) return
// 退
if (isFinish.value === true) {
return uni.showToast({ icon: 'none', title: '没有更多数据~' })
}
//
isLoading.value = true
//
// const res = await getMemberOrderAPI(queryParams)
const res = await new Promise((resolve, reject) => {
setTimeout(() => {
const data = [
{
id: 1,
},
{
id: 2,
},
{
id: 3,
},
{
id: 4,
},
{
id: 5,
},
{
id: 6,
},
{
id: 7,
},
{
id: 8,
},
]
const obj = {
result: data,
pages: 4,
}
resolve(obj)
}, 100)
})
//
isLoading.value = false
//
dataList.value.push(...res.result)
//
if (queryParams.page < res.result.pages) {
//
queryParams.page++
} else {
//
isFinish.value = true
}
}
const isTriggered = ref(false)
//
const onRefresherrefresh = async () => {
//
isTriggered.value = true
//
queryParams.page = 1
dataList.value = []
isFinish.value = false
//
await getDataList()
//
isTriggered.value = false
}
const handleMenuChange = (val) => {
activeMenuKey.value = val
getDataList()
}
onMounted(() => {
getDataList()
})
</script>
<template>
<view class="service-site">
<view class="menu-list">
<view
class="item"
@tap="handleMenuChange(index)"
:class="{ active: activeMenuKey == index }"
v-for="(item, index) in menuList"
:key="item.id"
>{{ item.name }} >
</view>
</view>
<scroll-view
enable-back-to-top
scroll-y
class="scroll-view"
:refresher-triggered="isTriggered"
@refresherrefresh="onRefresherrefresh"
@scrolltolower="getDataListList"
>
<siteItem class="item" v-for="item in dataList" :key="item.id" />
</scroll-view>
</view>
<!-- 底部占位空盒子 -->
<view class="toolbar-height" safe-area-inset-bottom></view>
</template>
<style lang="scss">
page {
height: 100%;
}
.service-site {
height: calc(100% - 100rpx);
.menu-list {
height: 80rpx;
line-height: 80rpx;
display: flex;
justify-content: space-around;
.item {
flex: 1;
display: flex;
justify-content: center;
align-items: center;
&.active {
color: #5386e4;
}
}
}
.scroll-view {
overflow: auto;
}
}
//
.toolbar-height {
height: 100rpx;
}
</style>

@ -1,243 +0,0 @@
<script setup lang="ts">
import { ref } from 'vue'
const bannerList = [
{
hrefUrl: '1005000',
id: '25',
imgUrl:
'http://yjy-xiaotuxian-dev.oss-cn-beijing.aliyuncs.com/picture/2021-04-15/e83efb1b-309c-46f7-98a3-f1fefa694338.jpg',
type: '1',
},
{
hrefUrl: '1005000',
id: '21',
imgUrl:
'http://yjy-xiaotuxian-dev.oss-cn-beijing.aliyuncs.com/picture/2021-04-15/dfc11bb0-4af5-4e9b-9458-99f615cc685a.jpg',
type: '1',
},
]
const leiList = [
{
id: 1,
name: '旧衣服',
},
{
id: 2,
name: '家用电器',
},
{
id: 2,
name: '废纸废书',
},
{
id: 3,
name: '废金属',
},
{
id: 4,
name: '废塑料',
},
]
const rateValue = ref(2)
</script>
<template>
<view class="site-detail">
<XtxSwiper :list="bannerList" />
<view class="cont">
<view class="info">
<view class="hd">
<view class="name">上海松江区佘山镇</view>
<view class="num">1.03km</view>
</view>
<view class="md">
<view class="label">营业时间</view>
<view class="time">09:00 - 18:00</view>
</view>
<view class="fd">
<view class="label">地址上海市松江区新松江路92弄开元地中海园区</view>
<view class="img"></view>
</view>
</view>
<view class="module-menu">
<view
class="item"
@tab="handleMenuChange(index)"
:class="{ active: activeMenuKey == index }"
v-for="(item, index) in leiList"
:key="item.id"
>{{ item.name }}</view
>
</view>
<view class="detail-list">
<view class="item arrow flex-row">
<view class="service-title">服务</view>
<view class="tag-list">
<view class="tag">上门服务</view>
<view class="tag">家电维修</view>
<view class="tag">品控质检</view>
</view>
</view>
<view class="item flex-column rate">
<view class="service-title">评分</view>
<uni-rate active-color="#FF7D00" v-model="rateValue" />
</view>
<view class="item flex-column activity">
<view class="activity-title">活动</view>
<view class="activity-list">
<view class="activity-item">会员价</view>
<view class="activity-item">赠送积分</view>
</view>
</view>
</view>
</view>
</view>
</template>
<style lang="scss" scoped>
.site-detail {
background: #f2f2fa;
.cont {
background-color: #fff;
margin: 32rpx;
padding: 16rpx;
min-height: 80vh;
.info {
padding: 20rpx 0;
box-shadow: 0px 0px 8px 0px rgba(161, 161, 177, 0.12);
.hd {
display: flex;
justify-content: space-between;
.name {
font-size: 30rpx;
font-weight: 500;
color: #0d0d26;
}
.num {
font-size: 28rpx;
color: #95969d;
}
}
.md {
margin: 10rpx 0;
font-size: 24rpx;
color: #95969d;
display: flex;
}
.fd {
display: flex;
justify-content: space-between;
align-items: center;
.label {
font-size: 24rpx;
}
.img {
width: 72rpx;
height: 72rpx;
border-radius: 50%;
background-color: #3a82fb;
}
}
}
.module-menu {
display: flex;
padding: 36rpx 0rpx;
box-shadow: 0px 0px 8px 0px rgba(161, 161, 177, 0.12);
.item {
flex: 1;
color: #95969d;
padding: 10rpx 0;
border-radius: 10rpx;
text-align: center;
&.active {
background: #fff7e8;
}
}
}
/* 列表 */
.detail-list {
padding: 0 20rpx;
background-color: #fff;
margin-bottom: 20rpx;
border-radius: 10rpx;
.item {
// line-height: 90rpx;
padding-left: 10rpx;
font-size: 30rpx;
color: #333;
border-bottom: 1rpx solid #ddd;
position: relative;
text-align: left;
border-radius: 0;
background-color: #fff;
display: flex;
&::after {
width: auto;
height: auto;
left: auto;
border: none;
}
// &:first-child {
// border: none;
// }
&::after {
right: 5rpx;
}
&.flex-column {
flex-direction: column;
&:first-child {
}
}
&.rate {
line-height: 90rpx;
padding-bottom: 20rpx;
}
&.flex-row {
line-height: 90rpx;
flex-direction: row;
}
.tag-list {
display: flex;
margin-left: 20rpx;
.tag {
color: #95969d;
font-size: 24rpx;
}
}
&.activity {
margin: 20rpx 0;
.activity-list {
display: flex;
.activity-item {
margin: 20rpx 10rpx;
&:first-child {
background: #484540;
padding: 4rpx 6rpx;
border-radius: 10rpx;
color: #ffe6b5;
font-size: 24rpx;
}
&:last-child {
padding: 4rpx 6rpx;
border-radius: 10rpx;
color: #ffb739;
border: 2rpx solid #ffb739;
font-size: 24rpx;
}
}
}
}
}
.arrow::after {
content: '\e6c2';
position: absolute;
top: 50%;
color: #ccc;
font-family: 'erabbit' !important;
font-size: 32rpx;
transform: translateY(-50%);
}
}
}
}
</style>

@ -325,7 +325,7 @@ page {
color: #fff;
border-radius: 80rpx;
font-size: 30rpx;
background-color: #27ba9b;
background: linear-gradient(158deg, #51B6FF -10%, #3775F6 129%);
}
}
</style>

@ -7,7 +7,7 @@ const onLogout = () => {
//
uni.showModal({
content: '是否退出登录?',
confirmColor: '#27BA9B',
confirmColor: '#3775F6',
success: (res) => {
if (res.confirm) {
//
@ -22,22 +22,14 @@ const onLogout = () => {
<template>
<view class="viewport">
<!-- 列表1 -->
<view class="list" v-if="memberStore.profile">
<navigator url="/pagesMember/address/address" hover-class="none" class="item arrow">
我的收货地址
</navigator>
</view>
<!-- #ifdef MP-WEIXIN -->
<!-- 列表2 -->
<view class="list">
<button hover-class="none" class="item arrow" open-type="openSetting">授权管理</button>
<button hover-class="none" class="item arrow" open-type="feedback">问题反馈</button>
<button hover-class="none" class="item arrow" open-type="contact">联系我们</button>
</view>
<!-- #endif -->
<!-- 操作按钮 -->
<view class="action" v-if="memberStore.profile">
<!-- <view class="action" v-if="memberStore.profile"> -->
<view class="action">
<view @tap="onLogout" class="button">退出登录</view>
</view>
</view>

@ -22,14 +22,35 @@ const { guessRef, onScrolltolower } = useGuessList()
//
const popup = ref<UniHelper.UniPopupInstance>()
//
const reasonList = ref([
'商品无货',
'不想要了',
'商品信息填错了',
'地址信息填写错误',
'商品降价',
'其它',
])
// const reasonList = ref([
// '',
// '',
// '',
// '',
// '',
// '',
// ])
const latitude = ref('37.488')
const longitude = ref('121.4499')
const polyline = ref({
points: [
{
longitude: 121.44577861,
latitude: 37.4820526,
},
{
longitude: 121.44611657,
latitude: 37.48207388,
},
{
longitude: 121.44725382,
latitude: 37.48224841,
},
],
color: '#0091ff',
width: 6,
dottedLine: true,
})
//
const reason = ref('')
//
@ -53,34 +74,7 @@ type PageInstance = Page.PageInstance & WechatMiniprogram.Page.InstanceMethods<a
const pageInstance = pages.at(-1) as PageInstance
//
onReady(() => {
// ,
pageInstance.animate(
'.navbar',
[{ backgroundColor: 'transparent' }, { backgroundColor: '#f8f8f8' }],
1000,
{
scrollSource: '#scroller',
timeRange: 1000,
startScrollOffset: 0,
endScrollOffset: 50,
},
)
// ,
pageInstance.animate('.navbar .title', [{ color: 'transparent' }, { color: '#000' }], 1000, {
scrollSource: '#scroller',
timeRange: 1000,
startScrollOffset: 0,
endScrollOffset: 50,
})
// ,
pageInstance.animate('.navbar .back', [{ color: '#fff' }, { color: '#000' }], 1000, {
scrollSource: '#scroller',
timeRange: 1000,
startScrollOffset: 0,
endScrollOffset: 50,
})
})
onReady(() => { })
// #endif
//
@ -105,7 +99,8 @@ const getMemberOrderLogisticsByIdData = async () => {
}
onLoad(() => {
getMemberOrderByIdData()
// getMemberOrderByIdData()
// buttonDriving()
})
//
@ -150,6 +145,16 @@ const onOrderSend = async () => {
order.value!.orderState = OrderState.DaiShouHuo
}
}
const phone = async () => {
uni
.makePhoneCall({
phoneNumber: '13601921745',
})
.catch((e) => {
// console.log(e) //catch(e){makePhoneCall:fail cancel}
})
}
//
const onOrderConfirm = () => {
//
@ -164,243 +169,145 @@ const onOrderConfirm = () => {
}
},
})
}
//
const onOrderDelete = () => {
//
uni.showModal({
content: '是否删除订单',
confirmColor: '#27BA9B',
success: async (success) => {
if (success.confirm) {
await deleteMemberOrderAPI({ ids: [query.id] })
uni.redirectTo({ url: '/pagesOrder/list/list' })
}
},
})
}
//
const onOrderCancel = async () => {
//
const res = await getMemberOrderCancelByIdAPI(query.id, { cancelReason: reason.value })
//
order.value = res.result
//
popup.value?.close!()
//
uni.showToast({ icon: 'none', title: '订单取消成功' })
const handlePay = (item: object) => {
uni.navigateTo({ url: '/payment/detail/detail' })
}
const buttonDriving = () => {
//wx.requestHTTPS
wx.request({
//WebserviceAPI线 使
url: 'https://apis.map.qq.com/ws/direction/v1/driving/?key=ZHGBZ-L3L3M-7C46H-6CX3A-L5MOO-BFBRO&from=39.894772,116.321668&to=39.902781,116.427171',
success(res) {
const result = res.data.result
debugger
const route = result.routes[0]
debugger
const coors = route.polyline,
pl = []
//
const kr = 1000000
for (let i = 2; i < coors.length; i++) {
coors[i] = Number(coors[i - 2]) + Number(coors[i]) / kr
}
//pl
for (let i = 0; i < coors.length; i += 2) {
pl.push({ latitude: coors[i], longitude: coors[i + 1] })
}
// _this.setData({
// // 线
// latitude:pl[0].latitude,
// longitude:pl[0].longitude,
// // 线
// polyline: [{
// points: pl,
// color: '#58c16c',
// width: 6,
// borderColor: '#2f693c',
// borderWidth: 1
// }]
// })
},
})
}
//
// const onOrderDelete = () => {
// //
// uni.showModal({
// content: '',
// confirmColor: '#27BA9B',
// success: async (success) => {
// if (success.confirm) {
// await deleteMemberOrderAPI({ ids: [query.id] })
// uni.redirectTo({ url: '/pagesOrder/list/list' })
// }
// },
// })
}
</script>
<template>
<!-- 自定义导航栏: 默认透明不可见, scroll-view 滚动到 50 时展示 -->
<view class="navbar" :style="{ paddingTop: safeAreaInsets?.top + 'px' }">
<view class="wrap">
<navigator
v-if="pages.length > 1"
open-type="navigateBack"
class="back icon-left"
></navigator>
<navigator v-else url="/pages/index/index" open-type="switchTab" class="back icon-home">
</navigator>
<view class="title">订单详情</view>
</view>
</view>
<scroll-view
enable-back-to-top
scroll-y
class="viewport"
id="scroller"
@scrolltolower="onScrolltolower"
>
<template v-if="order">
<!-- 订单状态 -->
<view class="overview" :style="{ paddingTop: safeAreaInsets!.top + 20 + 'px' }">
<!-- 待付款状态:展示倒计时 -->
<template v-if="order.orderState === OrderState.DaiFuKuan">
<view class="status icon-clock">等待付款</view>
<view class="tips">
<text class="money">应付金额: ¥ {{ order.payMoney }}</text>
<text class="time">支付剩余</text>
<uni-countdown
:second="order.countdown"
color="#fff"
splitor-color="#fff"
:show-day="false"
:show-colon="false"
@timeup="onTimeup"
/>
</view>
<view class="button" @tap="onOrderPay"></view>
</template>
<!-- 其他订单状态:展示再次购买按钮 -->
<template v-else>
<!-- 订单状态文字 -->
<view class="status"> {{ orderStateList[order.orderState].text }} </view>
<view class="button-group">
<navigator
class="button"
:url="`/pagesOrder/create/create?orderId=${query.id}`"
hover-class="none"
>
再次购买
</navigator>
<!-- 待发货状态模拟发货,开发期间使用,用于修改订单状态为已发货 -->
<view
v-if="isDev && order.orderState == OrderState.DaiFaHuo"
@tap="onOrderSend"
class="button"
>
模拟发货
<view class="viewport">
<template v-if="1">
<view class="map">
<map
style="width: 100%; height: 200px"
:polyline="polyline"
:latitude="latitude"
:longitude="longitude"
>
</map>
</view>
<view class="card">
<view class="title">已达到</view>
<view class="cont">
<view class="info1">
<view class="loction">
<view class="text ellipsis">上海市松江区新松江路92弄开元地中海园区</view>
<view class="num">0.4km</view>
</view>
<!-- 待收货状态: 展示确认收货按钮 -->
<view
v-if="order.orderState === OrderState.DaiShouHuo"
@tap="onOrderConfirm"
class="button"
>
确认收货
<view class="coming-time">
<view class="label">上门时间</view>
<view class="val">今天上午 12:00</view>
</view>
<view class="people"> 曾先生 18526235487 </view>
</view>
</template>
</view>
<!-- 配送状态 -->
<view class="shipment">
<!-- 订单物流信息 -->
<view v-for="item in logisticList" :key="item.id" class="item">
<view class="message">
{{ item.text }}
</view>
<view class="date"> {{ item.time }} </view>
</view>
<!-- 用户收货地址 -->
<view class="locate">
<view class="user"> {{ order.receiverContact }} {{ order.receiverMobile }} </view>
<view class="address"> {{ order.receiverAddress }} </view>
</view>
</view>
<!-- 商品信息 -->
<view class="goods">
<view class="item">
<navigator
class="navigator"
v-for="item in order.skus"
:key="item.id"
:url="`/pages/goods/goods?id=${item.spuId}`"
hover-class="none"
>
<image class="cover" :src="item.image"></image>
<view class="meta">
<view class="name ellipsis">{{ item.name }}</view>
<view class="type">{{ item.attrsText }}</view>
<view class="price">
<view class="actual">
<text class="symbol">¥</text>
<text>{{ item.curPrice }}</text>
</view>
</view>
<view class="quantity">x{{ item.quantity }}</view>
<view class="info2">
<view class="item">
<view class="label">回收品类</view>
<view class="val">塑料瓶/纸箱</view>
</view>
<view class="item">
<view class="label">预计重量</view>
<view class="val">2kg</view>
</view>
<view class="item">
<view class="label">备注</view>
<view class="val"></view>
</view>
</navigator>
<!-- 待评价状态:展示按钮 -->
<view class="action" v-if="order.orderState === OrderState.DaiPingJia">
<view class="button primary">申请售后</view>
<navigator url="" class="button"> 去评价 </navigator>
</view>
</view>
<!-- 合计 -->
<view class="total">
<view class="row">
<view class="text">商品总价: </view>
<view class="symbol">{{ order.totalMoney }}</view>
</view>
<view class="row">
<view class="text">运费: </view>
<view class="symbol">{{ order.postFee }}</view>
</view>
<view class="row">
<view class="text">应付金额: </view>
<view class="symbol primary">{{ order.payMoney }}</view>
</view>
</view>
</view>
<!-- 订单信息 -->
<view class="detail">
<view class="title">订单信息</view>
<view class="row">
<view class="item">
订单编号: {{ query.id }} <text class="copy" @tap="onCopy(query.id)"></text>
</view>
<view class="item">下单时间: {{ order.createTime }}</view>
<view class="time-status">剩余接单时间<text class="time">06:25:52</text></view>
</view>
</view>
<!-- 猜你喜欢 -->
<XtxGuess ref="guessRef" />
<!-- 底部操作栏 -->
<view class="toolbar-height" :style="{ paddingBottom: safeAreaInsets?.bottom + 'px' }"></view>
<view class="toolbar" :style="{ paddingBottom: safeAreaInsets?.bottom + 'px' }">
<!-- 待付款状态:展示支付按钮 -->
<template v-if="order.orderState === OrderState.DaiFuKuan">
<view class="button primary" @tap="onOrderPay"> </view>
<view class="button" @tap="popup?.open?.()"> </view>
</template>
<!-- 其他订单状态:按需展示按钮 -->
<template v-else>
<navigator
class="button secondary"
:url="`/pagesOrder/create/create?orderId=${query.id}`"
hover-class="none"
>
再次购买
</navigator>
<!-- 待收货状态: 展示确认收货 -->
<view
class="button primary"
v-if="order.orderState === OrderState.DaiShouHuo"
@tap="onOrderConfirm"
>
确认收货
</view>
<!-- 待评价状态: 展示去评价 -->
<view class="button" v-if="order.orderState === OrderState.DaiPingJia"> </view>
<!-- 待评价/已完成/已取消 状态: 展示删除订单 -->
<view
class="button delete"
v-if="order.orderState >= OrderState.DaiPingJia"
@tap="onOrderDelete"
>
删除订单
</view>
</template>
<view class="button" @tap="phone">
<image
class="concat-img"
src="../../../static/images/detail_iphone.png"
mode="scaleToFill"
/>
</view>
<view class="button">
<image
class="concat-img"
src="../../../static/images/detail_concat.png"
mode="scaleToFill"
/>
</view>
<view class="button primary" @click="handlePay"></view>
</view>
</template>
<template v-else>
<!-- 骨架屏组件 -->
<PageSkeleton />
</template>
</scroll-view>
<!-- 取消订单弹窗 -->
<uni-popup ref="popup" type="bottom" background-color="#fff">
<view class="popup-root">
<view class="title">订单取消</view>
<view class="description">
<view class="tips">请选择取消订单的原因</view>
<view class="cell" v-for="item in reasonList" :key="item" @tap="reason = item">
<text class="text">{{ item }}</text>
<text class="icon" :class="{ checked: item === reason }"></text>
</view>
</view>
<view class="footer">
<view class="button" @tap="popup?.close?.()"></view>
<view class="button primary" @tap="onOrderCancel"></view>
</view>
</view>
</uni-popup>
</view>
<!-- // <uni-popup ref="popup" type="bottom" background-color="#fff">
// <view class="popup-root">
// <view class="title"></view>
// <view class="description">
// <view class="tips"></view>
// <view class="cell" v-for="item in reasonList" :key="item" @tap="reason = item">
// <text class="text">{{ item }}</text>
// <text class="icon" :class="{ checked: item === reason }"></text>
// </view>
// </view>
// <view class="footer">
// <view class="button" @tap="popup?.close?.()"></view>
// <view class="button primary" @tap="onOrderCancel"></view>
// </view>
// </view>
// </uni-popup> -->
</template>
<style lang="scss">
@ -409,370 +316,145 @@ page {
flex-direction: column;
height: 100%;
overflow: hidden;
}
.navbar {
width: 750rpx;
color: #000;
position: fixed;
top: 0;
left: 0;
z-index: 9;
/* background-color: #f8f8f8; */
background-color: transparent;
.wrap {
position: relative;
.title {
height: 44px;
display: flex;
justify-content: center;
align-items: center;
font-size: 32rpx;
/* color: #000; */
color: transparent;
}
.back {
position: absolute;
left: 0;
height: 44px;
width: 44px;
font-size: 44rpx;
display: flex;
align-items: center;
justify-content: center;
/* color: #000; */
color: #fff;
}
}
scrollbar-width: none;
}
.viewport {
background-color: #f7f7f8;
}
.overview {
display: flex;
flex-direction: column;
align-items: center;
line-height: 1;
padding-bottom: 30rpx;
color: #fff;
background-image: url(https://pcapi-xiaotuxian-front-devtest.itheima.net/miniapp/images/order_bg.png);
background-size: cover;
margin-bottom: 100rpx;
overflow: auto;
scrollbar-width: none;
.status {
font-size: 36rpx;
}
.status::before {
margin-right: 6rpx;
font-weight: 500;
}
.tips {
margin: 30rpx 0;
.card {
display: flex;
font-size: 14px;
align-items: center;
flex-direction: column;
width: 718rpx;
margin: 0 auto;
border-radius: 16rpx;
background: linear-gradient(180deg, #d2eeff -7%, rgba(255, 255, 255, 0) 38%), #ffffff;
box-shadow: 0px -2px 8px 0px rgba(133, 155, 180, 0.4);
padding: 20rpx;
.money {
margin-right: 30rpx;
.title {
color: #0d0d26;
font-size: 44rpx;
margin: 10rpx;
padding-bottom: 20rpx;
border-bottom: 2rpx solid #e1e7f2;
}
}
.button-group {
margin-top: 30rpx;
display: flex;
justify-content: center;
align-items: center;
}
.info1 {
padding: 20rpx 0;
min-height: 100rpx;
width: 100%;
border-bottom: 2rpx solid #e1e7f2;
.loction {
display: flex;
flex-direction: row;
width: 100%;
justify-content: space-between;
.text {
color: #3d3d3d;
width: 80%;
-webkit-line-clamp: 1;
}
.num {}
}
.button {
width: 260rpx;
height: 64rpx;
margin: 0 10rpx;
text-align: center;
line-height: 64rpx;
font-size: 28rpx;
color: #27ba9b;
border-radius: 68rpx;
background-color: #fff;
}
}
.coming-time {
margin: 10rpx 0;
display: flex;
flex-direction: row;
color: #3d3d3d;
.shipment {
line-height: 1.4;
padding: 0 20rpx;
margin: 20rpx 20rpx 0;
border-radius: 10rpx;
background-color: #fff;
.locate,
.item {
min-height: 120rpx;
padding: 30rpx 30rpx 25rpx 75rpx;
background-size: 50rpx;
background-repeat: no-repeat;
background-position: 6rpx center;
}
.label {}
}
.locate {
background-image: url(https://pcapi-xiaotuxian-front-devtest.itheima.net/miniapp/images/locate.png);
.people {
color: #3d3d3d;
.user {
font-size: 26rpx;
color: #444;
.label {}
}
}
.address {
font-size: 24rpx;
color: #666;
}
}
.info2 {
padding: 20rpx 0;
min-height: 100rpx;
border-bottom: 2rpx solid #e1e7f2;
.item {
background-image: url(https://pcapi-xiaotuxian-front-devtest.itheima.net/miniapp/images/car.png);
border-bottom: 1rpx solid #eee;
position: relative;
.item {
display: flex;
flex-direction: row;
margin: 20rpx 0;
.message {
font-size: 26rpx;
color: #444;
.label {
color: #999a9f;
}
}
}
.date {
font-size: 24rpx;
color: #666;
.time-status {
margin: 20rpx 0;
font-size: 32rpx;
.time {
color: #e30000;
}
}
}
}
.goods {
margin: 20rpx 20rpx 0;
padding: 0 20rpx;
border-radius: 10rpx;
background-color: #fff;
.item {
padding: 30rpx 0;
border-bottom: 1rpx solid #eee;
.toolbar-height {
height: 100rpx;
box-sizing: content-box;
}
.navigator {
display: flex;
margin: 20rpx 0;
}
.toolbar {
position: fixed;
left: 0;
right: 0;
bottom: calc(var(--window-bottom));
z-index: 1;
.cover {
width: 170rpx;
height: 170rpx;
border-radius: 10rpx;
margin-right: 20rpx;
}
height: 100rpx;
display: flex;
align-items: center;
justify-content: space-around;
border-top: 1rpx solid #ededed;
border-bottom: 1rpx solid #ededed;
background-color: #fff;
box-sizing: content-box;
.meta {
flex: 1;
.button {
display: flex;
flex-direction: column;
justify-content: center;
position: relative;
}
.name {
height: 80rpx;
align-items: center;
flex: 1;
height: 100%;
font-size: 26rpx;
color: #444;
}
.type {
line-height: 1.8;
padding: 0 15rpx;
margin-top: 6rpx;
font-size: 24rpx;
align-self: flex-start;
border-radius: 4rpx;
color: #888;
background-color: #f7f7f8;
}
.price {
display: flex;
margin-top: 6rpx;
font-size: 24rpx;
}
.symbol {
font-size: 20rpx;
}
.original {
color: #999;
text-decoration: line-through;
}
.actual {
margin-left: 10rpx;
color: #444;
}
.text {
font-size: 22rpx;
}
.quantity {
position: absolute;
bottom: 0;
right: 0;
font-size: 24rpx;
color: #444;
}
border-right: 1rpx solid #ccc;
color: #fff;
.action {
display: flex;
flex-direction: row-reverse;
justify-content: flex-start;
padding: 30rpx 0 0;
.button {
width: 200rpx;
height: 60rpx;
text-align: center;
justify-content: center;
line-height: 60rpx;
margin-left: 20rpx;
border-radius: 60rpx;
border: 1rpx solid #ccc;
font-size: 26rpx;
color: #444;
.concat {
width: 48rpx;
height: 44rpx;
}
.primary {
color: #27ba9b;
border-color: #27ba9b;
.concat-img {
width: 48rpx;
height: 44rpx;
}
}
}
.total {
line-height: 1;
font-size: 26rpx;
padding: 20rpx 0;
color: #666;
.row {
display: flex;
align-items: center;
justify-content: space-between;
padding: 10rpx 0;
}
.symbol::before {
content: '¥';
font-size: 80%;
margin-right: 3rpx;
}
.primary {
color: #cf4444;
font-size: 36rpx;
}
}
}
.detail {
line-height: 1;
padding: 30rpx 20rpx 0;
margin: 20rpx 20rpx 0;
font-size: 26rpx;
color: #666;
border-radius: 10rpx;
background-color: #fff;
.title {
font-size: 30rpx;
color: #444;
}
.row {
padding: 20rpx 0;
.item {
padding: 10rpx 0;
display: flex;
align-items: center;
}
.copy {
border-radius: 20rpx;
font-size: 20rpx;
border: 1px solid #ccc;
padding: 5rpx 10rpx;
margin-left: 10rpx;
color: #fff;
background: linear-gradient(158deg, #51b6ff -10%, #3775f6 129%);
}
}
}
.toolbar-height {
height: 100rpx;
box-sizing: content-box;
}
.toolbar {
position: fixed;
left: 0;
right: 0;
bottom: calc(var(--window-bottom));
z-index: 1;
height: 100rpx;
padding: 0 20rpx;
display: flex;
align-items: center;
flex-direction: row-reverse;
border-top: 1rpx solid #ededed;
border-bottom: 1rpx solid #ededed;
background-color: #fff;
box-sizing: content-box;
.button {
display: flex;
justify-content: center;
align-items: center;
width: 200rpx;
height: 72rpx;
margin-left: 15rpx;
font-size: 26rpx;
border-radius: 72rpx;
border: 1rpx solid #ccc;
color: #444;
}
.delete {
order: 4;
color: #cf4444;
}
.button {
order: 3;
}
.secondary {
order: 2;
color: #27ba9b;
border-color: #27ba9b;
}
.primary {
order: 1;
color: #fff;
background-color: #27ba9b;
}
}
.popup-root {
padding: 30rpx 30rpx 0;
border-radius: 10rpx 10rpx 0 0;

@ -0,0 +1,165 @@
<script setup lang="ts">
import { ref } from 'vue'
const sumVal = ref('0')
const payment = () => {
uni.navigateTo({ url: '/payment/success/success' })
}
</script>
<template>
<view class="viewport">
<view class="cont">
<view class="title">回收详情</view>
<view class="form">
<view class="uni-form-item uni-row">
<view class="label">废纸Kg</view>
<input class="uni-input" type="digit" name="input" placeholder="请输入" />
</view>
<view class="uni-form-item uni-row">
<view class="label">塑料Kg</view>
<input class="uni-input" type="digit" name="input" placeholder="请输入" />
</view>
<view class="uni-form-item uni-row">
<view class="label">废金属Kg</view>
<input class="uni-input" type="digit" name="input" placeholder="请输入" />
</view>
<view class="uni-form-item uni-row">
<view class="label">玻璃制品Kg</view>
<input class="uni-input" type="digit" name="input" placeholder="请输入" />
</view>
<view class="sum">
<view class="item">
<view class="label">合计</view>
<input
class="uni-input"
v-model="sumVal"
type="digit"
name="input"
placeholder="请输入"
/>
</view>
<view class="item">
<view class="label">赠送积分积分</view>
<input
class="uni-input disabled"
disabled
v-model="sumVal"
type="digit"
name="input"
placeholder="请输入"
/>
</view>
</view>
</view>
</view>
<view class="action" @click="payment"> </view>
</view>
</template>
<style lang="scss">
page {
height: 100%;
}
.viewport {
height: 100%;
display: flex;
position: relative;
flex-direction: column;
// background-color: #3775F6;
.cont {
width: 716rpx;
margin: 30rpx auto;
height: 816rpx;
padding: 20rpx 20rpx;
border-radius: 16rpx;
background: linear-gradient(180deg, #d2eeff -2%, rgba(255, 255, 255, 0) 22%), #ffffff;
box-shadow: 0px -2px 8px 0px rgba(133, 155, 180, 0.4);
.title {
border-bottom: 2rpx solid #e1e7f2;
font-size: 44rpx;
padding: 20rpx 10rpx 20rpx;
}
.form {
margin: 20rpx 0;
.uni-form-item {
margin: 20rpx 0;
// padding: 10rpx 0;
}
.uni-row {
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
.label {
margin-right: 10rpx;
color: #0d0d26;
font-size: 30rpx;
width: 260rpx;
}
.uni-input {
padding: 0 20rpx;
height: 70rpx;
flex: 1;
line-height: 70rpx;
background: #f2f2fa;
border-radius: 8rpx;
}
}
}
.sum {
margin: 60rpx 0;
.item {
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
margin: 20rpx 0;
.label {
width: 360rpx;
color: #0d0d26;
font-size: 36rpx;
}
.uni-input {
flex: 1;
padding: 0 10rpx;
height: 70rpx;
line-height: 70rpx;
background: #f2f2fa;
border-radius: 8rpx;
&.disabled {
background: none;
}
}
}
}
}
.action {
position: absolute;
bottom: 100rpx;
left: 50%;
transform: translate(-50%, -50%);
background: linear-gradient(143deg, #51B6FF 1%, #3775F6 92%);
width: 400rpx;
height: 112rpx;
color: #fff;
display: flex;
border-radius: 100rpx;
font-size: 40rpx;
flex-direction: column;
justify-content: center;
align-items: center;
}
}</style>

@ -0,0 +1,106 @@
<script setup lang="ts">
import { ref } from 'vue'
//
const gotoHome = () => {
uni.switchTab({ url: '/pages/index/index' })
}
const gotoBack = () => {
uni.navigateBack({ delta: 1 })
}
const gotoTodo = () => {
uni.showToast({
title: 'todo...',
mask: true,
})
}
</script>
<template>
<view class="viewport">
<view class="cont">
<view class="status">
<image class="img" src="/static/images/fail_result.png" mode="scaleToFill" />
<view class="text">结算失败</view>
<view class="desc">貌似出了点问题点击下方按钮重新结算</view>
</view>
<view class="action" @click="gotoBack"> </view>
<view class="action-repeat">
<view class="desc">
主账户余额不足时可透支结算请及时提醒主账户拥有者充值充值后将自动扣除透支金额
</view>
<view class="button" @click="gotoTodo"> </view>
</view>
</view>
</view>
</template>
<style lang="scss">
page {
height: 100%;
}
.viewport {
height: 100%;
display: flex;
position: relative;
flex-direction: column;
// background-color: #3775F6;
.cont {
height: 100vh;
width: 100vw;
background: linear-gradient(180deg, #ff6666 -11%, rgba(250, 250, 253, 0) 43%), #fafafd;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
.status {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
.img {
width: 120rpx;
height: 120rpx;
}
.text {
color: #e30000;
margin: 20rpx 0;
font-size: 44rpx;
}
.desc {
color: #999a9f;
font-size: 30rpx;
}
}
.action {
background: linear-gradient(124deg, #fd815f 4%, #f1484a 98%);
width: 400rpx;
height: 112rpx;
margin: 100rpx 0 40rpx;
color: #fff;
display: flex;
border-radius: 100rpx;
font-size: 36rpx;
flex-direction: column;
justify-content: center;
align-items: center;
}
.action-repeat {
margin: 140rpx 60rpx 0;
.desc {
color: #999a9f;
font-size: 30rpx;
}
.button {
width: 384rpx;
margin: 40rpx auto;
border-radius: 100rpx;
color: #e30000;
border: 2rpx solid #e30000;
padding: 30rpx 120rpx;
}
}
}
}
</style>

@ -0,0 +1,75 @@
<script setup lang="ts">
import { ref } from 'vue'
//
const gotoHome = () => {
uni.switchTab({ url: '/pages/index/index' })
}
</script>
<template>
<view class="viewport">
<view class="cont">
<view class="status">
<image class="img" src="/static/images/success_result.png" mode="scaleToFill" />
<view class="text">结算成功</view>
<view class="desc">当前剩余3个订单未处理请尽快处理</view>
</view>
<view class="action" @click="gotoHome"> </view>
</view>
</view>
</template>
<style lang="scss">
page {
height: 100%;
}
.viewport {
height: 100%;
display: flex;
position: relative;
flex-direction: column;
// background-color: #3775F6;
.cont {
height: 100vh;
width: 100vw;
background: linear-gradient(180deg, #5089ff -13%, rgba(250, 250, 253, 0) 43%), #fafafd;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
.status {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
.img {
width: 120rpx;
height: 120rpx;
}
.text {
color: #3d3d3d;
margin: 20rpx 0;
font-size: 44rpx;
}
.desc {
color: #999a9f;
font-size: 30rpx;
}
}
.action {
background: linear-gradient(149deg, #51b6ff 19%, #3775f6 82%);
width: 400rpx;
height: 112rpx;
margin: 200rpx 0 40rpx;
color: #fff;
display: flex;
border-radius: 100rpx;
font-size: 36rpx;
flex-direction: column;
justify-content: center;
align-items: center;
}
}
}
</style>

@ -1,3 +1,11 @@
/*
* @Author:
* @Date: 2024-01-04 12:54:56
* @LastEditors:
* @LastEditTime: 2024-02-20 09:33:04
* @FilePath: /app-nx-recycle/src/services/login.ts
* @Description: ,`customMade`, koroFileHeader : https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
import type { LoginResult } from '@/types/member'
import { http } from '@/utils/http'
@ -13,7 +21,7 @@ type LoginWxMinParams = {
export const postLoginWxMinAPI = (data: LoginWxMinParams) => {
return http<LoginResult>({
method: 'POST',
url: '/login/wxMin',
url: '/scm/wx/hsyGetPhone',
data,
})
}

@ -129,14 +129,21 @@ export const getMemberOrderCancelByIdAPI = (id: string, data: { cancelReason: st
})
}
export const getMemberOrderAPI = (data: OrderListParams) => {
return http<OrderListResult>({
method: 'POST',
url: `/scm/RecycleOrder/getList`,
data,
})
}
/**
*
* @param data orderState
*/
export const getMemberOrderAPI = (data: OrderListParams) => {
export const getListOrderAPI = (data: OrderListParams) => {
return http<OrderListResult>({
method: 'GET',
url: `/member/order`,
method: 'POST',
url: `/scm/RecycleOrder/getList`,
data,
})
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 352 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.9 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.0 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.5 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

@ -9,5 +9,4 @@ pinia.use(persist)
// 默认导出,给 main.ts 使用
export default pinia
// 模块统一导出
export * from './modules/member'

@ -1,44 +1,33 @@
/*
* @Author:
* @Date: 2024-01-04 12:54:56
* @LastEditors:
* @LastEditTime: 2024-02-22 10:12:46
* @FilePath: /app-nx-recycle/src/stores/modules/member.ts
* @Description: ,`customMade`, koroFileHeader : https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
import type { LoginResult } from '@/types/member'
import { defineStore } from 'pinia'
import { ref } from 'vue'
// 定义 Store
export const useMemberStore = defineStore(
'member',
() => {
// 会员信息
const profile = ref<LoginResult>()
export const useMemberStore = defineStore('member', () => {
// 会员信息
const profile = ref<LoginResult>()
// 保存会员信息,登录时使用
const setProfile = (val: LoginResult) => {
profile.value = val
}
// 保存会员信息,登录时使用
const setProfile = (val: LoginResult) => {
profile.value = val
}
// 清理会员信息,退出时使用
const clearProfile = () => {
profile.value = undefined
}
// 清理会员信息,退出时使用
const clearProfile = () => {
profile.value = undefined
}
// 记得 return
return {
profile,
setProfile,
clearProfile,
}
},
{
// 网页端配置
// persist: true,
// 小程序端配置
persist: {
storage: {
getItem(key) {
return uni.getStorageSync(key)
},
setItem(key, value) {
uni.setStorageSync(key, value)
},
},
},
},
)
// 记得 return
return {
profile,
setProfile,
clearProfile,
}
})

@ -1,23 +1,38 @@
/*
* @Author:
* @Date: 2024-01-04 12:54:56
* @LastEditors:
* @LastEditTime: 2024-02-22 17:00:35
* @FilePath: /app-nx-recycle/src/types/global.d.ts
* @Description: ,`customMade`, koroFileHeader : https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
/** 通用分页结果类型 */
export type PageResult<T> = {
/** 列表数据 */
items: T[]
/** 总条数 */
counts: number
/** 当前页数 */
page: number
/** 总页数 */
pages: number
/** 每页条数 */
list: T[]
pagination: pagination
}
/** 二级分类项 */
export type pagination = {
/** 二级分类id */
currentPage: number
/** 二级分类名称 */
pageSize: number
/** 总条数 */
total: number
}
/** 通用分页参数类型 */
export type PageParams = {
/** 页码:默认值为 1 */
page?: number
currentPage?: number
/** 页大小:默认值为 10 */
pageSize?: number
pageSize?: number,
/** 订单状态 */
orderStafstatusId: String,
/** 员工id */
staffId: String
}
/** 通用商品类型 */

@ -1,3 +1,11 @@
/*
* @Author:
* @Date: 2024-01-04 12:54:56
* @LastEditors:
* @LastEditTime: 2024-02-22 10:29:50
* @FilePath: /app-nx-recycle/src/types/member.d.ts
* @Description: ,`customMade`, koroFileHeader : https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
/** 通用的用户信息 */
type BaseProfile = {
/** 用户ID */
@ -12,10 +20,10 @@ type BaseProfile = {
/** 小程序登录 登录用户信息 */
export type LoginResult = BaseProfile & {
/** 手机号 */
mobile: string
/** 登录凭证 */
token: string
token: string,
/** 用户信息 */
userInfo: Object
}
/** 个人信息 用户详情信息 */

@ -142,7 +142,7 @@ export type LogisticItem = {
}
/** 订单列表参数 */
export type OrderListParams = PageParams & { orderState: number }
export type OrderListParams = PageParams
/** 订单列表 */
export type OrderListResult = {

@ -1,3 +1,11 @@
/*
* @Author:
* @Date: 2024-01-04 12:54:56
* @LastEditors:
* @LastEditTime: 2024-02-23 10:49:25
* @FilePath: /app-nx-recycle/src/utils/http.ts
* @Description: ,`customMade`, koroFileHeader : https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
/**
* :
* request
@ -12,7 +20,7 @@
import { useMemberStore } from '@/stores'
const baseURL = 'https://pcapi-xiaotuxian-front-devtest.itheima.net'
const baseURL = 'http://222.71.165.187:3333/api'
// 添加拦截器
const httpInterceptor = {
@ -28,6 +36,7 @@ const httpInterceptor = {
options.header = {
...options.header,
'source-client': 'miniapp',
'jnpf-origin': 'app',
}
// 4. 添加 token 请求头标识
const memberStore = useMemberStore()
@ -58,6 +67,22 @@ type Data<T> = {
msg: string
result: T
}
function ajaxError(data) {
uni.showToast({
title: data.msg || '请求出错,请重试',
icon: 'none',
complete() {
if (data.code === 600 || data.code === 601 || data.code === 602) {
const memberStore = useMemberStore()
memberStore.clearProfile()
uni.reLaunch({
url: '/pages/login/login'
})
}
}
})
}
// 2.2 添加类型,支持泛型
export const http = <T>(options: UniApp.RequestOptions) => {
// 1. 返回 Promise 对象
@ -68,12 +93,18 @@ export const http = <T>(options: UniApp.RequestOptions) => {
success(res) {
// 状态码 2xx axios 就是这样设计的
if (res.statusCode >= 200 && res.statusCode < 300) {
if (res.data?.code == 200) {
resolve(res.data as Data<T>)
} else {
ajaxError(res.data)
reject(res.data?.msg)
}
// 2.1 提取核心数据 res.data
resolve(res.data as Data<T>)
// resolve(res.data as Data<T>)
} else if (res.statusCode === 401) {
// 401错误 -> 清理用户信息,跳转到登录页
const memberStore = useMemberStore()
memberStore.clearProfile()
// const userStore = useUserStore()
// userStore.clearProfile()
uni.navigateTo({ url: '/pages/login/login' })
reject(res)
} else {

@ -1,4 +1,5 @@
import { defineConfig } from 'vite'
import { viteMockServe } from 'vite-plugin-mock'
import uni from '@dcloudio/vite-plugin-uni'
// https://vitejs.dev/config/
@ -7,5 +8,10 @@ export default defineConfig({
// 开发阶段启用源码映射https://uniapp.dcloud.net.cn/tutorial/migration-to-vue3.html#需主动开启-sourcemap
sourcemap: process.env.NODE_ENV === 'development',
},
plugins: [uni()],
plugins: [
uni(),
viteMockServe({
supportTs: true,
}),
],
})

Loading…
Cancel
Save