mirror of
https://gitee.com/beijing_hongye_huicheng/lilishop-uniapp.git
synced 2026-08-06 10:57:25 +08:00
refactor: 重构多个组件以支持 Vue 3 语法和功能
- 将多个组件转换为 `<script setup>` 语法,提升可读性和性能 - 优化状态管理和事件处理逻辑,简化代码结构 - 更新样式和布局以适应新组件结构 - 添加新功能和修复已知问题,提升用户体验
This commit is contained in:
@@ -1,7 +1,14 @@
|
||||
<template>
|
||||
<view class="add-address">
|
||||
<u-form :model="form" ref="uForm" error-type="toast" :rules="rules">
|
||||
<u-form-item label="收货人" label-width="130" prop="name" :border-bottom="true">
|
||||
<up-form
|
||||
:model="form"
|
||||
ref="uForm"
|
||||
error-type="toast"
|
||||
:rules="rules"
|
||||
label-position="left"
|
||||
label-width="180rpx"
|
||||
>
|
||||
<up-form-item label="收货人" label-width="180rpx" prop="name" :border-bottom="true">
|
||||
<u-input
|
||||
v-model="form.name"
|
||||
border="none"
|
||||
@@ -9,9 +16,9 @@
|
||||
clearable
|
||||
placeholder="请输入收货人姓名"
|
||||
/>
|
||||
</u-form-item>
|
||||
</up-form-item>
|
||||
|
||||
<u-form-item label="手机号码" label-width="130" prop="mobile" :border-bottom="true">
|
||||
<up-form-item label="手机号码" label-width="180rpx" prop="mobile" :border-bottom="true">
|
||||
<u-input
|
||||
v-model="form.mobile"
|
||||
type="number"
|
||||
@@ -20,18 +27,18 @@
|
||||
input-align="right"
|
||||
placeholder="请输入收货人手机号码"
|
||||
/>
|
||||
</u-form-item>
|
||||
</up-form-item>
|
||||
|
||||
<u-form-item label="所在区域" label-width="130" prop="___path" :border-bottom="true">
|
||||
<up-form-item label="所在区域" label-width="180rpx" prop="___path" :border-bottom="true">
|
||||
<view class="form-value" @click="showPicker">
|
||||
{{ form.___path || '请选择所在地区' }}
|
||||
</view>
|
||||
<template #right>
|
||||
<u-icon name="arrow-right" color="#ccc" size="16"></u-icon>
|
||||
</template>
|
||||
</u-form-item>
|
||||
</up-form-item>
|
||||
|
||||
<u-form-item class="detailAddress" label="详细地址" label-width="130" prop="detail" :border-bottom="true">
|
||||
<up-form-item class="detailAddress" label="详细地址" label-width="180rpx" prop="detail" :border-bottom="true">
|
||||
<u-input
|
||||
type="textarea"
|
||||
v-model="form.detail"
|
||||
@@ -40,16 +47,16 @@
|
||||
border="none"
|
||||
placeholder="街道楼牌号等"
|
||||
/>
|
||||
</u-form-item>
|
||||
</up-form-item>
|
||||
|
||||
<u-form-item label="地址别名" label-width="130" :border-bottom="false">
|
||||
<up-form-item label="地址别名" label-width="180rpx" :border-bottom="false">
|
||||
<u-input
|
||||
v-model="form.alias"
|
||||
border="none"
|
||||
input-align="right"
|
||||
placeholder="请输入地址别名"
|
||||
/>
|
||||
</u-form-item>
|
||||
</up-form-item>
|
||||
|
||||
<view class="default-row">
|
||||
<u-checkbox
|
||||
@@ -63,7 +70,7 @@
|
||||
</view>
|
||||
|
||||
<view class="saveBtn" @click="save">保存</view>
|
||||
</u-form>
|
||||
</up-form>
|
||||
|
||||
<m-city
|
||||
:provinceData="list"
|
||||
@@ -76,266 +83,208 @@
|
||||
<uniMap v-if="mapFlag" @close="closeMap" @callback="callBackAddress" />
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
import { addAddress, editAddress, getAddressDetail } from "@/api/address.js";
|
||||
import city from "@/components/m-city/m-city.vue";
|
||||
import uniMap from "@/components/uniMap";
|
||||
import permision from "@/js_sdk/wa-permission/permission.js";
|
||||
export default {
|
||||
components: {
|
||||
"m-city": city,
|
||||
uniMap,
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, computed, getCurrentInstance } from 'vue'
|
||||
import { onLoad, onShow, onReady } from '@dcloudio/uni-app'
|
||||
import { useStore } from '@/store'
|
||||
import { addAddress as addAddressApi, editAddress, getAddressDetail } from '@/api/address.js'
|
||||
import MCity from '@/components/m-city/m-city.vue'
|
||||
import uniMap from '@/components/uniMap'
|
||||
import permision from '@/js_sdk/wa-permission/permission.js'
|
||||
|
||||
const store = useStore()
|
||||
const { proxy } = getCurrentInstance()!
|
||||
|
||||
const lightColor = computed(() => store.getters.lightColor)
|
||||
const mapFlag = ref(false)
|
||||
const routerVal = ref<Record<string, string>>({})
|
||||
const uForm = ref<any>(null)
|
||||
const cityPicker = ref<any>(null)
|
||||
|
||||
const form = reactive<Record<string, any>>({
|
||||
detail: '',
|
||||
name: '',
|
||||
mobile: '',
|
||||
consigneeAddressIdPath: [],
|
||||
consigneeAddressPath: [],
|
||||
___path: '',
|
||||
isDefault: false,
|
||||
})
|
||||
|
||||
const list = ref([
|
||||
{
|
||||
id: '',
|
||||
localName: '请选择',
|
||||
children: [],
|
||||
},
|
||||
onShow() {
|
||||
// 判断当前系统权限定位是否开启
|
||||
},
|
||||
methods: {
|
||||
// 关闭地图
|
||||
closeMap() {
|
||||
this.mapFlag = false;
|
||||
])
|
||||
|
||||
const rules = {
|
||||
name: [
|
||||
{
|
||||
required: true,
|
||||
message: '收货人姓名不能为空',
|
||||
trigger: ['blur', 'change'],
|
||||
},
|
||||
// 打开地图并访问权限
|
||||
clickUniMap() {
|
||||
// #ifdef APP-PLUS
|
||||
if (plus.os.name == "iOS") {
|
||||
// ios系统
|
||||
permision.judgeIosPermission("location")
|
||||
? (this.mapFlag = true)
|
||||
: this.refuseMap();
|
||||
} else {
|
||||
// 安卓
|
||||
this.requestAndroidPermission(
|
||||
"android.permission.ACCESS_FINE_LOCATION"
|
||||
);
|
||||
}
|
||||
// #endif
|
||||
|
||||
// #ifndef APP-PLUS
|
||||
this.mapFlag = true;
|
||||
// #endif
|
||||
],
|
||||
mobile: [
|
||||
{
|
||||
required: true,
|
||||
message: '手机号码不能为空',
|
||||
trigger: ['blur', 'change'],
|
||||
},
|
||||
|
||||
// 如果拒绝权限 提示区设置
|
||||
refuseMap() {
|
||||
uni.showModal({
|
||||
title: "温馨提示",
|
||||
content: "您已拒绝定位,请开启",
|
||||
confirmText: "去设置",
|
||||
success(res) {
|
||||
if (res.confirm) {
|
||||
//打开授权设置
|
||||
// #ifndef MP-WEIXIN
|
||||
uni.getSystemInfo({
|
||||
success(res) {
|
||||
if (res.platform == "ios") {
|
||||
//IOS
|
||||
plus.runtime.openURL("app-settings://");
|
||||
} else if (res.platform == "android") {
|
||||
//安卓
|
||||
let main = plus.android.runtimeMainActivity();
|
||||
let Intent = plus.android.importClass(
|
||||
"android.content.Intent"
|
||||
);
|
||||
let mIntent = new Intent("android.settings.ACTION_SETTINGS");
|
||||
main.startActivity(mIntent);
|
||||
}
|
||||
},
|
||||
});
|
||||
// #endif
|
||||
}
|
||||
},
|
||||
});
|
||||
{
|
||||
validator: (_rule: unknown, value: string) => proxy.$u.test.mobile(value),
|
||||
message: '手机号码不正确',
|
||||
trigger: ['change', 'blur'],
|
||||
},
|
||||
|
||||
// 获取安卓是否拥有地址权限
|
||||
async requestAndroidPermission(permisionID) {
|
||||
var result = await permision.requestAndroidPermission(permisionID);
|
||||
|
||||
if (result == 1) {
|
||||
this.mapFlag = true;
|
||||
} else {
|
||||
this.refuseMap();
|
||||
}
|
||||
],
|
||||
___path: [
|
||||
{
|
||||
required: true,
|
||||
message: '请选择所在区域',
|
||||
trigger: ['change'],
|
||||
},
|
||||
|
||||
// 选择地址后数据的回调
|
||||
callBackAddress(val) {
|
||||
console.log(val)
|
||||
uni.showLoading({
|
||||
title: "加载中",
|
||||
});
|
||||
|
||||
if (val.regeocode && val) {
|
||||
let address = val.regeocode;
|
||||
this.form.detail = address.formatted_address; //地址详情
|
||||
this.form.___path = val.data.result.name;
|
||||
this.form.consigneeAddressIdPath = val.data.result.id; // 地址id分割
|
||||
this.form.consigneeAddressPath = val.data.result.name; //地址名称, ','分割
|
||||
this.form.lat = val.latitude; //纬度
|
||||
this.form.lon = val.longitude; //经度
|
||||
uni.hideLoading();
|
||||
}
|
||||
|
||||
this.mapFlag = !this.mapFlag; //关闭地图
|
||||
],
|
||||
detail: [
|
||||
{
|
||||
required: true,
|
||||
message: '请填写详细地址',
|
||||
trigger: ['blur', 'change'],
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
// 保存当前 地址
|
||||
save() {
|
||||
this.$refs.uForm.validate().then(() => {
|
||||
const params = { ...this.form };
|
||||
delete params.___path;
|
||||
onShow(() => {})
|
||||
|
||||
if (Array.isArray(params.consigneeAddressIdPath)) {
|
||||
params.consigneeAddressIdPath = params.consigneeAddressIdPath.join(",");
|
||||
}
|
||||
if (Array.isArray(params.consigneeAddressPath)) {
|
||||
params.consigneeAddressPath = params.consigneeAddressPath.join(",");
|
||||
}
|
||||
onLoad((option) => {
|
||||
uni.showLoading({ title: '加载中' })
|
||||
routerVal.value = option || {}
|
||||
if (option.id) {
|
||||
getAddressDetail(option.id).then((res) => {
|
||||
const params = res.data.result
|
||||
params.___path = params.consigneeAddressPath
|
||||
Object.assign(form, params)
|
||||
if (store.state.isShowToast) uni.hideLoading()
|
||||
})
|
||||
}
|
||||
uni.hideLoading()
|
||||
})
|
||||
|
||||
if (!params.id) {
|
||||
addAddress(params).then((res) => {
|
||||
if (res.data.success) {
|
||||
uni.navigateBack();
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: res.data.message || "保存失败",
|
||||
icon: "none",
|
||||
});
|
||||
onReady(() => {
|
||||
uForm.value?.setRules(rules)
|
||||
})
|
||||
|
||||
function closeMap() {
|
||||
mapFlag.value = false
|
||||
}
|
||||
|
||||
function refuseMap() {
|
||||
uni.showModal({
|
||||
title: '温馨提示',
|
||||
content: '您已拒绝定位,请开启',
|
||||
confirmText: '去设置',
|
||||
success(res) {
|
||||
if (res.confirm) {
|
||||
// #ifndef MP-WEIXIN
|
||||
uni.getSystemInfo({
|
||||
success(sysRes) {
|
||||
if (sysRes.platform == 'ios') {
|
||||
plus.runtime.openURL('app-settings://')
|
||||
} else if (sysRes.platform == 'android') {
|
||||
const main = plus.android.runtimeMainActivity()
|
||||
const Intent = plus.android.importClass('android.content.Intent')
|
||||
const mIntent = new Intent('android.settings.ACTION_SETTINGS')
|
||||
main.startActivity(mIntent)
|
||||
}
|
||||
});
|
||||
} else {
|
||||
delete params.updateBy;
|
||||
delete params.updateTime;
|
||||
editAddress(params).then((res) => {
|
||||
if (res.data.success) {
|
||||
uni.navigateBack();
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: res.data.message || "保存失败",
|
||||
icon: "none",
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}).catch(() => {});
|
||||
},
|
||||
})
|
||||
// #endif
|
||||
}
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
// 三级地址联动回调
|
||||
getpickerParentValue(e) {
|
||||
// 将需要绑定的地址设置为空,并赋值
|
||||
this.form.consigneeAddressIdPath = [];
|
||||
this.form.consigneeAddressPath = [];
|
||||
let name = "";
|
||||
async function requestAndroidPermission(permisionID: string) {
|
||||
const result = await permision.requestAndroidPermission(permisionID)
|
||||
if (result == 1) {
|
||||
mapFlag.value = true
|
||||
} else {
|
||||
refuseMap()
|
||||
}
|
||||
}
|
||||
|
||||
e.forEach((item, index) => {
|
||||
if (item.id) {
|
||||
// 遍历数据
|
||||
this.form.consigneeAddressIdPath.push(item.id);
|
||||
this.form.consigneeAddressPath.push(item.localName);
|
||||
name += item.localName;
|
||||
this.form.___path = name;
|
||||
}
|
||||
if (index == e.length - 1) {
|
||||
//如果是最后一个
|
||||
let _town = item.children.filter((_child) => {
|
||||
return _child.id == item.id;
|
||||
});
|
||||
function callBackAddress(val: any) {
|
||||
uni.showLoading({ title: '加载中' })
|
||||
if (val.regeocode && val) {
|
||||
const address = val.regeocode
|
||||
form.detail = address.formatted_address
|
||||
form.___path = val.data.result.name
|
||||
form.consigneeAddressIdPath = val.data.result.id
|
||||
form.consigneeAddressPath = val.data.result.name
|
||||
form.lat = val.latitude
|
||||
form.lon = val.longitude
|
||||
uni.hideLoading()
|
||||
}
|
||||
mapFlag.value = !mapFlag.value
|
||||
}
|
||||
|
||||
this.form.lat = _town[0].center.split(",")[1];
|
||||
this.form.lon = _town[0].center.split(",")[0];
|
||||
}
|
||||
});
|
||||
},
|
||||
function save() {
|
||||
uForm.value?.validate().then(() => {
|
||||
const params = { ...form }
|
||||
delete params.___path
|
||||
|
||||
// 显示三级地址联动
|
||||
showPicker() {
|
||||
this.$refs.cityPicker.show();
|
||||
},
|
||||
},
|
||||
mounted() {},
|
||||
data() {
|
||||
return {
|
||||
lightColor: this.$lightColor, //高亮颜色
|
||||
mapFlag: false, // 地图选择开
|
||||
routerVal: "",
|
||||
form: {
|
||||
detail: "", //地址详情
|
||||
name: "", //收货人姓名
|
||||
mobile: "", //手机号码
|
||||
consigneeAddressIdPath: [], //地址id
|
||||
consigneeAddressPath: [], //地址名字
|
||||
___path: "", //所在区域
|
||||
isDefault: false, //是否默认地址
|
||||
},
|
||||
// 表单提交校验规则
|
||||
rules: {
|
||||
name: [
|
||||
{
|
||||
required: true,
|
||||
message: "收货人姓名不能为空",
|
||||
trigger: ["blur", "change"],
|
||||
},
|
||||
],
|
||||
mobile: [
|
||||
{
|
||||
required: true,
|
||||
message: "手机号码不能为空",
|
||||
trigger: ["blur", "change"],
|
||||
},
|
||||
{
|
||||
validator: (rule, value, callback) => {
|
||||
return this.$u.test.mobile(value);
|
||||
},
|
||||
message: "手机号码不正确",
|
||||
trigger: ["change", "blur"],
|
||||
},
|
||||
],
|
||||
___path: [
|
||||
{
|
||||
required: true,
|
||||
message: "请选择所在区域",
|
||||
trigger: ["change"],
|
||||
},
|
||||
],
|
||||
detail: [
|
||||
{
|
||||
required: true,
|
||||
message: "请填写详细地址",
|
||||
trigger: ["blur", "change"],
|
||||
},
|
||||
],
|
||||
},
|
||||
list: [
|
||||
{
|
||||
id: "",
|
||||
localName: "请选择",
|
||||
children: [],
|
||||
},
|
||||
],
|
||||
};
|
||||
},
|
||||
onLoad(option) {
|
||||
uni.showLoading({
|
||||
title: "加载中",
|
||||
});
|
||||
this.routerVal = option;
|
||||
// 如果当前是编辑地址,则需要查询出地址详情信息
|
||||
if (option.id) {
|
||||
getAddressDetail(option.id).then((res) => {
|
||||
const params = res.data.result;
|
||||
params.___path = params.consigneeAddressPath;
|
||||
this["form"] = params;
|
||||
|
||||
if (this.$store.state.isShowToast){ uni.hideLoading() };
|
||||
});
|
||||
if (Array.isArray(params.consigneeAddressIdPath)) {
|
||||
params.consigneeAddressIdPath = params.consigneeAddressIdPath.join(',')
|
||||
}
|
||||
uni.hideLoading();
|
||||
},
|
||||
// 初始化rules必须要在onReady生命周期,因为onLoad生命周期组件可能尚未创建完毕
|
||||
onReady() {
|
||||
this.$refs.uForm.setRules(this.rules);
|
||||
},
|
||||
};
|
||||
if (Array.isArray(params.consigneeAddressPath)) {
|
||||
params.consigneeAddressPath = params.consigneeAddressPath.join(',')
|
||||
}
|
||||
|
||||
if (!params.id) {
|
||||
addAddressApi(params).then((res) => {
|
||||
if (res.data.success) {
|
||||
uni.navigateBack()
|
||||
} else {
|
||||
uni.showToast({ title: res.data.message || '保存失败', icon: 'none' })
|
||||
}
|
||||
})
|
||||
} else {
|
||||
delete params.updateBy
|
||||
delete params.updateTime
|
||||
editAddress(params).then((res) => {
|
||||
if (res.data.success) {
|
||||
uni.navigateBack()
|
||||
} else {
|
||||
uni.showToast({ title: res.data.message || '保存失败', icon: 'none' })
|
||||
}
|
||||
})
|
||||
}
|
||||
}).catch(() => {})
|
||||
}
|
||||
|
||||
function getpickerParentValue(e: any[]) {
|
||||
form.consigneeAddressIdPath = []
|
||||
form.consigneeAddressPath = []
|
||||
let name = ''
|
||||
e.forEach((item, index) => {
|
||||
if (item.id) {
|
||||
form.consigneeAddressIdPath.push(item.id)
|
||||
form.consigneeAddressPath.push(item.localName)
|
||||
name += item.localName
|
||||
form.___path = name
|
||||
}
|
||||
if (index == e.length - 1) {
|
||||
const _town = item.children.filter((_child: any) => _child.id == item.id)
|
||||
form.lat = _town[0].center.split(',')[1]
|
||||
form.lon = _town[0].center.split(',')[0]
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function showPicker() {
|
||||
cityPicker.value?.show()
|
||||
}
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
page {
|
||||
|
||||
@@ -42,126 +42,95 @@
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as API_Trade from "@/api/trade";
|
||||
import * as API_Address from "@/api/address.js";
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
addressList: [], //地址列表
|
||||
showAction: false, //是否显示下栏框
|
||||
removeList: [
|
||||
{
|
||||
text: "确定",
|
||||
},
|
||||
],
|
||||
tips: {
|
||||
text: "确定要删除该收货人信息吗?",
|
||||
},
|
||||
removeId: "", //删除的地址id
|
||||
routerVal: "",
|
||||
params: {
|
||||
pageNumber: 1,
|
||||
pageSize: 1000,
|
||||
},
|
||||
};
|
||||
},
|
||||
onPullDownRefresh() {
|
||||
//下拉刷新
|
||||
this.addressList = [];
|
||||
this.getAddressList();
|
||||
},
|
||||
onLoad: function (val) {
|
||||
this.routerVal = val;
|
||||
},
|
||||
onShow() {
|
||||
this.addressList = [];
|
||||
this.getAddressList();
|
||||
},
|
||||
onHide() {},
|
||||
methods: {
|
||||
async selectAddressData(val) {
|
||||
await API_Trade.setAddressId(val.id, this.routerVal.way);
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { onLoad, onShow, onPullDownRefresh } from '@dcloudio/uni-app'
|
||||
import { useStore } from '@/store'
|
||||
import * as API_Trade from '@/api/trade'
|
||||
import * as API_Address from '@/api/address.js'
|
||||
|
||||
uni.navigateBack({
|
||||
delta: 1,
|
||||
});
|
||||
},
|
||||
//获取地址列表
|
||||
getAddressList() {
|
||||
uni.showLoading();
|
||||
const store = useStore()
|
||||
|
||||
API_Address.getAddressList(
|
||||
this.params.pageNumber,
|
||||
this.params.pageSize
|
||||
).then((res) => {
|
||||
res.data.result.records.forEach((item) => {
|
||||
item.consigneeAddressPath = item.consigneeAddressPath.split(",");
|
||||
});
|
||||
this.addressList = res.data.result.records;
|
||||
console.log(this.addressList);
|
||||
const addressList = ref<any[]>([])
|
||||
const showAction = ref(false)
|
||||
const removeList = [{ text: '确定' }]
|
||||
const tips = { text: '确定要删除该收货人信息吗?' }
|
||||
const removeId = ref('')
|
||||
const routerVal = ref<Record<string, string>>({})
|
||||
const params = { pageNumber: 1, pageSize: 1000 }
|
||||
|
||||
if (this.$store.state.isShowToast){ uni.hideLoading() };
|
||||
});
|
||||
},
|
||||
//删除地址
|
||||
removeAddress(id) {
|
||||
this.removeId = id;
|
||||
this.showAction = true;
|
||||
},
|
||||
deleteAddressMessage() {
|
||||
API_Address.deleteAddress(this.removeId).then((res) => {
|
||||
if (res.statusCode == 200) {
|
||||
uni.showToast({
|
||||
icon: "none",
|
||||
title: "删除成功",
|
||||
});
|
||||
this.getAddressList();
|
||||
} else {
|
||||
uni.showToast({
|
||||
icon: "none",
|
||||
title: res.data.message,
|
||||
duration: 2000,
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
//新建。编辑地址
|
||||
addAddress(id) {
|
||||
if (id) {
|
||||
uni.navigateTo({
|
||||
url:
|
||||
"/pages/mine/address/add?id=" +
|
||||
id +
|
||||
"&way=" +
|
||||
this.routerVal.way +
|
||||
"&type=order",
|
||||
});
|
||||
} else {
|
||||
uni.navigateTo({
|
||||
url:
|
||||
"/pages/mine/address/add?way=" + this.routerVal.way + "&type=order",
|
||||
});
|
||||
}
|
||||
},
|
||||
//设为默认地址
|
||||
setDefault(item) {
|
||||
delete item.updateBy;
|
||||
delete item.updateTime;
|
||||
delete item.deleteFlag;
|
||||
onPullDownRefresh(() => {
|
||||
addressList.value = []
|
||||
getAddressList()
|
||||
})
|
||||
|
||||
item.isDefault ? "" : (item.isDefault = !item.isDefault);
|
||||
onLoad((val) => {
|
||||
routerVal.value = val || {}
|
||||
})
|
||||
|
||||
API_Address.editAddress(item).then((res) => {
|
||||
uni.showToast({
|
||||
title: "设置默认地址成功",
|
||||
icon: "none",
|
||||
});
|
||||
this.getAddressList();
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
onShow(() => {
|
||||
addressList.value = []
|
||||
getAddressList()
|
||||
})
|
||||
|
||||
function hideLoadingIfNeeded() {
|
||||
if (store.state.isShowToast) uni.hideLoading()
|
||||
}
|
||||
|
||||
async function selectAddressData(val: any) {
|
||||
await API_Trade.setAddressId(val.id, routerVal.value.way)
|
||||
uni.navigateBack({ delta: 1 })
|
||||
}
|
||||
|
||||
function getAddressList() {
|
||||
uni.showLoading()
|
||||
API_Address.getAddressList(params.pageNumber, params.pageSize).then((res) => {
|
||||
res.data.result.records.forEach((item: any) => {
|
||||
item.consigneeAddressPath = item.consigneeAddressPath.split(',')
|
||||
})
|
||||
addressList.value = res.data.result.records
|
||||
hideLoadingIfNeeded()
|
||||
})
|
||||
}
|
||||
|
||||
function removeAddress(id: string) {
|
||||
removeId.value = id
|
||||
showAction.value = true
|
||||
}
|
||||
|
||||
function deleteAddressMessage() {
|
||||
API_Address.deleteAddress(removeId.value).then((res) => {
|
||||
if (res.statusCode == 200) {
|
||||
uni.showToast({ icon: 'none', title: '删除成功' })
|
||||
getAddressList()
|
||||
} else {
|
||||
uni.showToast({ icon: 'none', title: res.data.message, duration: 2000 })
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function addAddress(id: string) {
|
||||
if (id) {
|
||||
uni.navigateTo({
|
||||
url: `/pages/mine/address/add?id=${id}&way=${routerVal.value.way}&type=order`,
|
||||
})
|
||||
} else {
|
||||
uni.navigateTo({
|
||||
url: `/pages/mine/address/add?way=${routerVal.value.way}&type=order`,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
function setDefault(item: any) {
|
||||
delete item.updateBy
|
||||
delete item.updateTime
|
||||
delete item.deleteFlag
|
||||
if (!item.isDefault) item.isDefault = true
|
||||
API_Address.editAddress(item).then(() => {
|
||||
uni.showToast({ title: '设置默认地址成功', icon: 'none' })
|
||||
getAddressList()
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<view class="address">
|
||||
<u-empty class="empty" v-if="this.addressList.length === 0" text="暂无收货地址" mode="address"></u-empty>
|
||||
<u-empty class="empty" v-if="addressList.length === 0" text="暂无收货地址" mode="address"></u-empty>
|
||||
<view class="list" >
|
||||
<view class="item c-content" v-for="(item, index) in addressList" :key="index">
|
||||
<view class="basic">
|
||||
@@ -43,116 +43,90 @@
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as API_Address from "@/api/address.js";
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
addressList: [], //地址列表
|
||||
showAction: false, //是否显示下栏框
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { onLoad, onShow, onPullDownRefresh, onBackPress } from '@dcloudio/uni-app'
|
||||
import { useStore } from '@/store'
|
||||
import { tipsToLogin } from '@/utils/filters.js'
|
||||
import * as API_Address from '@/api/address.js'
|
||||
|
||||
removeList: [
|
||||
{
|
||||
text: "确定",
|
||||
},
|
||||
],
|
||||
tips: {
|
||||
text: "确定要删除该收货人信息吗?",
|
||||
},
|
||||
removeId: "", //删除的地址id
|
||||
routerVal: "",
|
||||
params: {
|
||||
pageNumber: 1,
|
||||
pageSize: 1000,
|
||||
},
|
||||
};
|
||||
},
|
||||
// 返回上一级
|
||||
onBackPress(e) {
|
||||
uni.switchTab({
|
||||
url: "/pages/tabbar/user/my",
|
||||
});
|
||||
return true;
|
||||
},
|
||||
onLoad: function (val) {
|
||||
this.routerVal = val;
|
||||
},
|
||||
onPullDownRefresh() {
|
||||
//下拉刷新
|
||||
this.addressList = [];
|
||||
this.getAddressList();
|
||||
},
|
||||
/**
|
||||
* 进入页面检测当前账户是否登录
|
||||
*/
|
||||
onShow() {
|
||||
if (this.tipsToLogin()) {
|
||||
this.getAddressList();
|
||||
const store = useStore()
|
||||
|
||||
const addressList = ref<any[]>([])
|
||||
const showAction = ref(false)
|
||||
const removeList = [{ text: '确定' }]
|
||||
const tips = { text: '确定要删除该收货人信息吗?' }
|
||||
const removeId = ref('')
|
||||
const routerVal = ref<Record<string, string>>({})
|
||||
const params = { pageNumber: 1, pageSize: 1000 }
|
||||
|
||||
onBackPress(() => {
|
||||
uni.switchTab({ url: '/pages/tabbar/user/my' })
|
||||
return true
|
||||
})
|
||||
|
||||
onLoad((val) => {
|
||||
routerVal.value = val || {}
|
||||
})
|
||||
|
||||
onPullDownRefresh(() => {
|
||||
addressList.value = []
|
||||
getAddressList()
|
||||
})
|
||||
|
||||
onShow(() => {
|
||||
if (tipsToLogin()) {
|
||||
getAddressList()
|
||||
}
|
||||
})
|
||||
|
||||
function hideLoadingIfNeeded() {
|
||||
if (store.state.isShowToast) uni.hideLoading()
|
||||
}
|
||||
|
||||
function getAddressList() {
|
||||
uni.showLoading()
|
||||
API_Address.getAddressList(params.pageNumber, params.pageSize).then((res) => {
|
||||
res.data.result.records.forEach((item: any) => {
|
||||
item.consigneeAddressPath = item.consigneeAddressPath.split(',')
|
||||
})
|
||||
addressList.value = res.data.result.records
|
||||
hideLoadingIfNeeded()
|
||||
})
|
||||
}
|
||||
|
||||
function removeAddress(id: string) {
|
||||
removeId.value = id
|
||||
showAction.value = true
|
||||
}
|
||||
|
||||
function deleteAddressMessage() {
|
||||
API_Address.deleteAddress(removeId.value).then((res) => {
|
||||
if (res.statusCode == 200) {
|
||||
uni.showToast({ icon: 'none', title: '删除成功' })
|
||||
getAddressList()
|
||||
} else {
|
||||
uni.showToast({ icon: 'none', title: res.data.message, duration: 2000 })
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
//获取地址列表
|
||||
getAddressList() {
|
||||
uni.showLoading();
|
||||
API_Address.getAddressList(
|
||||
this.params.pageNumber,
|
||||
this.params.pageSize
|
||||
).then((res) => {
|
||||
res.data.result.records.forEach((item) => {
|
||||
item.consigneeAddressPath = item.consigneeAddressPath.split(",");
|
||||
});
|
||||
this.addressList = res.data.result.records;
|
||||
})
|
||||
}
|
||||
|
||||
if (this.$store.state.isShowToast){ uni.hideLoading() };
|
||||
});
|
||||
},
|
||||
//删除地址
|
||||
removeAddress(id) {
|
||||
this.removeId = id;
|
||||
this.showAction = true;
|
||||
},
|
||||
// 删除地址
|
||||
deleteAddressMessage() {
|
||||
API_Address.deleteAddress(this.removeId).then((res) => {
|
||||
if (res.statusCode == 200) {
|
||||
uni.showToast({
|
||||
icon: "none",
|
||||
title: "删除成功",
|
||||
});
|
||||
this.getAddressList();
|
||||
} else {
|
||||
uni.showToast({
|
||||
icon: "none",
|
||||
title: res.data.message,
|
||||
duration: 2000,
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
//新建。编辑地址
|
||||
addAddress(id) {
|
||||
uni.navigateTo({
|
||||
url: `/pages/mine/address/add${id ? "?id=" + id : ""}`,
|
||||
});
|
||||
},
|
||||
//设为默认地址
|
||||
setDefault(item) {
|
||||
delete item.updateBy;
|
||||
delete item.updateTime;
|
||||
delete item.deleteFlag;
|
||||
function addAddress(id?: string) {
|
||||
uni.navigateTo({
|
||||
url: `/pages/mine/address/add${id ? '?id=' + id : ''}`,
|
||||
})
|
||||
}
|
||||
|
||||
item.isDefault ? "" : (item.isDefault = !item.isDefault);
|
||||
|
||||
API_Address.editAddress(item).then(() => {
|
||||
uni.showToast({
|
||||
title: "设置默认地址成功",
|
||||
icon: "none",
|
||||
});
|
||||
this.getAddressList();
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
function setDefault(item: any) {
|
||||
delete item.updateBy
|
||||
delete item.updateTime
|
||||
delete item.deleteFlag
|
||||
if (!item.isDefault) item.isDefault = true
|
||||
API_Address.editAddress(item).then(() => {
|
||||
uni.showToast({ title: '设置默认地址成功', icon: 'none' })
|
||||
getAddressList()
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
@@ -20,67 +20,57 @@
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as API_Trade from "@/api/trade";
|
||||
import * as API_Store from "@/api/store.js";
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
storeAddressList: [], //地址列表
|
||||
showAction: false, //是否显示下栏框
|
||||
removeList: [
|
||||
{
|
||||
text: "确定",
|
||||
},
|
||||
],
|
||||
tips: {
|
||||
text: "确定要删除该收货人信息吗?",
|
||||
},
|
||||
removeId: "", //删除的地址id
|
||||
routerVal: "",
|
||||
params: {
|
||||
pageNumber: 1,
|
||||
pageSize: 1000,
|
||||
},
|
||||
};
|
||||
},
|
||||
onPullDownRefresh() {
|
||||
//下拉刷新
|
||||
this.storeAddressList = [];
|
||||
this.getAddressList();
|
||||
},
|
||||
onLoad: function (val) {
|
||||
this.routerVal = val;
|
||||
},
|
||||
onShow() {
|
||||
this.storeAddressList = [];
|
||||
this.getAddressList();
|
||||
},
|
||||
onHide() {},
|
||||
methods: {
|
||||
async selectAddressData(val) {
|
||||
await API_Trade.setStoreAddressId(val.id, this.routerVal.way);
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { onLoad, onShow, onPullDownRefresh } from '@dcloudio/uni-app'
|
||||
import { useStore } from '@/store'
|
||||
import * as API_Trade from '@/api/trade'
|
||||
import * as API_Store from '@/api/store.js'
|
||||
|
||||
uni.navigateBack({
|
||||
delta: 1,
|
||||
});
|
||||
},
|
||||
//获取地址列表
|
||||
getAddressList() {
|
||||
uni.showLoading();
|
||||
const store = useStore()
|
||||
|
||||
API_Store.getStoreAddress(
|
||||
this.routerVal.storeId,
|
||||
this.params
|
||||
).then((res) => {
|
||||
this.storeAddressList = res.data.result.records;
|
||||
console.log(this.storeAddressList);
|
||||
const storeAddressList = ref<any[]>([])
|
||||
const showAction = ref(false)
|
||||
const removeList = [{ text: '确定' }]
|
||||
const tips = { text: '确定要删除该收货人信息吗?' }
|
||||
const removeId = ref('')
|
||||
const routerVal = ref<Record<string, string>>({})
|
||||
const params = { pageNumber: 1, pageSize: 1000 }
|
||||
|
||||
if (this.$store.state.isShowToast){ uni.hideLoading() };
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
onPullDownRefresh(() => {
|
||||
storeAddressList.value = []
|
||||
getAddressList()
|
||||
})
|
||||
|
||||
onLoad((val) => {
|
||||
routerVal.value = val || {}
|
||||
})
|
||||
|
||||
onShow(() => {
|
||||
storeAddressList.value = []
|
||||
getAddressList()
|
||||
})
|
||||
|
||||
function hideLoadingIfNeeded() {
|
||||
if (store.state.isShowToast) uni.hideLoading()
|
||||
}
|
||||
|
||||
async function selectAddressData(val: any) {
|
||||
await API_Trade.setStoreAddressId(val.id, routerVal.value.way)
|
||||
uni.navigateBack({ delta: 1 })
|
||||
}
|
||||
|
||||
function getAddressList() {
|
||||
uni.showLoading()
|
||||
API_Store.getStoreAddress(routerVal.value.storeId, params).then((res) => {
|
||||
storeAddressList.value = res.data.result.records
|
||||
hideLoadingIfNeeded()
|
||||
})
|
||||
}
|
||||
|
||||
function deleteAddressMessage() {
|
||||
// 保留 action-sheet 回调占位,当前页面无删除入口
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
@@ -52,84 +52,64 @@
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getUserRecharge, getWalletLog, getUserWallet } from "@/api/members";
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
walletNum: 0,
|
||||
current: 0,
|
||||
swiperCurrent: 0,
|
||||
userInfo: "",
|
||||
params: {
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
order: "desc",
|
||||
},
|
||||
depositData: [],
|
||||
rechargeList: "",
|
||||
walletLogList: "",
|
||||
list: [{ name: "预存款变动明细" }],
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
swiperCurrent(index) {
|
||||
this.swiperCurrent = index;
|
||||
},
|
||||
},
|
||||
async mounted() {
|
||||
this.getWallet();
|
||||
const result = await getUserWallet();
|
||||
this.walletNum = result.data.result.memberWallet;
|
||||
},
|
||||
methods: {
|
||||
isOutgoing(serviceType) {
|
||||
return serviceType === "WALLET_PAY" || serviceType === "WALLET_WITHDRAWAL";
|
||||
},
|
||||
isIncoming(serviceType) {
|
||||
return (
|
||||
serviceType === "WALLET_REFUND" ||
|
||||
serviceType === "WALLET_RECHARGE" ||
|
||||
serviceType === "WALLET_COMMISSION"
|
||||
);
|
||||
},
|
||||
getMoneyClass(serviceType) {
|
||||
if (this.isOutgoing(serviceType)) return "out";
|
||||
if (this.isIncoming(serviceType)) return "in";
|
||||
return "";
|
||||
},
|
||||
formatLogMoney(logItem) {
|
||||
const amount = this.unitPrice(logItem.money);
|
||||
if (this.isOutgoing(logItem.serviceType)) return `-${amount}`;
|
||||
if (this.isIncoming(logItem.serviceType)) return `+${amount}`;
|
||||
return amount;
|
||||
},
|
||||
getRecharge() {
|
||||
getUserRecharge(this.params).then((res) => {
|
||||
if (res.data.success && res.data.result.records.length) {
|
||||
this.depositData.push(...res.data.result.records);
|
||||
}
|
||||
});
|
||||
},
|
||||
getWallet() {
|
||||
getWalletLog(this.params).then((res) => {
|
||||
if (res.data.success && res.data.result.records.length) {
|
||||
this.depositData.push(...res.data.result.records);
|
||||
}
|
||||
});
|
||||
},
|
||||
changed(index) {
|
||||
this.depositData = [];
|
||||
this.swiperCurrent = index;
|
||||
this.params.pageNumber = 1;
|
||||
this.getWallet();
|
||||
},
|
||||
loadMore() {
|
||||
this.params.pageNumber++;
|
||||
this.getWallet();
|
||||
},
|
||||
},
|
||||
};
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { getWalletLog, getUserWallet } from '@/api/members'
|
||||
import { unitPrice } from '@/utils/filters.js'
|
||||
|
||||
const walletNum = ref(0)
|
||||
const swiperCurrent = ref(0)
|
||||
const params = ref({
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
order: 'desc',
|
||||
})
|
||||
const depositData = ref<any[]>([])
|
||||
const list = [{ name: '预存款变动明细' }]
|
||||
|
||||
onMounted(async () => {
|
||||
getWallet()
|
||||
const result = await getUserWallet()
|
||||
walletNum.value = result.data.result.memberWallet
|
||||
})
|
||||
|
||||
function isOutgoing(serviceType: string) {
|
||||
return serviceType === 'WALLET_PAY' || serviceType === 'WALLET_WITHDRAWAL'
|
||||
}
|
||||
|
||||
function isIncoming(serviceType: string) {
|
||||
return (
|
||||
serviceType === 'WALLET_REFUND' ||
|
||||
serviceType === 'WALLET_RECHARGE' ||
|
||||
serviceType === 'WALLET_COMMISSION'
|
||||
)
|
||||
}
|
||||
|
||||
function getMoneyClass(serviceType: string) {
|
||||
if (isOutgoing(serviceType)) return 'out'
|
||||
if (isIncoming(serviceType)) return 'in'
|
||||
return ''
|
||||
}
|
||||
|
||||
function formatLogMoney(logItem: any) {
|
||||
const amount = unitPrice(logItem.money)
|
||||
if (isOutgoing(logItem.serviceType)) return `-${amount}`
|
||||
if (isIncoming(logItem.serviceType)) return `+${amount}`
|
||||
return amount
|
||||
}
|
||||
|
||||
function getWallet() {
|
||||
getWalletLog(params.value).then((res) => {
|
||||
if (res.data.success && res.data.result.records.length) {
|
||||
depositData.value.push(...res.data.result.records)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function loadMore() {
|
||||
params.value.pageNumber++
|
||||
getWallet()
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
@@ -12,8 +12,7 @@
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {};
|
||||
<script setup lang="ts">
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
@@ -38,33 +38,30 @@
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getUserWallet } from "@/api/members";
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
walletNum: 0,
|
||||
};
|
||||
},
|
||||
async onShow() {
|
||||
if (this.isLogin("auth")) {
|
||||
let result = await getUserWallet();
|
||||
this.walletNum = result.data.result.memberWallet;
|
||||
} else {
|
||||
this.navigateToLogin("redirectTo");
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
back() {
|
||||
uni.switchTab({
|
||||
url: "/pages/tabbar/user/my",
|
||||
});
|
||||
},
|
||||
navigateTo(url) {
|
||||
uni.navigateTo({ url });
|
||||
},
|
||||
},
|
||||
};
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { onShow } from '@dcloudio/uni-app'
|
||||
import { getUserWallet } from '@/api/members'
|
||||
import { isLogin, navigateToLogin, unitPrice } from '@/utils/filters.js'
|
||||
|
||||
const walletNum = ref(0)
|
||||
|
||||
onShow(async () => {
|
||||
if (isLogin('auth')) {
|
||||
const result = await getUserWallet()
|
||||
walletNum.value = result.data.result.memberWallet
|
||||
} else {
|
||||
navigateToLogin('redirectTo')
|
||||
}
|
||||
})
|
||||
|
||||
function back() {
|
||||
uni.switchTab({ url: '/pages/tabbar/user/my' })
|
||||
}
|
||||
|
||||
function navigateTo(url: string) {
|
||||
uni.navigateTo({ url })
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
@@ -19,40 +19,30 @@
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { recharge } from "@/api/members";
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
price: "",
|
||||
flag: true,
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
price(val) {
|
||||
this.flag = !(Number(val) > 0);
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
async handlerRecharge() {
|
||||
const amount = Number(this.price);
|
||||
if (!(amount > 0)) {
|
||||
uni.showToast({
|
||||
title: "请输入充值金额",
|
||||
icon: "none",
|
||||
});
|
||||
return;
|
||||
}
|
||||
<script setup lang="ts">
|
||||
import { ref, watch } from 'vue'
|
||||
import { recharge } from '@/api/members'
|
||||
|
||||
const res = await recharge({ price: amount });
|
||||
if (res.data.success) {
|
||||
uni.navigateTo({
|
||||
url: `/pages/cart/payment/payOrder?orderType=RECHARGE&recharge_sn=${res.data.result.rechargeSn}`,
|
||||
});
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
const price = ref('')
|
||||
const flag = ref(true)
|
||||
|
||||
watch(price, (val) => {
|
||||
flag.value = !(Number(val) > 0)
|
||||
})
|
||||
|
||||
async function handlerRecharge() {
|
||||
const amount = Number(price.value)
|
||||
if (!(amount > 0)) {
|
||||
uni.showToast({ title: '请输入充值金额', icon: 'none' })
|
||||
return
|
||||
}
|
||||
const res = await recharge({ price: amount })
|
||||
if (res.data.success) {
|
||||
uni.navigateTo({
|
||||
url: `/pages/cart/payment/payOrder?orderType=RECHARGE&recharge_sn=${res.data.result.rechargeSn}`,
|
||||
})
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
@@ -25,182 +25,149 @@
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getWithdrawApplyPage, getWithdrawApplyWechatTransferInfo } from "@/api/members";
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
loaded: false,
|
||||
params: {
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
order: "desc",
|
||||
},
|
||||
records: [],
|
||||
};
|
||||
},
|
||||
onShow() {
|
||||
this.params.pageNumber = 1;
|
||||
this.records = [];
|
||||
this.loaded = false;
|
||||
this.getData();
|
||||
},
|
||||
methods: {
|
||||
withdrawStatusText(applyStatus) {
|
||||
switch (applyStatus) {
|
||||
case "APPLY":
|
||||
return "申请中";
|
||||
case "VIA_AUDITING":
|
||||
return "审核通过";
|
||||
case "D_VIA_AUDITING":
|
||||
return "分销提现审核通过";
|
||||
case "FAIL_AUDITING":
|
||||
return "审核未通过";
|
||||
case "D_FAIL_AUDITING":
|
||||
return "分销提现审核未通过";
|
||||
case "WAIT_USER_CONFIRM":
|
||||
return "等待用户确认";
|
||||
case "SUCCESS":
|
||||
return "提现成功";
|
||||
case "ERROR":
|
||||
return "提现失败";
|
||||
default:
|
||||
return applyStatus || "";
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { onShow } from '@dcloudio/uni-app'
|
||||
import { getWithdrawApplyPage, getWithdrawApplyWechatTransferInfo } from '@/api/members'
|
||||
import { unitPrice } from '@/utils/filters.js'
|
||||
|
||||
const loaded = ref(false)
|
||||
const params = ref({
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
order: 'desc',
|
||||
})
|
||||
const records = ref<any[]>([])
|
||||
|
||||
onShow(() => {
|
||||
params.value.pageNumber = 1
|
||||
records.value = []
|
||||
loaded.value = false
|
||||
getData()
|
||||
})
|
||||
|
||||
function withdrawStatusText(applyStatus: string) {
|
||||
switch (applyStatus) {
|
||||
case 'APPLY':
|
||||
return '申请中'
|
||||
case 'VIA_AUDITING':
|
||||
return '审核通过'
|
||||
case 'D_VIA_AUDITING':
|
||||
return '分销提现审核通过'
|
||||
case 'FAIL_AUDITING':
|
||||
return '审核未通过'
|
||||
case 'D_FAIL_AUDITING':
|
||||
return '分销提现审核未通过'
|
||||
case 'WAIT_USER_CONFIRM':
|
||||
return '等待用户确认'
|
||||
case 'SUCCESS':
|
||||
return '提现成功'
|
||||
case 'ERROR':
|
||||
return '提现失败'
|
||||
default:
|
||||
return applyStatus || ''
|
||||
}
|
||||
}
|
||||
|
||||
function getData() {
|
||||
getWithdrawApplyPage(params.value).then((res) => {
|
||||
loaded.value = true
|
||||
if (res.data.success && res.data.result.records.length != 0) {
|
||||
records.value.push(...res.data.result.records)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function loadMore() {
|
||||
params.value.pageNumber++
|
||||
getData()
|
||||
}
|
||||
|
||||
function confirmWechatReceive(item: any) {
|
||||
const id = item && item.id
|
||||
if (!id) {
|
||||
uni.showToast({ title: '缺少提现记录ID', duration: 2000, icon: 'none' })
|
||||
return
|
||||
}
|
||||
|
||||
uni.showLoading({ title: '加载中' })
|
||||
getWithdrawApplyWechatTransferInfo(id)
|
||||
.then((res) => {
|
||||
if (!res.data || !res.data.success) return
|
||||
|
||||
const info = res.data.result || {}
|
||||
const mchId = info.mchId
|
||||
const wechatPackage = info.wechatPackage
|
||||
let appId = info.appId
|
||||
|
||||
if (typeof wx !== 'undefined' && wx.getAccountInfoSync) {
|
||||
try {
|
||||
const accountInfo = wx.getAccountInfoSync()
|
||||
const mpAppId = accountInfo && accountInfo.miniProgram && accountInfo.miniProgram.appId
|
||||
if (mpAppId) appId = mpAppId
|
||||
} catch (e) {}
|
||||
}
|
||||
},
|
||||
getData() {
|
||||
getWithdrawApplyPage(this.params).then((res) => {
|
||||
this.loaded = true;
|
||||
if (res.data.success) {
|
||||
if (res.data.result.records.length != 0) {
|
||||
this.records.push(...res.data.result.records);
|
||||
}
|
||||
|
||||
if (!mchId || !appId || !wechatPackage) {
|
||||
uni.showToast({ title: '微信确认参数缺失', duration: 2000, icon: 'none' })
|
||||
return
|
||||
}
|
||||
|
||||
const openResultToast = (errMsg?: string) => {
|
||||
if (errMsg === 'requestMerchantTransfer:ok') {
|
||||
uni.showToast({ title: '已唤起确认页面', duration: 2000, icon: 'none' })
|
||||
return
|
||||
}
|
||||
if (errMsg === 'requestMerchantTransfer:cancel') {
|
||||
uni.showToast({ title: '已取消', duration: 2000, icon: 'none' })
|
||||
return
|
||||
}
|
||||
});
|
||||
},
|
||||
loadMore() {
|
||||
this.params.pageNumber++;
|
||||
this.getData();
|
||||
},
|
||||
confirmWechatReceive(item) {
|
||||
const id = item && item.id;
|
||||
if (!id) {
|
||||
uni.showToast({
|
||||
title: "缺少提现记录ID",
|
||||
duration: 2000,
|
||||
icon: "none",
|
||||
});
|
||||
return;
|
||||
title: errMsg ? `唤起失败:${errMsg}` : '唤起失败',
|
||||
duration: 2500,
|
||||
icon: 'none',
|
||||
})
|
||||
}
|
||||
|
||||
uni.showLoading({
|
||||
title: "加载中",
|
||||
});
|
||||
getWithdrawApplyWechatTransferInfo(id)
|
||||
.then((res) => {
|
||||
if (!res.data || !res.data.success) return;
|
||||
|
||||
const info = res.data.result || {};
|
||||
const mchId = info.mchId;
|
||||
const wechatPackage = info.wechatPackage;
|
||||
let appId = info.appId;
|
||||
|
||||
if (typeof wx !== "undefined" && wx.getAccountInfoSync) {
|
||||
try {
|
||||
const accountInfo = wx.getAccountInfoSync();
|
||||
const mpAppId = accountInfo && accountInfo.miniProgram && accountInfo.miniProgram.appId;
|
||||
if (mpAppId) appId = mpAppId;
|
||||
} catch (e) {}
|
||||
}
|
||||
|
||||
if (!mchId || !appId || !wechatPackage) {
|
||||
if (typeof wx !== 'undefined' && wx.getSystemInfoSync) {
|
||||
try {
|
||||
const sys = wx.getSystemInfoSync()
|
||||
if (sys && sys.platform === 'devtools') {
|
||||
uni.showToast({
|
||||
title: "微信确认参数缺失",
|
||||
duration: 2000,
|
||||
icon: "none",
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
const openResultToast = (errMsg) => {
|
||||
if (errMsg === "requestMerchantTransfer:ok") {
|
||||
uni.showToast({
|
||||
title: "已唤起确认页面",
|
||||
duration: 2000,
|
||||
icon: "none",
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (errMsg === "requestMerchantTransfer:cancel") {
|
||||
uni.showToast({
|
||||
title: "已取消",
|
||||
duration: 2000,
|
||||
icon: "none",
|
||||
});
|
||||
return;
|
||||
}
|
||||
uni.showToast({
|
||||
title: errMsg ? `唤起失败:${errMsg}` : "唤起失败",
|
||||
title: '开发者工具可能不支持,请真机测试',
|
||||
duration: 2500,
|
||||
icon: "none",
|
||||
});
|
||||
};
|
||||
|
||||
if (typeof wx !== "undefined" && wx.getSystemInfoSync) {
|
||||
try {
|
||||
const sys = wx.getSystemInfoSync();
|
||||
if (sys && sys.platform === "devtools") {
|
||||
uni.showToast({
|
||||
title: "开发者工具可能不支持,请真机测试",
|
||||
duration: 2500,
|
||||
icon: "none",
|
||||
});
|
||||
}
|
||||
} catch (e) {}
|
||||
icon: 'none',
|
||||
})
|
||||
}
|
||||
} catch (e) {}
|
||||
}
|
||||
|
||||
if (typeof wx !== "undefined" && wx.canIUse && wx.canIUse("requestMerchantTransfer")) {
|
||||
wx.requestMerchantTransfer({
|
||||
mchId,
|
||||
appId,
|
||||
package: wechatPackage,
|
||||
success: (r) => {
|
||||
openResultToast(r && (r.errMsg || r.err_msg));
|
||||
},
|
||||
fail: (r) => {
|
||||
openResultToast(r && (r.errMsg || r.err_msg));
|
||||
},
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (typeof WeixinJSBridge !== "undefined" && WeixinJSBridge.invoke) {
|
||||
WeixinJSBridge.invoke(
|
||||
"requestMerchantTransfer",
|
||||
{
|
||||
mchId,
|
||||
appId,
|
||||
package: wechatPackage,
|
||||
},
|
||||
(r) => {
|
||||
openResultToast(r && (r.errMsg || r.err_msg));
|
||||
}
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
uni.showToast({
|
||||
title: "请在微信内打开确认收款",
|
||||
duration: 2000,
|
||||
icon: "none",
|
||||
});
|
||||
if (typeof wx !== 'undefined' && wx.canIUse && wx.canIUse('requestMerchantTransfer')) {
|
||||
wx.requestMerchantTransfer({
|
||||
mchId,
|
||||
appId,
|
||||
package: wechatPackage,
|
||||
success: (r: any) => openResultToast(r && (r.errMsg || r.err_msg)),
|
||||
fail: (r: any) => openResultToast(r && (r.errMsg || r.err_msg)),
|
||||
})
|
||||
.finally(() => {
|
||||
uni.hideLoading();
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
return
|
||||
}
|
||||
|
||||
if (typeof WeixinJSBridge !== 'undefined' && WeixinJSBridge.invoke) {
|
||||
WeixinJSBridge.invoke(
|
||||
'requestMerchantTransfer',
|
||||
{ mchId, appId, package: wechatPackage },
|
||||
(r: any) => openResultToast(r && (r.errMsg || r.err_msg))
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
uni.showToast({ title: '请在微信内打开确认收款', duration: 2000, icon: 'none' })
|
||||
})
|
||||
.finally(() => {
|
||||
uni.hideLoading()
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
@@ -58,77 +58,68 @@
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getUserWallet, withdrawalApply, withdrawalSettingVO } from "@/api/members";
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
price: "",
|
||||
walletNum: 0,
|
||||
minPrice: 0,
|
||||
type: "",
|
||||
connectNumber: "",
|
||||
realName: "",
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
typeLabel() {
|
||||
if (this.type === "ALI") return "支付宝";
|
||||
if (this.type) return "微信";
|
||||
return "--";
|
||||
},
|
||||
},
|
||||
async mounted() {
|
||||
const result = await getUserWallet();
|
||||
const res = await withdrawalSettingVO();
|
||||
this.walletNum = result.data.result.memberWallet;
|
||||
this.minPrice = res.data.result.minPrice;
|
||||
this.type = res.data.result.type;
|
||||
},
|
||||
methods: {
|
||||
cashd() {
|
||||
const amount = Number(this.price);
|
||||
if (!this.$u.test.amount(parseInt(amount))) {
|
||||
uni.showToast({
|
||||
title: "请输入正确金额",
|
||||
duration: 2000,
|
||||
icon: "none",
|
||||
});
|
||||
return;
|
||||
}
|
||||
<script setup lang="ts">
|
||||
import { ref, computed, getCurrentInstance, onMounted } from 'vue'
|
||||
import { getUserWallet, withdrawalApply, withdrawalSettingVO } from '@/api/members'
|
||||
import { unitPrice } from '@/utils/filters.js'
|
||||
|
||||
const params = { price: amount };
|
||||
if (this.type === "ALI") {
|
||||
if (!this.connectNumber || !this.realName) {
|
||||
uni.showToast({
|
||||
title: "请输入真实姓名和第三方登录账号",
|
||||
duration: 2000,
|
||||
icon: "none",
|
||||
});
|
||||
return;
|
||||
}
|
||||
params.connectNumber = this.connectNumber;
|
||||
params.realName = this.realName;
|
||||
}
|
||||
const { proxy } = getCurrentInstance()!
|
||||
|
||||
withdrawalApply(params).then((res) => {
|
||||
if (res.data.success) {
|
||||
uni.showToast({
|
||||
title: "提现成功!",
|
||||
duration: 2000,
|
||||
icon: "none",
|
||||
});
|
||||
setTimeout(() => {
|
||||
uni.navigateBack({ delta: 1 });
|
||||
}, 1000);
|
||||
}
|
||||
});
|
||||
},
|
||||
handleAll() {
|
||||
this.price = String(this.walletNum || "");
|
||||
},
|
||||
},
|
||||
};
|
||||
const price = ref('')
|
||||
const walletNum = ref(0)
|
||||
const minPrice = ref(0)
|
||||
const type = ref('')
|
||||
const connectNumber = ref('')
|
||||
const realName = ref('')
|
||||
|
||||
const typeLabel = computed(() => {
|
||||
if (type.value === 'ALI') return '支付宝'
|
||||
if (type.value) return '微信'
|
||||
return '--'
|
||||
})
|
||||
|
||||
onMounted(async () => {
|
||||
const result = await getUserWallet()
|
||||
const res = await withdrawalSettingVO()
|
||||
walletNum.value = result.data.result.memberWallet
|
||||
minPrice.value = res.data.result.minPrice
|
||||
type.value = res.data.result.type
|
||||
})
|
||||
|
||||
function cashd() {
|
||||
const amount = Number(price.value)
|
||||
if (!proxy.$u.test.amount(parseInt(String(amount)))) {
|
||||
uni.showToast({ title: '请输入正确金额', duration: 2000, icon: 'none' })
|
||||
return
|
||||
}
|
||||
|
||||
const params: Record<string, any> = { price: amount }
|
||||
if (type.value === 'ALI') {
|
||||
if (!connectNumber.value || !realName.value) {
|
||||
uni.showToast({
|
||||
title: '请输入真实姓名和第三方登录账号',
|
||||
duration: 2000,
|
||||
icon: 'none',
|
||||
})
|
||||
return
|
||||
}
|
||||
params.connectNumber = connectNumber.value
|
||||
params.realName = realName.value
|
||||
}
|
||||
|
||||
withdrawalApply(params).then((res) => {
|
||||
if (res.data.success) {
|
||||
uni.showToast({ title: '提现成功!', duration: 2000, icon: 'none' })
|
||||
setTimeout(() => {
|
||||
uni.navigateBack({ delta: 1 })
|
||||
}, 1000)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function handleAll() {
|
||||
price.value = String(walletNum.value || '')
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
<template>
|
||||
|
||||
<view></view>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
|
||||
</style>
|
||||
<script setup lang="ts">
|
||||
// 占位页,暂无业务逻辑
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
</style>
|
||||
|
||||
@@ -3,160 +3,100 @@
|
||||
<view>
|
||||
<h4>实名认证(请上传真实的个人信息,认证通过后将无法修改)</h4>
|
||||
<view>
|
||||
<u-form :model="ruleForm" label-width="200rpx" ref="uForm">
|
||||
<u-form-item label="姓名" prop="name">
|
||||
<u-input v-model="ruleForm.name" placeholder="请输入您的真实姓名" />
|
||||
</u-form-item>
|
||||
<u-form-item label="身份证" prop="idNumber">
|
||||
<u-input v-model="ruleForm.idNumber" placeholder="请输入身份证号码" />
|
||||
</u-form-item>
|
||||
<u-form-item label="银行开户行" prop="settlementBankBranchName">
|
||||
<u-input v-model="ruleForm.settlementBankBranchName" type="text" placeholder="请输入银行开户行" />
|
||||
</u-form-item>
|
||||
<u-form-item label="银行开户名" prop="settlementBankAccountName">
|
||||
<u-input v-model="ruleForm.settlementBankAccountName" type="text" placeholder="请输入银行开户名" />
|
||||
</u-form-item>
|
||||
<u-form-item label="银行账号" prop="settlementBankAccountNum">
|
||||
<u-input v-model="ruleForm.settlementBankAccountNum" type="text" placeholder="请输入银行账号" />
|
||||
</u-form-item>
|
||||
<!-- <u-form-item label="身份证正面照" prop="name">
|
||||
<u-upload></u-upload>
|
||||
</u-form-item>
|
||||
<u-form-item label="身份证反面照" prop="name">
|
||||
<u-upload></u-upload>
|
||||
</u-form-item>
|
||||
<u-form-item label="手持身份证照" prop="name">
|
||||
<u-upload></u-upload>
|
||||
</u-form-item> -->
|
||||
</u-form>
|
||||
<u-button :customStyle="{'background':$lightColor,'color':'#fff' }" @click="submit">提交</u-button>
|
||||
<up-form
|
||||
:model="formData"
|
||||
label-position="left"
|
||||
label-width="180rpx"
|
||||
ref="uFormRef"
|
||||
>
|
||||
<up-form-item label="姓名" prop="name">
|
||||
<u-input v-model="formData.name" placeholder="请输入您的真实姓名" />
|
||||
</up-form-item>
|
||||
<up-form-item label="身份证" prop="idNumber">
|
||||
<u-input v-model="formData.idNumber" placeholder="请输入身份证号码" />
|
||||
</up-form-item>
|
||||
<up-form-item label="银行开户行" prop="settlementBankBranchName">
|
||||
<u-input v-model="formData.settlementBankBranchName" placeholder="请输入银行开户行" />
|
||||
</up-form-item>
|
||||
<up-form-item label="银行开户名" prop="settlementBankAccountName">
|
||||
<u-input v-model="formData.settlementBankAccountName" placeholder="请输入银行开户名" />
|
||||
</up-form-item>
|
||||
<up-form-item label="银行账号" prop="settlementBankAccountNum">
|
||||
<u-input v-model="formData.settlementBankAccountNum" placeholder="请输入银行账号" />
|
||||
</up-form-item>
|
||||
</up-form>
|
||||
<u-button :customStyle="{ background: lightColor, color: '#fff' }" @click="submitForm">提交</u-button>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="tips">
|
||||
<view>您提交的信息正在审核</view>
|
||||
<view>提交认证申请后,工作人员将在三个工作日进行核对完成审核</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
import { applyDistribution } from "@/api/goods";
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
ruleForm: {
|
||||
name: "",
|
||||
idNumber: "",
|
||||
settlementBankBranchName: "", // 银行开户行
|
||||
settlementBankAccountName: "", //银行开户名
|
||||
settlementBankAccountNum: "", //银行账号
|
||||
},
|
||||
rules: {
|
||||
name: [
|
||||
{
|
||||
required: true,
|
||||
message: "请输入姓名",
|
||||
// 可以单个或者同时写两个触发验证方式
|
||||
trigger: "blur",
|
||||
},
|
||||
{
|
||||
// 自定义验证函数,见上说明
|
||||
validator: (rule, value, callback) => {
|
||||
// 上面有说,返回true表示校验通过,返回false表示不通过
|
||||
// this.$u.test.mobile()就是返回true或者false的
|
||||
return this.$u.test.chinese(value);
|
||||
},
|
||||
message: "姓名输入不正确",
|
||||
// 触发器可以同时用blur和change
|
||||
trigger: ["change", "blur"],
|
||||
},
|
||||
],
|
||||
// 银行开户行
|
||||
settlementBankBranchName: [
|
||||
{
|
||||
required: true,
|
||||
message: "请输入银行开户行",
|
||||
// 可以单个或者同时写两个触发验证方式
|
||||
trigger: "blur",
|
||||
},
|
||||
], //银行开户名
|
||||
settlementBankAccountName: [
|
||||
{
|
||||
required: true,
|
||||
message: "银行开户名",
|
||||
// 可以单个或者同时写两个触发验证方式
|
||||
trigger: "blur",
|
||||
},
|
||||
],
|
||||
//银行账号
|
||||
settlementBankAccountNum: [
|
||||
{
|
||||
required: true,
|
||||
message: "请输入银行账号",
|
||||
// 可以单个或者同时写两个触发验证方式
|
||||
trigger: "blur",
|
||||
},
|
||||
],
|
||||
idNumber: [
|
||||
{
|
||||
required: true,
|
||||
message: "请输入身份证",
|
||||
// 可以单个或者同时写两个触发验证方式
|
||||
trigger: "blur",
|
||||
},
|
||||
{
|
||||
// 自定义验证函数,见上说明
|
||||
validator: (rule, value, callback) => {
|
||||
// 上面有说,返回true表示校验通过,返回false表示不通过
|
||||
// this.$u.test.mobile()就是返回true或者false的
|
||||
return this.$u.test.idCard(value);
|
||||
},
|
||||
message: "身份证号码不正确",
|
||||
// 触发器可以同时用blur和change
|
||||
trigger: ["change", "blur"],
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
submit() {
|
||||
this.$refs.uForm.validate((valid) => {
|
||||
if (valid) {
|
||||
applyDistribution(this.ruleForm).then((res) => {
|
||||
if (res.data.success) {
|
||||
uni.showToast({
|
||||
title: "认证提交成功!",
|
||||
duration: 2000,
|
||||
icon: "none",
|
||||
});
|
||||
|
||||
setTimeout(() => {
|
||||
uni.navigateBack();
|
||||
}, 500);
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: res.data.message,
|
||||
duration: 2000,
|
||||
icon: "none",
|
||||
});
|
||||
}
|
||||
});
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: "请填写有效信息",
|
||||
duration: 2000,
|
||||
icon: "none",
|
||||
});
|
||||
}
|
||||
});
|
||||
<script setup lang="ts">
|
||||
import { reactive, computed, ref, getCurrentInstance } from 'vue'
|
||||
import { onReady } from '@dcloudio/uni-app'
|
||||
import { useStore } from '@/store'
|
||||
import { applyDistribution } from '@/api/goods'
|
||||
|
||||
const store = useStore()
|
||||
const { proxy } = getCurrentInstance()!
|
||||
|
||||
const lightColor = computed(() => store.getters.lightColor)
|
||||
const uFormRef = ref<any>(null)
|
||||
|
||||
const formData = reactive({
|
||||
name: '',
|
||||
idNumber: '',
|
||||
settlementBankBranchName: '',
|
||||
settlementBankAccountName: '',
|
||||
settlementBankAccountNum: '',
|
||||
})
|
||||
|
||||
const rules = {
|
||||
name: [
|
||||
{ required: true, message: '请输入姓名', trigger: 'blur' },
|
||||
{
|
||||
validator: (_rule: unknown, value: string) => proxy.$u.test.chinese(value),
|
||||
message: '姓名输入不正确',
|
||||
trigger: ['change', 'blur'],
|
||||
},
|
||||
},
|
||||
onReady() {
|
||||
this.$refs.uForm.setRules(this.rules);
|
||||
},
|
||||
};
|
||||
],
|
||||
settlementBankBranchName: [{ required: true, message: '请输入银行开户行', trigger: 'blur' }],
|
||||
settlementBankAccountName: [{ required: true, message: '银行开户名', trigger: 'blur' }],
|
||||
settlementBankAccountNum: [{ required: true, message: '请输入银行账号', trigger: 'blur' }],
|
||||
idNumber: [
|
||||
{ required: true, message: '请输入身份证', trigger: 'blur' },
|
||||
{
|
||||
validator: (_rule: unknown, value: string) => proxy.$u.test.idCard(value),
|
||||
message: '身份证号码不正确',
|
||||
trigger: ['change', 'blur'],
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
onReady(() => {
|
||||
uFormRef.value?.setRules(rules)
|
||||
})
|
||||
|
||||
function submitForm() {
|
||||
uFormRef.value?.validate().then(() => {
|
||||
applyDistribution(formData).then((res) => {
|
||||
if (res.data.success) {
|
||||
uni.showToast({ title: '认证提交成功!', duration: 2000, icon: 'none' })
|
||||
setTimeout(() => uni.navigateBack(), 500)
|
||||
} else {
|
||||
uni.showToast({ title: res.data.message, duration: 2000, icon: 'none' })
|
||||
}
|
||||
})
|
||||
}).catch(() => {
|
||||
uni.showToast({ title: '请填写有效信息', duration: 2000, icon: 'none' })
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.wrapper {
|
||||
padding: 32rpx;
|
||||
|
||||
@@ -1,30 +1,38 @@
|
||||
<template>
|
||||
<view class="log-list">
|
||||
<!-- 提现记录 -->
|
||||
<view class="log-way" v-if="cashLogData.length != 0" v-for="(item, index) in cashLogData" :key="index">
|
||||
<view
|
||||
class="log-way"
|
||||
v-if="withdrawLogList.length != 0"
|
||||
v-for="(item, index) in withdrawLogList"
|
||||
:key="'cash-' + index"
|
||||
>
|
||||
<view class="log-item">
|
||||
<view class="log-item-view">
|
||||
<view class="title">{{
|
||||
item.distributionCashStatus == "APPLY"
|
||||
? "待处理"
|
||||
: item.distributionCashStatus == "VIA_AUDITING"
|
||||
? "通过"
|
||||
: "拒绝"
|
||||
item.distributionCashStatus == 'APPLY'
|
||||
? '待处理'
|
||||
: item.distributionCashStatus == 'VIA_AUDITING'
|
||||
? '通过'
|
||||
: '拒绝'
|
||||
}}</view>
|
||||
<view class="price">+{{unitPrice(item.price) }}</view>
|
||||
<view class="price">+{{ unitPrice(item.price) }}</view>
|
||||
</view>
|
||||
<view class="log-item-view">
|
||||
<view>{{ item.createTime }}</view>
|
||||
<view></view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 分销业绩 -->
|
||||
<view class="log-way" v-if="achievementData.length != 0" v-for="(item, index) in achievementData" :key="index">
|
||||
|
||||
<view
|
||||
class="log-way"
|
||||
v-if="achievementList.length != 0"
|
||||
v-for="(item, index) in achievementList"
|
||||
:key="'ach-' + index"
|
||||
>
|
||||
<view class="log-item">
|
||||
<view class="log-item-view">
|
||||
<view class="title">{{ item.goodsName }}</view>
|
||||
<view class="price">提成金额:+{{unitPrice(item.rebate) }}</view>
|
||||
<view class="price">提成金额:+{{ unitPrice(item.rebate) }}</view>
|
||||
</view>
|
||||
<view class="log-item-view">
|
||||
<view>创建时间:{{ item.createTime }}</view>
|
||||
@@ -38,101 +46,98 @@
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="empty" v-if="empty">
|
||||
<u-loadmore :status="status" :icon-type="iconType" bg-color="#f7f7f7" />
|
||||
|
||||
<view class="empty" v-if="isEmpty">
|
||||
<u-loadmore :status="loadStatus" :icon-type="iconType" bg-color="#f7f7f7" />
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
import { cashLog, distributionOrderList } from "@/api/goods";
|
||||
export default {
|
||||
data () {
|
||||
return {
|
||||
cashLogData: [], //提现记录数据集合
|
||||
achievementData: [], //分销业绩数据合集,
|
||||
status: "loadmore",
|
||||
iconType: "flower",
|
||||
empty: false,
|
||||
params: {
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
},
|
||||
|
||||
type: 0,
|
||||
routers: "",
|
||||
achParams: {
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
},
|
||||
};
|
||||
},
|
||||
onLoad (option) {
|
||||
let title;
|
||||
option.type == 0 ? (title = "分销业绩") : (title = "提现记录");
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { onLoad, onReachBottom } from '@dcloudio/uni-app'
|
||||
import { useStore } from '@/store'
|
||||
import { cashLog, distributionOrderList } from '@/api/goods'
|
||||
import { unitPrice } from '@/utils/filters.js'
|
||||
|
||||
uni.setNavigationBarTitle({
|
||||
title: title, //这是修改后的导航栏文字
|
||||
});
|
||||
this.routers = option;
|
||||
this.type = option.type;
|
||||
option.type == 0 ? this.achievement() : this.history();
|
||||
},
|
||||
mounted () { },
|
||||
onReachBottom () {
|
||||
this.status = "loading";
|
||||
this.type == 0 ? this.achParams.pageNumber++ : this.params.pageNumber++;
|
||||
this.type == 0 ? this.achievement() : this.history();
|
||||
},
|
||||
methods: {
|
||||
// 业绩
|
||||
achievement () {
|
||||
uni.showLoading({
|
||||
title: "加载中",
|
||||
});
|
||||
distributionOrderList(this.achParams).then((res) => {
|
||||
if (res.data.success && res.data.result.records.length >= 1) {
|
||||
this.achievementData.push(...res.data.result.records);
|
||||
} else {
|
||||
this.status = "nomore";
|
||||
this.empty = true;
|
||||
}
|
||||
if (this.$store.state.isShowToast){ uni.hideLoading() };
|
||||
});
|
||||
},
|
||||
// 初始化提现历史
|
||||
history () {
|
||||
uni.showLoading({
|
||||
title: "加载中",
|
||||
});
|
||||
cashLog(this.params).then((res) => {
|
||||
if (res.data.success && res.data.result.records.length >= 1) {
|
||||
this.cashLogData.push(...res.data.result.records);
|
||||
} else {
|
||||
this.status = "nomore";
|
||||
this.empty = true;
|
||||
}
|
||||
if (this.$store.state.isShowToast){ uni.hideLoading() };
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
const store = useStore()
|
||||
|
||||
const withdrawLogList = ref<any[]>([])
|
||||
const achievementList = ref<any[]>([])
|
||||
const loadStatus = ref('loadmore')
|
||||
const iconType = ref('flower')
|
||||
const isEmpty = ref(false)
|
||||
const listType = ref(0)
|
||||
const routeQuery = ref<Record<string, string>>({})
|
||||
|
||||
const withdrawParams = ref({ pageNumber: 1, pageSize: 10 })
|
||||
const achievementParams = ref({ pageNumber: 1, pageSize: 10 })
|
||||
|
||||
onLoad((option) => {
|
||||
const type = Number(option.type ?? 0)
|
||||
listType.value = type
|
||||
routeQuery.value = option || {}
|
||||
uni.setNavigationBarTitle({
|
||||
title: type === 0 ? '分销业绩' : '提现记录',
|
||||
})
|
||||
type === 0 ? fetchAchievementList() : fetchWithdrawLog()
|
||||
})
|
||||
|
||||
onReachBottom(() => {
|
||||
loadStatus.value = 'loading'
|
||||
if (listType.value === 0) {
|
||||
achievementParams.value.pageNumber++
|
||||
fetchAchievementList()
|
||||
} else {
|
||||
withdrawParams.value.pageNumber++
|
||||
fetchWithdrawLog()
|
||||
}
|
||||
})
|
||||
|
||||
function hideLoadingIfNeeded() {
|
||||
if (store.state.isShowToast) uni.hideLoading()
|
||||
}
|
||||
|
||||
function fetchAchievementList() {
|
||||
uni.showLoading({ title: '加载中' })
|
||||
distributionOrderList(achievementParams.value).then((res) => {
|
||||
if (res.data.success && res.data.result.records.length >= 1) {
|
||||
achievementList.value.push(...res.data.result.records)
|
||||
} else {
|
||||
loadStatus.value = 'nomore'
|
||||
isEmpty.value = true
|
||||
}
|
||||
hideLoadingIfNeeded()
|
||||
})
|
||||
}
|
||||
|
||||
function fetchWithdrawLog() {
|
||||
uni.showLoading({ title: '加载中' })
|
||||
cashLog(withdrawParams.value).then((res) => {
|
||||
if (res.data.success && res.data.result.records.length >= 1) {
|
||||
withdrawLogList.value.push(...res.data.result.records)
|
||||
} else {
|
||||
loadStatus.value = 'nomore'
|
||||
isEmpty.value = true
|
||||
}
|
||||
hideLoadingIfNeeded()
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.empty {
|
||||
margin: 40rpx 0;
|
||||
}
|
||||
|
||||
.price {
|
||||
color: $main-color;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.log-list {
|
||||
padding: 0 8rpx;
|
||||
overflow: hidden;
|
||||
margin: 20rpx 0;
|
||||
}
|
||||
|
||||
.log-way {
|
||||
margin: 10rpx 0;
|
||||
overflow: hidden;
|
||||
@@ -140,26 +145,17 @@ export default {
|
||||
border-radius: 10rpx;
|
||||
padding: 20rpx 0;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 30rpx;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.log-item-view {
|
||||
padding: 8rpx 32rpx;
|
||||
display: flex;
|
||||
font-size: 13px;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.log-item-footer {
|
||||
padding: 8rpx 32rpx;
|
||||
display: flex;
|
||||
font-size: 13px;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.log-item-footer,
|
||||
.log-item-footers {
|
||||
padding: 8rpx 32rpx;
|
||||
display: flex;
|
||||
|
||||
@@ -1,18 +1,15 @@
|
||||
<template>
|
||||
<view>
|
||||
|
||||
<view class="nav-list">
|
||||
<view class="total">可提现金额</view>
|
||||
<view class="price">{{unitPrice(distributionData.canRebate) }}</view>
|
||||
<view class="frozen"
|
||||
>冻结金额{{unitPrice(distributionData.commissionFrozen) }}</view
|
||||
>
|
||||
<view class="price">{{ unitPrice(distributionData.canRebate) }}</view>
|
||||
<view class="frozen">冻结金额{{ unitPrice(distributionData.commissionFrozen) }}</view>
|
||||
</view>
|
||||
<view class="nav">
|
||||
<view class="nav-item">
|
||||
<u-icon
|
||||
size="50"
|
||||
@click="handleClick('/pages/mine/distribution/list?id='+distributionData.id+'&name='+distributionData.memberName)"
|
||||
@click="navigateTo(`/pages/mine/distribution/list?id=${distributionData.id}&name=${distributionData.memberName}`)"
|
||||
color="#ff6b35"
|
||||
name="bag-fill"
|
||||
></u-icon>
|
||||
@@ -20,72 +17,54 @@
|
||||
</view>
|
||||
<view
|
||||
class="nav-item"
|
||||
@click="handleClick(`/pages/mine/distribution/history?type=0&id=${distributionData.id}&name=${distributionData.memberName}`)"
|
||||
@click="navigateTo(`/pages/mine/distribution/history?type=0&id=${distributionData.id}&name=${distributionData.memberName}`)"
|
||||
>
|
||||
<u-icon size="50" color="#ff6b35" name="order"></u-icon>
|
||||
<view>分销业绩</view>
|
||||
</view>
|
||||
<view
|
||||
class="nav-item"
|
||||
@click="handleClick('/pages/mine/distribution/history?type=1')"
|
||||
>
|
||||
<view class="nav-item" @click="navigateTo('/pages/mine/distribution/history?type=1')">
|
||||
<u-icon size="50" color="#ff6b35" name="red-packet-fill"></u-icon>
|
||||
<view>提现记录</view>
|
||||
</view>
|
||||
<view
|
||||
class="nav-item"
|
||||
@click="handleClick('/pages/mine/distribution/withdrawal')"
|
||||
>
|
||||
<view class="nav-item" @click="navigateTo('/pages/mine/distribution/withdrawal')">
|
||||
<u-icon size="50" color="#ffc71c" name="rmb-circle-fill"></u-icon>
|
||||
<view>提现</view>
|
||||
</view>
|
||||
|
||||
|
||||
</view>
|
||||
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { onShow } from '@dcloudio/uni-app'
|
||||
import { useStore } from '@/store'
|
||||
import { distribution } from '@/api/goods'
|
||||
import { unitPrice } from '@/utils/filters.js'
|
||||
|
||||
import { distribution } from "@/api/goods";
|
||||
export default {
|
||||
const store = useStore()
|
||||
const distributionData = ref<Record<string, any>>({})
|
||||
|
||||
data() {
|
||||
return {
|
||||
distributionData: "",
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
handleClick(url) {
|
||||
uni.navigateTo({
|
||||
url,
|
||||
});
|
||||
},
|
||||
queryGoods(src) {
|
||||
uni.navigateTo({
|
||||
url: `/pages/mine/distribution/${src}`,
|
||||
});
|
||||
},
|
||||
/**
|
||||
* 初始化推广商品
|
||||
*/
|
||||
init() {
|
||||
uni.showLoading({
|
||||
title: "加载中",
|
||||
});
|
||||
distribution().then((res) => {
|
||||
if (res.data.result) {
|
||||
this.distributionData = res.data.result;
|
||||
}
|
||||
if (this.$store.state.isShowToast){ uni.hideLoading() };
|
||||
});
|
||||
},
|
||||
},
|
||||
onShow() {
|
||||
this.init();
|
||||
},
|
||||
};
|
||||
onShow(() => {
|
||||
fetchDistributionInfo()
|
||||
})
|
||||
|
||||
function hideLoadingIfNeeded() {
|
||||
if (store.state.isShowToast) uni.hideLoading()
|
||||
}
|
||||
|
||||
function navigateTo(url: string) {
|
||||
uni.navigateTo({ url })
|
||||
}
|
||||
|
||||
function fetchDistributionInfo() {
|
||||
uni.showLoading({ title: '加载中' })
|
||||
distribution().then((res) => {
|
||||
if (res.data.result) {
|
||||
distributionData.value = res.data.result
|
||||
}
|
||||
hideLoadingIfNeeded()
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@@ -124,6 +103,5 @@ export default {
|
||||
justify-content: center;
|
||||
gap: 20rpx;
|
||||
width: 33%;
|
||||
// color: #fff;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,104 +1,127 @@
|
||||
<template>
|
||||
<view class="wrapper">
|
||||
<view class="wrapper" :style="themeStyle">
|
||||
<u-tabs
|
||||
:list="list"
|
||||
:list="stepList"
|
||||
:scrollable="false"
|
||||
v-model:current="current"
|
||||
v-model:current="currentStep"
|
||||
:lineColor="lightColor"
|
||||
:activeStyle="{ color: lightColor }"
|
||||
></u-tabs>
|
||||
|
||||
|
||||
|
||||
<!-- 推广人资料 -->
|
||||
<view class="message">
|
||||
<u-form :model="ruleForm" label-width="250rpx" ref="uForm">
|
||||
<u-form-item label="会员昵称" prop="name">
|
||||
<u-input v-model="ruleForm.name" />
|
||||
</u-form-item>
|
||||
<u-form-item label="账户类型" prop="name"> </u-form-item>
|
||||
<u-form-item
|
||||
label="收款人姓名"
|
||||
placeholder="请输入收款人姓名"
|
||||
prop="name"
|
||||
>
|
||||
<u-input v-model="ruleForm.name" />
|
||||
</u-form-item>
|
||||
<u-form-item
|
||||
label="收款账号"
|
||||
placeholder="请输入收款人账号"
|
||||
prop="name"
|
||||
>
|
||||
<u-input v-model="ruleForm.name" />
|
||||
</u-form-item>
|
||||
<u-form-item
|
||||
label="银行名称"
|
||||
placeholder="请输入开户银行支行名称"
|
||||
prop="name"
|
||||
>
|
||||
<u-input v-model="ruleForm.name" />
|
||||
</u-form-item>
|
||||
</u-form>
|
||||
<u-button :customStyle="{'background':$lightColor,'color':'#fff' }" @click="submit">提交</u-button>
|
||||
<view class="feedBack-box">
|
||||
<up-form
|
||||
:model="formData"
|
||||
label-position="top"
|
||||
ref="uFormRef"
|
||||
>
|
||||
<up-form-item label="会员昵称" prop="name">
|
||||
<u-input
|
||||
border="none"
|
||||
class="field-input"
|
||||
v-model="formData.name"
|
||||
:custom-style="fieldInputStyle"
|
||||
/>
|
||||
</up-form-item>
|
||||
<up-form-item label="账户类型" prop="name"></up-form-item>
|
||||
<up-form-item label="收款人姓名" prop="name">
|
||||
<u-input
|
||||
border="none"
|
||||
class="field-input"
|
||||
v-model="formData.name"
|
||||
placeholder="请输入收款人姓名"
|
||||
:custom-style="fieldInputStyle"
|
||||
/>
|
||||
</up-form-item>
|
||||
<up-form-item label="收款账号" prop="name">
|
||||
<u-input
|
||||
border="none"
|
||||
class="field-input"
|
||||
v-model="formData.name"
|
||||
placeholder="请输入收款人账号"
|
||||
:custom-style="fieldInputStyle"
|
||||
/>
|
||||
</up-form-item>
|
||||
<up-form-item label="银行名称" prop="name">
|
||||
<u-input
|
||||
border="none"
|
||||
class="field-input"
|
||||
v-model="formData.name"
|
||||
placeholder="请输入开户银行支行名称"
|
||||
:custom-style="fieldInputStyle"
|
||||
/>
|
||||
</up-form-item>
|
||||
</up-form>
|
||||
</view>
|
||||
|
||||
<view class="submit" @click="submitForm">提交</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
components: {},
|
||||
// 必须要在onReady生命周期,因为onLoad生命周期组件可能尚未创建完毕
|
||||
onReady() {
|
||||
this.$refs.uForm.setRules(this.rules);
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
current:0,
|
||||
lightColor: this.$lightColor,
|
||||
list: [
|
||||
{
|
||||
name: "推广人资料",
|
||||
},
|
||||
{
|
||||
name: "平台审核",
|
||||
},
|
||||
{
|
||||
name: "完成",
|
||||
},
|
||||
],
|
||||
ruleForm: {
|
||||
name: "",
|
||||
radio: "",
|
||||
},
|
||||
rules: {
|
||||
name: [
|
||||
{
|
||||
required: true,
|
||||
message: "请输入姓名",
|
||||
// 可以单个或者同时写两个触发验证方式
|
||||
trigger: "blur",
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, computed } from 'vue'
|
||||
import { onReady } from '@dcloudio/uni-app'
|
||||
import { useStore } from '@/store'
|
||||
import { getThemeStyle } from '@/utils/theme'
|
||||
import { fieldInputStyle } from '@/utils/form-style.js'
|
||||
|
||||
const store = useStore()
|
||||
|
||||
const themeStyle = computed(() => getThemeStyle(store.state.theme))
|
||||
const lightColor = computed(() => store.getters.lightColor)
|
||||
const currentStep = ref(0)
|
||||
const uFormRef = ref<any>(null)
|
||||
|
||||
const stepList = [
|
||||
{ name: '推广人资料' },
|
||||
{ name: '平台审核' },
|
||||
{ name: '完成' },
|
||||
]
|
||||
|
||||
const formData = reactive({
|
||||
name: '',
|
||||
radio: '',
|
||||
})
|
||||
|
||||
const rules = {
|
||||
name: [{ required: true, message: '请输入姓名', trigger: 'blur' }],
|
||||
}
|
||||
|
||||
onReady(() => {
|
||||
uFormRef.value?.setRules(rules)
|
||||
})
|
||||
|
||||
function submitForm() {
|
||||
uFormRef.value?.validate().catch(() => {
|
||||
uni.showToast({ title: '请填写有效信息', icon: 'none' })
|
||||
})
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.menu {
|
||||
height: 88rpx;
|
||||
line-height: 88rpx;
|
||||
background: $main-color;
|
||||
display: flex;
|
||||
> .menu-item {
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
color: $light-color;
|
||||
}
|
||||
}
|
||||
.active {
|
||||
color: #fff !important;
|
||||
}
|
||||
.message {
|
||||
padding: 0 32rpx;
|
||||
|
||||
<style lang="scss">
|
||||
page {
|
||||
background: #f8f8f8;
|
||||
}
|
||||
</style>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import '@/pages/passport/entry/seller/entry-form.scss';
|
||||
|
||||
.wrapper {
|
||||
box-sizing: border-box;
|
||||
min-height: 100vh;
|
||||
padding: 20rpx 24rpx 40rpx;
|
||||
background: #f8f8f8;
|
||||
@include seller-entry-form;
|
||||
}
|
||||
|
||||
.feedBack-box {
|
||||
background: #fff;
|
||||
border-radius: 20rpx;
|
||||
padding: 32rpx;
|
||||
margin-top: 20rpx;
|
||||
}
|
||||
|
||||
.submit {
|
||||
@include seller-entry-submit;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -58,44 +58,44 @@
|
||||
|
||||
<!-- 导航栏 -->
|
||||
<view class="nav">
|
||||
<view class="nav-item" @click="handleMyGoods(true)" :class="{ checked: params.checked }">已选择</view>
|
||||
<view class="nav-item" @click="handleMyGoods(false)" :class="{ checked: !params.checked }">未选择</view>
|
||||
<view class="nav-item" @click="toggleGoodsTab(true)" :class="{ checked: queryParams.checked }">已选择</view>
|
||||
<view class="nav-item" @click="toggleGoodsTab(false)" :class="{ checked: !queryParams.checked }">未选择</view>
|
||||
|
||||
<!-- <view class="nav-item" @click="popup = !popup">筛选</view> -->
|
||||
</view>
|
||||
<!-- 商品列表 -->
|
||||
|
||||
<view class="goods-list">
|
||||
<scroll-view class="body-view" scroll-y @scrolltolower="renderDate">
|
||||
<scroll-view class="body-view" scroll-y @scrolltolower="loadMore">
|
||||
<block v-for="(item, index) in goodsList" :key="item.id">
|
||||
<u-swipe-action v-if="params.checked" class="distribution-swipe">
|
||||
<u-swipe-action v-if="queryParams.checked" class="distribution-swipe">
|
||||
<u-swipe-action-item
|
||||
:show="item.___selected"
|
||||
@open="openAction(item)"
|
||||
@open="openSwipeAction(item)"
|
||||
:name="index"
|
||||
:options="options"
|
||||
@click="changeActionTab(item)"
|
||||
:options="swipeOptions"
|
||||
@click="confirmUnbindPrompt(item)"
|
||||
>
|
||||
<view class="goods-item">
|
||||
<view class="goods-item-img" @click="handleNavgationGoods(item)">
|
||||
<view class="goods-item-img" @click="navigateToGoods(item)">
|
||||
<u-image width="176rpx" height="176rpx" :src="item.thumbnail"></u-image>
|
||||
</view>
|
||||
<view class="goods-item-desc">
|
||||
<view class="-item-title" @click="handleNavgationGoods(item)">
|
||||
<view class="-item-title" @click="navigateToGoods(item)">
|
||||
{{ item.goodsName }}
|
||||
</view>
|
||||
<view class="-item-price" @click="handleNavgationGoods(item)">
|
||||
<view class="-item-price" @click="navigateToGoods(item)">
|
||||
佣金:
|
||||
<span> ¥{{ unitPrice(item.commission) }}</span>
|
||||
</view>
|
||||
<view class="-item-bottom">
|
||||
<view class="-item-bootom-money" @click="handleNavgationGoods(item)">
|
||||
<view class="-item-bootom-money" @click="navigateToGoods(item)">
|
||||
<view class="-item-yj">
|
||||
<span>¥{{ unitPrice(item.price) }}</span>
|
||||
</view>
|
||||
</view>
|
||||
<view>
|
||||
<view class="click" @click="handleLink(item)">分销商品</view>
|
||||
<view class="click" @click="shareDistributionGoods(item)">分销商品</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
@@ -104,25 +104,25 @@
|
||||
</u-swipe-action>
|
||||
|
||||
<view v-else class="goods-item">
|
||||
<view class="goods-item-img" @click="handleNavgationGoods(item)">
|
||||
<view class="goods-item-img" @click="navigateToGoods(item)">
|
||||
<u-image width="176rpx" height="176rpx" :src="item.thumbnail"></u-image>
|
||||
</view>
|
||||
<view class="goods-item-desc">
|
||||
<view class="-item-title" @click="handleNavgationGoods(item)">
|
||||
<view class="-item-title" @click="navigateToGoods(item)">
|
||||
{{ item.goodsName }}
|
||||
</view>
|
||||
<view class="-item-price" @click="handleNavgationGoods(item)">
|
||||
<view class="-item-price" @click="navigateToGoods(item)">
|
||||
佣金:
|
||||
<span> ¥{{ unitPrice(item.commission) }}</span>
|
||||
</view>
|
||||
<view class="-item-bottom">
|
||||
<view class="-item-bootom-money" @click="handleNavgationGoods(item)">
|
||||
<view class="-item-bootom-money" @click="navigateToGoods(item)">
|
||||
<view class="-item-yj">
|
||||
<span>¥{{ unitPrice(item.price) }}</span>
|
||||
</view>
|
||||
</view>
|
||||
<view>
|
||||
<view class="click" @click="handleClickGoods(item)">立即选取</view>
|
||||
<view class="click" @click="selectGoods(item)">立即选取</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
@@ -136,210 +136,164 @@
|
||||
</view>
|
||||
</view>
|
||||
<canvas class="canvas-hide" canvas-id="qrcode" />
|
||||
<drawCanvas ref="drawCanvas" v-if="showFlag" :res="res" />
|
||||
<u-modal v-model:show="deleteShow" :confirm-style="{'color':lightColor}" @confirm="delectConfirm" show-cancel-button :content="deleteContent" :async-close="true"></u-modal>
|
||||
<drawCanvas ref="drawCanvasRef" v-if="showPoster" :res="posterData" />
|
||||
<u-modal
|
||||
v-model:show="showUnbindModal"
|
||||
:confirm-style="{ color: lightColor }"
|
||||
@confirm="confirmUnbind"
|
||||
show-cancel-button
|
||||
:content="unbindModalContent"
|
||||
:async-close="true"
|
||||
></u-modal>
|
||||
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
<script setup lang="ts">
|
||||
import { ref, computed } from 'vue'
|
||||
import { onLoad, onShow } from '@dcloudio/uni-app'
|
||||
import { useStore } from '@/store'
|
||||
import {
|
||||
distributionGoods,
|
||||
checkedDistributionGoods,
|
||||
getMpCode,
|
||||
} from "@/api/goods";
|
||||
} from '@/api/goods'
|
||||
import drawCanvas from '@/components/m-canvas'
|
||||
import { unitPrice } from '@/utils/filters.js'
|
||||
|
||||
import drawCanvas from "@/components/m-canvas";
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
lightColor: this.$lightColor,
|
||||
deleteContent: "解绑该商品?", //删除显示的信息
|
||||
// 商品栏右侧滑动按钮
|
||||
options: [
|
||||
{
|
||||
text: "解绑",
|
||||
style: {
|
||||
backgroundColor: this.$lightColor, //高亮颜色
|
||||
},
|
||||
},
|
||||
],
|
||||
showFlag: false, //分销分享开关
|
||||
empty: false,
|
||||
popup: false, //弹出层开关
|
||||
active_color: this.$mainColor,
|
||||
current: 0,
|
||||
params: {
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
checked: true,
|
||||
},
|
||||
goodsList: [],
|
||||
|
||||
// 分销分享 实例
|
||||
res: {
|
||||
container: {
|
||||
width: 600,
|
||||
height: 960,
|
||||
background: "#fff",
|
||||
title: "分享背景",
|
||||
},
|
||||
// 分销分享
|
||||
bottom: {
|
||||
img: "",
|
||||
code: "",
|
||||
price: 0,
|
||||
},
|
||||
},
|
||||
|
||||
routers: "",
|
||||
deleteShow: false, //删除模态框
|
||||
goodsVal: false, //分销商铺信息
|
||||
};
|
||||
const store = useStore()
|
||||
const lightColor = computed(() => store.getters.lightColor)
|
||||
const swipeOptions = computed(() => [
|
||||
{
|
||||
text: '解绑',
|
||||
style: { backgroundColor: lightColor.value },
|
||||
},
|
||||
components: {
|
||||
drawCanvas,
|
||||
])
|
||||
|
||||
const unbindModalContent = '解绑该商品?'
|
||||
const showPoster = ref(false)
|
||||
const showUnbindModal = ref(false)
|
||||
const routeQuery = ref<Record<string, string>>({})
|
||||
const selectedGoods = ref<any>(null)
|
||||
const drawCanvasRef = ref<any>(null)
|
||||
|
||||
const queryParams = ref({
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
checked: true,
|
||||
})
|
||||
const goodsList = ref<any[]>([])
|
||||
|
||||
const posterData = ref({
|
||||
container: {
|
||||
width: 600,
|
||||
height: 960,
|
||||
background: '#fff',
|
||||
title: '分享背景',
|
||||
},
|
||||
onLoad(options) {
|
||||
this.routers = options;
|
||||
bottom: {
|
||||
img: '',
|
||||
code: '',
|
||||
price: 0,
|
||||
desc: '',
|
||||
},
|
||||
watch: {},
|
||||
onShow() {
|
||||
this.goodsList = [];
|
||||
this.init();
|
||||
},
|
||||
methods: {
|
||||
/**
|
||||
* 滑动删除
|
||||
*/
|
||||
changeActionTab(val) {
|
||||
this.deleteShow = true;
|
||||
this.goodsVal = val;
|
||||
},
|
||||
})
|
||||
|
||||
/**
|
||||
* 点击解绑商品
|
||||
*/
|
||||
delectConfirm() {
|
||||
checkedDistributionGoods({ id: this.goodsVal.id, checked: false }).then(
|
||||
(res) => {
|
||||
if (res.data.success) {
|
||||
uni.showToast({
|
||||
title: "此商品解绑成功",
|
||||
duration: 2000,
|
||||
});
|
||||
this.deleteShow = false;
|
||||
this.goodsList = [];
|
||||
this.init();
|
||||
}
|
||||
}
|
||||
);
|
||||
},
|
||||
onLoad((options) => {
|
||||
routeQuery.value = options || {}
|
||||
})
|
||||
|
||||
/**
|
||||
* 左滑打开删除
|
||||
*/
|
||||
openAction(val) {
|
||||
this.goodsList.forEach((item) => {
|
||||
item["___selected"] = false;
|
||||
});
|
||||
val["___selected"] = true;
|
||||
},
|
||||
onShow(() => {
|
||||
goodsList.value = []
|
||||
queryParams.value.pageNumber = 1
|
||||
fetchGoodsList()
|
||||
})
|
||||
|
||||
/**
|
||||
* 查看图片
|
||||
*/
|
||||
handleNavgationGoods(val) {
|
||||
uni.navigateTo({
|
||||
url: `/pages/product/goods?id=${val.skuId}&goodsId=${val.goodsId}`,
|
||||
});
|
||||
},
|
||||
function confirmUnbindPrompt(item: any) {
|
||||
showUnbindModal.value = true
|
||||
selectedGoods.value = item
|
||||
}
|
||||
|
||||
async handleLink(goods) {
|
||||
uni.showToast({
|
||||
title: "请请按住保存图片",
|
||||
duration: 2000,
|
||||
icon: "none",
|
||||
});
|
||||
let page = `pages/product/goods`;
|
||||
let scene = `${goods.skuId},${goods.goodsId},${this.routers.id}`;
|
||||
let result = await getMpCode({ page, scene });
|
||||
if (result.data.success) {
|
||||
let callback = result.data.result;
|
||||
this.res.container.title = `${goods.goodsName}`;
|
||||
this.res.bottom.code = `data:image/png;base64,${callback}`;
|
||||
this.res.bottom.price = this.unitPrice(
|
||||
goods.price,
|
||||
"¥"
|
||||
);
|
||||
this.res.bottom.desc = `${goods.goodsName}`;
|
||||
this.res.bottom.img = `${goods.thumbnail}`;
|
||||
function confirmUnbind() {
|
||||
checkedDistributionGoods({ id: selectedGoods.value.id, checked: false }).then((res) => {
|
||||
if (res.data.success) {
|
||||
uni.showToast({ title: '此商品解绑成功', duration: 2000 })
|
||||
showUnbindModal.value = false
|
||||
goodsList.value = []
|
||||
queryParams.value.pageNumber = 1
|
||||
fetchGoodsList()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
if (this.showFlag) {
|
||||
this.$refs.drawCanvas.init();
|
||||
}
|
||||
this.showFlag = true;
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: `制作二维码失败!请稍后重试`,
|
||||
duration: 2000,
|
||||
icon: "none",
|
||||
});
|
||||
}
|
||||
},
|
||||
function openSwipeAction(item: any) {
|
||||
goodsList.value.forEach((row) => {
|
||||
row.___selected = false
|
||||
})
|
||||
item.___selected = true
|
||||
}
|
||||
|
||||
change(index) {
|
||||
this.current = index;
|
||||
},
|
||||
// 点击我的选品库
|
||||
handleMyGoods(flag) {
|
||||
this.goodsList = [];
|
||||
this.params.checked = flag;
|
||||
this.init();
|
||||
},
|
||||
function navigateToGoods(item: any) {
|
||||
uni.navigateTo({
|
||||
url: `/pages/product/goods?id=${item.skuId}&goodsId=${item.goodsId}`,
|
||||
})
|
||||
}
|
||||
|
||||
// 选择商品
|
||||
handleClickGoods(val) {
|
||||
checkedDistributionGoods({ id: val.id, checked: true }).then((res) => {
|
||||
if (res.data.success) {
|
||||
uni.showToast({
|
||||
title: "已添加到我的选品库",
|
||||
duration: 2000,
|
||||
icon: "none",
|
||||
});
|
||||
async function shareDistributionGoods(goods: any) {
|
||||
uni.showToast({ title: '请请按住保存图片', duration: 2000, icon: 'none' })
|
||||
const page = 'pages/product/goods'
|
||||
const scene = `${goods.skuId},${goods.goodsId},${routeQuery.value.id}`
|
||||
const result = await getMpCode({ page, scene })
|
||||
if (result.data.success) {
|
||||
const callback = result.data.result
|
||||
posterData.value.container.title = `${goods.goodsName}`
|
||||
posterData.value.bottom.code = `data:image/png;base64,${callback}`
|
||||
posterData.value.bottom.price = unitPrice(goods.price, '¥')
|
||||
posterData.value.bottom.desc = `${goods.goodsName}`
|
||||
posterData.value.bottom.img = `${goods.thumbnail}`
|
||||
if (showPoster.value) {
|
||||
drawCanvasRef.value?.init()
|
||||
}
|
||||
showPoster.value = true
|
||||
} else {
|
||||
uni.showToast({ title: '制作二维码失败!请稍后重试', duration: 2000, icon: 'none' })
|
||||
}
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
this.goodsList = [];
|
||||
this.init();
|
||||
}, 500);
|
||||
}
|
||||
});
|
||||
},
|
||||
function toggleGoodsTab(isSelected: boolean) {
|
||||
goodsList.value = []
|
||||
queryParams.value.checked = isSelected
|
||||
queryParams.value.pageNumber = 1
|
||||
fetchGoodsList()
|
||||
}
|
||||
|
||||
init() {
|
||||
distributionGoods(this.params).then((res) => {
|
||||
if (res.data.success && res.data.result.records.length >= 1) {
|
||||
res.data.result.records.forEach((item) => {
|
||||
item["___selected"] = false;
|
||||
});
|
||||
this.goodsList.push(...res.data.result.records);
|
||||
}
|
||||
if (this.goodsList.length === 0) {
|
||||
this.empty = true;
|
||||
}
|
||||
});
|
||||
},
|
||||
function selectGoods(item: any) {
|
||||
checkedDistributionGoods({ id: item.id, checked: true }).then((res) => {
|
||||
if (res.data.success) {
|
||||
uni.showToast({ title: '已添加到我的选品库', duration: 2000, icon: 'none' })
|
||||
setTimeout(() => {
|
||||
goodsList.value = []
|
||||
queryParams.value.pageNumber = 1
|
||||
fetchGoodsList()
|
||||
}, 500)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 底部加载数据
|
||||
*/
|
||||
renderDate() {
|
||||
function fetchGoodsList() {
|
||||
distributionGoods(queryParams.value).then((res) => {
|
||||
if (res.data.success && res.data.result.records.length >= 1) {
|
||||
res.data.result.records.forEach((item: any) => {
|
||||
item.___selected = false
|
||||
})
|
||||
goodsList.value.push(...res.data.result.records)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
this.params.pageNumber += 1;
|
||||
this.init();
|
||||
},
|
||||
|
||||
},
|
||||
};
|
||||
function loadMore() {
|
||||
queryParams.value.pageNumber += 1
|
||||
fetchGoodsList()
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
|
||||
|
||||
@@ -1,129 +1,182 @@
|
||||
<template>
|
||||
<view>
|
||||
<view class="withdrawal-list">
|
||||
<view class="title">提现金额</view>
|
||||
<view class="content">
|
||||
<view class="price">
|
||||
<span> ¥</span>
|
||||
<u-input v-model="price" placeholder="" type="number" />
|
||||
</view>
|
||||
|
||||
<view class="all">
|
||||
<view @click="handleAll" :style="{ color: $mainColor }">全部</view>
|
||||
<view style="font-size: 24rpx; color: #999"
|
||||
>可提现金额<span>{{unitPrice(distributionData.canRebate) }}</span
|
||||
>元</view
|
||||
>
|
||||
<view class="wrapper" :style="themeStyle">
|
||||
<view class="feedBack-box">
|
||||
<view class="box-title">提现金额</view>
|
||||
<view class="amount-row">
|
||||
<text class="currency">¥</text>
|
||||
<u-input
|
||||
v-model="price"
|
||||
type="digit"
|
||||
border="none"
|
||||
placeholder="请输入提现金额"
|
||||
class="amount-input"
|
||||
/>
|
||||
</view>
|
||||
<view class="amount-extra">
|
||||
<view class="all-btn" @click="fillAllAmount">全部</view>
|
||||
<view class="balance-tip">
|
||||
可提现金额
|
||||
<text class="balance-value">{{ unitPrice(distributionData.canRebate) }}</text>
|
||||
元
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="submit" @click="cashd">提现</view>
|
||||
<view class="submit" @click="submitWithdraw">提现</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
import { distribution, cash } from "@/api/goods";
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
price: 0,
|
||||
distributionData: "",
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
this.init();
|
||||
},
|
||||
methods: {
|
||||
cashd() {
|
||||
this.price = this.price + "";
|
||||
|
||||
|
||||
if (this.$u.test.amount(parseInt(this.price))) {
|
||||
cash({ price: this.price }).then((res) => {
|
||||
if(res.data.success){
|
||||
uni.showToast({
|
||||
title: '提现成功!',
|
||||
duration: 2000,
|
||||
icon:"none"
|
||||
});
|
||||
setTimeout(()=>{
|
||||
uni.navigateBack({
|
||||
delta: 1
|
||||
});
|
||||
},1000)
|
||||
}
|
||||
});
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: "请输入正确金额",
|
||||
duration: 2000,
|
||||
icon: "none",
|
||||
});
|
||||
<script setup lang="ts">
|
||||
import { ref, computed, getCurrentInstance, onMounted } from 'vue'
|
||||
import { useStore } from '@/store'
|
||||
import { distribution, cash } from '@/api/goods'
|
||||
import { unitPrice } from '@/utils/filters.js'
|
||||
import { getThemeStyle } from '@/utils/theme'
|
||||
|
||||
const store = useStore()
|
||||
const { proxy } = getCurrentInstance()!
|
||||
|
||||
const themeStyle = computed(() => getThemeStyle(store.state.theme))
|
||||
const price = ref('')
|
||||
const distributionData = ref<Record<string, any>>({})
|
||||
|
||||
onMounted(() => {
|
||||
fetchDistributionInfo()
|
||||
})
|
||||
|
||||
function hideLoadingIfNeeded() {
|
||||
if (store.state.isShowToast) uni.hideLoading()
|
||||
}
|
||||
|
||||
function fetchDistributionInfo() {
|
||||
uni.showLoading({ title: '加载中' })
|
||||
distribution().then((res) => {
|
||||
if (res.data.result) {
|
||||
distributionData.value = res.data.result
|
||||
}
|
||||
hideLoadingIfNeeded()
|
||||
})
|
||||
}
|
||||
|
||||
function submitWithdraw() {
|
||||
const amount = String(price.value ?? '')
|
||||
if (proxy.$u.test.amount(parseInt(amount))) {
|
||||
cash({ price: amount }).then((res) => {
|
||||
if (res.data.success) {
|
||||
uni.showToast({ title: '提现成功!', duration: 2000, icon: 'none' })
|
||||
setTimeout(() => {
|
||||
uni.navigateBack({ delta: 1 })
|
||||
}, 1000)
|
||||
}
|
||||
},
|
||||
handleAll() {
|
||||
this.price = this.distributionData.canRebate;
|
||||
},
|
||||
/**
|
||||
* 初始化推广商品
|
||||
*/
|
||||
init() {
|
||||
uni.showLoading({
|
||||
title: "加载中",
|
||||
});
|
||||
distribution().then((res) => {
|
||||
if (res.data.result) {
|
||||
this.distributionData = res.data.result;
|
||||
}
|
||||
if (this.$store.state.isShowToast){ uni.hideLoading() };
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
})
|
||||
} else {
|
||||
uni.showToast({ title: '请输入正确金额', duration: 2000, icon: 'none' })
|
||||
}
|
||||
}
|
||||
|
||||
function fillAllAmount() {
|
||||
price.value = distributionData.value.canRebate ?? ''
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
::v-deep .u-input__input,
|
||||
.u-input {
|
||||
font-size: 80rpx !important;
|
||||
height: 102rpx !important;
|
||||
|
||||
}
|
||||
::v-deep .u-input__input{
|
||||
height: 100%;
|
||||
font-size: 80rpx;
|
||||
}
|
||||
.content {
|
||||
display: flex;
|
||||
> .price {
|
||||
width: 60%;
|
||||
margin: 20rpx 0;
|
||||
font-size: 80rpx;
|
||||
display: flex;
|
||||
}
|
||||
> .all {
|
||||
justify-content: center;
|
||||
width: 40%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-end;
|
||||
}
|
||||
}
|
||||
.withdrawal-list {
|
||||
margin: 20rpx 0;
|
||||
background: #fff;
|
||||
padding: 16rpx 32rpx;
|
||||
}
|
||||
.title {
|
||||
font-size: 35rpx;
|
||||
}
|
||||
.submit {
|
||||
margin: 80rpx auto;
|
||||
width: 94%;
|
||||
background: $light-color;
|
||||
height: 90rpx;
|
||||
color: #fff;
|
||||
border-radius: 10rpx;
|
||||
text-align: center;
|
||||
line-height: 90rpx;
|
||||
|
||||
<style lang="scss">
|
||||
page {
|
||||
background: #f8f8f8;
|
||||
}
|
||||
</style>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import '@/pages/passport/entry/seller/entry-form.scss';
|
||||
|
||||
.wrapper {
|
||||
box-sizing: border-box;
|
||||
min-height: 100vh;
|
||||
padding: 20rpx 24rpx 40rpx;
|
||||
background: #f8f8f8;
|
||||
}
|
||||
|
||||
.feedBack-box {
|
||||
background: #fff;
|
||||
border-radius: 20rpx;
|
||||
padding: 32rpx;
|
||||
}
|
||||
|
||||
.box-title {
|
||||
font-size: 30rpx;
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
.amount-row {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
margin-top: 24rpx;
|
||||
padding: 16rpx 24rpx;
|
||||
background: #fafafa;
|
||||
border-radius: 12rpx;
|
||||
}
|
||||
|
||||
.currency {
|
||||
flex-shrink: 0;
|
||||
margin-right: 16rpx;
|
||||
font-size: 56rpx;
|
||||
font-weight: 600;
|
||||
line-height: 1;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.amount-input {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
:deep(.amount-input .u-input) {
|
||||
padding: 0 !important;
|
||||
}
|
||||
|
||||
:deep(.amount-input .u-input__content) {
|
||||
background: transparent !important;
|
||||
}
|
||||
|
||||
:deep(.amount-input .u-input__content__field-wrapper__field) {
|
||||
height: 72rpx !important;
|
||||
min-height: 72rpx !important;
|
||||
font-size: 56rpx !important;
|
||||
font-weight: 600 !important;
|
||||
color: #333 !important;
|
||||
}
|
||||
|
||||
:deep(.amount-input .u-input__content__field-wrapper__field--placeholder) {
|
||||
font-size: 32rpx !important;
|
||||
font-weight: 400 !important;
|
||||
color: #c0c4cc !important;
|
||||
}
|
||||
|
||||
.amount-extra {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-top: 24rpx;
|
||||
}
|
||||
|
||||
.all-btn {
|
||||
font-size: 28rpx;
|
||||
color: var(--theme-light, #ff6b35);
|
||||
}
|
||||
|
||||
.balance-tip {
|
||||
font-size: 24rpx;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.balance-value {
|
||||
margin: 0 4rpx;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.submit {
|
||||
@include seller-entry-submit;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,62 +1,42 @@
|
||||
<template>
|
||||
<div class="wrapper">
|
||||
<u-parse :lazy-load="true" :selectable="true" :content="res.content" v-if="res"></u-parse>
|
||||
|
||||
<u-parse :lazy-load="true" :selectable="true" :content="article.content" v-if="article"></u-parse>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { getArticleDetailByType } from "@/api/article";
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
res: "",
|
||||
way: {
|
||||
USER_AGREEMENT: {
|
||||
title: "服务协议",
|
||||
type: "USER_AGREEMENT",
|
||||
},
|
||||
PRIVACY_POLICY: {
|
||||
title: "隐私政策",
|
||||
type: "PRIVACY_POLICY",
|
||||
},
|
||||
LICENSE_INFORMATION: {
|
||||
title: "证照信息",
|
||||
type: "LICENSE_INFORMATION",
|
||||
},
|
||||
ABOUT: {
|
||||
title: "关于我们",
|
||||
type: "ABOUT",
|
||||
},
|
||||
STORE_REGISTER: {
|
||||
title: "店铺入驻协议",
|
||||
type: "STORE_REGISTER",
|
||||
},
|
||||
},
|
||||
};
|
||||
},
|
||||
mounted() {},
|
||||
onLoad(option) {
|
||||
console.log(this.way)
|
||||
uni.setNavigationBarTitle({
|
||||
title: this.way[option.type].title,
|
||||
});
|
||||
this.init(option);
|
||||
},
|
||||
|
||||
methods: {
|
||||
init(option) {
|
||||
getArticleDetailByType(this.way[option.type].type).then((res) => {
|
||||
if (res.data.success) {
|
||||
this.res = res.data.result;
|
||||
console.log(res)
|
||||
}
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { onLoad } from '@dcloudio/uni-app'
|
||||
import { getArticleDetailByType } from '@/api/article'
|
||||
|
||||
const ARTICLE_TYPE_MAP: Record<string, { title: string; type: string }> = {
|
||||
USER_AGREEMENT: { title: '服务协议', type: 'USER_AGREEMENT' },
|
||||
PRIVACY_POLICY: { title: '隐私政策', type: 'PRIVACY_POLICY' },
|
||||
LICENSE_INFORMATION: { title: '证照信息', type: 'LICENSE_INFORMATION' },
|
||||
ABOUT: { title: '关于我们', type: 'ABOUT' },
|
||||
STORE_REGISTER: { title: '店铺入驻协议', type: 'STORE_REGISTER' },
|
||||
}
|
||||
|
||||
const article = ref<any>(null)
|
||||
|
||||
onLoad((option) => {
|
||||
const meta = ARTICLE_TYPE_MAP[option.type]
|
||||
if (!meta) return
|
||||
uni.setNavigationBarTitle({ title: meta.title })
|
||||
fetchArticle(meta.type)
|
||||
})
|
||||
|
||||
function fetchArticle(type: string) {
|
||||
getArticleDetailByType(type).then((res) => {
|
||||
if (res.data.success) {
|
||||
article.value = res.data.result
|
||||
}
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.wrapper {
|
||||
padding: 16rpx;
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
||||
@@ -196,515 +196,356 @@
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// rpx和px的比率
|
||||
var l
|
||||
// 可用窗口高度
|
||||
var wh
|
||||
// 顶部空盒子的高度
|
||||
var mgUpHeight
|
||||
<script setup lang="ts">
|
||||
import { ref, nextTick, getCurrentInstance } from 'vue'
|
||||
import {
|
||||
getTalkMessage,
|
||||
onLoad,
|
||||
onHide,
|
||||
onUnload,
|
||||
onPullDownRefresh,
|
||||
onPageScroll,
|
||||
} from '@dcloudio/uni-app'
|
||||
import {
|
||||
getTalkMessage as fetchTalkMessageApi,
|
||||
getTalkByUser,
|
||||
jumpObtain
|
||||
} from "@/api/im.js";
|
||||
import SocketService from "@/utils/socket_service.js";
|
||||
import storage from "@/utils/storage.js";
|
||||
import {
|
||||
beautifyTime
|
||||
} from "@/utils/filters.js"
|
||||
jumpObtain,
|
||||
} from '@/api/im.js'
|
||||
import SocketService from '@/utils/socket_service.js'
|
||||
import storage from '@/utils/storage.js'
|
||||
import { beautifyTime, unitPrice } from '@/utils/filters.js'
|
||||
import config from '@/config/config.js'
|
||||
import { textReplaceEmoji, emojistwo } from '@/utils/emojis.js';
|
||||
export default {
|
||||
// 页面卸载后清除imGoodId
|
||||
onUnload () {
|
||||
// #ifdef H5
|
||||
uni.setStorageSync("imGoodId", '');
|
||||
// #endif
|
||||
import { textReplaceEmoji, emojistwo } from '@/utils/emojis.js'
|
||||
|
||||
if (this.socketOpen == true) {
|
||||
uni.closeSocket();
|
||||
}
|
||||
},
|
||||
onLoad (options) {
|
||||
// 没有goodsid则不显示 发送商品弹窗
|
||||
this.showHideModel = options.goodsid
|
||||
// 发送后刷新页面不显示 发送商品弹窗 local里面imGoodId不为空显示
|
||||
// #ifdef H5
|
||||
this.localImGoodsId = uni.getStorageSync("imGoodId");
|
||||
// #endif
|
||||
this.resolve = options
|
||||
// 请求商品信息
|
||||
if (this.resolve.goodsid) {
|
||||
this.commodityDetails()
|
||||
}
|
||||
|
||||
var query = uni.getSystemInfoSync()
|
||||
// rpx和px的比率
|
||||
let l: number
|
||||
// 可用窗口高度
|
||||
let wh: number
|
||||
// 顶部空盒子的高度
|
||||
let mgUpHeight: number
|
||||
|
||||
l = query.screenWidth / 750
|
||||
wh = query.windowHeight
|
||||
this.scrollHeight = (query.windowHeight - 44) + "px"
|
||||
this.user = storage.getUserInfo()
|
||||
this.toUser = storage.getTalkToUser()
|
||||
const { proxy } = getCurrentInstance()!
|
||||
|
||||
if (options.talkId) {
|
||||
this.params.talkId = options.talkId;
|
||||
this.getTalkMessage()
|
||||
} else {
|
||||
this.getTalk(options.userId)
|
||||
const socketOpen = ref(false)
|
||||
const showHideModel = ref<string | undefined>(undefined)
|
||||
const localImGoodsId = ref('')
|
||||
const showHide = ref(true)
|
||||
const anData = ref<Record<string, any>>({})
|
||||
const animationData = ref<Record<string, any>>({})
|
||||
const msgList = ref<any[]>([])
|
||||
const oldHeight = ref(0)
|
||||
const params = ref({
|
||||
talkId: '',
|
||||
pageSize: 10,
|
||||
pageNumber: 1,
|
||||
})
|
||||
const msg = ref('')
|
||||
const go = ref(0)
|
||||
const user = ref<Record<string, any>>({})
|
||||
const toUser = ref<Record<string, any>>({})
|
||||
const scrollHeight = ref(0)
|
||||
const ws = new SocketService()
|
||||
const resolve = ref<Record<string, any>>({})
|
||||
const goodListData = ref<Record<string, any>>({})
|
||||
const reconnectCount = ref(0)
|
||||
const inputHeight = ref(0)
|
||||
const isShow = ref(false)
|
||||
|
||||
}
|
||||
|
||||
// this.ws.connect();
|
||||
this.socket();
|
||||
},
|
||||
|
||||
|
||||
|
||||
|
||||
// 页面隐藏
|
||||
onHide () {
|
||||
uni.closeSocket();
|
||||
},
|
||||
onUnload () {
|
||||
uni.closeSocket();
|
||||
},
|
||||
onPullDownRefresh () {
|
||||
this.params.pageNumber = this.params.pageNumber + 1
|
||||
this.getTalkMessage()
|
||||
setTimeout(function () {
|
||||
uni.stopPullDownRefresh();
|
||||
}, 1000);
|
||||
},
|
||||
|
||||
data () {
|
||||
return {
|
||||
textReplaceEmoji,
|
||||
emojistwo,
|
||||
socketOpen: false, //是否连接
|
||||
storage,
|
||||
fixed: 'fixed',
|
||||
bottom: '50px',
|
||||
width: '100%',
|
||||
showHideModel: undefined,
|
||||
localImGoodsId: '',
|
||||
showHide: true,
|
||||
msgLoad: false,
|
||||
anData: {},
|
||||
animationData: {},
|
||||
msgList: [],
|
||||
oldHeight: 0,
|
||||
params: { //搜索条件
|
||||
talkId: '',
|
||||
pageSize: 10,
|
||||
pageNumber: 1,
|
||||
},
|
||||
goToIndex: 0, // 前往位置
|
||||
msg: "",
|
||||
go: 0,
|
||||
newMessageNum: 0,
|
||||
user: {},
|
||||
toUser: {},
|
||||
scrollHeight: 0,
|
||||
ws: new SocketService(),
|
||||
resolve: {},
|
||||
goodListData: {},
|
||||
count: 0, //判断socket断开连接请求次数
|
||||
inputHeight:0,
|
||||
isShow:false,
|
||||
|
||||
|
||||
}
|
||||
},
|
||||
onPageScroll (e) {
|
||||
|
||||
// #ifdef APP-PLUS
|
||||
uni.hideKeyboard()
|
||||
this.isShow = false
|
||||
// #endif
|
||||
},
|
||||
methods: {
|
||||
navigateToBottom(){
|
||||
// #ifdef H5
|
||||
this.isShow = true
|
||||
this.$refs.inputRef.focus()
|
||||
// #endif
|
||||
|
||||
// #ifdef APP-PLUS
|
||||
this.$nextTick(() => {
|
||||
uni.pageScrollTo({
|
||||
scrollTop: 5000000,
|
||||
duration: 50,
|
||||
success: () => {
|
||||
setTimeout(() => {
|
||||
this.isShow = true
|
||||
}, 200);
|
||||
;
|
||||
},
|
||||
fail: () => { },
|
||||
complete: () => {}
|
||||
});
|
||||
});
|
||||
// #endif
|
||||
|
||||
},
|
||||
|
||||
eventHandle(){
|
||||
|
||||
this.inputHeight = 0
|
||||
this.isShow = false
|
||||
},
|
||||
inputBindFocus(e){
|
||||
if (e.detail.height) {
|
||||
|
||||
|
||||
// #ifdef APP-PLUS
|
||||
// 判断是否是ios
|
||||
if (uni.getSystemInfoSync().platform == 'ios') {
|
||||
this.inputHeight = e.detail.height - 40 //这个高度就是软键盘的高度
|
||||
}else{
|
||||
this.inputHeight = e.detail.height
|
||||
}
|
||||
// #endif
|
||||
|
||||
// #ifndef APP-PLUS
|
||||
this.inputHeight = e.detail.height //这个高度就是软键盘的高度
|
||||
// #endif
|
||||
}
|
||||
},
|
||||
sendMessage () {
|
||||
if (this.msg == "") {
|
||||
return 0;
|
||||
}
|
||||
if (this.socketOpen == false) {
|
||||
return
|
||||
}
|
||||
let msg = {
|
||||
operation_type: "MESSAGE",
|
||||
to: this.toUser.userId,
|
||||
from: this.user.id,
|
||||
message_type: "MESSAGE",
|
||||
context: this.msg,
|
||||
talk_id: this.params.talkId,
|
||||
}
|
||||
let data = JSON.stringify(msg);
|
||||
uni.sendSocketMessage({
|
||||
data: data,
|
||||
});
|
||||
this.msgList.push({
|
||||
"text": this.msg,
|
||||
"my": true,
|
||||
"messageType": 'MESSAGE'
|
||||
})
|
||||
let type = 'down';
|
||||
this.msgGo(type)
|
||||
this.msg = ""
|
||||
},
|
||||
sendGoodsMessage () {
|
||||
let msg = {
|
||||
operation_type: "MESSAGE",
|
||||
to: this.toUser.userId,
|
||||
from: this.user.id,
|
||||
message_type: "GOODS",
|
||||
context: this.goodListData,
|
||||
talk_id: this.params.talkId,
|
||||
}
|
||||
let data = JSON.stringify(msg);
|
||||
uni.sendSocketMessage({
|
||||
data: data
|
||||
});
|
||||
this.msgList.push({
|
||||
"text": JSON.stringify(this.goodListData),
|
||||
"my": true,
|
||||
"messageType": 'GOODS'
|
||||
})
|
||||
this.showHide = false
|
||||
// #ifdef H5
|
||||
uni.setStorageSync("imGoodId", 1111111);
|
||||
// #endif
|
||||
this.$nextTick(() => {
|
||||
uni.pageScrollTo({
|
||||
scrollTop: 2000000,
|
||||
duration: 300
|
||||
});
|
||||
})
|
||||
},
|
||||
socket () {
|
||||
var _this = this;
|
||||
uni.closeSocket();
|
||||
this.socketOpen = false;
|
||||
try {
|
||||
//WebSocket的地址
|
||||
var url = config.baseWsUrl + '/' + storage.getAccessToken();
|
||||
// 连接
|
||||
uni.connectSocket({
|
||||
url: url,
|
||||
});
|
||||
// 监听WebSocket连接已打开
|
||||
uni.onSocketOpen(function (res) {
|
||||
_this.socketOpen = true;
|
||||
});
|
||||
if (!this.socketOpen) {
|
||||
// 监听连接失败
|
||||
|
||||
uni.onSocketError(function (err) {
|
||||
if (this.count < 3) {
|
||||
if (err && err.code != 1000) {
|
||||
_this.socketOpen = true;
|
||||
setTimeout(() => {
|
||||
uni.connectSocket({
|
||||
url: url,
|
||||
});
|
||||
}, 2000)
|
||||
}
|
||||
} else {
|
||||
uni.closeSocket();
|
||||
}
|
||||
this.count++
|
||||
});
|
||||
}
|
||||
// 监听收到信息
|
||||
uni.onSocketMessage(function (res) {
|
||||
res.data = JSON.parse(res.data)
|
||||
console.log(res.data.result);
|
||||
if (res.data.messageResultType == 'MESSAGE') {
|
||||
_this.msgList.push(res.data.result)
|
||||
console.log(_this.msgList)
|
||||
}
|
||||
console.log(res.data)
|
||||
_this.msgGo()
|
||||
})
|
||||
} catch (e) {
|
||||
uni.closeSocket();
|
||||
}
|
||||
// 监听是否断线,断线进行重新连接
|
||||
uni.onSocketClose((res) => {
|
||||
if (res.code != null && res.code != 1000) {
|
||||
this.socket()
|
||||
}
|
||||
})
|
||||
},
|
||||
beautifyTime,
|
||||
//订单详情
|
||||
linkTosOrders (val) {
|
||||
let order = JSON.parse(val)
|
||||
uni.navigateTo({
|
||||
url: '/pages/order/orderDetail?sn=' + order.sn,
|
||||
});
|
||||
|
||||
},
|
||||
// 跳转商品详情页
|
||||
jumpGoodDesc (item) {
|
||||
let info = JSON.parse(item.text)
|
||||
uni.navigateTo({
|
||||
url: `/pages/product/goods?id=${info.id}&goodsId=${info.goodsId}`,
|
||||
});
|
||||
},
|
||||
|
||||
//取消发送
|
||||
cancelModel () {
|
||||
this.showHide = false
|
||||
},
|
||||
// 请求商品详情
|
||||
commodityDetails () {
|
||||
jumpObtain(this.resolve.skuid, this.resolve.goodsid).then((res) => {
|
||||
this.goodListData = res.data.result.data
|
||||
})
|
||||
},
|
||||
// 切换输入法时移动输入框(按照官方的上推页面的原理应该会自动适应不同的键盘高度-->官方bug)
|
||||
goPag (kh) {
|
||||
this.retractBox(0, 250)
|
||||
if (this.keyHeight != 0) {
|
||||
if (kh - this.keyHeight > 0) {
|
||||
this.retractBox(this.keyHeight - kh, 250)
|
||||
}
|
||||
}
|
||||
},
|
||||
// 移动顶部的空盒子
|
||||
messageBoxMove (x, t) {
|
||||
var animation = uni.createAnimation({
|
||||
duration: t,
|
||||
timingFunction: 'linear',
|
||||
})
|
||||
this.animation = animation
|
||||
animation.height(x).step()
|
||||
this.anData = animation.export()
|
||||
},
|
||||
// 保持消息体可见
|
||||
msgGo (type) {
|
||||
const query = uni.createSelectorQuery()
|
||||
// 延时100ms保证是最新的高度
|
||||
setTimeout(() => {
|
||||
// 获取消息体高度
|
||||
query.select('#msgList').boundingClientRect(data => {
|
||||
// 如果超过scorll高度就滚动scorll
|
||||
if (type == 'up') {
|
||||
this.go = data.height - this.oldHeight
|
||||
} else if (type == 'down') {
|
||||
this.go = data.height - wh + 120
|
||||
}
|
||||
// if (this.oldHeight > 0) {
|
||||
// this.go = data.height - this.oldHeight
|
||||
// } else {
|
||||
// // if (data.height - (wh - 32) > 0) {
|
||||
// this.go = data.height - wh + 120
|
||||
// }
|
||||
// 保证键盘第一次拉起时消息体能保持可见
|
||||
var moveY = wh - data.height
|
||||
// 超出页面则缩回空盒子
|
||||
if (moveY - mgUpHeight < 0) {
|
||||
// 小于0则视为0
|
||||
if (moveY < 0) {
|
||||
this.messageBoxMove(0, 200)
|
||||
} else {
|
||||
// 否则缩回盒子对应的高度
|
||||
this.messageBoxMove(moveY, 200)
|
||||
}
|
||||
}
|
||||
uni.pageScrollTo({
|
||||
scrollTop: this.go,
|
||||
duration: 0
|
||||
})
|
||||
this.oldHeight = data.height
|
||||
}).exec();
|
||||
}, 100)
|
||||
},
|
||||
// 回答问题的业务逻辑
|
||||
answer (id) {
|
||||
// 这里应该传入问题的id,模拟就用index代替了
|
||||
|
||||
},
|
||||
// 不建议输入框聚焦时操作此动画
|
||||
ckAdd () {
|
||||
if (!this.showTow) {
|
||||
this.retractBox(-180, 350)
|
||||
} else {
|
||||
this.retractBox(0, 200)
|
||||
}
|
||||
this.showTow = !this.showTow
|
||||
},
|
||||
hideKey () {
|
||||
uni.hideKeyboard()
|
||||
},
|
||||
// 拉起/收回附加栏
|
||||
retractBox (x, t) {
|
||||
var animation = uni.createAnimation({
|
||||
duration: t,
|
||||
timingFunction: 'ease',
|
||||
})
|
||||
this.animation = animation
|
||||
animation.translateY(x).step()
|
||||
this.animationData = animation.export()
|
||||
},
|
||||
async getTalkMessage () {
|
||||
let type = '';
|
||||
await getTalkMessage(this.params).then(res => {
|
||||
if (res.data.success) {
|
||||
if (this.msgList.length >= 10) {
|
||||
this.msgList.unshift(...res.data.result)
|
||||
type = 'up'
|
||||
} else {
|
||||
this.msgList.unshift(...res.data.result)
|
||||
type = 'down'
|
||||
}
|
||||
this.msgList.forEach(item => {
|
||||
if (item.fromUser === this.user.id) {
|
||||
item.my = true
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
console.log(this.msgList);
|
||||
this.msgGo(type)
|
||||
},
|
||||
// 上拉加载
|
||||
touchMoreMessage (e) {
|
||||
if (e.target.scrollTop == 0) {
|
||||
this.params.pageNumber = this.params.pageNumber + 1
|
||||
this.getTalkMessage()
|
||||
}
|
||||
},
|
||||
async getTalk (userId) {
|
||||
getTalkByUser(userId).then(res => {
|
||||
if (res.data.success) {
|
||||
this.toUser = res.data.result
|
||||
this.params.talkId = res.data.result.id
|
||||
this.getTalkMessage()
|
||||
}
|
||||
})
|
||||
},
|
||||
// 处理消息时间是否显示
|
||||
compareTime (index, datetime) {
|
||||
if (datetime == undefined) {
|
||||
return false;
|
||||
}
|
||||
if (typeof datetime == "number") {
|
||||
datetime = this.unixToDate(datetime, "yyyy-MM-dd hh:mm");
|
||||
}
|
||||
|
||||
if (this.msgList[index].is_revoke == 1) {
|
||||
return false;
|
||||
}
|
||||
if (datetime) {
|
||||
datetime = datetime.replace(/-/g, "/");
|
||||
}
|
||||
|
||||
let time = Math.floor(Date.parse(datetime) / 1000);
|
||||
let currTime = Math.floor(new Date().getTime() / 1000);
|
||||
|
||||
// 当前时间5分钟内时间不显示
|
||||
if (currTime - time < 300) return false;
|
||||
// 判断是否是最后一条消息,最后一条消息默认显示时间
|
||||
if (index == this.msgList.length - 1) {
|
||||
return true;
|
||||
}
|
||||
let nextDate
|
||||
if (this.msgList[index + 1] && this.msgList[index + 1].createTime) {
|
||||
nextDate = this.msgList[index + 1].createTime.replace(/-/g, "/");
|
||||
if (nextDate - datetime < 300) return false;
|
||||
}
|
||||
|
||||
return !(
|
||||
this.unixToDate(new Date(datetime), "{y}-{m}-{d} {h}:{i}") ==
|
||||
this.unixToDate(new Date(nextDate), "{y}-{m}-{d} {h}:{i}")
|
||||
);
|
||||
},
|
||||
|
||||
/**
|
||||
* 将unix时间戳转换为指定格式
|
||||
* @param unix 时间戳【秒】
|
||||
* @param format 转换格式
|
||||
* @returns {*|string}
|
||||
*/
|
||||
unixToDate (unix, format) {
|
||||
if (!unix) return unix;
|
||||
let _format = format || "yyyy-MM-dd hh:mm:ss";
|
||||
const d = new Date(unix);
|
||||
const o = {
|
||||
"M+": d.getMonth() + 1,
|
||||
"d+": d.getDate(),
|
||||
"h+": d.getHours(),
|
||||
"m+": d.getMinutes(),
|
||||
"s+": d.getSeconds(),
|
||||
"q+": Math.floor((d.getMonth() + 3) / 3),
|
||||
S: d.getMilliseconds(),
|
||||
};
|
||||
if (/(y+)/.test(_format))
|
||||
_format = _format.replace(
|
||||
RegExp.$1,
|
||||
(d.getFullYear() + "").substr(4 - RegExp.$1.length)
|
||||
);
|
||||
for (const k in o)
|
||||
if (new RegExp("(" + k + ")").test(_format))
|
||||
_format = _format.replace(
|
||||
RegExp.$1,
|
||||
RegExp.$1.length === 1 ?
|
||||
o[k] :
|
||||
("00" + o[k]).substr(("" + o[k]).length)
|
||||
);
|
||||
return _format;
|
||||
},
|
||||
onLoad((options: Record<string, string | undefined> = {}) => {
|
||||
showHideModel.value = options.goodsid
|
||||
// #ifdef H5
|
||||
localImGoodsId.value = uni.getStorageSync('imGoodId')
|
||||
// #endif
|
||||
resolve.value = options
|
||||
if (resolve.value.goodsid) {
|
||||
commodityDetails()
|
||||
}
|
||||
|
||||
const query = uni.getSystemInfoSync()
|
||||
l = query.screenWidth / 750
|
||||
wh = query.windowHeight
|
||||
scrollHeight.value = query.windowHeight - 44 + 'px'
|
||||
user.value = storage.getUserInfo()
|
||||
toUser.value = storage.getTalkToUser()
|
||||
|
||||
if (options.talkId) {
|
||||
params.value.talkId = options.talkId
|
||||
fetchTalkMessages()
|
||||
} else {
|
||||
getTalk(options.userId!)
|
||||
}
|
||||
|
||||
socket()
|
||||
})
|
||||
|
||||
onHide(() => {
|
||||
uni.closeSocket()
|
||||
})
|
||||
|
||||
onUnload(() => {
|
||||
// #ifdef H5
|
||||
uni.setStorageSync('imGoodId', '')
|
||||
// #endif
|
||||
uni.closeSocket()
|
||||
})
|
||||
|
||||
onPullDownRefresh(() => {
|
||||
params.value.pageNumber = params.value.pageNumber + 1
|
||||
fetchTalkMessages()
|
||||
setTimeout(() => {
|
||||
uni.stopPullDownRefresh()
|
||||
}, 1000)
|
||||
})
|
||||
|
||||
onPageScroll(() => {
|
||||
// #ifdef APP-PLUS
|
||||
uni.hideKeyboard()
|
||||
isShow.value = false
|
||||
// #endif
|
||||
})
|
||||
|
||||
function navigateToBottom() {
|
||||
// #ifdef H5
|
||||
isShow.value = true
|
||||
;(proxy as any).$refs.inputRef?.focus()
|
||||
// #endif
|
||||
|
||||
// #ifdef APP-PLUS
|
||||
nextTick(() => {
|
||||
uni.pageScrollTo({
|
||||
scrollTop: 5000000,
|
||||
duration: 50,
|
||||
success: () => {
|
||||
setTimeout(() => {
|
||||
isShow.value = true
|
||||
}, 200)
|
||||
},
|
||||
fail: () => {},
|
||||
complete: () => {},
|
||||
})
|
||||
})
|
||||
// #endif
|
||||
}
|
||||
|
||||
function eventHandle() {
|
||||
inputHeight.value = 0
|
||||
isShow.value = false
|
||||
}
|
||||
|
||||
function inputBindFocus(e: any) {
|
||||
if (e.detail.height) {
|
||||
// #ifdef APP-PLUS
|
||||
if (uni.getSystemInfoSync().platform == 'ios') {
|
||||
inputHeight.value = e.detail.height - 40
|
||||
} else {
|
||||
inputHeight.value = e.detail.height
|
||||
}
|
||||
// #endif
|
||||
|
||||
// #ifndef APP-PLUS
|
||||
inputHeight.value = e.detail.height
|
||||
// #endif
|
||||
}
|
||||
}
|
||||
|
||||
function sendMessage() {
|
||||
if (msg.value == '') {
|
||||
return 0
|
||||
}
|
||||
if (socketOpen.value == false) {
|
||||
return
|
||||
}
|
||||
const payload = {
|
||||
operation_type: 'MESSAGE',
|
||||
to: toUser.value.userId,
|
||||
from: user.value.id,
|
||||
message_type: 'MESSAGE',
|
||||
context: msg.value,
|
||||
talk_id: params.value.talkId,
|
||||
}
|
||||
const data = JSON.stringify(payload)
|
||||
uni.sendSocketMessage({
|
||||
data: data,
|
||||
})
|
||||
msgList.value.push({
|
||||
text: msg.value,
|
||||
my: true,
|
||||
messageType: 'MESSAGE',
|
||||
})
|
||||
const type = 'down'
|
||||
msgGo(type)
|
||||
msg.value = ''
|
||||
}
|
||||
|
||||
function sendGoodsMessage() {
|
||||
const payload = {
|
||||
operation_type: 'MESSAGE',
|
||||
to: toUser.value.userId,
|
||||
from: user.value.id,
|
||||
message_type: 'GOODS',
|
||||
context: goodListData.value,
|
||||
talk_id: params.value.talkId,
|
||||
}
|
||||
const data = JSON.stringify(payload)
|
||||
uni.sendSocketMessage({
|
||||
data: data,
|
||||
})
|
||||
msgList.value.push({
|
||||
text: JSON.stringify(goodListData.value),
|
||||
my: true,
|
||||
messageType: 'GOODS',
|
||||
})
|
||||
showHide.value = false
|
||||
// #ifdef H5
|
||||
uni.setStorageSync('imGoodId', 1111111)
|
||||
// #endif
|
||||
nextTick(() => {
|
||||
uni.pageScrollTo({
|
||||
scrollTop: 2000000,
|
||||
duration: 300,
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
function socket() {
|
||||
uni.closeSocket()
|
||||
socketOpen.value = false
|
||||
try {
|
||||
const url = config.baseWsUrl + '/' + storage.getAccessToken()
|
||||
uni.connectSocket({
|
||||
url: url,
|
||||
})
|
||||
uni.onSocketOpen(function () {
|
||||
socketOpen.value = true
|
||||
})
|
||||
if (!socketOpen.value) {
|
||||
uni.onSocketError(function (err: any) {
|
||||
if (reconnectCount.value < 3) {
|
||||
if (err && err.code != 1000) {
|
||||
socketOpen.value = true
|
||||
setTimeout(() => {
|
||||
uni.connectSocket({
|
||||
url: url,
|
||||
})
|
||||
}, 2000)
|
||||
}
|
||||
} else {
|
||||
uni.closeSocket()
|
||||
}
|
||||
reconnectCount.value++
|
||||
})
|
||||
}
|
||||
uni.onSocketMessage(function (res) {
|
||||
const data = JSON.parse(res.data as string)
|
||||
console.log(data.result)
|
||||
if (data.messageResultType == 'MESSAGE') {
|
||||
msgList.value.push(data.result)
|
||||
console.log(msgList.value)
|
||||
}
|
||||
console.log(data)
|
||||
msgGo()
|
||||
})
|
||||
} catch (e) {
|
||||
uni.closeSocket()
|
||||
}
|
||||
uni.onSocketClose((res) => {
|
||||
if (res.code != null && res.code != 1000) {
|
||||
socket()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function linkTosOrders(val: string) {
|
||||
const order = JSON.parse(val)
|
||||
uni.navigateTo({
|
||||
url: '/pages/order/orderDetail?sn=' + order.sn,
|
||||
})
|
||||
}
|
||||
|
||||
function jumpGoodDesc(item: any) {
|
||||
const info = JSON.parse(item.text)
|
||||
uni.navigateTo({
|
||||
url: `/pages/product/goods?id=${info.id}&goodsId=${info.goodsId}`,
|
||||
})
|
||||
}
|
||||
|
||||
function cancelModel() {
|
||||
showHide.value = false
|
||||
}
|
||||
|
||||
function commodityDetails() {
|
||||
jumpObtain(resolve.value.skuid, resolve.value.goodsid).then((res) => {
|
||||
goodListData.value = res.data.result.data
|
||||
})
|
||||
}
|
||||
|
||||
function messageBoxMove(x: number, t: number) {
|
||||
const animation = uni.createAnimation({
|
||||
duration: t,
|
||||
timingFunction: 'linear',
|
||||
})
|
||||
animation.height(x).step()
|
||||
anData.value = animation.export()
|
||||
}
|
||||
|
||||
function msgGo(type?: string) {
|
||||
const query = uni.createSelectorQuery()
|
||||
setTimeout(() => {
|
||||
query
|
||||
.select('#msgList')
|
||||
.boundingClientRect((data: any) => {
|
||||
if (type == 'up') {
|
||||
go.value = data.height - oldHeight.value
|
||||
} else if (type == 'down') {
|
||||
go.value = data.height - wh + 120
|
||||
}
|
||||
const moveY = wh - data.height
|
||||
if (moveY - mgUpHeight < 0) {
|
||||
if (moveY < 0) {
|
||||
messageBoxMove(0, 200)
|
||||
} else {
|
||||
messageBoxMove(moveY, 200)
|
||||
}
|
||||
}
|
||||
uni.pageScrollTo({
|
||||
scrollTop: go.value,
|
||||
duration: 0,
|
||||
})
|
||||
oldHeight.value = data.height
|
||||
})
|
||||
.exec()
|
||||
}, 100)
|
||||
}
|
||||
|
||||
async function fetchTalkMessages() {
|
||||
let type = ''
|
||||
await fetchTalkMessageApi(params.value).then((res) => {
|
||||
if (res.data.success) {
|
||||
if (msgList.value.length >= 10) {
|
||||
msgList.value.unshift(...res.data.result)
|
||||
type = 'up'
|
||||
} else {
|
||||
msgList.value.unshift(...res.data.result)
|
||||
type = 'down'
|
||||
}
|
||||
msgList.value.forEach((item) => {
|
||||
if (item.fromUser === user.value.id) {
|
||||
item.my = true
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
console.log(msgList.value)
|
||||
msgGo(type)
|
||||
}
|
||||
|
||||
function getTalk(userId: string) {
|
||||
getTalkByUser(userId).then((res) => {
|
||||
if (res.data.success) {
|
||||
toUser.value = res.data.result
|
||||
params.value.talkId = res.data.result.id
|
||||
fetchTalkMessages()
|
||||
}
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
@@ -9,12 +9,12 @@
|
||||
:border="false"
|
||||
:auto-back="true"
|
||||
></u-navbar>
|
||||
<scroll-view class="list-scroll-content" scroll-y @scrolltolower="loadData(tabIndex)">
|
||||
<scroll-view class="list-scroll-content" scroll-y @scrolltolower="fetchTalkList">
|
||||
|
||||
<!-- 消息列表 -->
|
||||
<div class="iconBox">
|
||||
<view class="icon-list">
|
||||
<view class="icon-item" @click="cleanUnread()">
|
||||
<view class="icon-item" @click="clearUnreadMessages()">
|
||||
<div class="bag bag1">
|
||||
<u-icon name="trash" size="50" color="#fff"></u-icon>
|
||||
</div>
|
||||
@@ -28,7 +28,7 @@
|
||||
</view>
|
||||
</view>
|
||||
</div>
|
||||
<u-search class="nav-search" v-model="userName" clearabled @change="userTalkList()" placeholder="搜索用户"
|
||||
<u-search class="nav-search" v-model="userName" clearabled @change="fetchTalkList()" placeholder="搜索用户"
|
||||
:show-action="false"></u-search>
|
||||
<view class="talk-view" :key="index" v-for="(item, index) in talkList">
|
||||
<view>
|
||||
@@ -65,85 +65,80 @@
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getTalkList, clearmeaager } from "@/api/im.js";
|
||||
import storage from "@/utils/storage.js";
|
||||
import { beautifyTime } from "@/utils/filters.js"
|
||||
export default {
|
||||
data () {
|
||||
return {
|
||||
storage,
|
||||
count: {
|
||||
loadStatus: "more",
|
||||
},
|
||||
talkList: [], //聊天列表
|
||||
userName: '',
|
||||
pointData: {}, //累计获取 未输入 集合
|
||||
};
|
||||
},
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { onShow, onPullDownRefresh, onReachBottom } from '@dcloudio/uni-app'
|
||||
import { useStore } from '@/store'
|
||||
import { getTalkList, clearmeaager } from '@/api/im.js'
|
||||
import storage from '@/utils/storage.js'
|
||||
import { beautifyTime } from '@/utils/filters.js'
|
||||
|
||||
onShow () {
|
||||
this.userTalkList();
|
||||
},
|
||||
onPullDownRefresh () {
|
||||
this.userTalkList()
|
||||
console.log('下拉事件');
|
||||
setTimeout(function () {
|
||||
uni.stopPullDownRefresh();
|
||||
}, 1000);
|
||||
},
|
||||
/**
|
||||
* 触底加载
|
||||
*/
|
||||
onReachBottom () {
|
||||
this.userTalkList();
|
||||
},
|
||||
methods: {
|
||||
beautifyTime,
|
||||
onclickToTalkInfo (val) {
|
||||
storage.setTalkToUser(val)
|
||||
uni.navigateTo({
|
||||
url:
|
||||
"/pages/mine/im/index?talkId=" + val.id,
|
||||
});
|
||||
},
|
||||
/**
|
||||
* 获取聊天列表
|
||||
*/
|
||||
userTalkList () {
|
||||
let params = {
|
||||
userName: this.userName,
|
||||
}
|
||||
uni.showLoading({
|
||||
title: "加载中",
|
||||
});
|
||||
getTalkList(params).then((res) => {
|
||||
if (this.$store.state.isShowToast){ uni.hideLoading() };
|
||||
if (res.data.success) {
|
||||
this.talkList = res.data.result;
|
||||
console.log(this.talkList, 'this.talkListthis.talkList');
|
||||
}
|
||||
});
|
||||
},
|
||||
navigateTo (url) {
|
||||
uni.navigateTo({
|
||||
url,
|
||||
});
|
||||
},
|
||||
cleanUnread () {
|
||||
clearmeaager().then((res) => {
|
||||
console.log(res);
|
||||
if (res.data.code == 200) {
|
||||
this.userTalkList();
|
||||
uni.showToast({
|
||||
icon: "none",
|
||||
title: res.data.message,
|
||||
});
|
||||
}
|
||||
const store = useStore()
|
||||
|
||||
const talkList = ref<any[]>([])
|
||||
const userName = ref('')
|
||||
|
||||
onShow(() => {
|
||||
fetchTalkList()
|
||||
})
|
||||
|
||||
onPullDownRefresh(() => {
|
||||
fetchTalkList()
|
||||
console.log('下拉事件')
|
||||
setTimeout(() => {
|
||||
uni.stopPullDownRefresh()
|
||||
}, 1000)
|
||||
})
|
||||
|
||||
onReachBottom(() => {
|
||||
fetchTalkList()
|
||||
})
|
||||
|
||||
function hideLoadingIfNeeded() {
|
||||
if (store.state.isShowToast) uni.hideLoading()
|
||||
}
|
||||
|
||||
function onclickToTalkInfo(val: any) {
|
||||
storage.setTalkToUser(val)
|
||||
uni.navigateTo({
|
||||
url: '/pages/mine/im/index?talkId=' + val.id,
|
||||
})
|
||||
}
|
||||
|
||||
function fetchTalkList() {
|
||||
const params = {
|
||||
userName: userName.value,
|
||||
}
|
||||
uni.showLoading({
|
||||
title: '加载中',
|
||||
})
|
||||
getTalkList(params).then((res) => {
|
||||
hideLoadingIfNeeded()
|
||||
if (res.data.success) {
|
||||
talkList.value = res.data.result
|
||||
console.log(talkList.value, 'this.talkListthis.talkList')
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function navigateTo(url: string) {
|
||||
uni.navigateTo({
|
||||
url,
|
||||
})
|
||||
}
|
||||
|
||||
function clearUnreadMessages() {
|
||||
clearmeaager().then((res) => {
|
||||
console.log(res)
|
||||
if (res.data.code == 200) {
|
||||
fetchTalkList()
|
||||
uni.showToast({
|
||||
icon: 'none',
|
||||
title: res.data.message,
|
||||
})
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
@@ -1,183 +1,98 @@
|
||||
<template>
|
||||
<view class="container">
|
||||
<view class="list-cell b-b m-t" hover-class="cell-hover" :hover-stay-time="50">
|
||||
<u-row gutter="12" justify="start" @click="navigateTo('/pages/msgTips/sysMsg/index')">
|
||||
<u-col span="2" class="uCol" style="text-align:center;">
|
||||
<image class="img" src="/static/mine/setting.png"></image>
|
||||
</u-col>
|
||||
<u-col span="7">
|
||||
<p class="tit_title">系统消息</p>
|
||||
<p class="tit_tips">查看系统消息</p>
|
||||
</u-col>
|
||||
<u-col span="3">
|
||||
<view class="cell-more">
|
||||
<u-tag size="mini" v-if="no_read.system_num>0" shape="circle" mode="dark" type="error" :text="no_read.system_num"></u-tag>
|
||||
<span class="yticon icon-you"></span>
|
||||
</view>
|
||||
</u-col>
|
||||
</u-row>
|
||||
</view>
|
||||
<!-- <view class="list-cell b-b m-t" hover-class="cell-hover" :hover-stay-time="50">
|
||||
<u-row gutter="12" justify="start" @click="navigateTo('/pages/msgTips/packagemsg/index')">
|
||||
<u-col span="2" class="uCol" style="text-align:center;">
|
||||
<image class="img" src="/static/mine/logistics.png"></image>
|
||||
|
||||
</u-col>
|
||||
<u-col span="7">
|
||||
<p class="tit_title">物流消息</p>
|
||||
<p class="tit_tips">查看物流消息</p>
|
||||
</u-col>
|
||||
<u-col span="3">
|
||||
<view class="cell-more">
|
||||
|
||||
<u-tag v-if="no_read.logistics_num>0" shape="circle" mode="dark" type="warning" :text="no_read.logistics_num"></u-tag>
|
||||
<span class="yticon icon-you"></span>
|
||||
</view>
|
||||
</u-col>
|
||||
</u-row>
|
||||
</view> -->
|
||||
</view>
|
||||
<view class="container">
|
||||
<view class="list-cell b-b m-t" hover-class="cell-hover" :hover-stay-time="50">
|
||||
<u-row gutter="12" justify="start" @click="navigateTo('/pages/mine/msgTips/sysMsg/index')">
|
||||
<u-col span="2" class="uCol" style="text-align: center">
|
||||
<image class="img" src="/static/mine/setting.png"></image>
|
||||
</u-col>
|
||||
<u-col span="7">
|
||||
<p class="tit_title">系统消息</p>
|
||||
<p class="tit_tips">查看系统消息</p>
|
||||
</u-col>
|
||||
<u-col span="3">
|
||||
<view class="cell-more">
|
||||
<u-tag
|
||||
size="mini"
|
||||
v-if="unreadCount.system_num > 0"
|
||||
shape="circle"
|
||||
mode="dark"
|
||||
type="error"
|
||||
:text="String(unreadCount.system_num)"
|
||||
></u-tag>
|
||||
<span class="yticon icon-you"></span>
|
||||
</view>
|
||||
</u-col>
|
||||
</u-row>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
mapMutations
|
||||
} from "vuex";
|
||||
import * as API_Message from "@/api/members.js";
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
no_read: ''
|
||||
};
|
||||
},
|
||||
onLoad() {
|
||||
this.GET_NoReadMessageNum();
|
||||
},
|
||||
methods: {
|
||||
...mapMutations(["logout"]),
|
||||
navigateTo(url) {
|
||||
uni.navigateTo({
|
||||
url
|
||||
});
|
||||
},
|
||||
/** 获取未读消息数量信息 */
|
||||
GET_NoReadMessageNum() {
|
||||
API_Message.getNoReadMessageNum().then(response => {
|
||||
this.no_read = response.data
|
||||
})
|
||||
}
|
||||
}
|
||||
};
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { onLoad } from '@dcloudio/uni-app'
|
||||
import { getNoReadMessageNum } from '@/api/members.js'
|
||||
|
||||
const unreadCount = ref<Record<string, number>>({ system_num: 0 })
|
||||
|
||||
onLoad(() => {
|
||||
fetchUnreadCount()
|
||||
})
|
||||
|
||||
function navigateTo(url: string) {
|
||||
uni.navigateTo({ url })
|
||||
}
|
||||
|
||||
function fetchUnreadCount() {
|
||||
getNoReadMessageNum().then((response) => {
|
||||
unreadCount.value = response.data || { system_num: 0 }
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang='scss'>
|
||||
.uCol {
|
||||
display: flex;
|
||||
justify-content: center !important;
|
||||
}
|
||||
|
||||
.img {
|
||||
width: 60rpx;
|
||||
height: 60rpx;
|
||||
|
||||
}
|
||||
|
||||
.container {
|
||||
background: #f9f9f9;
|
||||
}
|
||||
|
||||
::v-deep .u-col-2 {
|
||||
height: 60px;
|
||||
line-height: 60px;
|
||||
text-align: center !important;
|
||||
|
||||
}
|
||||
|
||||
.qicon {
|
||||
text-align: center;
|
||||
display: block;
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.redBox {
|
||||
display: inline-block;
|
||||
text-align: center;
|
||||
line-height: 1.5em;
|
||||
font-size: 12px;
|
||||
min-width: 1.5em;
|
||||
min-height: 1.5em;
|
||||
|
||||
background: #ed6533;
|
||||
border-radius: 50%;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.tit_title {
|
||||
color: $u-main-color;
|
||||
}
|
||||
|
||||
.tit_tips {
|
||||
color: $u-tips-color;
|
||||
}
|
||||
|
||||
.u-col-3 {
|
||||
text-align: right !important;
|
||||
padding-right: 20rpx !important;
|
||||
}
|
||||
|
||||
.list-cell {
|
||||
background: #fff;
|
||||
align-items: baseline;
|
||||
padding: 20rpx 0;
|
||||
line-height: 60rpx;
|
||||
|
||||
background: #fff;
|
||||
justify-content: center;
|
||||
|
||||
&.log-out-btn {
|
||||
margin-top: 40rpx;
|
||||
|
||||
.cell-tit {
|
||||
color: $uni-color-primary;
|
||||
text-align: center;
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&.cell-hover {
|
||||
background: #fafafa;
|
||||
}
|
||||
|
||||
&.b-b:after {
|
||||
left: 30rpx;
|
||||
}
|
||||
|
||||
&.m-t {
|
||||
margin-top: 16rpx;
|
||||
}
|
||||
|
||||
.cell-more {
|
||||
/* margin-top: 10rpx; */
|
||||
height: 60rpx;
|
||||
text-align: right;
|
||||
/* display: flex;
|
||||
justify-content: center; //这个是X轴居中
|
||||
align-items: center; //这个是 Y轴居中 */
|
||||
font-size: $font-lg;
|
||||
color: $font-color-light;
|
||||
/* width: 100rpx; */
|
||||
}
|
||||
|
||||
.cell-tit {
|
||||
flex: 1;
|
||||
font-size: $font-base + 2rpx;
|
||||
color: $font-color-dark;
|
||||
margin-right: 10rpx;
|
||||
}
|
||||
|
||||
.cell-tip {
|
||||
font-size: $font-base;
|
||||
color: $font-color-light;
|
||||
}
|
||||
}
|
||||
<style scoped lang="scss">
|
||||
.uCol {
|
||||
display: flex;
|
||||
justify-content: center !important;
|
||||
}
|
||||
.img {
|
||||
width: 60rpx;
|
||||
height: 60rpx;
|
||||
}
|
||||
.container {
|
||||
background: #f9f9f9;
|
||||
}
|
||||
::v-deep .u-col-2 {
|
||||
height: 60px;
|
||||
line-height: 60px;
|
||||
text-align: center !important;
|
||||
}
|
||||
.tit_title {
|
||||
color: $u-main-color;
|
||||
}
|
||||
.tit_tips {
|
||||
color: $u-tips-color;
|
||||
}
|
||||
.u-col-3 {
|
||||
text-align: right !important;
|
||||
padding-right: 20rpx !important;
|
||||
}
|
||||
.list-cell {
|
||||
background: #fff;
|
||||
align-items: baseline;
|
||||
padding: 20rpx 0;
|
||||
line-height: 60rpx;
|
||||
justify-content: center;
|
||||
&.cell-hover {
|
||||
background: #fafafa;
|
||||
}
|
||||
&.m-t {
|
||||
margin-top: 16rpx;
|
||||
}
|
||||
.cell-more {
|
||||
height: 60rpx;
|
||||
text-align: right;
|
||||
font-size: $font-lg;
|
||||
color: $font-color-light;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,99 +1,113 @@
|
||||
<template>
|
||||
<view class="container " style="font-size: 13px;">
|
||||
<block v-for="(row, index) in messageList" :key="index">
|
||||
<view class="msgItem">
|
||||
<div class="msgMsg">
|
||||
<div class="bagbar">{{$u.timeFormat(row.send_time, 'yyyy-mm-dd')}}</div>
|
||||
</div>
|
||||
<u-card @click="goDetail(row.sn,row.logi_id,row.ship_no)" :title="title" title-color="#666666" title-size="24" sub-title-color="#666666" sub-title-size="24" :border="false" :sub-title=row.status>
|
||||
<template #body>
|
||||
<view class="msg-body">
|
||||
<image class="msgImg" :src="row.goods_img" mode=""></image>
|
||||
<view class="msgView">
|
||||
<view>{{row.goodsName}}</view>
|
||||
<view class="msgNum">订单号:{{row.sn}}</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
</u-card>
|
||||
</view>
|
||||
</block>
|
||||
<uni-load-more :status="loadStatus"></uni-load-more>
|
||||
<view class="container" style="font-size: 13px">
|
||||
<block v-for="(row, index) in messageList" :key="index">
|
||||
<view class="msgItem">
|
||||
<div class="msgMsg">
|
||||
<div class="bagbar">{{ formatSendTime(row.send_time) }}</div>
|
||||
</div>
|
||||
<u-card
|
||||
@click="navigateToLogisticsDetail(row.sn, row.logi_id, row.ship_no)"
|
||||
:title="pageTitle"
|
||||
title-color="#666666"
|
||||
title-size="24"
|
||||
sub-title-color="#666666"
|
||||
sub-title-size="24"
|
||||
:border="false"
|
||||
:sub-title="row.status"
|
||||
>
|
||||
<template #body>
|
||||
<view class="msg-body">
|
||||
<image class="msgImg" :src="row.goods_img" mode=""></image>
|
||||
<view class="msgView">
|
||||
<view>{{ row.goodsName }}</view>
|
||||
<view class="msgNum">订单号:{{ row.sn }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
</u-card>
|
||||
</view>
|
||||
</block>
|
||||
<uni-load-more :status="loadStatus"></uni-load-more>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as API_Message from "@/api/message.js";
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
messageList: [],
|
||||
title: "物流更新通知",
|
||||
subTitle: "运输中",
|
||||
loadStatus:'more',
|
||||
params: {
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
},
|
||||
loadStatus:'more'
|
||||
};
|
||||
},
|
||||
onLoad(){
|
||||
this.GET_LogisticsList(true);
|
||||
},
|
||||
onReachBottom() {
|
||||
this.params.pageNumber++
|
||||
this.GET_LogisticsList(false)
|
||||
},
|
||||
methods: {
|
||||
goDetail(sn,logi_id,ship_no){
|
||||
uni.navigateTo({
|
||||
url:'/pages/msgTips/packagemsg/logisticsDetail?order_sn=' + sn +'&logi_id='+logi_id+'&ship_no='+ship_no,
|
||||
})
|
||||
},
|
||||
//获取物流消息
|
||||
GET_LogisticsList(reset){
|
||||
if (reset) {
|
||||
this.params.pageNumber = 1
|
||||
}
|
||||
uni.showLoading({
|
||||
title:"加载中"
|
||||
})
|
||||
API_Message.getLogisticsMessages(this.params).then(async response => {
|
||||
if (this.$store.state.isShowToast){ uni.hideLoading() }
|
||||
const { data } = response
|
||||
if (!data || !data.length) {
|
||||
this.messageList.push(...data.data)
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, getCurrentInstance } from 'vue'
|
||||
import { onLoad, onReachBottom } from '@dcloudio/uni-app'
|
||||
import { useStore } from '@/store'
|
||||
import * as API_Message from '@/api/message.js'
|
||||
|
||||
const store = useStore()
|
||||
const { proxy } = getCurrentInstance()!
|
||||
|
||||
const messageList = ref<any[]>([])
|
||||
const pageTitle = '物流更新通知'
|
||||
const loadStatus = ref('more')
|
||||
const queryParams = ref({ pageNumber: 1, pageSize: 10 })
|
||||
|
||||
onLoad(() => {
|
||||
fetchLogisticsList(true)
|
||||
})
|
||||
|
||||
onReachBottom(() => {
|
||||
queryParams.value.pageNumber++
|
||||
fetchLogisticsList(false)
|
||||
})
|
||||
|
||||
function hideLoadingIfNeeded() {
|
||||
if (store.state.isShowToast) uni.hideLoading()
|
||||
}
|
||||
|
||||
function formatSendTime(time: number) {
|
||||
return proxy.$u.timeFormat(time, 'yyyy-mm-dd')
|
||||
}
|
||||
|
||||
function extractRecords(res: any) {
|
||||
if (Array.isArray(res?.result?.records)) return res.result.records
|
||||
if (Array.isArray(res?.result)) return res.result
|
||||
if (Array.isArray(res?.data)) return res.data
|
||||
return []
|
||||
}
|
||||
|
||||
function navigateToLogisticsDetail(sn: string, logiId: string, shipNo: string) {
|
||||
uni.navigateTo({
|
||||
url: `/pages/mine/msgTips/packageMsg/logisticsDetail?order_sn=${sn}&logi_id=${logiId}&ship_no=${shipNo}`,
|
||||
})
|
||||
}
|
||||
|
||||
function fetchLogisticsList(reset: boolean) {
|
||||
if (reset) {
|
||||
queryParams.value.pageNumber = 1
|
||||
messageList.value = []
|
||||
loadStatus.value = 'more'
|
||||
}
|
||||
};
|
||||
uni.showLoading({ title: '加载中' })
|
||||
API_Message.getLogisticsMessages(queryParams.value).then((response) => {
|
||||
hideLoadingIfNeeded()
|
||||
const records = extractRecords(response.data)
|
||||
if (records.length) {
|
||||
messageList.value.push(...records)
|
||||
} else {
|
||||
loadStatus.value = 'noMore'
|
||||
}
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang='scss'>
|
||||
.ddnumber {
|
||||
color: $u-tips-color;
|
||||
font-size: 24rpx;
|
||||
}
|
||||
.msg-body{
|
||||
display: flex;
|
||||
background-color: rgba(102, 110, 232, 0.0470588235294118);
|
||||
|
||||
|
||||
.msgImg{
|
||||
width: 160rpx;
|
||||
height: 160rpx;
|
||||
}
|
||||
.msgView{
|
||||
margin-left: 20rpx;
|
||||
.msgNum:last-child{
|
||||
margin-top: 60rpx;
|
||||
}
|
||||
}
|
||||
|
||||
<style scoped lang="scss">
|
||||
.msg-body {
|
||||
display: flex;
|
||||
background-color: rgba(102, 110, 232, 0.0470588235294118);
|
||||
.msgImg {
|
||||
width: 160rpx;
|
||||
height: 160rpx;
|
||||
}
|
||||
.msgView {
|
||||
margin-left: 20rpx;
|
||||
.msgNum:last-child {
|
||||
margin-top: 60rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
.bagbar {
|
||||
display: inline;
|
||||
@@ -103,13 +117,8 @@ export default {
|
||||
padding: 10rpx 20rpx;
|
||||
background: $u-info-disabled;
|
||||
}
|
||||
.storeImg {
|
||||
width: 100%;
|
||||
height: 100rpx;
|
||||
margin-right: 20rpx;
|
||||
}
|
||||
.container {
|
||||
background: #F9F9F9;
|
||||
background: #f9f9f9;
|
||||
min-height: 100vh;
|
||||
}
|
||||
.msgMsg {
|
||||
@@ -119,12 +128,8 @@ export default {
|
||||
.msgItem {
|
||||
padding: 1em 0;
|
||||
}
|
||||
view{
|
||||
font-size: 13px;
|
||||
color: #666666;
|
||||
view {
|
||||
font-size: 13px;
|
||||
color: #666666;
|
||||
}
|
||||
u-card{
|
||||
font-size: 13px;
|
||||
color: #666666;
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
||||
@@ -2,21 +2,23 @@
|
||||
<view class="logistics-detail">
|
||||
<view class="card">
|
||||
<view class="card-title">
|
||||
<span>{{ logiList.shipper }}</span>快递 <span>{{ logiList.logisticCode }}</span>
|
||||
<span>{{ logisticsInfo.shipper }}</span>快递 <span>{{ logisticsInfo.logisticCode }}</span>
|
||||
</view>
|
||||
<view class="time-line">
|
||||
<u-time-line v-if="logiList.traces && logiList.traces.length != 0">
|
||||
<u-time-line-item nodeTop="2" v-for="(item, index) in logiList.traces" :key="index">
|
||||
<!-- 此处自定义了左边内容,用一个图标替代 -->
|
||||
<template v-slot:node >
|
||||
<view v-if="index == logiList.traces.length - 1" class="u-node" :style="{ background: $lightColor }" style="padding: 0 4px">
|
||||
<!-- 此处为uView的icon组件 -->
|
||||
<u-time-line v-if="logisticsInfo.traces && logisticsInfo.traces.length != 0">
|
||||
<u-time-line-item nodeTop="2" v-for="(item, index) in logisticsInfo.traces" :key="index">
|
||||
<template #node>
|
||||
<view
|
||||
v-if="index == logisticsInfo.traces.length - 1"
|
||||
class="u-node"
|
||||
:style="{ background: lightColor }"
|
||||
style="padding: 0 4px"
|
||||
>
|
||||
<u-icon name="pushpin-fill" color="#fff" :size="24"></u-icon>
|
||||
</view>
|
||||
</template>
|
||||
<template v-slot:content>
|
||||
<template #content>
|
||||
<view>
|
||||
<!-- <view class="u-order-title">待取件</view> -->
|
||||
<view class="u-order-desc">{{ item.AcceptStation }}</view>
|
||||
<view class="u-order-time">{{ item.AcceptTime }}</view>
|
||||
</view>
|
||||
@@ -29,32 +31,26 @@
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getExpress } from "@/api/trade.js";
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
express: "",
|
||||
resData: {
|
||||
title: "物流详情",
|
||||
},
|
||||
<script setup lang="ts">
|
||||
import { ref, computed } from 'vue'
|
||||
import { onLoad } from '@dcloudio/uni-app'
|
||||
import { useStore } from '@/store'
|
||||
import { getExpress } from '@/api/trade.js'
|
||||
|
||||
logiList: "",
|
||||
activeStep: 0,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
init(sn) {
|
||||
getExpress(sn).then((res) => {
|
||||
this.logiList = res.data.result;
|
||||
});
|
||||
},
|
||||
},
|
||||
onLoad(option) {
|
||||
let sn = option.order_sn;
|
||||
this.init(sn);
|
||||
},
|
||||
};
|
||||
const store = useStore()
|
||||
|
||||
const lightColor = computed(() => store.getters.lightColor)
|
||||
const logisticsInfo = ref<Record<string, any>>({})
|
||||
|
||||
onLoad((option) => {
|
||||
fetchLogistics(option.order_sn)
|
||||
})
|
||||
|
||||
function fetchLogistics(orderSn: string) {
|
||||
getExpress(orderSn).then((res) => {
|
||||
logisticsInfo.value = res.data.result || {}
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
@@ -79,9 +75,6 @@ export default {
|
||||
padding: 16rpx 32rpx;
|
||||
}
|
||||
}
|
||||
.u-order-title {
|
||||
font-weight: bold;
|
||||
}
|
||||
.u-order-desc {
|
||||
font-size: 26rpx;
|
||||
color: #666;
|
||||
|
||||
@@ -30,20 +30,11 @@
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapMutations } from "vuex";
|
||||
export default {
|
||||
data() {
|
||||
return {};
|
||||
},
|
||||
methods: {
|
||||
...mapMutations(["logout"]),
|
||||
|
||||
}
|
||||
};
|
||||
<script setup lang="ts">
|
||||
// 占位页,后续接入客服消息
|
||||
</script>
|
||||
|
||||
<style scoped lang='scss'>
|
||||
<style scoped lang="scss">
|
||||
.msgTime {
|
||||
font-size: 13px;
|
||||
}
|
||||
@@ -56,11 +47,6 @@ page {
|
||||
vertical-align: middle;
|
||||
border-radius: 0.4em;
|
||||
}
|
||||
.qicon {
|
||||
text-align: center;
|
||||
display: block;
|
||||
font-size: 20px;
|
||||
}
|
||||
.redBox {
|
||||
padding: 10rpx 12rpx;
|
||||
display: inline-block;
|
||||
@@ -71,7 +57,6 @@ page {
|
||||
height: 1em;
|
||||
background: #ed6533;
|
||||
border-radius: 50%;
|
||||
|
||||
color: #fff;
|
||||
}
|
||||
.tit_title,
|
||||
@@ -92,25 +77,14 @@ page {
|
||||
}
|
||||
.list-cell {
|
||||
align-items: baseline;
|
||||
padding: 20rpx 30rpx;
|
||||
padding: 20rpx 30rpx;
|
||||
line-height: 60rpx;
|
||||
position: relative;
|
||||
background: #fff;
|
||||
justify-content: center;
|
||||
&.log-out-btn {
|
||||
margin-top: 40rpx;
|
||||
.cell-tit {
|
||||
color: $uni-color-primary;
|
||||
text-align: center;
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
&.cell-hover {
|
||||
background: #fafafa;
|
||||
}
|
||||
&.b-b:after {
|
||||
left: 30rpx;
|
||||
}
|
||||
&.m-t {
|
||||
margin-top: 16rpx;
|
||||
}
|
||||
@@ -119,22 +93,12 @@ page {
|
||||
margin-top: 10rpx;
|
||||
height: 60rpx;
|
||||
display: flex;
|
||||
justify-content: center; //这个是X轴居中
|
||||
align-items: center; //这个是 Y轴居中
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
align-self: baseline;
|
||||
font-size: $font-lg;
|
||||
color: $font-color-light;
|
||||
margin-left: 10rpx;
|
||||
}
|
||||
.cell-tit {
|
||||
flex: 1;
|
||||
font-size: $font-base + 2rpx;
|
||||
color: $font-color-dark;
|
||||
margin-right: 10rpx;
|
||||
}
|
||||
.cell-tip {
|
||||
font-size: $font-base;
|
||||
color: $font-color-light;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
||||
@@ -2,17 +2,15 @@
|
||||
<view class="container">
|
||||
<block v-for="(row, index) in messageList" :key="index">
|
||||
<view class="msgItem">
|
||||
<div class="is_read">
|
||||
<!-- {{row.is_read}} -->
|
||||
<span v-if="row.is_read"></span>
|
||||
<span v-else class="red">·</span>
|
||||
|
||||
</div>
|
||||
<div class="msgMsg">{{$u.timeFormat(row.send_time, 'yyyy-mm-dd')}}</div>
|
||||
<u-card :title="title" :title-size="35" :border="false">
|
||||
<div class="is_read">
|
||||
<span v-if="row.is_read"></span>
|
||||
<span v-else class="red">·</span>
|
||||
</div>
|
||||
<div class="msgMsg">{{ formatSendTime(row.send_time) }}</div>
|
||||
<u-card :title="pageTitle" :title-size="35" :border="false">
|
||||
<template #body>
|
||||
<view class="u-body-item u-flex u-row-between u-p-b-0">
|
||||
<view class="u-body-item-title u-line-2">{{row.content}}</view>
|
||||
<view class="u-body-item-title u-line-2">{{ row.content }}</view>
|
||||
</view>
|
||||
</template>
|
||||
</u-card>
|
||||
@@ -22,74 +20,85 @@
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapMutations } from "vuex";
|
||||
import * as API_Message from "@/api/message.js";
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: "系统消息",
|
||||
subTitle: "未读",
|
||||
finished: false,
|
||||
loadStatus: "more",
|
||||
params: {
|
||||
pageNumber: 0,
|
||||
pageSize: 5
|
||||
},
|
||||
messageList: []
|
||||
};
|
||||
},
|
||||
onLoad() {
|
||||
this.GET_MessageList(true);
|
||||
},
|
||||
onReachBottom() {
|
||||
this.params.pageNumber++;
|
||||
this.GET_MessageList(false);
|
||||
},
|
||||
methods: {
|
||||
...mapMutations(["logout"]),
|
||||
|
||||
/** 获取站内消息 */
|
||||
GET_MessageList(reset) {
|
||||
if (reset) {
|
||||
this.params.pageNumber = 1;
|
||||
this.messageList = [];
|
||||
}
|
||||
uni.showLoading({
|
||||
title: "加载中"
|
||||
});
|
||||
API_Message.getMessages(this.params).then(async response => {
|
||||
if (this.$store.state.isShowToast){ uni.hideLoading() };
|
||||
const { data } = response;
|
||||
if (!data || !data.length) {
|
||||
this.messageList.push(...data.data);
|
||||
this.handleReadPageMessages();
|
||||
}
|
||||
});
|
||||
},
|
||||
/** 设置消息已读 **/
|
||||
handleReadPageMessages() {
|
||||
const ids = this.messageList.map(item => item.id).join(",");
|
||||
API_Message.messageMarkAsRead(ids).then(async () => {});
|
||||
}
|
||||
<script setup lang="ts">
|
||||
import { ref, getCurrentInstance } from 'vue'
|
||||
import { onLoad, onReachBottom } from '@dcloudio/uni-app'
|
||||
import { useStore } from '@/store'
|
||||
import * as API_Message from '@/api/message.js'
|
||||
|
||||
const store = useStore()
|
||||
const { proxy } = getCurrentInstance()!
|
||||
|
||||
const pageTitle = '系统消息'
|
||||
const loadStatus = ref('more')
|
||||
const queryParams = ref({ pageNumber: 1, pageSize: 5 })
|
||||
const messageList = ref<any[]>([])
|
||||
|
||||
onLoad(() => {
|
||||
fetchMessageList(true)
|
||||
})
|
||||
|
||||
onReachBottom(() => {
|
||||
queryParams.value.pageNumber++
|
||||
fetchMessageList(false)
|
||||
})
|
||||
|
||||
function hideLoadingIfNeeded() {
|
||||
if (store.state.isShowToast) uni.hideLoading()
|
||||
}
|
||||
|
||||
function formatSendTime(time: number) {
|
||||
return proxy.$u.timeFormat(time, 'yyyy-mm-dd')
|
||||
}
|
||||
|
||||
function extractRecords(res: any) {
|
||||
if (Array.isArray(res?.result?.records)) return res.result.records
|
||||
if (Array.isArray(res?.result)) return res.result
|
||||
if (Array.isArray(res?.data)) return res.data
|
||||
return []
|
||||
}
|
||||
|
||||
function fetchMessageList(reset: boolean) {
|
||||
if (reset) {
|
||||
queryParams.value.pageNumber = 1
|
||||
messageList.value = []
|
||||
loadStatus.value = 'more'
|
||||
}
|
||||
};
|
||||
uni.showLoading({ title: '加载中' })
|
||||
API_Message.getMessages(queryParams.value).then((response) => {
|
||||
hideLoadingIfNeeded()
|
||||
const res = response.data
|
||||
const records = extractRecords(res)
|
||||
if (records.length) {
|
||||
messageList.value.push(...records)
|
||||
markPageMessagesAsRead()
|
||||
} else {
|
||||
loadStatus.value = 'noMore'
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function markPageMessagesAsRead() {
|
||||
const ids = messageList.value.map((item) => item.id).join(',')
|
||||
if (!ids) return
|
||||
API_Message.messageMarkAsRead(ids)
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang='scss'>
|
||||
.is_read{
|
||||
position: absolute;
|
||||
right: 25px;
|
||||
top: 80rpx;
|
||||
z-index: 999;
|
||||
<style scoped lang="scss">
|
||||
.is_read {
|
||||
position: absolute;
|
||||
right: 25px;
|
||||
top: 80rpx;
|
||||
z-index: 999;
|
||||
}
|
||||
.container {
|
||||
background: #f9f9f9;
|
||||
min-height: 100vh;
|
||||
}
|
||||
.red{
|
||||
color: coral;
|
||||
font-size: 100rpx;
|
||||
.red {
|
||||
color: coral;
|
||||
font-size: 100rpx;
|
||||
}
|
||||
.msgMsg {
|
||||
text-align: center;
|
||||
@@ -99,4 +108,4 @@ export default {
|
||||
padding: 1em 0;
|
||||
position: relative;
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
:activeStyle="{ color: lightColor }"
|
||||
class="collect-tabs"
|
||||
:list="navList"
|
||||
:scrollable="true"
|
||||
:scrollable="false"
|
||||
v-model:current="tabCurrentIndex"
|
||||
></u-tabs>
|
||||
</view>
|
||||
@@ -22,278 +22,238 @@
|
||||
</u-navbar>
|
||||
<view class="collect-body">
|
||||
<!-- 显示商品栏 -->
|
||||
<view v-if="tabCurrentIndex == 0" class="tab-content">
|
||||
<scroll-view class="list-scroll-content" scroll-y>
|
||||
<u-empty style="margin-top: 40rpx" text="暂无收藏商品数据" mode="favor" v-if="goodsEmpty"></u-empty>
|
||||
<template v-else>
|
||||
<u-swipe-action
|
||||
v-for="(item, index) in goodList"
|
||||
:key="index"
|
||||
class="collect-swipe"
|
||||
<view v-if="tabCurrentIndex === 0" class="tab-content">
|
||||
<u-empty style="margin-top: 40rpx" text="暂无收藏商品数据" mode="favor" v-if="goodsEmpty"></u-empty>
|
||||
<template v-else>
|
||||
<u-swipe-action
|
||||
v-for="(item, index) in goodsList"
|
||||
:key="item.skuId || item.goodsId || index"
|
||||
class="collect-swipe"
|
||||
>
|
||||
<u-swipe-action-item
|
||||
@open="openSwipeItem(item, 'goods')"
|
||||
:show="item.selected"
|
||||
:options="swipeOptions"
|
||||
@click="removeGoodsCollection(item, index)"
|
||||
:name="index"
|
||||
>
|
||||
<u-swipe-action-item
|
||||
@open="openLeftChange(item, 'goods')"
|
||||
:show="item.selected"
|
||||
:options="LeftOptions"
|
||||
@click="clickGoodsSwiperAction(item, index)"
|
||||
:name="index"
|
||||
>
|
||||
<view class="goods" @click="goGoodsDetail(item)">
|
||||
<u-image width="131rpx" height="131rpx" :src="item.image" mode="aspectFit">
|
||||
<template #loading><u-loading></u-loading></template>
|
||||
</u-image>
|
||||
<view class="goods-intro">
|
||||
<view class="goods-name">{{ item.goodsName }}</view>
|
||||
<view class="goods-sn">{{ item.goods_sn }}</view>
|
||||
<view class="goods-price">¥{{ unitPrice(item.price) }}</view>
|
||||
</view>
|
||||
<view class="goods" @click="goGoodsDetail(item)">
|
||||
<u-image width="131rpx" height="131rpx" :src="item.image" mode="aspectFit">
|
||||
<template #loading><u-loading-icon></u-loading-icon></template>
|
||||
</u-image>
|
||||
<view class="goods-intro">
|
||||
<view class="goods-name">{{ item.goodsName }}</view>
|
||||
<view class="goods-sn">{{ item.goods_sn }}</view>
|
||||
<view class="goods-price">¥{{ unitPrice(item.price) }}</view>
|
||||
</view>
|
||||
</u-swipe-action-item>
|
||||
</u-swipe-action>
|
||||
</template>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</u-swipe-action-item>
|
||||
</u-swipe-action>
|
||||
</template>
|
||||
</view>
|
||||
<!-- 显示收藏的店铺栏 -->
|
||||
<view v-else class="tab-content">
|
||||
<scroll-view class="list-scroll-content" scroll-y>
|
||||
<u-empty style="margin-top: 40rpx" text="暂无收藏店铺数据" mode="favor" v-if="storeEmpty"></u-empty>
|
||||
<template v-else>
|
||||
<u-swipe-action
|
||||
v-for="(item, index) in storeList"
|
||||
:key="index"
|
||||
class="collect-swipe"
|
||||
<u-empty style="margin-top: 40rpx" text="暂无收藏店铺数据" mode="favor" v-if="storeEmpty"></u-empty>
|
||||
<template v-else>
|
||||
<u-swipe-action
|
||||
v-for="(item, index) in storeList"
|
||||
:key="item.id || index"
|
||||
class="collect-swipe"
|
||||
>
|
||||
<u-swipe-action-item
|
||||
@open="openSwipeItem(item, 'store')"
|
||||
:show="item.selected"
|
||||
:options="swipeOptions"
|
||||
@click="removeStoreCollection(item)"
|
||||
:name="index"
|
||||
>
|
||||
<u-swipe-action-item
|
||||
@open="openLeftChange(item, 'store')"
|
||||
:show="item.selected"
|
||||
:options="LeftOptions"
|
||||
@click="clickStoreSwiperAction(item)"
|
||||
:name="index"
|
||||
>
|
||||
<view class="store" @click="goStoreMainPage(item.id)">
|
||||
<view class="intro">
|
||||
<view class="store-logo">
|
||||
<u-image width="102rpx" height="102rpx" :src="item.storeLogo" :alt="item.storeName"
|
||||
mode="aspectFit">
|
||||
<template #loading><u-loading></u-loading></template>
|
||||
</u-image>
|
||||
</view>
|
||||
<view class="store-name">
|
||||
<view>{{ item.storeName }}</view>
|
||||
<u-tag size="mini" type="error" :color="$mainColor" v-if="item.selfOperated"
|
||||
text="自营" mode="plain" shape="circle" />
|
||||
</view>
|
||||
<view class="store-collect">
|
||||
<view>进店逛逛</view>
|
||||
</view>
|
||||
<view class="store" @click="goStoreMainPage(item.id)">
|
||||
<view class="intro">
|
||||
<view class="store-logo">
|
||||
<u-image width="102rpx" height="102rpx" :src="item.storeLogo" :alt="item.storeName"
|
||||
mode="aspectFit">
|
||||
<template #loading><u-loading-icon></u-loading-icon></template>
|
||||
</u-image>
|
||||
</view>
|
||||
<view class="store-name">
|
||||
<view>{{ item.storeName }}</view>
|
||||
<u-tag size="mini" type="error" :color="mainColor" v-if="item.selfOperated"
|
||||
text="自营" mode="plain" shape="circle" />
|
||||
</view>
|
||||
<view class="store-collect">
|
||||
<view>进店逛逛</view>
|
||||
</view>
|
||||
</view>
|
||||
</u-swipe-action-item>
|
||||
</u-swipe-action>
|
||||
</template>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</u-swipe-action-item>
|
||||
</u-swipe-action>
|
||||
</template>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
getGoodsCollection,
|
||||
getStoreCollection,
|
||||
deleteGoodsCollection,
|
||||
deleteStoreCollection,
|
||||
} from "@/api/members.js";
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
lightColor:this.$lightColor,
|
||||
// 商品左滑侧边栏
|
||||
LeftOptions: [{
|
||||
text: "取消",
|
||||
style: {
|
||||
backgroundColor: this.$lightColor,
|
||||
},
|
||||
}, ],
|
||||
tabCurrentIndex: 0, //tab的下标默认为0,也就是说会默认请求商品
|
||||
navList: [
|
||||
//tab显示数据
|
||||
{
|
||||
name: "商品(0)",
|
||||
|
||||
params: {
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "店铺(0)",
|
||||
|
||||
params: {
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
},
|
||||
},
|
||||
],
|
||||
|
||||
goodsEmpty: false, //商品数据是否为空
|
||||
storeEmpty: false, //店铺数据是否为空
|
||||
goodList: [], //商品集合
|
||||
storeList: [], //店铺集合
|
||||
};
|
||||
},
|
||||
onShow() {
|
||||
this.fetchReloadOrNextPage('reload')
|
||||
},
|
||||
onReachBottom() {
|
||||
this.fetchReloadOrNextPage('next')
|
||||
},
|
||||
<script setup lang="ts">
|
||||
import { ref, computed } from 'vue'
|
||||
import { onShow, onReachBottom, onPullDownRefresh } from '@dcloudio/uni-app'
|
||||
import { useStore } from '@/store'
|
||||
import { unitPrice } from '@/utils/filters.js'
|
||||
import {
|
||||
getGoodsCollection,
|
||||
getStoreCollection,
|
||||
deleteGoodsCollection,
|
||||
deleteStoreCollection,
|
||||
} from '@/api/members.js'
|
||||
|
||||
methods: {
|
||||
// 刷新或者下一页
|
||||
fetchReloadOrNextPage(type) {
|
||||
if(type == 'next'){
|
||||
this.navList[this.tabCurrentIndex].params.pageNumber ++;
|
||||
if (this.tabCurrentIndex == 0) {
|
||||
this.getGoodList();
|
||||
} else {
|
||||
this.getStoreList();
|
||||
}
|
||||
const store = useStore()
|
||||
|
||||
const lightColor = computed(() => store.getters.lightColor)
|
||||
const mainColor = computed(() => store.getters.mainColor)
|
||||
|
||||
const swipeOptions = computed(() => [
|
||||
{
|
||||
text: '取消',
|
||||
style: { backgroundColor: lightColor.value },
|
||||
},
|
||||
])
|
||||
|
||||
const tabCurrentIndex = ref(0)
|
||||
const navList = ref([
|
||||
{ name: '商品(0)', params: { pageNumber: 1, pageSize: 10 } },
|
||||
{ name: '店铺(0)', params: { pageNumber: 1, pageSize: 10 } },
|
||||
])
|
||||
const goodsEmpty = ref(false)
|
||||
const storeEmpty = ref(false)
|
||||
const goodsList = ref<any[]>([])
|
||||
const storeList = ref<any[]>([])
|
||||
|
||||
onShow(() => {
|
||||
reloadOrLoadMore('reload')
|
||||
})
|
||||
|
||||
onReachBottom(() => {
|
||||
reloadOrLoadMore('next')
|
||||
})
|
||||
|
||||
onPullDownRefresh(() => {
|
||||
if (tabCurrentIndex.value === 0) {
|
||||
navList.value[0].params.pageNumber = 1
|
||||
goodsList.value = []
|
||||
fetchGoodsList()
|
||||
} else {
|
||||
navList.value[1].params.pageNumber = 1
|
||||
storeList.value = []
|
||||
fetchStoreList()
|
||||
}
|
||||
})
|
||||
|
||||
function hideLoadingIfNeeded() {
|
||||
if (store.state.isShowToast) uni.hideLoading()
|
||||
}
|
||||
|
||||
function reloadOrLoadMore(type: 'reload' | 'next') {
|
||||
if (type === 'next') {
|
||||
navList.value[tabCurrentIndex.value].params.pageNumber++
|
||||
if (tabCurrentIndex.value === 0) {
|
||||
fetchGoodsList()
|
||||
} else {
|
||||
fetchStoreList()
|
||||
}
|
||||
return
|
||||
}
|
||||
navList.value[0].params.pageNumber = 1
|
||||
navList.value[1].params.pageNumber = 1
|
||||
goodsEmpty.value = false
|
||||
storeEmpty.value = false
|
||||
goodsList.value = []
|
||||
storeList.value = []
|
||||
fetchGoodsList()
|
||||
fetchStoreList()
|
||||
}
|
||||
|
||||
function openSwipeItem(val: any, type: 'goods' | 'store') {
|
||||
const targetList = type === 'goods' ? goodsList.value : storeList.value
|
||||
targetList.forEach((item) => {
|
||||
item.selected = false
|
||||
})
|
||||
val.selected = true
|
||||
}
|
||||
|
||||
function removeGoodsCollection(val: any) {
|
||||
deleteGoodsCollection(val.skuId).then((res) => {
|
||||
if (res.statusCode === 200) {
|
||||
goodsList.value = []
|
||||
navList.value[0].params.pageNumber = 1
|
||||
fetchGoodsList()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function removeStoreCollection(val: any) {
|
||||
deleteStoreCollection(val.id).then((res) => {
|
||||
if (res.statusCode === 200) {
|
||||
storeList.value = []
|
||||
navList.value[1].params.pageNumber = 1
|
||||
fetchStoreList()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function goGoodsDetail(val: any) {
|
||||
uni.navigateTo({
|
||||
url: `/pages/product/goods?id=${val.skuId}&goodsId=${val.goodsId}`,
|
||||
})
|
||||
}
|
||||
|
||||
function goStoreMainPage(id: string) {
|
||||
uni.navigateTo({
|
||||
url: `/pages/product/shopPage?id=${id}`,
|
||||
})
|
||||
}
|
||||
|
||||
function fetchGoodsList() {
|
||||
uni.showLoading({ title: '加载中' })
|
||||
getGoodsCollection(navList.value[0].params, 'GOODS')
|
||||
.then((res) => {
|
||||
hideLoadingIfNeeded()
|
||||
uni.stopPullDownRefresh()
|
||||
if (res.data.success) {
|
||||
const data = res.data.result
|
||||
navList.value[0].name = `商品(${data.total})`
|
||||
goodsEmpty.value = data.total === 0
|
||||
if (data.records?.length) {
|
||||
const records = data.records.map((item: any) => ({ ...item, selected: false }))
|
||||
goodsList.value.push(...records)
|
||||
}
|
||||
else{
|
||||
this.navList[0].params.pageNumber = 1;
|
||||
this.navList[1].params.pageNumber = 1;
|
||||
this.goodList = [];
|
||||
this.storeList = [];
|
||||
this.getGoodList();
|
||||
this.getStoreList();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 打开商品左侧取消收藏
|
||||
*/
|
||||
openLeftChange(val, type) {
|
||||
const way = type === "goods" ? this.goodList : this.storeList;
|
||||
way.forEach((item) => {
|
||||
item.selected = false;
|
||||
});
|
||||
val.selected = true;
|
||||
},
|
||||
|
||||
/**
|
||||
* 点击商品左侧取消收藏
|
||||
*/
|
||||
clickGoodsSwiperAction(val) {
|
||||
deleteGoodsCollection(val.skuId).then((res) => {
|
||||
if (res.statusCode == 200) {
|
||||
this.storeList = [];
|
||||
this.goodList = [];
|
||||
this.getGoodList();
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 点击店铺左侧取消收藏
|
||||
*/
|
||||
clickStoreSwiperAction(val) {
|
||||
deleteStoreCollection(val.id).then((res) => {
|
||||
if (res.statusCode == 200) {
|
||||
this.storeList = [];
|
||||
this.getStoreList();
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 查看商品详情
|
||||
*/
|
||||
goGoodsDetail(val) {
|
||||
//商品详情
|
||||
uni.navigateTo({
|
||||
url: "/pages/product/goods?id=" + val.skuId + "&goodsId=" + val.goodsId,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 查看店铺详情
|
||||
*/
|
||||
goStoreMainPage(id) {
|
||||
//店铺主页
|
||||
uni.navigateTo({
|
||||
url: "/pages/product/shopPage?id=" + id,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取商品集合
|
||||
*/
|
||||
getGoodList() {
|
||||
uni.showLoading({
|
||||
title: "加载中",
|
||||
});
|
||||
getGoodsCollection(this.navList[0].params, "GOODS").then((res) => {
|
||||
if (this.$store.state.isShowToast){ uni.hideLoading() };
|
||||
uni.stopPullDownRefresh();
|
||||
if (res.data.success) {
|
||||
let data = res.data.result;
|
||||
data.selected = false;
|
||||
this.navList[0].name = `商品(${data.total})`;
|
||||
|
||||
if (data.total == 0) {
|
||||
this.goodsEmpty = true;
|
||||
} else if (data.total < 10) {
|
||||
this.goodsLoad = "noMore";
|
||||
this.goodList.push(...data.records);
|
||||
} else {
|
||||
this.goodList.push(...data.records);
|
||||
if (data.total.length < 10) this.goodsLoad = "noMore";
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取店铺集合
|
||||
*/
|
||||
getStoreList() {
|
||||
uni.showLoading({
|
||||
title: "加载中",
|
||||
});
|
||||
getStoreCollection(this.navList[1].params, "STORE").then((res) => {
|
||||
if (this.$store.state.isShowToast){ uni.hideLoading() };
|
||||
uni.stopPullDownRefresh();
|
||||
if (res.data.success) {
|
||||
let data = res.data.result;
|
||||
data.selected = false;
|
||||
this.navList[1].name = `店铺(${data.total})`;
|
||||
if (data.total == 0) {
|
||||
this.storeEmpty = true;
|
||||
} else if (data.total < 10) {
|
||||
|
||||
this.storeList.push(...data.records);
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
},
|
||||
|
||||
/**
|
||||
* 下拉刷新时
|
||||
*/
|
||||
onPullDownRefresh() {
|
||||
if (this.tabCurrentIndex == 0) {
|
||||
this.navList[0].params.pageNumber = 1;
|
||||
this.goodList = [];
|
||||
this.getGoodList();
|
||||
} else {
|
||||
this.navList[1].params.pageNumber = 1;
|
||||
this.storeList = [];
|
||||
this.getStoreList();
|
||||
}
|
||||
},
|
||||
};
|
||||
})
|
||||
.catch(() => {
|
||||
hideLoadingIfNeeded()
|
||||
uni.stopPullDownRefresh()
|
||||
})
|
||||
}
|
||||
|
||||
function fetchStoreList() {
|
||||
uni.showLoading({ title: '加载中' })
|
||||
getStoreCollection(navList.value[1].params, 'STORE')
|
||||
.then((res) => {
|
||||
hideLoadingIfNeeded()
|
||||
uni.stopPullDownRefresh()
|
||||
if (res.data.success) {
|
||||
const data = res.data.result
|
||||
navList.value[1].name = `店铺(${data.total})`
|
||||
storeEmpty.value = data.total === 0
|
||||
if (data.records?.length) {
|
||||
const records = data.records.map((item: any) => ({ ...item, selected: false }))
|
||||
storeList.value.push(...records)
|
||||
}
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
hideLoadingIfNeeded()
|
||||
uni.stopPullDownRefresh()
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
@@ -324,15 +284,18 @@
|
||||
|
||||
.collect-body {
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.tab-content {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.list-scroll-content {
|
||||
height: 100%;
|
||||
:deep(.u-tabs),
|
||||
:deep(.u-tabs__wrapper),
|
||||
:deep(.u-tabs__wrapper__scroll-view-wrapper),
|
||||
:deep(.u-tabs__wrapper__scroll-view),
|
||||
:deep(.u-tabs__wrapper__nav) {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
|
||||
@@ -7,14 +7,14 @@
|
||||
:auto-back="true"
|
||||
>
|
||||
<template #right>
|
||||
<div class="light-color edit" @click="isEdit = !isEdit">{{ !isEdit ? '编辑' : '完成'}}</div>
|
||||
<view class="light-color edit" @click="isEdit = !isEdit">{{ !isEdit ? '编辑' : '完成'}}</view>
|
||||
</template>
|
||||
</u-navbar>
|
||||
<view class="tracks-tip">
|
||||
<u-icon name="volume" color="#f9ae3d" size="19"></u-icon>
|
||||
<text class="tracks-tip-text">右划删除浏览记录</text>
|
||||
</view>
|
||||
<u-empty text="暂无历史记录" style="margin-top:200rpx;" mode="history" v-if="whetherEmpty"></u-empty>
|
||||
<u-empty text="暂无历史记录" style="margin-top:200rpx;" mode="history" v-if="isEmpty"></u-empty>
|
||||
<view v-else class="tracks-list">
|
||||
<block v-for="(item, index) in trackList" :key="index">
|
||||
<view
|
||||
@@ -26,9 +26,9 @@
|
||||
<u-swipe-action-item
|
||||
:show="item.show"
|
||||
:name="index"
|
||||
@click="delTracks"
|
||||
@open="open"
|
||||
:options="options"
|
||||
@click="deleteTracks"
|
||||
@open="openSwipe"
|
||||
:options="swipeOptions"
|
||||
>
|
||||
<view class="myTracks-item">
|
||||
<u-checkbox-group v-if="isEdit" class="store-line-check">
|
||||
@@ -37,7 +37,7 @@
|
||||
shape="circle"
|
||||
:active-color="lightColor"
|
||||
v-model:checked="item.checked"
|
||||
@change="checkboxChangeDP(item)"
|
||||
@change="onTrackCheckChange(item)"
|
||||
></u-checkbox>
|
||||
</u-checkbox-group>
|
||||
<view class="myTracks-item-img" @click.stop="navigateToDetail(item)">
|
||||
@@ -56,7 +56,7 @@
|
||||
</u-swipe-action>
|
||||
<view class="myTracks-divider"></view>
|
||||
</block>
|
||||
<view v-if="isEdit" class="submit" @click="handleClickDeleteSelected">
|
||||
<view v-if="isEdit" class="submit" @click="deleteSelectedTracks">
|
||||
删除所选
|
||||
</view>
|
||||
</view>
|
||||
@@ -64,172 +64,147 @@
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
myTrackList,
|
||||
deleteHistoryListId
|
||||
} from "@/api/members.js";
|
||||
import { getStoreBaseInfo } from "@/api/store.js";
|
||||
<script setup lang="ts">
|
||||
import { ref, computed } from 'vue'
|
||||
import { onShow, onReachBottom, onPullDownRefresh } from '@dcloudio/uni-app'
|
||||
import { useStore } from '@/store'
|
||||
import { unitPrice } from '@/utils/filters.js'
|
||||
import { myTrackList, deleteHistoryListId } from '@/api/members.js'
|
||||
import { getStoreBaseInfo } from '@/api/store.js'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
isEdit:false,
|
||||
whetherEmpty: false, //是否数据为空
|
||||
params: {
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
order: "desc",
|
||||
sort: "updateTime",
|
||||
},
|
||||
lightColor:this.$lightColor,
|
||||
options: [{
|
||||
text: '删除',
|
||||
style: {
|
||||
backgroundColor: '#dd524d'
|
||||
}
|
||||
}],
|
||||
trackList: [], //足迹列表
|
||||
storeNameMap: {},
|
||||
};
|
||||
},
|
||||
const store = useStore()
|
||||
const lightColor = computed(() => store.getters.lightColor)
|
||||
|
||||
/**
|
||||
* 滑到底部加载下一页数据
|
||||
*/
|
||||
onReachBottom() {
|
||||
this.params.pageNumber++;
|
||||
this.getList();
|
||||
},
|
||||
onShow() {
|
||||
this.params.pageNumber = 1
|
||||
this.trackList = [];
|
||||
this.getList();
|
||||
},
|
||||
onPullDownRefresh() {
|
||||
this.trackList = [];
|
||||
this.getList();
|
||||
},
|
||||
methods: {
|
||||
getStoreName(item) {
|
||||
return item.storeName || this.storeNameMap[item.storeId] || "";
|
||||
},
|
||||
async enrichStoreNames(records) {
|
||||
const storeIds = [
|
||||
...new Set(
|
||||
records
|
||||
.filter((item) => !item.storeName && item.storeId)
|
||||
.map((item) => item.storeId)
|
||||
),
|
||||
].filter((storeId) => !this.storeNameMap[storeId]);
|
||||
const isEdit = ref(false)
|
||||
const isEmpty = ref(false)
|
||||
const params = ref({
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
order: 'desc',
|
||||
sort: 'updateTime',
|
||||
})
|
||||
const swipeOptions = [{ text: '删除', style: { backgroundColor: '#dd524d' } }]
|
||||
const trackList = ref<any[]>([])
|
||||
const storeNameMap = ref<Record<string, string>>({})
|
||||
|
||||
await Promise.all(
|
||||
storeIds.map(async (storeId) => {
|
||||
try {
|
||||
const res = await getStoreBaseInfo(storeId);
|
||||
const name = res.data?.result?.storeName;
|
||||
if (name) {
|
||||
this.storeNameMap[storeId] = name;
|
||||
}
|
||||
} catch (e) {
|
||||
// ignore
|
||||
}
|
||||
})
|
||||
);
|
||||
},
|
||||
checkboxChangeDP(val){
|
||||
console.log(val)
|
||||
},
|
||||
// 删除所选的数据
|
||||
handleClickDeleteSelected(val){
|
||||
const ids = this.trackList.filter(item=>item.checked).map(item=>item.goodsId);
|
||||
if(!ids.length){
|
||||
uni.showToast({
|
||||
title:"请选择删除数据",
|
||||
icon:"none"
|
||||
})
|
||||
}else{
|
||||
this.delTracks(0,ids)
|
||||
onReachBottom(() => {
|
||||
params.value.pageNumber++
|
||||
fetchTrackList()
|
||||
})
|
||||
|
||||
onShow(() => {
|
||||
params.value.pageNumber = 1
|
||||
trackList.value = []
|
||||
fetchTrackList()
|
||||
})
|
||||
|
||||
onPullDownRefresh(() => {
|
||||
params.value.pageNumber = 1
|
||||
trackList.value = []
|
||||
fetchTrackList()
|
||||
})
|
||||
|
||||
function getStoreName(item: any) {
|
||||
return item.storeName || storeNameMap.value[item.storeId] || ''
|
||||
}
|
||||
|
||||
async function enrichStoreNames(records: any[]) {
|
||||
const storeIds = [
|
||||
...new Set(
|
||||
records
|
||||
.filter((item) => !item.storeName && item.storeId)
|
||||
.map((item) => item.storeId)
|
||||
),
|
||||
].filter((storeId) => !storeNameMap.value[storeId])
|
||||
|
||||
await Promise.all(
|
||||
storeIds.map(async (storeId) => {
|
||||
try {
|
||||
const res = await getStoreBaseInfo(storeId)
|
||||
const name = res.data?.result?.storeName
|
||||
if (name) {
|
||||
storeNameMap.value[storeId] = name
|
||||
}
|
||||
},
|
||||
/**
|
||||
* 导航到店铺
|
||||
*/
|
||||
navigateToStore(val) {
|
||||
uni.navigateTo({
|
||||
url: "/pages/product/shopPage?id=" + val.storeId,
|
||||
});
|
||||
},
|
||||
open(index) {
|
||||
// 先将正在被操作的swipeAction标记为打开状态,否则由于props的特性限制,
|
||||
// 原本为'false',再次设置为'false'会无效
|
||||
this.trackList[index].show = true;
|
||||
this.trackList.map((val, idx) => {
|
||||
if (index != idx) this.trackList[idx].show = false;
|
||||
})
|
||||
},
|
||||
/**
|
||||
* 跳转详情
|
||||
*/
|
||||
navigateToDetail(item) {
|
||||
uni.navigateTo({
|
||||
url: "/pages/product/goods?id=" + item.id + "&goodsId=" + item.goodsId,
|
||||
});
|
||||
},
|
||||
} catch {
|
||||
// ignore
|
||||
}
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取我的足迹列表
|
||||
*/
|
||||
getList() {
|
||||
uni.showLoading({
|
||||
title: "加载中",
|
||||
});
|
||||
myTrackList(this.params).then(async (res) => {
|
||||
uni.stopPullDownRefresh();
|
||||
uni.hideLoading();
|
||||
if (res.statusCode == 200) {
|
||||
const records = res.data.result.records || [];
|
||||
records.forEach((item) => {
|
||||
item.show = false;
|
||||
item.checked = false;
|
||||
});
|
||||
function onTrackCheckChange(_val: any) {
|
||||
// 勾选状态由 v-model:checked 维护
|
||||
}
|
||||
|
||||
if (!records.length) {
|
||||
if (this.trackList.length === 0) {
|
||||
this.whetherEmpty = true;
|
||||
}
|
||||
} else {
|
||||
await this.enrichStoreNames(records);
|
||||
this.trackList.push(...records);
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
function deleteSelectedTracks() {
|
||||
const ids = trackList.value.filter((item) => item.checked).map((item) => item.goodsId)
|
||||
if (!ids.length) {
|
||||
uni.showToast({ title: '请选择删除数据', icon: 'none' })
|
||||
return
|
||||
}
|
||||
deleteTracks(0, ids)
|
||||
}
|
||||
|
||||
function navigateToStore(val: any) {
|
||||
uni.navigateTo({ url: `/pages/product/shopPage?id=${val.storeId}` })
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除足迹
|
||||
*/
|
||||
delTracks(e, ids) {
|
||||
const index = typeof e === 'object' ? (e.name ?? e.index) : e;
|
||||
const goodsId = ids || this.trackList[index]?.goodsId;
|
||||
if (!goodsId) return;
|
||||
deleteHistoryListId(goodsId).then((res) => {
|
||||
if (res.data.code == 200) {
|
||||
this.trackList = [];
|
||||
this.params.pageNumber = 1
|
||||
this.getList();
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: res.data.message,
|
||||
duration: 2000,
|
||||
icon: "none",
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
function openSwipe(index: number) {
|
||||
trackList.value[index].show = true
|
||||
trackList.value.forEach((val, idx) => {
|
||||
if (index !== idx) val.show = false
|
||||
})
|
||||
}
|
||||
|
||||
function navigateToDetail(item: any) {
|
||||
uni.navigateTo({
|
||||
url: `/pages/product/goods?id=${item.id}&goodsId=${item.goodsId}`,
|
||||
})
|
||||
}
|
||||
|
||||
function fetchTrackList() {
|
||||
uni.showLoading({ title: '加载中' })
|
||||
myTrackList(params.value).then(async (res) => {
|
||||
uni.stopPullDownRefresh()
|
||||
uni.hideLoading()
|
||||
if (res.statusCode === 200) {
|
||||
const records = res.data.result.records || []
|
||||
records.forEach((item: any) => {
|
||||
item.show = false
|
||||
item.checked = false
|
||||
})
|
||||
|
||||
if (!records.length) {
|
||||
if (trackList.value.length === 0) {
|
||||
isEmpty.value = true
|
||||
}
|
||||
} else {
|
||||
isEmpty.value = false
|
||||
await enrichStoreNames(records)
|
||||
trackList.value.push(...records)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function deleteTracks(e: any, ids?: any) {
|
||||
const index = typeof e === 'object' ? (e.name ?? e.index) : e
|
||||
const goodsId = ids || trackList.value[index]?.goodsId
|
||||
if (!goodsId) return
|
||||
deleteHistoryListId(goodsId).then((res) => {
|
||||
if (res.data.code === 200) {
|
||||
trackList.value = []
|
||||
params.value.pageNumber = 1
|
||||
fetchTrackList()
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: res.data.message,
|
||||
duration: 2000,
|
||||
icon: 'none',
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
@@ -1,249 +1,245 @@
|
||||
<template>
|
||||
<view class="content">
|
||||
<view class="portrait-box">
|
||||
<image src="/static/pointTrade/point_bg_1.png" mode=""></image>
|
||||
<image class="point-img" src="/static/pointTrade/tradehall.png" />
|
||||
<view class="position-point">
|
||||
|
||||
|
||||
</view>
|
||||
</view>
|
||||
<view class="point-summary">
|
||||
<view class="point-summary-item">
|
||||
<text>累计获得:</text>
|
||||
<text class="pcolor">{{ pointData.totalPoint || 0 }}</text>
|
||||
</view>
|
||||
<view class="point-summary-divider"></view>
|
||||
<view class="point-summary-item">
|
||||
<text>剩余积分:</text>
|
||||
<text class="pcolor">{{ pointData.point || 0 }}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<div class="point-list">
|
||||
<view class="point-item" v-for="(item, index) in pointList" :key="index">
|
||||
<view class="point-item-left">
|
||||
<view class="point-label">{{ item.content }}</view>
|
||||
<view class="point-item-time">{{ item.createTime }}</view>
|
||||
</view>
|
||||
<view class="point-item-value" :class="[item.pointType == 'INCREASE' ? 'plus' : 'reduce']">
|
||||
<text>{{ item.pointType == "INCREASE" ? "+" : "-" }}</text>{{ item.variablePoint }}
|
||||
</view>
|
||||
</view>
|
||||
<uni-load-more :status="count.loadStatus"></uni-load-more>
|
||||
</div>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getPointsData } from "@/api/members.js";
|
||||
import { getMemberPointSum } from "@/api/members.js";
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
count: {
|
||||
loadStatus: "more",
|
||||
},
|
||||
pointList: [], //积分数据集合
|
||||
params: {
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
},
|
||||
pointData: {}, //累计获取 未输入 集合
|
||||
};
|
||||
},
|
||||
|
||||
onLoad() {
|
||||
this.initPointData();
|
||||
this.getList();
|
||||
},
|
||||
|
||||
/**
|
||||
* 触底加载
|
||||
*/
|
||||
onReachBottom() {
|
||||
this.params.pageNumber++;
|
||||
this.getList();
|
||||
},
|
||||
methods: {
|
||||
/**
|
||||
* 获取积分数据
|
||||
*/
|
||||
getList() {
|
||||
let params = this.params;
|
||||
uni.showLoading({
|
||||
title: "加载中",
|
||||
});
|
||||
getPointsData(params).then((res) => {
|
||||
if (this.$store.state.isShowToast){ uni.hideLoading() };
|
||||
if (res.data.success) {
|
||||
let data = res.data.result.records;
|
||||
if (data.length < 10) {
|
||||
this.count["loadStatus"] = "noMore";
|
||||
this.pointList.push(...data);
|
||||
} else {
|
||||
this.pointList.push(...data);
|
||||
if (data.length < 10) this.count["loadStatus"] = "noMore";
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 获得累计积分使用
|
||||
*/
|
||||
initPointData() {
|
||||
getMemberPointSum().then((res) => {
|
||||
this.pointData = res.data.result;
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.point-list {
|
||||
margin-top: 20rpx;
|
||||
}
|
||||
.title {
|
||||
height: 80rpx;
|
||||
text-align: center;
|
||||
line-height: 80rpx;
|
||||
font-size: 32rpx;
|
||||
font-weight: bold;
|
||||
}
|
||||
.plus{
|
||||
color: $light-color;
|
||||
font-weight: bold;
|
||||
}
|
||||
.reduce{
|
||||
color: $weChat-color;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.point-item {
|
||||
width: 100%;
|
||||
min-height: 130rpx;
|
||||
padding: 24rpx 20rpx;
|
||||
background: #ffffff;
|
||||
font-size: $font-sm;
|
||||
border-bottom: 1px solid $border-color-light;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
box-sizing: border-box;
|
||||
|
||||
.point-item-left {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
line-height: 40rpx;
|
||||
}
|
||||
|
||||
.point-item-time {
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.point-item-value {
|
||||
flex-shrink: 0;
|
||||
width: 100rpx;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
.point-summary {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
min-height: 100rpx;
|
||||
padding: 28rpx 0;
|
||||
background: #ffffff;
|
||||
border-radius: 0 0 20rpx 20rpx;
|
||||
margin: 0 20rpx;
|
||||
font-size: 26rpx;
|
||||
box-sizing: border-box;
|
||||
|
||||
.point-summary-item {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.point-summary-divider {
|
||||
width: 1px;
|
||||
height: 48rpx;
|
||||
background: $border-color-light;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.pcolor {
|
||||
color: $light-color;
|
||||
margin-left: 8rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.content {
|
||||
background: #f9f9f9;
|
||||
}
|
||||
|
||||
.more {
|
||||
text-align: right;
|
||||
color: $u-tips-color;
|
||||
font-size: 24rpx;
|
||||
padding-right: 40rpx !important;
|
||||
}
|
||||
|
||||
.portrait-box {
|
||||
background-color: $main-color;
|
||||
height: 250rpx;
|
||||
background: linear-gradient(91deg, $light-color 1%, $aider-light-color 99%);
|
||||
border-radius: 20rpx 20rpx 0 0;
|
||||
margin: 20rpx 20rpx 0;
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
color: #ffffff;
|
||||
|
||||
> image:first-child {
|
||||
width: 263rpx;
|
||||
height: 250rpx;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
transform: rotateY(180deg);
|
||||
}
|
||||
|
||||
.position-point {
|
||||
position: absolute;
|
||||
right: -2rpx;
|
||||
top: 0;
|
||||
|
||||
.apply-point {
|
||||
margin-top: 30rpx;
|
||||
text-align: center;
|
||||
line-height: 40rpx;
|
||||
font-size: $font-sm;
|
||||
color: #ffffff;
|
||||
width: 142rpx;
|
||||
height: 40rpx;
|
||||
background: rgba(#ffffff, 0.2);
|
||||
border-radius: 20rpx 0px 0px 20rpx;
|
||||
}
|
||||
}
|
||||
.point-img {
|
||||
height: 108rpx;
|
||||
width: 108rpx;
|
||||
margin-bottom: 30rpx;
|
||||
}
|
||||
.point {
|
||||
font-size: 56rpx;
|
||||
}
|
||||
|
||||
}
|
||||
.point-label {
|
||||
font-weight: bold;
|
||||
margin-bottom: 10rpx;
|
||||
color: #666666;
|
||||
}
|
||||
</style>
|
||||
<template>
|
||||
<view class="content">
|
||||
<view class="portrait-box">
|
||||
<image src="/static/pointTrade/point_bg_1.png" mode=""></image>
|
||||
<image class="point-img" src="/static/pointTrade/tradehall.png" />
|
||||
<view class="position-point">
|
||||
|
||||
|
||||
</view>
|
||||
</view>
|
||||
<view class="point-summary">
|
||||
<view class="point-summary-item">
|
||||
<text>累计获得:</text>
|
||||
<text class="pcolor">{{ pointSummary.totalPoint || 0 }}</text>
|
||||
</view>
|
||||
<view class="point-summary-divider"></view>
|
||||
<view class="point-summary-item">
|
||||
<text>剩余积分:</text>
|
||||
<text class="pcolor">{{ pointSummary.point || 0 }}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="point-list">
|
||||
<view class="point-item" v-for="(item, index) in pointList" :key="index">
|
||||
<view class="point-item-left">
|
||||
<view class="point-label">{{ item.content }}</view>
|
||||
<view class="point-item-time">{{ item.createTime }}</view>
|
||||
</view>
|
||||
<view class="point-item-value" :class="[item.pointType == 'INCREASE' ? 'plus' : 'reduce']">
|
||||
<text>{{ item.pointType == "INCREASE" ? "+" : "-" }}</text>{{ item.variablePoint }}
|
||||
</view>
|
||||
</view>
|
||||
<uni-load-more :status="loadStatus"></uni-load-more>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { onLoad, onReachBottom } from '@dcloudio/uni-app'
|
||||
import { useStore } from '@/store'
|
||||
import { getPointsData, getMemberPointSum } from '@/api/members.js'
|
||||
|
||||
const store = useStore()
|
||||
|
||||
const loadStatus = ref('more')
|
||||
const pointList = ref<any[]>([])
|
||||
const params = ref({ pageNumber: 1, pageSize: 10 })
|
||||
const pointSummary = ref<Record<string, any>>({})
|
||||
|
||||
onLoad(() => {
|
||||
fetchPointSummary()
|
||||
fetchPointLogList()
|
||||
})
|
||||
|
||||
onReachBottom(() => {
|
||||
params.value.pageNumber++
|
||||
fetchPointLogList()
|
||||
})
|
||||
|
||||
function hideLoadingIfNeeded() {
|
||||
if (store.state.isShowToast) uni.hideLoading()
|
||||
}
|
||||
|
||||
function fetchPointLogList() {
|
||||
uni.showLoading({ title: '加载中' })
|
||||
getPointsData(params.value).then((res) => {
|
||||
hideLoadingIfNeeded()
|
||||
if (res.data.success) {
|
||||
const data = res.data.result.records || []
|
||||
if (data.length < params.value.pageSize) {
|
||||
loadStatus.value = 'noMore'
|
||||
}
|
||||
pointList.value.push(...data)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function fetchPointSummary() {
|
||||
getMemberPointSum().then((res) => {
|
||||
pointSummary.value = res.data.result
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
page,
|
||||
.content {
|
||||
min-height: 100vh;
|
||||
background: #f9f9f9;
|
||||
}
|
||||
|
||||
.content {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.point-list {
|
||||
margin-top: 20rpx;
|
||||
background: #f9f9f9;
|
||||
min-height: calc(100vh - 390rpx);
|
||||
padding-bottom: 24rpx;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.title {
|
||||
height: 80rpx;
|
||||
text-align: center;
|
||||
line-height: 80rpx;
|
||||
font-size: 32rpx;
|
||||
font-weight: bold;
|
||||
}
|
||||
.plus{
|
||||
color: $light-color;
|
||||
font-weight: bold;
|
||||
}
|
||||
.reduce{
|
||||
color: $weChat-color;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.point-item {
|
||||
width: 100%;
|
||||
min-height: 130rpx;
|
||||
padding: 24rpx 20rpx;
|
||||
background: #ffffff;
|
||||
font-size: $font-sm;
|
||||
border-bottom: 1px solid $border-color-light;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
box-sizing: border-box;
|
||||
|
||||
.point-item-left {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
line-height: 40rpx;
|
||||
}
|
||||
|
||||
.point-item-time {
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.point-item-value {
|
||||
flex-shrink: 0;
|
||||
width: 100rpx;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
.point-summary {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
min-height: 100rpx;
|
||||
padding: 28rpx 0;
|
||||
background: #ffffff;
|
||||
border-radius: 0 0 20rpx 20rpx;
|
||||
margin: 0 20rpx;
|
||||
font-size: 26rpx;
|
||||
box-sizing: border-box;
|
||||
|
||||
.point-summary-item {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.point-summary-divider {
|
||||
width: 1px;
|
||||
height: 48rpx;
|
||||
background: $border-color-light;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.pcolor {
|
||||
color: $light-color;
|
||||
margin-left: 8rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.more {
|
||||
text-align: right;
|
||||
color: $u-tips-color;
|
||||
font-size: 24rpx;
|
||||
padding-right: 40rpx !important;
|
||||
}
|
||||
|
||||
.portrait-box {
|
||||
background-color: $main-color;
|
||||
height: 250rpx;
|
||||
background: linear-gradient(91deg, $light-color 1%, $aider-light-color 99%);
|
||||
border-radius: 20rpx 20rpx 0 0;
|
||||
margin: 20rpx 20rpx 0;
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
color: #ffffff;
|
||||
|
||||
> image:first-child {
|
||||
width: 263rpx;
|
||||
height: 250rpx;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
transform: rotateY(180deg);
|
||||
}
|
||||
|
||||
.position-point {
|
||||
position: absolute;
|
||||
right: -2rpx;
|
||||
top: 0;
|
||||
|
||||
.apply-point {
|
||||
margin-top: 30rpx;
|
||||
text-align: center;
|
||||
line-height: 40rpx;
|
||||
font-size: $font-sm;
|
||||
color: #ffffff;
|
||||
width: 142rpx;
|
||||
height: 40rpx;
|
||||
background: rgba(#ffffff, 0.2);
|
||||
border-radius: 20rpx 0px 0px 20rpx;
|
||||
}
|
||||
}
|
||||
.point-img {
|
||||
height: 108rpx;
|
||||
width: 108rpx;
|
||||
margin-bottom: 30rpx;
|
||||
}
|
||||
.point {
|
||||
font-size: 56rpx;
|
||||
}
|
||||
|
||||
}
|
||||
.point-label {
|
||||
font-weight: bold;
|
||||
margin-bottom: 10rpx;
|
||||
color: #666666;
|
||||
}
|
||||
|
||||
.point-list .uni-load-more {
|
||||
background: #f9f9f9;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
<u-cell-group class="cell-group" :border="false">
|
||||
<!-- #ifdef APP-PLUS -->
|
||||
<u-cell v-if="IosWhether" is-link title="去评分" @click="checkStar"></u-cell>
|
||||
<u-cell v-if="showIosRating" is-link title="去评分" @click="openAppStoreRating"></u-cell>
|
||||
<u-cell is-link title="功能介绍" @click="navigateTo('/pages/mine/set/versionFunctionList')"></u-cell>
|
||||
<u-cell is-link title="检查更新" @click="checkUpdate"></u-cell>
|
||||
<!-- #endif -->
|
||||
@@ -40,93 +40,72 @@
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import APPUpdate from "@/plugins/APPUpdate";
|
||||
import config from "@/config/config";
|
||||
import { getAppVersion } from "@/api/message.js";
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
config,
|
||||
IosWhether: false,
|
||||
editionHistory: [],
|
||||
versionData: {},
|
||||
localVersion: "",
|
||||
params: {
|
||||
pageNumber: 1,
|
||||
pageSize: 5,
|
||||
},
|
||||
};
|
||||
},
|
||||
onLoad() {
|
||||
// #ifdef APP-PLUS
|
||||
const platform = uni.getSystemInfoSync().platform;
|
||||
if (platform === "android") {
|
||||
this.params.type = 0;
|
||||
} else {
|
||||
this.IosWhether = true;
|
||||
this.params.type = 1;
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { onLoad } from '@dcloudio/uni-app'
|
||||
import APPUpdate from '@/plugins/APPUpdate'
|
||||
import config from '@/config/config'
|
||||
import { getAppVersion } from '@/api/message.js'
|
||||
|
||||
const showIosRating = ref(false)
|
||||
const versionData = ref<Record<string, any>>({})
|
||||
const localVersion = ref<Record<string, any>>({})
|
||||
const params = ref<Record<string, any>>({ pageNumber: 1, pageSize: 5 })
|
||||
|
||||
onLoad(() => {
|
||||
// #ifdef APP-PLUS
|
||||
const platform = uni.getSystemInfoSync().platform
|
||||
if (platform === 'android') {
|
||||
params.value.type = 0
|
||||
} else {
|
||||
showIosRating.value = true
|
||||
params.value.type = 1
|
||||
}
|
||||
fetchRemoteVersion(platform)
|
||||
|
||||
plus.runtime.getProperty(plus.runtime.appid, (inf) => {
|
||||
localVersion.value = {
|
||||
versionCode: inf.version.replace(/\./g, ''),
|
||||
version: inf.version,
|
||||
}
|
||||
this.getVersion(platform);
|
||||
})
|
||||
// #endif
|
||||
|
||||
plus.runtime.getProperty(plus.runtime.appid, (inf) => {
|
||||
this.localVersion = {
|
||||
versionCode: inf.version.replace(/\./g, ""),
|
||||
version: inf.version,
|
||||
};
|
||||
});
|
||||
// #endif
|
||||
// #ifdef MP-WEIXIN
|
||||
const accountInfo = wx.getAccountInfoSync()
|
||||
localVersion.value = {
|
||||
versionCode: accountInfo.miniProgram.version.replace(/\./g, ''),
|
||||
version: accountInfo.miniProgram.version,
|
||||
envVersion: accountInfo.miniProgram.envVersion,
|
||||
}
|
||||
// #endif
|
||||
})
|
||||
|
||||
// #ifdef MP-WEIXIN
|
||||
const accountInfo = wx.getAccountInfoSync();
|
||||
this.version_number = accountInfo.miniProgram.version;
|
||||
this.localVersion = {
|
||||
versionCode: accountInfo.miniProgram.version.replace(/\./g, ""),
|
||||
version: accountInfo.miniProgram.version,
|
||||
envVersion: accountInfo.miniProgram.envVersion,
|
||||
};
|
||||
// #endif
|
||||
},
|
||||
async function fetchRemoteVersion(platform: string) {
|
||||
const type = platform === 'android' ? 'ANDROID' : 'IOS'
|
||||
const res = await getAppVersion(type)
|
||||
if (res.data.success) {
|
||||
versionData.value = res.data.result
|
||||
}
|
||||
}
|
||||
|
||||
methods: {
|
||||
async getVersion(platform) {
|
||||
let type;
|
||||
platform == "android" ? (type = "ANDROID") : (type = "IOS");
|
||||
function navigateTo(url: string) {
|
||||
uni.navigateTo({ url })
|
||||
}
|
||||
|
||||
let res = await getAppVersion(type);
|
||||
if (res.data.success) {
|
||||
this.versionData = res.data.result;
|
||||
}
|
||||
},
|
||||
function openAppStoreRating() {
|
||||
plus.runtime.launchApplication({
|
||||
action: `itms-apps://itunes.apple.com/app/${config.iosAppId}?action=write-review`,
|
||||
})
|
||||
}
|
||||
|
||||
navigateTo(url) {
|
||||
uni.navigateTo({
|
||||
url,
|
||||
});
|
||||
},
|
||||
|
||||
checkStar() {
|
||||
plus.runtime.launchApplication({
|
||||
action: `itms-apps://itunes.apple.com/app/${config.iosAppId}?action=write-review`,
|
||||
});
|
||||
},
|
||||
|
||||
checkUpdate() {
|
||||
if (
|
||||
this.versionData.version.replace(/\./g, "") <
|
||||
this.localVersion.versionCode
|
||||
) {
|
||||
APPUpdate();
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: "当前版本已是最新版",
|
||||
duration: 2000,
|
||||
icon: "none",
|
||||
});
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
function checkUpdate() {
|
||||
if (versionData.value.version?.replace(/\./g, '') < localVersion.value.versionCode) {
|
||||
APPUpdate()
|
||||
} else {
|
||||
uni.showToast({ title: '当前版本已是最新版', duration: 2000, icon: 'none' })
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
<view class="box-title">猜你想问</view>
|
||||
<view
|
||||
class="feedBack-item"
|
||||
:class="{ active: feedBack.type == item.value }"
|
||||
@click="handleClick(index)"
|
||||
v-for="(item, index) in list"
|
||||
:class="{ active: feedbackForm.type == item.value }"
|
||||
@click="selectFeedbackType(index)"
|
||||
v-for="(item, index) in feedbackTypeList"
|
||||
:key="index"
|
||||
>
|
||||
{{ item.text }}
|
||||
@@ -15,11 +15,11 @@
|
||||
|
||||
<view class="feedBack-box">
|
||||
<view class="box-title">问题反馈
|
||||
<text class="box-tag" v-if="feedBack.type">@{{ list.find(item => item.value == feedBack.type).text }}</text>
|
||||
<text class="box-tag" v-if="feedbackForm.type">@{{ feedbackTypeList.find(item => item.value == feedbackForm.type)?.text }}</text>
|
||||
</view>
|
||||
<u-textarea
|
||||
class="field-textarea"
|
||||
v-model="feedBack.context"
|
||||
v-model="feedbackForm.context"
|
||||
placeholder="请输入反馈信息"
|
||||
border="none"
|
||||
height="240"
|
||||
@@ -39,7 +39,7 @@
|
||||
<view class="box-title">手机号</view>
|
||||
<u-input
|
||||
class="field-input"
|
||||
v-model="feedBack.mobile"
|
||||
v-model="feedbackForm.mobile"
|
||||
type="number"
|
||||
maxlength="11"
|
||||
border="none"
|
||||
@@ -48,98 +48,69 @@
|
||||
></u-input>
|
||||
</view>
|
||||
|
||||
<view class="submit" @click="submit()">提交</view>
|
||||
<view class="submit" @click="submitFeedback">提交</view>
|
||||
</view>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import storage from "@/utils/storage.js";
|
||||
import config from "@/config/config";
|
||||
import { feedBack } from "@/api/members.js";
|
||||
import { handleUploadAfterRead } from "@/utils/uploadHelper.js";
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
storage,
|
||||
config,
|
||||
feedBack: {
|
||||
type: "FUNCTION",
|
||||
context: "",
|
||||
mobile: "",
|
||||
},
|
||||
inputStyle: {
|
||||
background: "#fafafa",
|
||||
borderRadius: "12rpx",
|
||||
padding: "0 24rpx",
|
||||
height: "80rpx",
|
||||
},
|
||||
uploadFileList: [],
|
||||
list: [
|
||||
{ text: "功能相关", value: "FUNCTION" },
|
||||
{ text: "优化反馈", value: "OPTIMIZE" },
|
||||
{ text: "其他", value: "OTHER" },
|
||||
],
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
// 点击反馈内容
|
||||
handleClick(index) {
|
||||
this.feedBack["type"] = this.list[index].value;
|
||||
},
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, getCurrentInstance } from 'vue'
|
||||
import { feedBack as submitFeedBackApi } from '@/api/members.js'
|
||||
import { handleUploadAfterRead } from '@/utils/uploadHelper.js'
|
||||
|
||||
onUploadAfterRead(event) {
|
||||
handleUploadAfterRead(event, this.uploadFileList, (urls) => {
|
||||
this.feedBack.images = urls.join(",");
|
||||
});
|
||||
},
|
||||
const { proxy } = getCurrentInstance()!
|
||||
|
||||
/**
|
||||
* 提交意见反馈
|
||||
*/
|
||||
submit() {
|
||||
if (!this.feedBack.type) {
|
||||
uni.showToast({
|
||||
title: "请填写反馈类型",
|
||||
duration: 2000,
|
||||
icon: "none",
|
||||
});
|
||||
return false;
|
||||
}
|
||||
if (!this.feedBack.context) {
|
||||
uni.showToast({
|
||||
title: "请填写反馈信息",
|
||||
duration: 2000,
|
||||
icon: "none",
|
||||
});
|
||||
return false;
|
||||
}
|
||||
if (this.feedBack.mobile && !this.$u.test.mobile(this.feedBack.mobile)) {
|
||||
uni.showToast({
|
||||
title: "请填写您的正确手机号",
|
||||
duration: 2000,
|
||||
icon: "none",
|
||||
});
|
||||
return false;
|
||||
}
|
||||
/** 提交 */
|
||||
feedBack(this.feedBack).then((res) => {
|
||||
if (res.data.success) {
|
||||
uni.showToast({
|
||||
title: "提交成功!",
|
||||
duration: 2000,
|
||||
icon: "none",
|
||||
});
|
||||
setTimeout(() => {
|
||||
uni.navigateBack({
|
||||
delta: 1,
|
||||
});
|
||||
}, 500);
|
||||
}
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
const feedbackForm = reactive({
|
||||
type: 'FUNCTION',
|
||||
context: '',
|
||||
mobile: '',
|
||||
images: '',
|
||||
})
|
||||
const inputStyle = {
|
||||
background: '#fafafa',
|
||||
borderRadius: '12rpx',
|
||||
padding: '0 24rpx',
|
||||
height: '80rpx',
|
||||
}
|
||||
const uploadFileList = ref<any[]>([])
|
||||
const feedbackTypeList = [
|
||||
{ text: '功能相关', value: 'FUNCTION' },
|
||||
{ text: '优化反馈', value: 'OPTIMIZE' },
|
||||
{ text: '其他', value: 'OTHER' },
|
||||
]
|
||||
|
||||
function selectFeedbackType(index: number) {
|
||||
feedbackForm.type = feedbackTypeList[index].value
|
||||
}
|
||||
|
||||
function onUploadAfterRead(event: any) {
|
||||
handleUploadAfterRead(event, uploadFileList.value, (urls) => {
|
||||
feedbackForm.images = urls.join(',')
|
||||
})
|
||||
}
|
||||
|
||||
function submitFeedback() {
|
||||
if (!feedbackForm.type) {
|
||||
uni.showToast({ title: '请填写反馈类型', duration: 2000, icon: 'none' })
|
||||
return
|
||||
}
|
||||
if (!feedbackForm.context) {
|
||||
uni.showToast({ title: '请填写反馈信息', duration: 2000, icon: 'none' })
|
||||
return
|
||||
}
|
||||
if (feedbackForm.mobile && !proxy.$u.test.mobile(feedbackForm.mobile)) {
|
||||
uni.showToast({ title: '请填写您的正确手机号', duration: 2000, icon: 'none' })
|
||||
return
|
||||
}
|
||||
submitFeedBackApi(feedbackForm).then((res) => {
|
||||
if (res.data.success) {
|
||||
uni.showToast({ title: '提交成功!', duration: 2000, icon: 'none' })
|
||||
setTimeout(() => {
|
||||
uni.navigateBack({ delta: 1 })
|
||||
}, 500)
|
||||
}
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
@@ -5,48 +5,54 @@
|
||||
<view>点击修改头像</view>
|
||||
</view>
|
||||
|
||||
<u-form :model="form" ref="uForm" class="form">
|
||||
<u-form-item label="昵称" label-width="150" :border-bottom="true">
|
||||
<up-form
|
||||
:model="form"
|
||||
ref="uForm"
|
||||
class="form"
|
||||
label-position="left"
|
||||
label-width="180rpx"
|
||||
>
|
||||
<up-form-item label="昵称" label-width="180rpx" :border-bottom="true">
|
||||
<u-input
|
||||
v-model="form.nickName"
|
||||
border="none"
|
||||
input-align="right"
|
||||
placeholder="请输入昵称"
|
||||
/>
|
||||
</u-form-item>
|
||||
</up-form-item>
|
||||
|
||||
<u-form-item label="性别" label-width="150" :border-bottom="true">
|
||||
<up-form-item label="性别" label-width="180rpx" :border-bottom="true">
|
||||
<view class="sex-row">
|
||||
<u-radio-group v-model="form.sex" :active-color="lightColor" :gap="40">
|
||||
<u-radio name="1" label="男" shape="circle"></u-radio>
|
||||
<u-radio name="0" label="女" shape="circle"></u-radio>
|
||||
</u-radio-group>
|
||||
</view>
|
||||
</u-form-item>
|
||||
</up-form-item>
|
||||
|
||||
<u-form-item label="生日" label-width="150" :border-bottom="true">
|
||||
<up-form-item label="生日" label-width="180rpx" :border-bottom="true">
|
||||
<view class="form-value" @click="showBirthday = true">
|
||||
{{ birthday || '请选择出生日期' }}
|
||||
</view>
|
||||
<template #right>
|
||||
<u-icon name="arrow-right" color="#ccc" size="16"></u-icon>
|
||||
</template>
|
||||
</u-form-item>
|
||||
</up-form-item>
|
||||
|
||||
<u-form-item label="城市" label-width="150" :border-bottom="true">
|
||||
<up-form-item label="城市" label-width="180rpx" :border-bottom="true">
|
||||
<view class="form-value" @click="clickRegion">
|
||||
{{ form.___path || '请选择城市' }}
|
||||
{{ form.regionPath || '请选择城市' }}
|
||||
</view>
|
||||
<template #right>
|
||||
<u-icon name="arrow-right" color="#ccc" size="16"></u-icon>
|
||||
</template>
|
||||
</u-form-item>
|
||||
</up-form-item>
|
||||
|
||||
<u-form-item label="手机号" label-width="150" :border-bottom="false">
|
||||
<up-form-item label="手机号" label-width="180rpx" :border-bottom="false">
|
||||
<view v-if="form.mobile" class="form-value">{{ form.mobile }}</view>
|
||||
<view v-else class="bind-mobile" @click="navigateTo(form.username)">绑定手机号码</view>
|
||||
</u-form-item>
|
||||
</u-form>
|
||||
<view v-else class="bind-mobile" @click="navigateToBindMobile(form.username)">绑定手机号码</view>
|
||||
</up-form-item>
|
||||
</up-form>
|
||||
|
||||
<view class="bottom">
|
||||
<view class="submit" @click="submit">保存</view>
|
||||
@@ -74,152 +80,135 @@
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { saveUserInfo } from "@/api/members.js";
|
||||
import { upload } from "@/api/common.js";
|
||||
import storage from "@/utils/storage.js";
|
||||
import city from "@/components/m-city/m-city.vue";
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, computed } from 'vue'
|
||||
import { onShow } from '@dcloudio/uni-app'
|
||||
import { useStore } from '@/store'
|
||||
import { quiteLoginOut } from '@/utils/filters.js'
|
||||
import { saveUserInfo } from '@/api/members.js'
|
||||
import { upload } from '@/api/common.js'
|
||||
import storage from '@/utils/storage.js'
|
||||
import MCity from '@/components/m-city/m-city.vue'
|
||||
|
||||
function parseBirthdayTimestamp(str) {
|
||||
if (!str) {
|
||||
return Date.now();
|
||||
}
|
||||
const timestamp = Date.parse(String(str).replace(/-/g, "/"));
|
||||
return Number.isFinite(timestamp) ? timestamp : Date.now();
|
||||
function parseBirthdayTimestamp(str?: string) {
|
||||
if (!str) return Date.now()
|
||||
const timestamp = Date.parse(String(str).replace(/-/g, '/'))
|
||||
return Number.isFinite(timestamp) ? timestamp : Date.now()
|
||||
}
|
||||
|
||||
function formatBirthday(timestamp) {
|
||||
const date = new Date(timestamp);
|
||||
const year = date.getFullYear();
|
||||
const month = String(date.getMonth() + 1).padStart(2, "0");
|
||||
const day = String(date.getDate()).padStart(2, "0");
|
||||
return `${year}-${month}-${day}`;
|
||||
function formatBirthday(timestamp: number) {
|
||||
const date = new Date(timestamp)
|
||||
const year = date.getFullYear()
|
||||
const month = String(date.getMonth() + 1).padStart(2, '0')
|
||||
const day = String(date.getDate()).padStart(2, '0')
|
||||
return `${year}-${month}-${day}`
|
||||
}
|
||||
|
||||
export default {
|
||||
components: { "m-city": city },
|
||||
data() {
|
||||
const userInfo = storage.getUserInfo() || {};
|
||||
return {
|
||||
lightColor: this.$lightColor,
|
||||
form: {
|
||||
nickName: userInfo.nickName || "",
|
||||
birthday: userInfo.birthday || "",
|
||||
face: userInfo.face || "/static/missing-face.png",
|
||||
regionId: [],
|
||||
region: userInfo.region || [],
|
||||
sex: userInfo.sex != null ? String(userInfo.sex) : "1",
|
||||
___path: userInfo.region,
|
||||
mobile: userInfo.mobile,
|
||||
username: userInfo.username,
|
||||
},
|
||||
birthday: userInfo.birthday || "",
|
||||
birthdayValue: parseBirthdayTimestamp(userInfo.birthday),
|
||||
minBirthdayDate: new Date("1950-01-01").getTime(),
|
||||
maxBirthdayDate: Date.now(),
|
||||
region: [
|
||||
{
|
||||
id: "",
|
||||
localName: "请选择",
|
||||
children: [],
|
||||
},
|
||||
],
|
||||
showBirthday: false,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
getPickerParentValue(e) {
|
||||
this.form.region = [];
|
||||
this.form.regionId = [];
|
||||
let name = "";
|
||||
const store = useStore()
|
||||
const lightColor = computed(() => store.getters.lightColor)
|
||||
|
||||
e.forEach((item, index) => {
|
||||
if (item.id) {
|
||||
this.form.region.push(item.localName);
|
||||
this.form.regionId.push(item.id);
|
||||
if (index == e.length - 1) {
|
||||
name += item.localName;
|
||||
} else {
|
||||
name += item.localName + ",";
|
||||
}
|
||||
this.form.___path = name;
|
||||
}
|
||||
});
|
||||
},
|
||||
const userInfo = storage.getUserInfo() || {}
|
||||
const form = reactive<Record<string, any>>({
|
||||
nickName: userInfo.nickName || '',
|
||||
birthday: userInfo.birthday || '',
|
||||
face: userInfo.face || '/static/missing-face.png',
|
||||
regionId: [],
|
||||
region: userInfo.region || [],
|
||||
sex: userInfo.sex != null ? String(userInfo.sex) : '1',
|
||||
regionPath: userInfo.region,
|
||||
mobile: userInfo.mobile,
|
||||
username: userInfo.username,
|
||||
})
|
||||
const birthday = ref(userInfo.birthday || '')
|
||||
const birthdayValue = ref(parseBirthdayTimestamp(userInfo.birthday))
|
||||
const minBirthdayDate = new Date('1950-01-01').getTime()
|
||||
const maxBirthdayDate = Date.now()
|
||||
const region = ref([{ id: '', localName: '请选择', children: [] }])
|
||||
const showBirthday = ref(false)
|
||||
const cityPicker = ref<any>(null)
|
||||
|
||||
clickRegion() {
|
||||
this.$refs.cityPicker.show();
|
||||
},
|
||||
function getPickerParentValue(selected: any[]) {
|
||||
form.region = []
|
||||
form.regionId = []
|
||||
let name = ''
|
||||
selected.forEach((item, index) => {
|
||||
if (item.id) {
|
||||
form.region.push(item.localName)
|
||||
form.regionId.push(item.id)
|
||||
name += index === selected.length - 1 ? item.localName : `${item.localName},`
|
||||
form.regionPath = name
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
submit() {
|
||||
delete this.form.___path;
|
||||
const params = JSON.parse(JSON.stringify(this.form));
|
||||
saveUserInfo(params).then((res) => {
|
||||
if (res.statusCode == 200) {
|
||||
storage.setUserInfo(res.data.result);
|
||||
uni.navigateBack();
|
||||
}
|
||||
});
|
||||
},
|
||||
function clickRegion() {
|
||||
cityPicker.value?.show()
|
||||
}
|
||||
|
||||
changeFace() {
|
||||
uni.chooseImage({
|
||||
success: (chooseImageRes) => {
|
||||
const tempFilePaths = chooseImageRes.tempFilePaths;
|
||||
uni.uploadFile({
|
||||
url: upload,
|
||||
filePath: tempFilePaths[0],
|
||||
name: "file",
|
||||
header: {
|
||||
accessToken: storage.getAccessToken(),
|
||||
},
|
||||
success: (uploadFileRes) => {
|
||||
const data = JSON.parse(uploadFileRes.data);
|
||||
this.form.face = data.result;
|
||||
},
|
||||
});
|
||||
},
|
||||
});
|
||||
},
|
||||
function submit() {
|
||||
const params = JSON.parse(JSON.stringify(form))
|
||||
delete params.regionPath
|
||||
saveUserInfo(params).then((res) => {
|
||||
if (res.statusCode === 200) {
|
||||
storage.setUserInfo(res.data.result)
|
||||
uni.navigateBack()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
selectTime(e) {
|
||||
const timestamp = typeof e?.value === "number" ? e.value : this.birthdayValue;
|
||||
const formatted = formatBirthday(timestamp);
|
||||
this.birthdayValue = timestamp;
|
||||
this.form.birthday = formatted;
|
||||
this.birthday = formatted;
|
||||
this.showBirthday = false;
|
||||
},
|
||||
function changeFace() {
|
||||
uni.chooseImage({
|
||||
success: (chooseImageRes) => {
|
||||
uni.uploadFile({
|
||||
url: upload,
|
||||
filePath: chooseImageRes.tempFilePaths[0],
|
||||
name: 'file',
|
||||
header: { accessToken: storage.getAccessToken() },
|
||||
success: (uploadFileRes) => {
|
||||
const data = JSON.parse(uploadFileRes.data)
|
||||
form.face = data.result
|
||||
},
|
||||
})
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
closeBirthdayPicker() {
|
||||
this.showBirthday = false;
|
||||
},
|
||||
function selectTime(e: any) {
|
||||
const timestamp = typeof e?.value === 'number' ? e.value : birthdayValue.value
|
||||
const formatted = formatBirthday(timestamp)
|
||||
birthdayValue.value = timestamp
|
||||
form.birthday = formatted
|
||||
birthday.value = formatted
|
||||
showBirthday.value = false
|
||||
}
|
||||
|
||||
navigateTo(username) {
|
||||
uni.navigateTo({
|
||||
url: "/pages/mine/set/securityCenter/bindMobile?username=" + username,
|
||||
});
|
||||
},
|
||||
function closeBirthdayPicker() {
|
||||
showBirthday.value = false
|
||||
}
|
||||
|
||||
syncUserInfo() {
|
||||
const userInfo = storage.getUserInfo() || {};
|
||||
this.form.nickName = userInfo.nickName || "";
|
||||
this.form.birthday = userInfo.birthday || "";
|
||||
this.form.face = userInfo.face || "/static/missing-face.png";
|
||||
this.form.region = userInfo.region || [];
|
||||
this.form.sex = userInfo.sex != null ? String(userInfo.sex) : "1";
|
||||
this.form.___path = userInfo.region;
|
||||
this.form.mobile = userInfo.mobile;
|
||||
this.form.username = userInfo.username;
|
||||
this.birthday = userInfo.birthday || "";
|
||||
this.birthdayValue = parseBirthdayTimestamp(userInfo.birthday);
|
||||
},
|
||||
},
|
||||
function navigateToBindMobile(username: string) {
|
||||
uni.navigateTo({
|
||||
url: `/pages/mine/set/securityCenter/bindMobile?username=${username}`,
|
||||
})
|
||||
}
|
||||
|
||||
onShow() {
|
||||
this.syncUserInfo();
|
||||
},
|
||||
};
|
||||
function syncUserInfo() {
|
||||
const latest = storage.getUserInfo() || {}
|
||||
form.nickName = latest.nickName || ''
|
||||
form.birthday = latest.birthday || ''
|
||||
form.face = latest.face || '/static/missing-face.png'
|
||||
form.region = latest.region || []
|
||||
form.sex = latest.sex != null ? String(latest.sex) : '1'
|
||||
form.regionPath = latest.region
|
||||
form.mobile = latest.mobile
|
||||
form.username = latest.username
|
||||
birthday.value = latest.birthday || ''
|
||||
birthdayValue.value = parseBirthdayTimestamp(latest.birthday)
|
||||
}
|
||||
|
||||
onShow(() => {
|
||||
syncUserInfo()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
@@ -1,227 +1,211 @@
|
||||
<template>
|
||||
<view class="box">
|
||||
<view class="box-tips">
|
||||
<h2 class='h2'>
|
||||
绑定手机号码
|
||||
</h2>
|
||||
<h2 class="h2">绑定手机号码</h2>
|
||||
<view class="verification"></view>
|
||||
</view>
|
||||
<view class="form">
|
||||
<u-form :model="codeForm" ref="validateCodeForm">
|
||||
<view v-if="!validateFlage">
|
||||
<u-form-item label-width="120" label="手机号" prop="mobile">
|
||||
<up-form
|
||||
:model="codeForm"
|
||||
ref="validateCodeForm"
|
||||
label-position="left"
|
||||
label-width="180rpx"
|
||||
>
|
||||
<view v-if="!phoneVerified">
|
||||
<up-form-item label-width="180rpx" label="手机号" prop="mobile">
|
||||
<u-input maxlength="11" v-model="codeForm.mobile" placeholder="请输入您的手机号" />
|
||||
</u-form-item>
|
||||
|
||||
<u-form-item class="sendCode" label-width="120" prop="code" label="验证码">
|
||||
<u-input v-model="codeForm.code" placeholder="请输入验证码" />
|
||||
<u-code unique-key="page-edit" :seconds="seconds" @end="end" @start="start"
|
||||
ref="uCode" @change="codeChange"></u-code>
|
||||
<view @tap="getCode" class="text-tips">{{ tips }}</view>
|
||||
</u-form-item>
|
||||
</up-form-item>
|
||||
|
||||
<view class="submit" @click="validatePhone">绑定</view>
|
||||
<myVerification keep-running @send="verification" class="verification" ref="verification"
|
||||
business="BIND_MOBILE" />
|
||||
<up-form-item class="sendCode" label-width="180rpx" prop="code" label="验证码">
|
||||
<u-input v-model="codeForm.code" placeholder="请输入验证码" />
|
||||
<u-code
|
||||
unique-key="page-edit"
|
||||
:seconds="seconds"
|
||||
@end="onCodeCountdownEnd"
|
||||
@start="onCodeCountdownStart"
|
||||
ref="uCodeRef"
|
||||
@change="onCodeTextChange"
|
||||
></u-code>
|
||||
<view @tap="requestSmsCode" class="text-tips">{{ codeTips }}</view>
|
||||
</up-form-item>
|
||||
|
||||
<view class="submit" @click="submitBindMobile">绑定</view>
|
||||
<myVerification
|
||||
keep-running
|
||||
@send="onVerificationPassed"
|
||||
class="verification"
|
||||
ref="verificationRef"
|
||||
business="BIND_MOBILE"
|
||||
/>
|
||||
</view>
|
||||
</u-form>
|
||||
</up-form>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
sendMobile,
|
||||
bindMobile
|
||||
} from "@/api/login";
|
||||
import { getUserInfo } from "@/api/members.js";
|
||||
import storage from "@/utils/storage.js";
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, watch, getCurrentInstance } from 'vue'
|
||||
import { onLoad, onReady } from '@dcloudio/uni-app'
|
||||
import { useStore } from '@/store'
|
||||
import { sendMobile, bindMobile } from '@/api/login'
|
||||
import { getUserInfo } from '@/api/members.js'
|
||||
import storage from '@/utils/storage.js'
|
||||
import MyVerification from '@/components/verification/verification.vue'
|
||||
|
||||
import myVerification from "@/components/verification/verification.vue"; //验证
|
||||
import uuid from "@/utils/uuid.modified.js";
|
||||
export default {
|
||||
components: {
|
||||
myVerification,
|
||||
const store = useStore()
|
||||
const { proxy } = getCurrentInstance()!
|
||||
|
||||
const phoneVerified = ref(false)
|
||||
const verificationPassed = ref(false)
|
||||
const codeForm = reactive({
|
||||
mobile: '',
|
||||
code: '',
|
||||
username: '',
|
||||
})
|
||||
const codeTips = ref('')
|
||||
const seconds = 69
|
||||
|
||||
const validateCodeForm = ref<any>(null)
|
||||
const uCodeRef = ref<any>(null)
|
||||
const verificationRef = ref<any>(null)
|
||||
|
||||
const codeRules = {
|
||||
mobile: [
|
||||
{
|
||||
validator: (_rule: any, value: string) => proxy.$u.test.mobile(value),
|
||||
message: '手机号码不正确',
|
||||
trigger: ['blur'],
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
uuid,
|
||||
validateFlage: false, //是否进行了手机号验证
|
||||
step: 0, //当前验证步骤
|
||||
flage: false, //是否验证码验证
|
||||
codeForm: {
|
||||
mobile: "", //手机号
|
||||
code: "", //验证码
|
||||
username: "", //用户名
|
||||
},
|
||||
tips: "", //提示
|
||||
seconds: 69, // 60s等待时间
|
||||
|
||||
// 验证码登录校验
|
||||
codeRules: {
|
||||
mobile: [{
|
||||
validator: (rule, value, callback) => {
|
||||
return this.$u.test.mobile(value);
|
||||
},
|
||||
message: "手机号码不正确",
|
||||
trigger: ["blur"],
|
||||
}, ],
|
||||
code: [{
|
||||
min: 4,
|
||||
max: 6,
|
||||
required: true,
|
||||
message: "请输入验证码",
|
||||
trigger: ["blur"],
|
||||
}, ],
|
||||
},
|
||||
};
|
||||
},
|
||||
onLoad(options) {
|
||||
this.codeForm.username = options.username;
|
||||
},
|
||||
onReady() {
|
||||
// 必须要在onReady生命周期,因为onLoad生命周期组件可能尚未创建完毕
|
||||
this.$refs.validateCodeForm.setRules(this.codeRules);
|
||||
},
|
||||
watch: {
|
||||
flage(val) {
|
||||
if (val) {
|
||||
if (this.$refs.uCode.canGetCode) {
|
||||
uni.showLoading({
|
||||
title: "正在获取验证码",
|
||||
});
|
||||
sendMobile(this.codeForm.mobile, "BIND_MOBILE").then((res) => {
|
||||
if (this.$store.state.isShowToast){ uni.hideLoading() };
|
||||
// 这里此提示会被this.start()方法中的提示覆盖
|
||||
if (res.data.success) {
|
||||
this.$refs.uCode.start();
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: res.data.message,
|
||||
duration: 2000,
|
||||
icon: "none",
|
||||
});
|
||||
this.flage = false;
|
||||
this.$refs.verification.getCode();
|
||||
}
|
||||
})
|
||||
} else {
|
||||
this.$u.toast("请倒计时结束后再发送");
|
||||
}
|
||||
}
|
||||
},
|
||||
],
|
||||
code: [
|
||||
{
|
||||
min: 4,
|
||||
max: 6,
|
||||
required: true,
|
||||
message: '请输入验证码',
|
||||
trigger: ['blur'],
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
methods: {
|
||||
// 验证码验证
|
||||
verification(val) {
|
||||
this.flage = val == this.$store.state.verificationKey ? true : false;
|
||||
},
|
||||
onLoad((options) => {
|
||||
codeForm.username = options?.username || ''
|
||||
})
|
||||
|
||||
// 验证手机号
|
||||
validatePhone() {
|
||||
this.$refs.validateCodeForm.validate((valid) => {
|
||||
if (valid) {
|
||||
bindMobile(this.codeForm).then((res) => {
|
||||
if (res.data.success) {
|
||||
this.validateFlage = !this.validateFlage;
|
||||
// 获取最新的用户信息并更新缓存
|
||||
getUserInfo().then(userRes => {
|
||||
if (userRes.data.success) {
|
||||
storage.setUserInfo(userRes.data.result);
|
||||
}
|
||||
// 显示成功提示
|
||||
uni.showToast({
|
||||
title: "绑定成功!",
|
||||
duration: 2000,
|
||||
icon: "none",
|
||||
});
|
||||
// 返回上一页
|
||||
setTimeout(() => {
|
||||
uni.navigateBack({
|
||||
delta: 1,
|
||||
});
|
||||
}, 1000);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
onReady(() => {
|
||||
validateCodeForm.value?.setRules(codeRules)
|
||||
})
|
||||
|
||||
codeChange(text) {
|
||||
this.tips = text;
|
||||
},
|
||||
end() {
|
||||
|
||||
this.flage = false;
|
||||
this.$refs.verification.getCode()
|
||||
},
|
||||
|
||||
/**获取验证码 */
|
||||
getCode() {
|
||||
if (this.tips == "重新获取") {
|
||||
this.$refs.verification.error(); //发送
|
||||
}
|
||||
if (!this.$u.test.mobile(this.codeForm.mobile)) {
|
||||
uni.showToast({
|
||||
title: "请输入正确手机号",
|
||||
icon: "none",
|
||||
});
|
||||
return false;
|
||||
}
|
||||
if (!this.flage) {
|
||||
this.$refs.verification.error(); //发送
|
||||
return false;
|
||||
}
|
||||
},
|
||||
start() {
|
||||
this.$u.toast("验证码已发送");
|
||||
this.flage = true;
|
||||
|
||||
this.$refs.verification.hide();
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
@import url("@/pages/passport/login.scss");
|
||||
|
||||
::v-deep .u-form-item {
|
||||
margin: 40rpx 0;
|
||||
watch(verificationPassed, (val) => {
|
||||
if (!val) return
|
||||
if (!uCodeRef.value?.canGetCode) {
|
||||
proxy.$u.toast('请倒计时结束后再发送')
|
||||
return
|
||||
}
|
||||
|
||||
.sendCode {
|
||||
::v-deep .u-form-item--right__content__slot {
|
||||
display: flex;
|
||||
uni.showLoading({ title: '正在获取验证码' })
|
||||
sendMobile(codeForm.mobile, 'BIND_MOBILE').then((res) => {
|
||||
if (store.state.isShowToast) uni.hideLoading()
|
||||
if (res.data.success) {
|
||||
uCodeRef.value?.start()
|
||||
} else {
|
||||
uni.showToast({ title: res.data.message, duration: 2000, icon: 'none' })
|
||||
verificationPassed.value = false
|
||||
verificationRef.value?.getCode()
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
.h2 {
|
||||
font-size: 40rpx;
|
||||
font-weight: bold;
|
||||
}
|
||||
function onVerificationPassed(val: string) {
|
||||
verificationPassed.value = val === store.state.verificationKey
|
||||
}
|
||||
|
||||
page {
|
||||
background: #fff;
|
||||
}
|
||||
function submitBindMobile() {
|
||||
validateCodeForm.value?.validate((valid: boolean) => {
|
||||
if (!valid) return
|
||||
bindMobile(codeForm).then((res) => {
|
||||
if (res.data.success) {
|
||||
phoneVerified.value = true
|
||||
getUserInfo().then((userRes) => {
|
||||
if (userRes.data.success) {
|
||||
storage.setUserInfo(userRes.data.result)
|
||||
}
|
||||
uni.showToast({ title: '绑定成功!', duration: 2000, icon: 'none' })
|
||||
setTimeout(() => {
|
||||
uni.navigateBack({ delta: 1 })
|
||||
}, 1000)
|
||||
})
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
.box {
|
||||
padding: 80rpx 0;
|
||||
border-radius: 20rpx;
|
||||
}
|
||||
function onCodeTextChange(text: string) {
|
||||
codeTips.value = text
|
||||
}
|
||||
|
||||
.submit {
|
||||
background: $light-color;
|
||||
}
|
||||
function onCodeCountdownEnd() {
|
||||
verificationPassed.value = false
|
||||
verificationRef.value?.getCode()
|
||||
}
|
||||
|
||||
.box-tips {
|
||||
margin: 0 72rpx;
|
||||
function requestSmsCode() {
|
||||
if (codeTips.value === '重新获取') {
|
||||
verificationRef.value?.error()
|
||||
}
|
||||
if (!proxy.$u.test.mobile(codeForm.mobile)) {
|
||||
uni.showToast({ title: '请输入正确手机号', icon: 'none' })
|
||||
return
|
||||
}
|
||||
if (!verificationPassed.value) {
|
||||
verificationRef.value?.error()
|
||||
}
|
||||
}
|
||||
|
||||
.verification {
|
||||
font-size: 24rpx;
|
||||
color: #999;
|
||||
margin-top: 10rpx;
|
||||
function onCodeCountdownStart() {
|
||||
proxy.$u.toast('验证码已发送')
|
||||
verificationPassed.value = true
|
||||
verificationRef.value?.hide()
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import url("@/pages/passport/login.scss");
|
||||
|
||||
::v-deep .u-form-item {
|
||||
margin: 40rpx 0;
|
||||
}
|
||||
|
||||
.sendCode {
|
||||
::v-deep .u-form-item__body__right__content__slot {
|
||||
display: flex;
|
||||
}
|
||||
}
|
||||
|
||||
.h2 {
|
||||
font-size: 40rpx;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
page {
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.box {
|
||||
padding: 80rpx 0;
|
||||
border-radius: 20rpx;
|
||||
}
|
||||
|
||||
.submit {
|
||||
background: $light-color;
|
||||
}
|
||||
|
||||
.box-tips {
|
||||
margin: 0 72rpx;
|
||||
}
|
||||
|
||||
.verification {
|
||||
font-size: 24rpx;
|
||||
color: #999;
|
||||
margin-top: 10rpx;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,160 +1,99 @@
|
||||
<template>
|
||||
<view class="box">
|
||||
<view class="box-tips">
|
||||
<h2 class='h2'>
|
||||
{{verificationTitle.title}}
|
||||
</h2>
|
||||
<view class="verification">{{verificationTitle.desc}}</view>
|
||||
<h2 class="h2">{{ verificationTitle.title }}</h2>
|
||||
<view class="verification">{{ verificationTitle.desc }}</view>
|
||||
</view>
|
||||
<view class="form">
|
||||
<u-form :model="codeForm" ref="validateCodeForm">
|
||||
<u-form-item label-width="120" label="旧密码">
|
||||
<u-input type="password" v-model="oldPassword" placeholder="请输入您的旧密码" />
|
||||
</u-form-item>
|
||||
<up-form
|
||||
:model="codeForm"
|
||||
ref="validateCodeForm"
|
||||
label-position="left"
|
||||
label-width="180rpx"
|
||||
>
|
||||
<up-form-item label-width="180rpx" label="旧密码">
|
||||
<u-input type="password" v-model="oldPassword" placeholder="请输入您的旧密码" />
|
||||
</up-form-item>
|
||||
|
||||
<u-form-item label-width="120" label="密码">
|
||||
<u-input type="password" v-model="password" placeholder="请输入您的密码" />
|
||||
</u-form-item>
|
||||
<up-form-item label-width="180rpx" label="密码">
|
||||
<u-input type="password" v-model="password" placeholder="请输入您的密码" />
|
||||
</up-form-item>
|
||||
|
||||
<u-form-item label-width="120" label="确认密码">
|
||||
<u-input type="password" v-model="newPassword" placeholder="请再次输入您的密码" />
|
||||
</u-form-item>
|
||||
<up-form-item label-width="180rpx" label="确认密码">
|
||||
<u-input type="password" v-model="confirmPassword" placeholder="请再次输入您的密码" />
|
||||
</up-form-item>
|
||||
|
||||
<view class="submit" @click="updatePassword">修改密码</view>
|
||||
</u-form>
|
||||
<view class="submit" @click="updatePassword">修改密码</view>
|
||||
</up-form>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
resetByMobile,
|
||||
modifyPass
|
||||
} from "@/api/login";
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive } from 'vue'
|
||||
import { modifyPass } from '@/api/login'
|
||||
import { md5 } from '@/utils/md5.js'
|
||||
|
||||
import {
|
||||
md5
|
||||
} from "@/utils/md5.js"; // md5
|
||||
import myVerification from "@/components/verification/verification.vue"; //验证
|
||||
import uuid from "@/utils/uuid.modified.js";
|
||||
export default {
|
||||
components: {
|
||||
myVerification,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
uuid,
|
||||
validateFlage: false, //是否进行了手机号验证
|
||||
verificationTitle: {
|
||||
title: "修改密码",
|
||||
desc: "请验证并输入密码",
|
||||
},
|
||||
step: 0, //当前验证步骤
|
||||
flage: false, //是否验证码验证
|
||||
const verificationTitle = {
|
||||
title: '修改密码',
|
||||
desc: '请验证并输入密码',
|
||||
}
|
||||
const codeForm = reactive({ mobile: '', code: '' })
|
||||
const oldPassword = ref('')
|
||||
const password = ref('')
|
||||
const confirmPassword = ref('')
|
||||
|
||||
codeForm: {
|
||||
mobile: "", //手机号
|
||||
code: "", //验证码
|
||||
},
|
||||
newPassword: "", //新密码
|
||||
password: "", //密码
|
||||
oldPassword: '', //旧密码
|
||||
tips: "", //提示
|
||||
seconds: 69, // 60s等待时间
|
||||
|
||||
// 验证码登录校验
|
||||
codeRules: {
|
||||
mobile: [{
|
||||
validator: (rule, value, callback) => {
|
||||
return this.$u.test.mobile(value);
|
||||
},
|
||||
message: "手机号码不正确",
|
||||
trigger: ["blur"],
|
||||
}, ],
|
||||
code: [{
|
||||
min: 4,
|
||||
max: 6,
|
||||
required: true,
|
||||
message: "请输入验证码",
|
||||
trigger: ["blur"],
|
||||
}, ],
|
||||
},
|
||||
};
|
||||
},
|
||||
onReady() {
|
||||
// 必须要在onReady生命周期,因为onLoad生命周期组件可能尚未创建完毕
|
||||
this.$refs.validateCodeForm.setRules(this.codeRules);
|
||||
},
|
||||
|
||||
methods: {
|
||||
// 修改密码
|
||||
updatePassword() {
|
||||
if(this.password !== this.newPassword){
|
||||
uni.showToast({
|
||||
title: "两次输入密码不一致!",
|
||||
icon: "none",
|
||||
});
|
||||
return;
|
||||
}
|
||||
modifyPass({
|
||||
password: md5(this.oldPassword),
|
||||
newPassword: md5(this.newPassword),
|
||||
}).then((res) => {
|
||||
if (res.data.success) {
|
||||
uni.showToast({
|
||||
title: "修改成功!",
|
||||
duration: 2000,
|
||||
icon: "none",
|
||||
});
|
||||
setTimeout(() => {
|
||||
uni.navigateBack({
|
||||
delta: 1,
|
||||
});
|
||||
}, 1000);
|
||||
}
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
@import url("@/pages/passport/login.scss");
|
||||
|
||||
::v-deep .u-form-item {
|
||||
margin: 40rpx 0;
|
||||
function updatePassword() {
|
||||
if (password.value !== confirmPassword.value) {
|
||||
uni.showToast({ title: '两次输入密码不一致!', icon: 'none' })
|
||||
return
|
||||
}
|
||||
|
||||
.sendCode {
|
||||
::v-deep .u-form-item--right__content__slot {
|
||||
display: flex;
|
||||
modifyPass({
|
||||
password: md5(oldPassword.value),
|
||||
newPassword: md5(password.value),
|
||||
}).then((res) => {
|
||||
if (res.data.success) {
|
||||
uni.showToast({ title: '修改成功!', duration: 2000, icon: 'none' })
|
||||
setTimeout(() => {
|
||||
uni.navigateBack({ delta: 1 })
|
||||
}, 1000)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
.h2 {
|
||||
font-size: 40rpx;
|
||||
font-weight: bold;
|
||||
}
|
||||
<style lang="scss" scoped>
|
||||
@import url("@/pages/passport/login.scss");
|
||||
|
||||
page {
|
||||
background: #fff;
|
||||
}
|
||||
::v-deep .u-form-item {
|
||||
margin: 40rpx 0;
|
||||
}
|
||||
|
||||
.box {
|
||||
padding: 80rpx 0;
|
||||
border-radius: 20rpx;
|
||||
}
|
||||
.h2 {
|
||||
font-size: 40rpx;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.submit {
|
||||
background: $light-color;
|
||||
}
|
||||
page {
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.box-tips {
|
||||
margin: 0 72rpx;
|
||||
}
|
||||
.box {
|
||||
padding: 80rpx 0;
|
||||
border-radius: 20rpx;
|
||||
}
|
||||
|
||||
.verification {
|
||||
font-size: 24rpx;
|
||||
color: #999;
|
||||
margin-top: 10rpx;
|
||||
}
|
||||
.submit {
|
||||
background: $light-color;
|
||||
}
|
||||
|
||||
.box-tips {
|
||||
margin: 0 72rpx;
|
||||
}
|
||||
|
||||
.verification {
|
||||
font-size: 24rpx;
|
||||
color: #999;
|
||||
margin-top: 10rpx;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,281 +1,238 @@
|
||||
<template>
|
||||
<view class="box">
|
||||
<view class="box-tips">
|
||||
<h2 class='h2'>
|
||||
{{verificationTitle[validateFlage==false ? 0 : 1].title}}
|
||||
</h2>
|
||||
<view class="verification">{{verificationTitle[step].desc}}</view>
|
||||
<h2 class="h2">{{ verificationTitle[phoneVerified ? 1 : 0].title }}</h2>
|
||||
<view class="verification">{{ verificationTitle[step].desc }}</view>
|
||||
</view>
|
||||
<view class="form">
|
||||
<u-form :model="codeForm" ref="validateCodeForm">
|
||||
<view v-if="!validateFlage">
|
||||
<u-form-item label-width="120" label="手机号" prop="mobile">
|
||||
<up-form
|
||||
:model="codeForm"
|
||||
ref="validateCodeForm"
|
||||
label-position="left"
|
||||
label-width="180rpx"
|
||||
>
|
||||
<view v-if="!phoneVerified">
|
||||
<up-form-item label-width="180rpx" label="手机号" prop="mobile">
|
||||
<u-input maxlength="11" v-model="codeForm.mobile" placeholder="请输入您的手机号" />
|
||||
</u-form-item>
|
||||
</up-form-item>
|
||||
|
||||
<u-form-item class="sendCode" label-width="120" prop="code" label="验证码">
|
||||
<up-form-item class="sendCode" label-width="180rpx" prop="code" label="验证码">
|
||||
<u-input v-model="codeForm.code" placeholder="请输入验证码" />
|
||||
<u-code unique-key="page-edit" :seconds="seconds" @end="end" @start="start"
|
||||
ref="uCode" @change="codeChange"></u-code>
|
||||
<view @tap="getCode" class="text-tips">{{ tips }}</view>
|
||||
</u-form-item>
|
||||
<u-code
|
||||
unique-key="page-edit"
|
||||
:seconds="seconds"
|
||||
@end="onCodeCountdownEnd"
|
||||
@start="onCodeCountdownStart"
|
||||
ref="uCodeRef"
|
||||
@change="onCodeTextChange"
|
||||
></u-code>
|
||||
<view @tap="requestSmsCode" class="text-tips">{{ codeTips }}</view>
|
||||
</up-form-item>
|
||||
|
||||
<view class="submit" @click="validatePhone">验证</view>
|
||||
<myVerification keep-running @send="verification" class="verification" ref="verification"
|
||||
business="FIND_USER" />
|
||||
<view class="submit" @click="verifyMobile">验证</view>
|
||||
<myVerification
|
||||
keep-running
|
||||
@send="onVerificationPassed"
|
||||
class="verification"
|
||||
ref="verificationRef"
|
||||
business="FIND_USER"
|
||||
/>
|
||||
</view>
|
||||
<view v-if="validateFlage">
|
||||
<u-form-item label-width="120" label="密码">
|
||||
<view v-if="phoneVerified">
|
||||
<up-form-item label-width="180rpx" label="密码">
|
||||
<u-input type="password" v-model="password" placeholder="请输入您的密码" />
|
||||
</u-form-item>
|
||||
</up-form-item>
|
||||
|
||||
<u-form-item label-width="120" label="确认密码">
|
||||
<u-input type="password" v-model="newPassword" placeholder="请再次输入您的密码" />
|
||||
</u-form-item>
|
||||
<up-form-item label-width="180rpx" label="确认密码">
|
||||
<u-input type="password" v-model="confirmPassword" placeholder="请再次输入您的密码" />
|
||||
</up-form-item>
|
||||
|
||||
<view class="submit" @click="updatePassword">修改密码</view>
|
||||
</view>
|
||||
</u-form>
|
||||
</up-form>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
sendMobile,
|
||||
resetByMobile,
|
||||
resetPassword
|
||||
} from "@/api/login";
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, watch, getCurrentInstance } from 'vue'
|
||||
import { onReady } from '@dcloudio/uni-app'
|
||||
import { useStore } from '@/store'
|
||||
import { isLogin } from '@/utils/filters.js'
|
||||
import { sendMobile, resetByMobile, resetPassword } from '@/api/login'
|
||||
import { md5 } from '@/utils/md5.js'
|
||||
import MyVerification from '@/components/verification/verification.vue'
|
||||
|
||||
import {
|
||||
md5
|
||||
} from "@/utils/md5.js"; // md5
|
||||
import myVerification from "@/components/verification/verification.vue"; //验证
|
||||
import uuid from "@/utils/uuid.modified.js";
|
||||
export default {
|
||||
components: {
|
||||
myVerification,
|
||||
const store = useStore()
|
||||
const { proxy } = getCurrentInstance()!
|
||||
|
||||
const phoneVerified = ref(false)
|
||||
const verificationPassed = ref(false)
|
||||
const verificationTitle = [
|
||||
{ title: '安全验证', desc: '请输入当前手机号进行安全验证' },
|
||||
{ title: '修改密码', desc: '请输入新密码' },
|
||||
]
|
||||
const step = ref(0)
|
||||
const codeForm = reactive({ mobile: '', code: '' })
|
||||
const password = ref('')
|
||||
const confirmPassword = ref('')
|
||||
const codeTips = ref('')
|
||||
const seconds = 69
|
||||
|
||||
const validateCodeForm = ref<any>(null)
|
||||
const uCodeRef = ref<any>(null)
|
||||
const verificationRef = ref<any>(null)
|
||||
|
||||
const codeRules = {
|
||||
mobile: [
|
||||
{
|
||||
validator: (_rule: any, value: string) => proxy.$u.test.mobile(value),
|
||||
message: '手机号码不正确',
|
||||
trigger: ['blur'],
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
uuid,
|
||||
validateFlage: false, //是否进行了手机号验证
|
||||
verificationTitle: [{
|
||||
title: "安全验证",
|
||||
desc: "请输入当前手机号进行安全验证",
|
||||
},
|
||||
{
|
||||
title: "修改密码",
|
||||
desc: "请输入新密码",
|
||||
},
|
||||
],
|
||||
step: 0, //当前验证步骤
|
||||
flage: false, //是否验证码验证
|
||||
|
||||
codeForm: {
|
||||
mobile: "", //手机号
|
||||
code: "", //验证码
|
||||
},
|
||||
newPassword: "", //新密码
|
||||
password: "", //密码
|
||||
tips: "", //提示
|
||||
seconds: 69, // 60s等待时间
|
||||
|
||||
// 验证码登录校验
|
||||
codeRules: {
|
||||
mobile: [{
|
||||
validator: (rule, value, callback) => {
|
||||
return this.$u.test.mobile(value);
|
||||
},
|
||||
message: "手机号码不正确",
|
||||
trigger: ["blur"],
|
||||
}, ],
|
||||
code: [{
|
||||
min: 4,
|
||||
max: 6,
|
||||
required: true,
|
||||
message: "请输入验证码",
|
||||
trigger: ["blur"],
|
||||
}, ],
|
||||
},
|
||||
};
|
||||
],
|
||||
code: [
|
||||
{
|
||||
min: 4,
|
||||
max: 6,
|
||||
required: true,
|
||||
message: '请输入验证码',
|
||||
trigger: ['blur'],
|
||||
},
|
||||
onReady() {
|
||||
// 必须要在onReady生命周期,因为onLoad生命周期组件可能尚未创建完毕
|
||||
this.$refs.validateCodeForm.setRules(this.codeRules);
|
||||
},
|
||||
watch: {
|
||||
flage(val) {
|
||||
if (val) {
|
||||
],
|
||||
}
|
||||
|
||||
if (this.$refs.uCode.canGetCode) {
|
||||
uni.showLoading({
|
||||
title: "正在获取验证码",
|
||||
});
|
||||
sendMobile(this.codeForm.mobile, "FIND_USER").then((res) => {
|
||||
if (this.$store.state.isShowToast){ uni.hideLoading() };
|
||||
// 这里此提示会被this.start()方法中的提示覆盖
|
||||
if (res.data.success) {
|
||||
this.$refs.uCode.start();
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: res.data.message,
|
||||
duration: 2000,
|
||||
icon: "none",
|
||||
});
|
||||
this.flage = false;
|
||||
this.$refs.verification.getCode();
|
||||
}
|
||||
})
|
||||
} else {
|
||||
this.$u.toast("请倒计时结束后再发送");
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
onReady(() => {
|
||||
validateCodeForm.value?.setRules(codeRules)
|
||||
})
|
||||
|
||||
methods: {
|
||||
// 修改密码
|
||||
updatePassword() {
|
||||
if(this.password !== this.newPassword){
|
||||
uni.showToast({
|
||||
title: "两次输入密码不一致!",
|
||||
icon: "none",
|
||||
});
|
||||
return;
|
||||
}
|
||||
resetPassword({
|
||||
password: md5(this.password),
|
||||
}).then((res) => {
|
||||
if (res.data.success) {
|
||||
uni.showToast({
|
||||
title: "修改成功!",
|
||||
duration: 2000,
|
||||
icon: "none",
|
||||
});
|
||||
setTimeout(() => {
|
||||
uni.navigateBack({
|
||||
delta: 1,
|
||||
});
|
||||
}, 1000);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
// 验证码验证
|
||||
verification(val) {
|
||||
this.flage = val == this.$store.state.verificationKey ? true : false;
|
||||
},
|
||||
|
||||
// 验证手机号
|
||||
validatePhone() {
|
||||
this.$refs.validateCodeForm.validate((valid) => {
|
||||
if (valid) {
|
||||
resetByMobile(this.codeForm).then((res) => {
|
||||
if (res.data.success) {
|
||||
this.validateFlage = !this.validateFlage;
|
||||
// 登录成功
|
||||
uni.showToast({
|
||||
title: "验证成功!",
|
||||
icon: "none",
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
codeChange(text) {
|
||||
this.tips = text;
|
||||
},
|
||||
end() {
|
||||
|
||||
this.flage = false;
|
||||
this.$refs.verification.getCode()
|
||||
},
|
||||
|
||||
/**判断是否是当前用户的手机号 */
|
||||
isUserPhone() {
|
||||
let flage = false;
|
||||
let user = this.isLogin();
|
||||
if (user.mobile != this.codeForm.mobile) {
|
||||
uni.showToast({
|
||||
title: "请输入当前绑定手机号",
|
||||
icon: "none",
|
||||
});
|
||||
flage = false;
|
||||
} else {
|
||||
flage = true;
|
||||
}
|
||||
|
||||
return flage;
|
||||
},
|
||||
/**获取验证码 */
|
||||
getCode() {
|
||||
if (this.isUserPhone()) {
|
||||
if (this.tips == "重新获取") {
|
||||
this.$refs.verification.error(); //发送
|
||||
}
|
||||
if (!this.$u.test.mobile(this.codeForm.mobile)) {
|
||||
uni.showToast({
|
||||
title: "请输入正确手机号",
|
||||
icon: "none",
|
||||
});
|
||||
return false;
|
||||
}
|
||||
if (!this.flage) {
|
||||
this.$refs.verification.error(); //发送
|
||||
return false;
|
||||
}
|
||||
}
|
||||
},
|
||||
start() {
|
||||
this.$u.toast("验证码已发送");
|
||||
this.flage = true;
|
||||
|
||||
this.$refs.verification.hide();
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
@import url("@/pages/passport/login.scss");
|
||||
|
||||
::v-deep .u-form-item {
|
||||
margin: 40rpx 0;
|
||||
watch(verificationPassed, (val) => {
|
||||
if (!val) return
|
||||
if (!uCodeRef.value?.canGetCode) {
|
||||
proxy.$u.toast('请倒计时结束后再发送')
|
||||
return
|
||||
}
|
||||
|
||||
.sendCode {
|
||||
::v-deep .u-form-item--right__content__slot {
|
||||
display: flex;
|
||||
uni.showLoading({ title: '正在获取验证码' })
|
||||
sendMobile(codeForm.mobile, 'FIND_USER').then((res) => {
|
||||
if (store.state.isShowToast) uni.hideLoading()
|
||||
if (res.data.success) {
|
||||
uCodeRef.value?.start()
|
||||
} else {
|
||||
uni.showToast({ title: res.data.message, duration: 2000, icon: 'none' })
|
||||
verificationPassed.value = false
|
||||
verificationRef.value?.getCode()
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
.h2 {
|
||||
font-size: 40rpx;
|
||||
font-weight: bold;
|
||||
}
|
||||
function onVerificationPassed(val: string) {
|
||||
verificationPassed.value = val === store.state.verificationKey
|
||||
}
|
||||
|
||||
page {
|
||||
background: #fff;
|
||||
function updatePassword() {
|
||||
if (password.value !== confirmPassword.value) {
|
||||
uni.showToast({ title: '两次输入密码不一致!', icon: 'none' })
|
||||
return
|
||||
}
|
||||
resetPassword({ password: md5(password.value) }).then((res) => {
|
||||
if (res.data.success) {
|
||||
uni.showToast({ title: '修改成功!', duration: 2000, icon: 'none' })
|
||||
setTimeout(() => {
|
||||
uni.navigateBack({ delta: 1 })
|
||||
}, 1000)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
.box {
|
||||
padding: 80rpx 0;
|
||||
border-radius: 20rpx;
|
||||
}
|
||||
function verifyMobile() {
|
||||
validateCodeForm.value?.validate((valid: boolean) => {
|
||||
if (!valid) return
|
||||
resetByMobile(codeForm).then((res) => {
|
||||
if (res.data.success) {
|
||||
phoneVerified.value = true
|
||||
uni.showToast({ title: '验证成功!', icon: 'none' })
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
.submit {
|
||||
background: $light-color;
|
||||
}
|
||||
function onCodeTextChange(text: string) {
|
||||
codeTips.value = text
|
||||
}
|
||||
|
||||
.box-tips {
|
||||
margin: 0 72rpx;
|
||||
}
|
||||
function onCodeCountdownEnd() {
|
||||
verificationPassed.value = false
|
||||
verificationRef.value?.getCode()
|
||||
}
|
||||
|
||||
.verification {
|
||||
font-size: 24rpx;
|
||||
color: #999;
|
||||
margin-top: 10rpx;
|
||||
function isCurrentUserPhone() {
|
||||
const user = isLogin()
|
||||
if (user?.mobile !== codeForm.mobile) {
|
||||
uni.showToast({ title: '请输入当前绑定手机号', icon: 'none' })
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
function requestSmsCode() {
|
||||
if (!isCurrentUserPhone()) return
|
||||
if (codeTips.value === '重新获取') {
|
||||
verificationRef.value?.error()
|
||||
}
|
||||
if (!proxy.$u.test.mobile(codeForm.mobile)) {
|
||||
uni.showToast({ title: '请输入正确手机号', icon: 'none' })
|
||||
return
|
||||
}
|
||||
if (!verificationPassed.value) {
|
||||
verificationRef.value?.error()
|
||||
}
|
||||
}
|
||||
|
||||
function onCodeCountdownStart() {
|
||||
proxy.$u.toast('验证码已发送')
|
||||
verificationPassed.value = true
|
||||
verificationRef.value?.hide()
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import url("@/pages/passport/login.scss");
|
||||
|
||||
::v-deep .u-form-item {
|
||||
margin: 40rpx 0;
|
||||
}
|
||||
|
||||
.sendCode {
|
||||
::v-deep .u-form-item__body__right__content__slot {
|
||||
display: flex;
|
||||
}
|
||||
}
|
||||
|
||||
.h2 {
|
||||
font-size: 40rpx;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
page {
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.box {
|
||||
padding: 80rpx 0;
|
||||
border-radius: 20rpx;
|
||||
}
|
||||
|
||||
.submit {
|
||||
background: $light-color;
|
||||
}
|
||||
|
||||
.box-tips {
|
||||
margin: 0 72rpx;
|
||||
}
|
||||
|
||||
.verification {
|
||||
font-size: 24rpx;
|
||||
color: #999;
|
||||
margin-top: 10rpx;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<u-cell-group>
|
||||
<u-cell class="border-top" :isLink="false" title="面容登录">
|
||||
<template #right-icon>
|
||||
<u-switch @change="faceSwitchChange" active-color="#1abc9c" size="40" v-model="checked"></u-switch>
|
||||
<u-switch @change="onFaceSwitchChange" active-color="#1abc9c" size="40" v-model="enabled"></u-switch>
|
||||
</template>
|
||||
</u-cell>
|
||||
</u-cell-group>
|
||||
@@ -12,74 +12,65 @@
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import storage from "@/utils/storage.js";
|
||||
import { setBiolofy } from "@/api/passport.js";
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { onLoad } from '@dcloudio/uni-app'
|
||||
import storage from '@/utils/storage.js'
|
||||
import { setBiolofy } from '@/api/passport.js'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
lightColor: this.$lightColor,
|
||||
checked: true,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
faceSwitchChange(value) {
|
||||
if (value === true) {
|
||||
const res = uni.getSystemInfoSync();
|
||||
plus.device.getInfo({
|
||||
success: function (e) {
|
||||
let params = {
|
||||
mobile_type: res.model,
|
||||
secret_key: e.uuid,
|
||||
};
|
||||
setBiolofy(params).then((res) => {
|
||||
if (res.statusCode === 200) {
|
||||
storage.setFaceLogin(true);
|
||||
}
|
||||
});
|
||||
},
|
||||
fail: function (e) {
|
||||
//plus.nativeUI.toast('获取设备信息错误:' + JSON.stringify(e));
|
||||
console.error("getDeviceInfo failed: " + JSON.stringify(e));
|
||||
},
|
||||
});
|
||||
} else {
|
||||
storage.setFaceLogin(false);
|
||||
const enabled = ref(false)
|
||||
|
||||
onLoad(() => {
|
||||
// #ifdef APP-PLUS
|
||||
uni.checkIsSupportSoterAuthentication({
|
||||
success(res) {
|
||||
if (!res.supportMode.find((e) => e === 'facial')) {
|
||||
plus.nativeUI.toast('此设备不支持面部识别')
|
||||
uni.navigateBack()
|
||||
}
|
||||
uni.checkIsSoterEnrolledInDevice({
|
||||
checkAuthMode: 'facial',
|
||||
success(_res) {
|
||||
if (!_res.isEnrolled) {
|
||||
plus.nativeUI.toast('此设备未录入面部信息')
|
||||
uni.navigateBack()
|
||||
}
|
||||
},
|
||||
fail() {
|
||||
uni.navigateBack()
|
||||
},
|
||||
})
|
||||
},
|
||||
},
|
||||
onLoad() {
|
||||
// #ifdef APP-PLUS
|
||||
uni.checkIsSupportSoterAuthentication({
|
||||
success(res) {
|
||||
if (!res.supportMode.find((e) => e === "facial")) {
|
||||
plus.nativeUI.toast("此设备不支持面部识别");
|
||||
uni.navigateBack();
|
||||
}
|
||||
uni.checkIsSoterEnrolledInDevice({
|
||||
checkAuthMode: "facial",
|
||||
success(_res) {
|
||||
if (!_res.isEnrolled) {
|
||||
plus.nativeUI.toast("此设备未录入面部信息");
|
||||
uni.navigateBack();
|
||||
}
|
||||
},
|
||||
fail(_err) {
|
||||
// plus.nativeUI.toast(JSON.stringify(_err));
|
||||
uni.navigateBack();
|
||||
},
|
||||
});
|
||||
fail() {
|
||||
uni.navigateBack()
|
||||
},
|
||||
})
|
||||
enabled.value = storage.getFaceLogin() || false
|
||||
// #endif
|
||||
})
|
||||
|
||||
function onFaceSwitchChange(value: boolean) {
|
||||
if (value) {
|
||||
const systemInfo = uni.getSystemInfoSync()
|
||||
plus.device.getInfo({
|
||||
success(e) {
|
||||
setBiolofy({
|
||||
mobile_type: systemInfo.model,
|
||||
secret_key: e.uuid,
|
||||
}).then((res) => {
|
||||
if (res.statusCode === 200) {
|
||||
storage.setFaceLogin(true)
|
||||
}
|
||||
})
|
||||
},
|
||||
fail(err) {
|
||||
// plus.nativeUI.toast(JSON.stringify(err));
|
||||
uni.navigateBack();
|
||||
console.error('getDeviceInfo failed: ' + JSON.stringify(err))
|
||||
},
|
||||
});
|
||||
this.checked = storage.getFaceLogin() || false;
|
||||
// #endif
|
||||
},
|
||||
};
|
||||
})
|
||||
} else {
|
||||
storage.setFaceLogin(false)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<u-cell-group>
|
||||
<u-cell class="border-top" :isLink="false" title="指纹登录">
|
||||
<template #right-icon>
|
||||
<u-switch @change="fingerSwitchChange" :active-color="lightColor" size="40" v-model="checked"></u-switch>
|
||||
<u-switch @change="onFingerSwitchChange" :active-color="lightColor" size="40" v-model="enabled"></u-switch>
|
||||
</template>
|
||||
</u-cell>
|
||||
</u-cell-group>
|
||||
@@ -12,60 +12,57 @@
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import storage from "@/utils/storage.js";
|
||||
import { setBiolofy } from "@/api/passport.js";
|
||||
<script setup lang="ts">
|
||||
import { ref, computed } from 'vue'
|
||||
import { onLoad } from '@dcloudio/uni-app'
|
||||
import { useStore } from '@/store'
|
||||
import storage from '@/utils/storage.js'
|
||||
import { setBiolofy } from '@/api/passport.js'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
lightColor: this.$lightColor,
|
||||
checked: false,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
fingerSwitchChange(value) {
|
||||
if (value === true) {
|
||||
const res = uni.getSystemInfoSync();
|
||||
plus.device.getInfo({
|
||||
success: function (e) {
|
||||
let params = {
|
||||
mobile_type: res.model,
|
||||
secret_key: e.uuid,
|
||||
};
|
||||
setBiolofy(params).then((res) => {
|
||||
if (res.statusCode === 200) {
|
||||
storage.setFingerLogin(true);
|
||||
}
|
||||
});
|
||||
},
|
||||
fail: function (e) {
|
||||
console.error("getDeviceInfo failed: " + JSON.stringify(e));
|
||||
},
|
||||
});
|
||||
} else {
|
||||
storage.setFingerLogin(false);
|
||||
}
|
||||
},
|
||||
},
|
||||
onLoad() {
|
||||
// #ifdef APP-PLUS
|
||||
if (!plus.fingerprint.isSupport()) {
|
||||
plus.nativeUI.toast("此设备不支持指纹识别");
|
||||
uni.navigateBack();
|
||||
}
|
||||
if (!plus.fingerprint.isKeyguardSecure()) {
|
||||
plus.nativeUI.toast("此设备未设置密码锁屏");
|
||||
uni.navigateBack();
|
||||
}
|
||||
if (!plus.fingerprint.isEnrolledFingerprints()) {
|
||||
plus.nativeUI.toast("此设备未录入指纹");
|
||||
uni.navigateBack();
|
||||
}
|
||||
this.checked = storage.getFingerLogin() || false;
|
||||
// #endif
|
||||
},
|
||||
};
|
||||
const store = useStore()
|
||||
const lightColor = computed(() => store.getters.lightColor)
|
||||
const enabled = ref(false)
|
||||
|
||||
onLoad(() => {
|
||||
// #ifdef APP-PLUS
|
||||
if (!plus.fingerprint.isSupport()) {
|
||||
plus.nativeUI.toast('此设备不支持指纹识别')
|
||||
uni.navigateBack()
|
||||
}
|
||||
if (!plus.fingerprint.isKeyguardSecure()) {
|
||||
plus.nativeUI.toast('此设备未设置密码锁屏')
|
||||
uni.navigateBack()
|
||||
}
|
||||
if (!plus.fingerprint.isEnrolledFingerprints()) {
|
||||
plus.nativeUI.toast('此设备未录入指纹')
|
||||
uni.navigateBack()
|
||||
}
|
||||
enabled.value = storage.getFingerLogin() || false
|
||||
// #endif
|
||||
})
|
||||
|
||||
function onFingerSwitchChange(value: boolean) {
|
||||
if (value) {
|
||||
const systemInfo = uni.getSystemInfoSync()
|
||||
plus.device.getInfo({
|
||||
success(e) {
|
||||
setBiolofy({
|
||||
mobile_type: systemInfo.model,
|
||||
secret_key: e.uuid,
|
||||
}).then((res) => {
|
||||
if (res.statusCode === 200) {
|
||||
storage.setFingerLogin(true)
|
||||
}
|
||||
})
|
||||
},
|
||||
fail(err) {
|
||||
console.error('getDeviceInfo failed: ' + JSON.stringify(err))
|
||||
},
|
||||
})
|
||||
} else {
|
||||
storage.setFingerLogin(false)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
||||
@@ -2,56 +2,44 @@
|
||||
<view class="securityCenter">
|
||||
<u-cell-group>
|
||||
<u-cell title="修改密码" @click="navigateTo('/pages/mine/set/securityCenter/updatePwdTab')"></u-cell>
|
||||
<u-cell title="注销账户" @click="zhuxiao"></u-cell>
|
||||
<u-cell title="注销账户" @click="confirmAccountDeletion"></u-cell>
|
||||
</u-cell-group>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
mobile: "", //存储手机号
|
||||
};
|
||||
},
|
||||
<script setup lang="ts">
|
||||
function navigateTo(url: string) {
|
||||
uni.navigateTo({ url })
|
||||
}
|
||||
|
||||
methods: {
|
||||
zhuxiao(){
|
||||
|
||||
uni.showModal({
|
||||
title: "警告",
|
||||
content: "您确定要注销当前账号吗?",
|
||||
confirmText: "确定注销",
|
||||
confirmColor: "#FF0000",
|
||||
cancelText: "取消",
|
||||
success: (res) => {
|
||||
if (res.confirm) {
|
||||
uni.showModal({
|
||||
title: "谨慎操作",
|
||||
content: "再次向您确认,您确定要注销当前账号吗?",
|
||||
confirmText: "坚持注销",
|
||||
confirmColor: "#FF0000",
|
||||
cancelText: "取消",
|
||||
success: (res) => {
|
||||
if (res.confirm) {
|
||||
uni.showToast({
|
||||
title: "您的注销申请已经提交,待管理员审核后。会自动注销当前账号",
|
||||
duration: 10000,
|
||||
});
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
},
|
||||
});
|
||||
function confirmAccountDeletion() {
|
||||
uni.showModal({
|
||||
title: '警告',
|
||||
content: '您确定要注销当前账号吗?',
|
||||
confirmText: '确定注销',
|
||||
confirmColor: '#FF0000',
|
||||
cancelText: '取消',
|
||||
success: (res) => {
|
||||
if (res.confirm) {
|
||||
uni.showModal({
|
||||
title: '谨慎操作',
|
||||
content: '再次向您确认,您确定要注销当前账号吗?',
|
||||
confirmText: '坚持注销',
|
||||
confirmColor: '#FF0000',
|
||||
cancelText: '取消',
|
||||
success: (confirmRes) => {
|
||||
if (confirmRes.confirm) {
|
||||
uni.showToast({
|
||||
title: '您的注销申请已经提交,待管理员审核后。会自动注销当前账号',
|
||||
duration: 10000,
|
||||
})
|
||||
}
|
||||
},
|
||||
})
|
||||
}
|
||||
},
|
||||
navigateTo(url) {
|
||||
uni.navigateTo({
|
||||
url: url,
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
@@ -7,22 +7,10 @@
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
mobile: "", //存储手机号
|
||||
};
|
||||
},
|
||||
|
||||
methods: {
|
||||
navigateTo(url) {
|
||||
uni.navigateTo({
|
||||
url: url,
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
<script setup lang="ts">
|
||||
function navigateTo(url: string) {
|
||||
uni.navigateTo({ url })
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
@@ -38,112 +38,95 @@
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import config from "@/config/config";
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
config,
|
||||
userImage: config.defaultUserPhoto,
|
||||
isCertificate: false,
|
||||
userInfo: {},
|
||||
fileSizeString: "0B",
|
||||
};
|
||||
},
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { onShow } from '@dcloudio/uni-app'
|
||||
import config from '@/config/config'
|
||||
import { isLogin, tipsToLogin, quiteLoginOut, logoff } from '@/utils/filters.js'
|
||||
|
||||
methods: {
|
||||
navigateTo(url) {
|
||||
if (url == "/pages/set/securityCenter/securityCenter") {
|
||||
url += `?mobile=${this.userInfo.mobile}`;
|
||||
}
|
||||
uni.navigateTo({
|
||||
url: url,
|
||||
});
|
||||
},
|
||||
const userImage = config.defaultUserPhoto
|
||||
const userInfo = ref<Record<string, any>>({})
|
||||
const fileSizeString = ref('0B')
|
||||
|
||||
getCacheSize() {
|
||||
let that = this;
|
||||
plus.cache.calculate(function (size) {
|
||||
let sizeCache = parseInt(size);
|
||||
if (sizeCache == 0) {
|
||||
that.fileSizeString = "0B";
|
||||
} else if (sizeCache < 1024) {
|
||||
that.fileSizeString = sizeCache + "B";
|
||||
} else if (sizeCache < 1048576) {
|
||||
that.fileSizeString = (sizeCache / 1024).toFixed(2) + "KB";
|
||||
} else if (sizeCache < 1073741824) {
|
||||
that.fileSizeString = (sizeCache / 1048576).toFixed(2) + "MB";
|
||||
} else {
|
||||
that.fileSizeString = (sizeCache / 1073741824).toFixed(2) + "GB";
|
||||
}
|
||||
});
|
||||
},
|
||||
onShow(() => {
|
||||
userInfo.value = isLogin() || {}
|
||||
// #ifdef APP-PLUS
|
||||
getCacheSize()
|
||||
// #endif
|
||||
})
|
||||
|
||||
checkUserInfo() {
|
||||
if (this.isLogin("auth")) {
|
||||
this.navigateTo("/pages/mine/set/personMsg");
|
||||
} else {
|
||||
this.tipsToLogin();
|
||||
}
|
||||
},
|
||||
function navigateTo(url: string) {
|
||||
if (url === '/pages/mine/set/securityCenter/securityCenter') {
|
||||
url += `?mobile=${userInfo.value.mobile || ''}`
|
||||
}
|
||||
uni.navigateTo({ url })
|
||||
}
|
||||
|
||||
clearCache() {
|
||||
let that = this;
|
||||
let os = plus.os.name;
|
||||
if (os == "Android") {
|
||||
let main = plus.android.runtimeMainActivity();
|
||||
let sdRoot = main.getCacheDir();
|
||||
let files = plus.android.invoke(sdRoot, "listFiles");
|
||||
let len = files.length;
|
||||
for (let i = 0; i < len; i++) {
|
||||
let filePath = "" + files[i];
|
||||
plus.io.resolveLocalFileSystemURL(
|
||||
filePath,
|
||||
function (entry) {
|
||||
if (entry.isDirectory) {
|
||||
entry.removeRecursively(
|
||||
function () {
|
||||
uni.showToast({
|
||||
title: "缓存清理完成",
|
||||
duration: 2000,
|
||||
icon: "none",
|
||||
});
|
||||
that.getCacheSize();
|
||||
},
|
||||
function () {}
|
||||
);
|
||||
} else {
|
||||
entry.remove();
|
||||
}
|
||||
},
|
||||
function () {
|
||||
uni.showToast({
|
||||
title: "文件路径读取失败",
|
||||
duration: 2000,
|
||||
icon: "none",
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
} else {
|
||||
plus.cache.clear(function () {
|
||||
uni.showToast({
|
||||
title: "缓存清理完成",
|
||||
duration: 2000,
|
||||
icon: "none",
|
||||
});
|
||||
that.getCacheSize();
|
||||
});
|
||||
}
|
||||
},
|
||||
},
|
||||
onShow() {
|
||||
this.userInfo = this.isLogin();
|
||||
// #ifdef APP-PLUS
|
||||
this.getCacheSize();
|
||||
// #endif
|
||||
},
|
||||
};
|
||||
function getCacheSize() {
|
||||
// #ifdef APP-PLUS
|
||||
plus.cache.calculate((size) => {
|
||||
const sizeCache = parseInt(String(size))
|
||||
if (sizeCache === 0) {
|
||||
fileSizeString.value = '0B'
|
||||
} else if (sizeCache < 1024) {
|
||||
fileSizeString.value = `${sizeCache}B`
|
||||
} else if (sizeCache < 1048576) {
|
||||
fileSizeString.value = `${(sizeCache / 1024).toFixed(2)}KB`
|
||||
} else if (sizeCache < 1073741824) {
|
||||
fileSizeString.value = `${(sizeCache / 1048576).toFixed(2)}MB`
|
||||
} else {
|
||||
fileSizeString.value = `${(sizeCache / 1073741824).toFixed(2)}GB`
|
||||
}
|
||||
})
|
||||
// #endif
|
||||
}
|
||||
|
||||
function checkUserInfo() {
|
||||
if (isLogin('auth')) {
|
||||
navigateTo('/pages/mine/set/personMsg')
|
||||
} else {
|
||||
tipsToLogin()
|
||||
}
|
||||
}
|
||||
|
||||
function clearCache() {
|
||||
// #ifdef APP-PLUS
|
||||
const os = plus.os.name
|
||||
if (os === 'Android') {
|
||||
const main = plus.android.runtimeMainActivity()
|
||||
const sdRoot = main.getCacheDir()
|
||||
const files = plus.android.invoke(sdRoot, 'listFiles')
|
||||
const len = files.length
|
||||
for (let i = 0; i < len; i++) {
|
||||
const filePath = `${files[i]}`
|
||||
plus.io.resolveLocalFileSystemURL(
|
||||
filePath,
|
||||
(entry) => {
|
||||
if (entry.isDirectory) {
|
||||
entry.removeRecursively(
|
||||
() => {
|
||||
uni.showToast({ title: '缓存清理完成', duration: 2000, icon: 'none' })
|
||||
getCacheSize()
|
||||
},
|
||||
() => {}
|
||||
)
|
||||
} else {
|
||||
entry.remove()
|
||||
}
|
||||
},
|
||||
() => {
|
||||
uni.showToast({ title: '文件路径读取失败', duration: 2000, icon: 'none' })
|
||||
}
|
||||
)
|
||||
}
|
||||
} else {
|
||||
plus.cache.clear(() => {
|
||||
uni.showToast({ title: '缓存清理完成', duration: 2000, icon: 'none' })
|
||||
getCacheSize()
|
||||
})
|
||||
}
|
||||
// #endif
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
@@ -1,58 +1,45 @@
|
||||
<template>
|
||||
<div>
|
||||
<u-collapse v-if="versionData.length !=0">
|
||||
<u-collapse-item class="version-item" :title="item.versionName" v-for="(item, index) in versionData" :key="index">
|
||||
<!-- {{item.body}} -->
|
||||
|
||||
{{item.content}}
|
||||
<u-collapse v-if="versionList.length !== 0">
|
||||
<u-collapse-item
|
||||
class="version-item"
|
||||
:title="item.versionName"
|
||||
v-for="(item, index) in versionList"
|
||||
:key="index"
|
||||
>
|
||||
{{ item.content }}
|
||||
</u-collapse-item>
|
||||
|
||||
</u-collapse>
|
||||
<u-empty class="empty" v-else text="暂无版本信息" mode="list"></u-empty>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getAppVersionList } from "@/api/message";
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
versionData: [],
|
||||
appType: "",
|
||||
params: {
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
},
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
const platform = uni.getSystemInfoSync().platform;
|
||||
/**
|
||||
* 获取是否是安卓
|
||||
*/
|
||||
if (platform === "android") {
|
||||
this.appType = "ANDROID";
|
||||
} else {
|
||||
this.IosWhether = true;
|
||||
this.appType = "IOS";
|
||||
}
|
||||
this.getVersionList();
|
||||
},
|
||||
methods: {
|
||||
async getVersionList() {
|
||||
let res = await getAppVersionList(this.appType, this.params);
|
||||
if (res.data.success) {
|
||||
this.versionData = res.data.result.records;
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { onLoad } from '@dcloudio/uni-app'
|
||||
import { getAppVersionList } from '@/api/message'
|
||||
|
||||
const versionList = ref<any[]>([])
|
||||
const appType = ref('')
|
||||
const params = { pageNumber: 1, pageSize: 10 }
|
||||
|
||||
onLoad(() => {
|
||||
const platform = uni.getSystemInfoSync().platform
|
||||
appType.value = platform === 'android' ? 'ANDROID' : 'IOS'
|
||||
fetchVersionList()
|
||||
})
|
||||
|
||||
async function fetchVersionList() {
|
||||
const res = await getAppVersionList(appType.value, params)
|
||||
if (res.data.success) {
|
||||
versionList.value = res.data.result.records
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.version-item{
|
||||
padding: 10rpx;
|
||||
background: #fff;
|
||||
.version-item {
|
||||
padding: 10rpx;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
</style>
|
||||
</style>
|
||||
|
||||
@@ -3,10 +3,10 @@
|
||||
<view class="date-card">
|
||||
<div class="box">
|
||||
<div class="circle-box">
|
||||
<div class="cricle" @click="signIn()">
|
||||
<span v-if="!ifSign" :class="{ active: signFlag || ifSign }">签到</span>
|
||||
<span v-else :class="{ active: signFlag || ifSign }"
|
||||
:style="ifSign ? 'transform: rotateY(0deg);' : ''">已签</span>
|
||||
<div class="cricle" @click="handleSignIn()">
|
||||
<span v-if="!hasSignedToday" :class="{ active: signAnimating || hasSignedToday }">签到</span>
|
||||
<span v-else :class="{ active: signAnimating || hasSignedToday }"
|
||||
:style="hasSignedToday ? 'transform: rotateY(0deg);' : ''">已签</span>
|
||||
</div>
|
||||
</div>
|
||||
<text class="tips">坚持每天连续签到可以获多重奖励哦</text>
|
||||
@@ -22,19 +22,19 @@
|
||||
<view class="week">
|
||||
<text v-for="item in weekArr" :key="item.id">{{ item }}</text>
|
||||
</view>
|
||||
<view class="date" v-for="obj in dataObj" :key="obj.id">
|
||||
<view class="item" v-for="item in obj" :key="item.id" :class="item == '' ? 'hide' : ''"
|
||||
<view class="date" v-for="(obj, rowIndex) in calendarRows" :key="rowIndex">
|
||||
<view class="item" v-for="(item, dayIndex) in obj" :key="dayIndex" :class="item == '' ? 'hide' : ''"
|
||||
:animation="item == currentDay ? animationData : ''">
|
||||
<view class="just" :class="signArr.indexOf(item) != -1 ? 'active' : ''">
|
||||
<view class="just" :class="signedDays.indexOf(item) != -1 ? 'active' : ''">
|
||||
<view class="top">{{ item }} </view>
|
||||
<view class="bottom">
|
||||
<u-icon name="error" v-if="item <= currentDay" size="24" color="#999"></u-icon>
|
||||
</view>
|
||||
</view>
|
||||
<view class="back" :class="signArr.indexOf(item) != -1 ? 'active' : ''" :style="
|
||||
signArr.indexOf(item) != -1 && ifSign
|
||||
<view class="back" :class="signedDays.indexOf(item) != -1 ? 'active' : ''" :style="
|
||||
signedDays.indexOf(item) != -1 && hasSignedToday
|
||||
? 'transform: rotateY(0deg);'
|
||||
: signArr.indexOf(item) != -1 && item != currentDay
|
||||
: signedDays.indexOf(item) != -1 && item != currentDay
|
||||
? 'transform: rotateY(0deg);'
|
||||
: ''
|
||||
">
|
||||
@@ -47,11 +47,11 @@
|
||||
</view>
|
||||
</view>
|
||||
</div>
|
||||
<view class="mask" :class="{ show: maskFlag, trans: transFlag }" ref="mask">
|
||||
<view class="mask" :class="{ show: showSuccessMask, trans: maskClosing }" ref="mask">
|
||||
<view class="mask-header">
|
||||
<text class="close"></text>
|
||||
<text>签到成功</text>
|
||||
<text class="close" @click="close">×</text>
|
||||
<text class="close" @click="closeSuccessMask">×</text>
|
||||
</view>
|
||||
<view class="mask-con">
|
||||
<u-icon size="120" style="margin: 50rpx 0" :color="aiderLightColor" name="checkmark"></u-icon>
|
||||
@@ -61,231 +61,147 @@
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { sign, signTime } from "@/api/point.js";
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
aiderLightColor:this.$aiderLightColor,
|
||||
signFlag: false,
|
||||
animationData: {},
|
||||
maskFlag: false, //
|
||||
transFlag: false, //动画
|
||||
weekArr: ["日", "一", "二", "三", "四", "五", "六"], //周数组
|
||||
dateArr: [], //每个月的天数
|
||||
monthArr: [
|
||||
//实例化每个月
|
||||
"1月",
|
||||
"2月",
|
||||
"3月",
|
||||
"4月",
|
||||
"5月",
|
||||
"6月",
|
||||
"7月",
|
||||
"8月",
|
||||
"9月",
|
||||
"10月",
|
||||
"11月",
|
||||
"12月",
|
||||
], //今天一个月英文
|
||||
currentMonth: "", //当月
|
||||
currentMonthIndex: "", //当月
|
||||
currentYear: "", //今年
|
||||
currentDay: "", //今天
|
||||
currentWeek: "", //获取当月一号是周几
|
||||
dataObj: [], //一个月有多少天这个获取
|
||||
signArr: [], //本月签到过的天数 该参数用于请求接口后获取当月都哪天签到了
|
||||
signAll: [], //所有签到数据
|
||||
ifSign: false, //今天是否签到
|
||||
};
|
||||
},
|
||||
async onLoad() {
|
||||
//获取签到数据
|
||||
var response = await signTime(
|
||||
new Date().getFullYear() + "" + this.makeUp(new Date().getMonth() + 1)
|
||||
);
|
||||
this.signAll = response.data.result;
|
||||
//获取展示数据
|
||||
this.getDate();
|
||||
},
|
||||
methods: {
|
||||
/**
|
||||
* 补0
|
||||
*/
|
||||
makeUp(val) {
|
||||
if (val >= 10) {
|
||||
return val;
|
||||
} else {
|
||||
return "0" + val;
|
||||
}
|
||||
},
|
||||
<script setup lang="ts">
|
||||
import { ref, computed } from 'vue'
|
||||
import { onLoad } from '@dcloudio/uni-app'
|
||||
import { useStore } from '@/store'
|
||||
import { sign, signTime } from '@/api/point.js'
|
||||
|
||||
/**
|
||||
* 点击签到
|
||||
*/
|
||||
async signIn() {
|
||||
await sign().then((response) => {
|
||||
if (this.ifSign) return;
|
||||
if (this.signFlag) return;
|
||||
if (response.data.code != 200) {
|
||||
uni.showToast({
|
||||
title: response.data.message,
|
||||
duration: 2000,
|
||||
icon: "none",
|
||||
});
|
||||
const store = useStore()
|
||||
const aiderLightColor = computed(() => store.getters.aiderLightColor)
|
||||
|
||||
return false;
|
||||
}
|
||||
var that = this;
|
||||
var animation = uni.createAnimation({
|
||||
duration: 200,
|
||||
timingFunction: "linear",
|
||||
});
|
||||
this.signArr.push(this.currentDay);
|
||||
this.animation = animation;
|
||||
animation.rotateY(0).step();
|
||||
this.animationData = animation.export();
|
||||
const signAnimating = ref(false)
|
||||
const animationData = ref({})
|
||||
const showSuccessMask = ref(false)
|
||||
const maskClosing = ref(false)
|
||||
const weekArr = ['日', '一', '二', '三', '四', '五', '六']
|
||||
const monthLabels = ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月']
|
||||
const currentMonth = ref('')
|
||||
const currentMonthIndex = ref(0)
|
||||
const currentYear = ref(0)
|
||||
const currentDay = ref(0)
|
||||
const calendarRows = ref<any[][]>([])
|
||||
const signedDays = ref<number[]>([])
|
||||
const signRecords = ref<any[]>([])
|
||||
const hasSignedToday = ref(false)
|
||||
|
||||
setTimeout(
|
||||
function () {
|
||||
that.signFlag = true;
|
||||
this.maskFlag = true;
|
||||
this.ifSign = !this.ifSign;
|
||||
animation.rotateY(0).step();
|
||||
this.animationData = animation.export();
|
||||
}.bind(this),
|
||||
200
|
||||
);
|
||||
});
|
||||
},
|
||||
onLoad(async () => {
|
||||
const response = await signTime(
|
||||
`${new Date().getFullYear()}${padZero(new Date().getMonth() + 1)}`
|
||||
)
|
||||
signRecords.value = response.data.result
|
||||
buildCalendar()
|
||||
})
|
||||
|
||||
/**
|
||||
* 签到成功后关闭弹窗
|
||||
*/
|
||||
close() {
|
||||
var that = this;
|
||||
this.maskFlag = false;
|
||||
this.transFlag = true;
|
||||
setTimeout(() => {
|
||||
that.transFlag = false;
|
||||
}, 500);
|
||||
},
|
||||
function padZero(val: number) {
|
||||
return val >= 10 ? String(val) : `0${val}`
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取今天时间
|
||||
*
|
||||
*/
|
||||
getDate() {
|
||||
var date = new Date(),
|
||||
index = date.getMonth(),
|
||||
curDay = null;
|
||||
this.currentYear = date.getFullYear();
|
||||
this.currentMonth = this.monthArr[index];
|
||||
this.currentMonthIndex = index + 1;
|
||||
this.currentDay = date.getDate();
|
||||
if (this.currentDay == this.signArr[this.signArr.length - 1]) {
|
||||
this.ifSign = true;
|
||||
}
|
||||
curDay = this.getWeekByDay(this.currentYear + "-" + (index + 1) + "-1");
|
||||
this.getMonthDays(index, curDay);
|
||||
this.curentSignData();
|
||||
},
|
||||
async function handleSignIn() {
|
||||
if (hasSignedToday.value || signAnimating.value) return
|
||||
|
||||
/**
|
||||
* 获取当前已经签到的时间
|
||||
*/
|
||||
curentSignData() {
|
||||
var date = new Date(),
|
||||
index = date.getMonth(),
|
||||
curDay = null;
|
||||
this.signArr = [];
|
||||
for (var i = 0; i < this.signAll.length; i++) {
|
||||
var item = this.signAll[i];
|
||||
item.createTime = item.createTime.split(" ")[0];
|
||||
var itemVal = item.createTime.split("-");
|
||||
if (
|
||||
Number(itemVal[0]) === Number(this.currentYear) &&
|
||||
Number(itemVal[1]) === Number(this.currentMonthIndex)
|
||||
) {
|
||||
this.signArr.push(Number(itemVal[2]));
|
||||
}
|
||||
if (
|
||||
Number(itemVal[0]) === Number(date.getFullYear()) &&
|
||||
Number(itemVal[1]) === Number(index + 1) &&
|
||||
Number(itemVal[2]) === Number(date.getDate())
|
||||
) {
|
||||
this.ifSign = true;
|
||||
}
|
||||
}
|
||||
},
|
||||
const response = await sign()
|
||||
if (response.data.code !== 200) {
|
||||
uni.showToast({
|
||||
title: response.data.message,
|
||||
duration: 2000,
|
||||
icon: 'none',
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
/**
|
||||
* 循环出当前月份的时间
|
||||
* 例子:
|
||||
* "","","","","","",1,
|
||||
* 2 ,3 ,4 ,5 ,6 ,7 ,8,
|
||||
* ...依次向下排
|
||||
*/
|
||||
getMonthDays(index, day) {
|
||||
//day 当月1号是周几
|
||||
this.dateArr = [];
|
||||
this.dataObj = [];
|
||||
for (var i = 0; i < day; i++) {
|
||||
this.dateArr.push("");
|
||||
}
|
||||
if (
|
||||
index == 0 ||
|
||||
index == 2 ||
|
||||
index == 4 ||
|
||||
index == 6 ||
|
||||
index == 7 ||
|
||||
index == 9 ||
|
||||
index == 11
|
||||
) {
|
||||
for (let i = 1; i < 32; i++) {
|
||||
this.dateArr.push(i);
|
||||
}
|
||||
}
|
||||
if (index == 3 || index == 5 || index == 8 || index == 10) {
|
||||
for (let i = 1; i < 31; i++) {
|
||||
this.dateArr.push(i);
|
||||
}
|
||||
}
|
||||
if (index == 1) {
|
||||
if (
|
||||
(this.currentYear % 4 == 0 && this.currentYear % 100 != 0) ||
|
||||
this.currentYear % 400 == 0
|
||||
) {
|
||||
for (let i = 1; i < 30; i++) {
|
||||
this.dateArr.push(i);
|
||||
}
|
||||
} else {
|
||||
for (let i = 1; i < 29; i++) {
|
||||
this.dateArr.push(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (var y = 0; y < 10; y++) {
|
||||
if (this.dateArr.length > 7) {
|
||||
this.dataObj.push(this.dateArr.splice(0, 7));
|
||||
} else {
|
||||
for (let i = 0; i < 7 - this.dateArr.length; i++) {
|
||||
this.dateArr.push("");
|
||||
}
|
||||
}
|
||||
}
|
||||
this.dataObj.push(this.dateArr);
|
||||
},
|
||||
const animation = uni.createAnimation({ duration: 200, timingFunction: 'linear' })
|
||||
signedDays.value.push(currentDay.value)
|
||||
animation.rotateY(0).step()
|
||||
animationData.value = animation.export()
|
||||
|
||||
/**
|
||||
* 获取当前月份有几周
|
||||
*/
|
||||
getWeekByDay(dayValue) {
|
||||
var day = new Date(Date.parse(dayValue.replace(/-/g, "/"))).getDay(); //将日期值格式化
|
||||
return day;
|
||||
},
|
||||
},
|
||||
};
|
||||
setTimeout(() => {
|
||||
signAnimating.value = true
|
||||
showSuccessMask.value = true
|
||||
hasSignedToday.value = true
|
||||
animation.rotateY(0).step()
|
||||
animationData.value = animation.export()
|
||||
}, 200)
|
||||
}
|
||||
|
||||
function closeSuccessMask() {
|
||||
showSuccessMask.value = false
|
||||
maskClosing.value = true
|
||||
setTimeout(() => {
|
||||
maskClosing.value = false
|
||||
}, 500)
|
||||
}
|
||||
|
||||
function buildCalendar() {
|
||||
const date = new Date()
|
||||
const monthIndex = date.getMonth()
|
||||
currentYear.value = date.getFullYear()
|
||||
currentMonth.value = monthLabels[monthIndex]
|
||||
currentMonthIndex.value = monthIndex + 1
|
||||
currentDay.value = date.getDate()
|
||||
syncSignedDays()
|
||||
const firstWeekDay = getWeekByDay(`${currentYear.value}-${monthIndex + 1}-1`)
|
||||
buildMonthDays(monthIndex, firstWeekDay)
|
||||
}
|
||||
|
||||
function syncSignedDays() {
|
||||
const date = new Date()
|
||||
const monthIndex = date.getMonth()
|
||||
signedDays.value = []
|
||||
hasSignedToday.value = false
|
||||
|
||||
signRecords.value.forEach((item) => {
|
||||
const datePart = item.createTime.split(' ')[0]
|
||||
const parts = datePart.split('-')
|
||||
if (
|
||||
Number(parts[0]) === currentYear.value &&
|
||||
Number(parts[1]) === currentMonthIndex.value
|
||||
) {
|
||||
signedDays.value.push(Number(parts[2]))
|
||||
}
|
||||
if (
|
||||
Number(parts[0]) === date.getFullYear() &&
|
||||
Number(parts[1]) === monthIndex + 1 &&
|
||||
Number(parts[2]) === date.getDate()
|
||||
) {
|
||||
hasSignedToday.value = true
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function buildMonthDays(monthIndex: number, firstWeekDay: number) {
|
||||
const daysInRow: any[] = []
|
||||
const rows: any[][] = []
|
||||
for (let i = 0; i < firstWeekDay; i++) {
|
||||
daysInRow.push('')
|
||||
}
|
||||
|
||||
const isLongMonth = [0, 2, 4, 6, 7, 9, 11].includes(monthIndex)
|
||||
const isFebruary = monthIndex === 1
|
||||
let totalDays = isLongMonth ? 31 : 30
|
||||
if (isFebruary) {
|
||||
const year = currentYear.value
|
||||
const isLeap = (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0
|
||||
totalDays = isLeap ? 29 : 28
|
||||
}
|
||||
|
||||
for (let day = 1; day <= totalDays; day++) {
|
||||
daysInRow.push(day)
|
||||
}
|
||||
|
||||
while (daysInRow.length) {
|
||||
const row = daysInRow.splice(0, 7)
|
||||
while (row.length < 7) {
|
||||
row.push('')
|
||||
}
|
||||
rows.push(row)
|
||||
}
|
||||
calendarRows.value = rows
|
||||
}
|
||||
|
||||
function getWeekByDay(dayValue: string) {
|
||||
return new Date(Date.parse(dayValue.replace(/-/g, '/'))).getDay()
|
||||
}
|
||||
</script>
|
||||
<style scoped>
|
||||
page {
|
||||
|
||||
Reference in New Issue
Block a user