smart-app alpha 版本

This commit is contained in:
zhuoda
2024-03-10 22:26:32 +08:00
parent d64b769d40
commit 728ddb9a7e
295 changed files with 20261 additions and 1 deletions

View File

@@ -0,0 +1,293 @@
<template>
<view class="container">
<view>
<smart-tabs :tabsList="tabs" v-model="smartTabIndex" @change="onTabChange" :fixed="true" />
</view>
<view class="smart-detail smart-margin-top60 content" id="detail1">
<view class="smart-detail-card">
<view class="smart-detail-card-title"> 企业基础信息</view>
<view class="smart-detail-card-cell">
<view class="smart-detail-card-label"> 企业名称 </view>
<view class="smart-detail-card-value">
{{ data.enterpriseName }}
</view>
</view>
<view class="smart-detail-card-cell">
<view class="smart-detail-card-label"> 统一社会信用代码 </view>
<view class="smart-detail-card-value">
{{ data.unifiedSocialCreditCode }}
</view>
</view>
<view class="smart-detail-card-cell">
<view class="smart-detail-card-label"> 类型 </view>
<view class="smart-detail-card-value">
{{ $smartEnumPlugin.getDescByValue('ENTERPRISE_TYPE_ENUM', data.type) }}
</view>
</view>
<view class="smart-detail-card-cell">
<view class="smart-detail-card-label"> 企业ID </view>
<view class="smart-detail-card-value">
{{ data.enterpriseId }}
</view>
</view>
</view>
<view class="smart-detail-card" id="detail2">
<view class="smart-detail-card-title"> 图片信息</view>
<view class="smart-detail-card-cell" v-if="data.enterpriseLogo && data.enterpriseLogo.length > 0">
<view class="smart-detail-card-label"> 企业logo </view>
<view class="smart-detail-card-value" @click="preview([data.enterpriseLogo[0].fileUrl])">
<image :src="data.enterpriseLogo[0].fileUrl"></image>
</view>
</view>
<view class="smart-detail-card-cell" v-if="data.businessLicense && data.businessLicense.length > 0">
<view class="smart-detail-card-label"> 营业执照 </view>
<view class="smart-detail-card-value" @click="preview([data.businessLicense[0].fileUrl])">
<image :src="data.businessLicense[0].fileUrl"></image>
</view>
</view>
</view>
<view class="smart-detail-card" id="detail3">
<view class="smart-detail-card-title"> 联系方式</view>
<view class="smart-detail-card-cell">
<view class="smart-detail-card-label"> 联系人 </view>
<view class="smart-detail-card-value">
{{ data.contact }}
</view>
</view>
<view class="smart-detail-card-cell">
<view class="smart-detail-card-label"> 联系人电话 </view>
<view class="smart-detail-card-value">
{{ data.contactPhone }}
</view>
</view>
<view class="smart-detail-card-cell">
<view class="smart-detail-card-label"> 邮箱 </view>
<view class="smart-detail-card-value">
{{ data.email }}
</view>
</view>
</view>
</view>
<view class="btn-group">
<button class="btn" type="warn" @click="onDelete">删除</button>
<button class="btn" type="primary" @click="onChange">修改</button>
</view>
</view>
</template>
<script setup>
import SmartTabs from '/@/components/smart-tabs/index.vue';
import { ref, reactive } from 'vue';
import { enterpriseApi } from '/@/api/business/oa/enterprise-api';
import { onShow, onLoad } from '@dcloudio/uni-app';
import { smartSentry } from '/@/lib/smart-sentry';
import { SmartLoading, SmartToast } from '/@/lib/smart-support';
// ----------------------- tab -----------------------
const tabs = ref([
{
label: '基础信息',
value: 1,
},
{
label: '图片信息',
value: 2,
},
{
label: '联系人',
value: 3,
},
]);
const smartTabIndex = ref(1);
function onTabChange(tabIndex) {
console.log(12, tabIndex);
uni.pageScrollTo({
selector: '#detail' + tabIndex,
duration: 300,
success: console.log,
fail: console.log,
});
}
// ----------------------- 详情 -----------------------
const data = reactive({
//企业ID
enterpriseId: '',
//企业名称
enterpriseName: '',
//统一社会信用代码
unifiedSocialCreditCode: '',
//类型
type: '',
//联系人
contact: '',
//联系人电话
contactPhone: '',
//邮箱
email: '',
//详细地址
address: '',
//企业logo
enterpriseLogo: undefined,
//营业执照
businessLicense: undefined,
});
async function getDetail(id) {
try {
SmartLoading.show();
let res = await enterpriseApi.detail(id);
data.enterpriseId = res.data.enterpriseId;
data.enterpriseName = res.data.enterpriseName;
data.unifiedSocialCreditCode = res.data.unifiedSocialCreditCode;
data.type = res.data.type;
data.contact = res.data.contact;
data.contactPhone = res.data.contactPhone;
data.email = res.data.email;
data.address = res.data.address;
data.enterpriseLogo = res.data.enterpriseLogo;
data.businessLicense = res.data.businessLicense;
} catch (e) {
smartSentry.captureError(e);
} finally {
SmartLoading.hide();
}
}
function preview(urls) {
uni.previewImage({
urls: urls,
});
}
onLoad((options) => {
if (options.enterpriseId) {
data.enterpriseId = options.enterpriseId;
getDetail(options.enterpriseId);
}
});
onShow(() => {
getDetail(data.enterpriseId);
});
function onChange() {
uni.navigateTo({ url: '/pages/enterprise/enterprise-form?enterpriseId=' + data.enterpriseId });
}
function onDelete() {
uni.showModal({
title: '提示',
content: '确定要删除吗?',
confirmText: '确定删除',
success: function (res) {
if (res.confirm) {
doDelete();
}
},
});
}
async function doDelete() {
try {
SmartLoading.show();
await enterpriseApi.delete(data.enterpriseId);
SmartToast.success('删除成功');
setTimeout(() => {
uni.redirectTo({ url: '/pages/enterprise/enterprise-list' });
}, 500);
} catch (e) {
smartSentry.captureError(e);
} finally {
SmartLoading.hide();
}
}
</script>
<style lang="scss" scoped>
.container {
background-color: #f4f4f4;
height: 100vh;
overflow-y: scroll;
}
.smart-detail {
.smart-detail-card {
background-color: white;
margin: 0 auto 14px auto;
width: 94%;
border-radius: 16rpx;
box-sizing: border-box;
padding: 16rpx 30rpx;
.smart-detail-card-title {
height: 70rpx;
display: flex;
align-items: center;
font-size: $uni-font-size-lg;
color: #323333;
font-weight: bold;
margin-bottom: 16rpx;
&::before {
content: '';
height: 32rpx;
width: 3px;
border-radius: 4rpx;
margin-right: 10rpx;
background-color: $uni-color-primary;
}
}
.smart-detail-card-cell {
display: flex;
min-height: 80rpx;
padding: 10rpx 0;
justify-content: space-between;
align-items: center;
flex-wrap: wrap;
border-top: 1rpx solid #ededed;
.smart-detail-card-label {
color: #666666;
font-size: $uni-font-size-lg;
}
.smart-detail-card-value {
color: black;
font-size: $uni-font-size-lg;
padding: 20rpx 0;
}
}
}
}
.content {
margin-bottom: 120px;
}
.btn-group {
border-top: #eee 1px solid;
height: 80px;
display: flex;
flex-direction: row;
align-items: center;
position: fixed;
bottom: 0;
background-color: white;
width: 100%;
.btn {
margin: 10px;
flex: 1;
}
}
</style>

View File

@@ -0,0 +1,184 @@
<template>
<view class="container">
<view class="smart-form">
<uni-forms ref="formRef" :label-width="100" :modelValue="form" label-position="left" :rules="rules">
<view class="smart-form-group">
<view class="smart-form-group-title"> 基本信息 </view>
<view class="smart-form-group-content">
<uni-forms-item class="smart-form-item" label="企业名称:" name="enterpriseName" required>
<uni-easyinput class="uni-mt-5" trim="all" v-model="form.enterpriseName" placeholder="请输入 企业名称" />
</uni-forms-item>
<uni-forms-item class="smart-form-item" label="统一社会信用代码:" name="unifiedSocialCreditCode" required>
<uni-easyinput class="uni-mt-5" trim="all" v-model="form.unifiedSocialCreditCode" placeholder="请输入 统一社会信用代码" />
</uni-forms-item>
<uni-forms-item class="smart-form-item" label="企业类型:" name="type" required>
<smart-enum-radio v-model="form.type" enumName="ENTERPRISE_TYPE_ENUM" />
</uni-forms-item>
<uni-forms-item class="smart-form-item" label="公司地址:" name="address">
<uni-easyinput class="uni-mt-5" trim="all" v-model="form.address" placeholder="请输入 公司地址" />
</uni-forms-item>
</view>
</view>
<view class="smart-form-group">
<view class="smart-form-group-title"> 联系方式 </view>
<view class="smart-form-group-content">
<uni-forms-item class="smart-form-item" label="联系人" name="contact" required>
<uni-easyinput class="uni-mt-5" trim="all" v-model="form.contact" placeholder="请输入 联系人" />
</uni-forms-item>
<uni-forms-item class="smart-form-item" label="联系人电话" name="contactPhone" required>
<uni-easyinput class="uni-mt-5" trim="all" v-model="form.contactPhone" placeholder="请输入 联系人电话" />
</uni-forms-item>
<uni-forms-item class="smart-form-item" label="邮箱" name="email">
<uni-easyinput class="uni-mt-5" trim="all" v-model="form.email" placeholder="请输入 邮箱" />
</uni-forms-item>
</view>
</view>
</uni-forms>
<view class="smart-form-submit smart-margin-top20 bottom-button">
<button class="smart-form-submit-btn smart-margin-right20" type="default" @click="cancel">取消</button>
<button class="smart-form-submit-btn" type="warn" @click="reset">重置</button>
<button class="smart-form-submit-btn" type="primary" @click="ok">保存</button>
</view>
</view>
</view>
</template>
<script setup>
import { reactive, ref } from 'vue';
import { enterpriseApi } from '/@/api/business/oa/enterprise-api';
import { regular } from '/@/constants/regular-const';
import SmartEnumRadio from '/@/components/smart-enum-radio/index.vue';
import { smartSentry } from '/@/lib/smart-sentry';
import { SmartLoading, SmartToast } from '/@/lib/smart-support';
import { onLoad, onReady, onShow } from '@dcloudio/uni-app';
// --------------------- 表单 ---------------------
const defaultFormData = {
enterpriseId: undefined,
enterpriseName: undefined,
unifiedSocialCreditCode: undefined,
type: undefined,
contact: undefined,
contactPhone: undefined,
email: undefined,
address: undefined,
disabledFlag: false,
};
let form = reactive({ ...defaultFormData });
const rules = {
enterpriseName: {
rules: [{ required: true, errorMessage: '请输入企业名称' }],
},
unifiedSocialCreditCode: {
rules: [{ required: true, errorMessage: '请输入 统一社会信用代码' }],
},
contact: {
rules: [{ required: true, errorMessage: '请输入 联系人' }],
},
contactPhone: {
rules: [
{ required: true, errorMessage: '请输入联系人电话' },
{ pattern: regular.phone, errorMessage: '电话格式错误' },
],
},
type: {
rules: [{ required: true, errorMessage: '请选择 类型' }],
},
};
// --------------------- 详情 ---------------------
onLoad((options) => {
if (options.enterpriseId) {
form.enterpriseId = options.enterpriseId;
getDetail(options.enterpriseId);
}
});
onReady(() => {
if (form.enterpriseId) {
uni.setNavigationBarTitle({
title: '修改客户',
});
}
});
async function getDetail(id) {
try {
SmartLoading.show();
let res = await enterpriseApi.detail(id);
form.enterpriseId = res.data.enterpriseId;
form.enterpriseName = res.data.enterpriseName;
form.unifiedSocialCreditCode = res.data.unifiedSocialCreditCode;
form.type = res.data.type;
form.contact = res.data.contact;
form.contactPhone = res.data.contactPhone;
form.email = res.data.email;
form.address = res.data.address;
} catch (e) {
smartSentry.captureError(e);
} finally {
SmartLoading.hide();
}
}
// ----------------------- 表单操作 ------------------------
const formRef = ref();
// 取消
function cancel() {
close();
uni.navigateBack();
}
// 重置
function reset() {
Object.assign(form, defaultFormData);
formRef.value.clearValidate();
}
// 确定
function ok() {
formRef.value
.validate()
.then(async () => {
SmartLoading.show();
try {
if (form.enterpriseId) {
await enterpriseApi.update(form);
} else {
await enterpriseApi.create(form);
}
SmartToast.success(`${form.enterpriseId ? '修改' : '添加'}成功`);
uni.navigateBack();
} catch (error) {
smartSentry.captureError(error);
} finally {
SmartLoading.hide();
}
})
.catch((error) => {
console.log('error', error);
SmartToast.toast('参数验证错误,请仔细填写表单数据!');
});
}
</script>
<style lang="scss" scoped>
.query-form-pop {
height: 800rpx;
overflow-y: scroll;
}
.bottom-button {
position: fixed;
bottom: 0;
}
</style>

View File

@@ -0,0 +1,217 @@
<template>
<view class="container">
<mescroll-body @init="mescrollInit" :down="{ auto: false }" @down="onDown" @up="onUp" :up="{ toTop: { src: '' } }">
<!--搜索框-->
<uni-nav-bar :border="false" fixed :leftWidth="0" rightWidth="70px">
<view class="input">
<uni-easyinput
prefixIcon="search"
:clearable="true"
trim="all"
v-model="queryForm.keywords"
placeholder="搜索:企业名称、联系人、联系电话等"
@confirm="search"
@clear="search"
/>
</view>
<template #right>
<view class="nav-right" @click="search">
<uni-icons type="search" size="30"></uni-icons>
<view class="nav-right-name"> 搜索 </view>
</view>
</template>
</uni-nav-bar>
<!-- 列表 -->
<view class="list-container">
<view class="list-item" @click="gotoDetail(item.enterpriseId)" v-for="item in listData" :key="item.enterpriseId">
<view class="list-item-row">
<view class="list-item-label">公司</view>
<view class="list-item-content bolder">{{ item.enterpriseName }}</view>
<view class="list-item-phone" @click="callPhone(item.contactPhone)">
<uni-icons type="phone" size="18" color="#007aff"></uni-icons>
联系
</view>
</view>
<view class="list-item-row">
<view class="list-item-label">营业执照</view>
<view class="list-item-content">{{ item.unifiedSocialCreditCode }}</view>
</view>
<view class="list-item-row">
<view class="list-item-label">联系人</view>
<view class="list-item-content">{{ item.contact }}</view>
</view>
<view class="list-item-row">
<view class="list-item-label">电话</view>
<view class="list-item-content">{{ item.contactPhone }}</view>
</view>
</view>
</view>
</mescroll-body>
<uni-fab ref="fab" :pattern="fabPattern" horizontal="right" @fabClick="gotoAdd" />
</view>
</template>
<script setup>
import { reactive, ref } from 'vue';
import { enterpriseApi } from '/@/api/business/oa/enterprise-api';
import { onPageScroll, onReachBottom, onShow } from '@dcloudio/uni-app';
import useMescroll from '@/uni_modules/uni-mescroll/hooks/useMescroll';
import { smartSentry } from '/@/lib/smart-sentry';
import _ from 'lodash';
// --------------------------- 查询 ---------------------------------
const defaultForm = {
keywords: '', //标题、作者、来源
pageNum: 1,
pageSize: 10,
};
// 查询表单
const queryForm = reactive({ ...defaultForm });
// 列表数据
const listData = ref([]);
function buildQueryParam(pageNum) {
queryForm.pageNum = pageNum;
return Object.assign({}, queryForm, { pageNum });
}
async function query(mescroll, isDownFlag, param) {
try {
let res = await enterpriseApi.pageQuery(param);
if (!isDownFlag) {
listData.value = listData.value.concat(res.data.list);
} else {
listData.value = res.data.list;
}
mescroll.endSuccess(res.data.list.length, res.data.pages > res.data.pageNum);
} catch (e) {
smartSentry.captureError(e);
//联网失败, 结束加载
mescroll.endErr();
}
}
const { mescrollInit, getMescroll } = useMescroll(onPageScroll, onReachBottom);
/**
* 搜索
*/
function search() {
query(getMescroll(), true, buildQueryParam(1));
uni.pageScrollTo({
scrollTop: 0,
});
}
/**
* 下拉刷新
*/
function onDown(mescroll) {
queryForm.pageNum = 1;
query(mescroll, true, buildQueryParam(1));
}
/**
* 上拉加载更多
*/
function onUp(mescroll) {
query(mescroll, false, buildQueryParam(mescroll.num));
}
onShow(() => {
search();
});
// --------------------------- 添加 ---------------------------------
const fabPattern = reactive({
color: 'blue',
backgroundColor: 'blue',
});
function gotoAdd() {
uni.navigateTo({ url: '/pages/enterprise/enterprise-form' });
}
// --------------------------- 详情 ---------------------------------
function callPhone(phone) {
uni.makePhoneCall({
phoneNumber: phone, //仅为示例
});
}
function gotoDetail(id) {
uni.navigateTo({ url: '/pages/enterprise/enterprise-detail?enterpriseId=' + id });
}
</script>
<style lang="scss" scoped>
.container {
background-color: #f4f4f4;
}
.input {
width: 100%;
height: 60rpx;
background: #f7f8f9;
border-radius: 4px;
margin: 8rpx 0;
display: flex;
align-items: center;
}
.nav-right {
width: 140rpx;
display: flex;
height: 88rpx;
flex-direction: row;
line-height: 88rpx;
.nav-right-name {
margin-left: 5px;
line-height: 88rpx;
font-size: 30rpx;
}
}
.list-container {
padding: 10rpx 20rpx;
margin-top: 10rpx;
.list-item {
background: #ffffff;
box-shadow: 0px 3px 4px 0px rgba(24, 144, 255, 0.06);
margin-bottom: 20rpx;
padding: 30rpx 40rpx;
.list-item-row {
display: flex;
flex-direction: row;
margin-bottom: 16rpx;
justify-content: flex-start;
.list-item-label {
font-size: 28rpx;
font-weight: 400;
text-align: left;
color: #999999;
}
.bolder {
font-weight: 600 !important;
}
.list-item-content {
font-size: 30rpx;
font-weight: 500;
text-align: left;
color: #323333;
}
.list-item-phone {
color: $uni-color-primary;
margin-left: auto;
}
}
}
}
</style>

View File

@@ -0,0 +1,49 @@
<template>
<view class="font-item-box">
<text :class="modelValue==0?'active':''" @click="modelValue=0">标准</text>
<view></view>
<text :class="modelValue==1?'active':''" @click="modelValue=1">大号</text>
<view></view>
<text :class="modelValue==2?'active':''" @click="modelValue=2">小号</text>
</view>
</template>
<script setup>
import { watch } from 'vue';
const emits = defineEmits(['update:modelValue'])
const props = defineProps({
modelValue:{
type:Number,
default:0
}
})
watch(()=>props.modelValue,(newValue,oldValue)=>{
emits('update:modelValue',newValue)
})
</script>
<style lang="scss" scoped>
.font-item-box {
width: 100%;
display: flex;
justify-content: flex-end;
align-items: center;
text {
font-size: 30rpx;
color: #cccccc;
&.active {
color: #1A9AFF;
}
}
view {
width: 4rpx;
height: 16rpx;
background-color: #e6e6e6;
margin: 0 42rpx;
}
}
</style>

View File

@@ -0,0 +1,59 @@
<template>
<view class="card-content">
<view @click="modelValue = index" :class="modelValue == index?'active':''"
v-for="(item,index) in list" :key="index">
{{item}}
</view>
</view>
</template>
<script setup>
import { watch } from 'vue';
const emits = defineEmits(['update:modelValue'])
const props = defineProps({
modelValue:{
type:Number,
default:0
},
list:{
type:Array,
default:[]
}
})
watch(()=>props.modelValue,(newValue,oldValue)=>{
emits('update:modelValue',newValue)
})
</script>
<style lang="scss" scoped>
.card-content {
padding: 0 30rpx 24rpx;
display: flex;
flex-wrap: wrap;
view {
box-sizing: border-box;
width: 197rpx;
height: 72rpx;
background: #f7f8f9;
border-radius: 8rpx;
text-align: center;
line-height: 72rpx;
margin-right: 24rpx;
margin-top: 24rpx;
font-size: 30rpx;
color: #323333;
border: 2rpx solid #f7f8f9;
&:nth-child(3n) {
margin-right: 0;
}
}
.active {
background: #eff8ff;
border: 2rpx solid #2291f9;
}
}
</style>

View File

@@ -0,0 +1,60 @@
<template>
<view class="sex-box">
<view class="sex-item" :class="modelValue?'active':''" @click="modelValue=true">
<uni-icons type="circle" v-if="!modelValue" color="#ccc" size="30"></uni-icons>
<uni-icons v-else type="checkbox-filled" color="#1A9AFF" size="30"></uni-icons>
<view>
</view>
</view>
<view class="sex-item" :class="!modelValue?'active':''" @click="modelValue=false">
<uni-icons type="circle" v-if="modelValue" color="#ccc" size="30"></uni-icons>
<uni-icons v-else type="checkbox-filled" color="#1A9AFF" size="30"></uni-icons>
<view>
</view>
</view>
</view>
</template>
<script setup>
import { watch } from 'vue';
const emits = defineEmits(['update:modelValue'])
const props = defineProps({
modelValue:{
type:Boolean,
default:true
}
})
watch(()=>props.modelValue,(newValue,oldValue)=>{
emits('update:modelValue',newValue)
})
</script>
<style lang="scss" scoped>
.sex-box {
width: 100%;
display: flex;
justify-content: flex-end;
.sex-item {
display: flex;
width: 112rpx;
height: 64rpx;
background-color: #f3f3f3;
border: 1rpx solid #ededed;
align-items: center;
margin-left: 40rpx;
justify-content: center;
border-radius: 8rpx;
font-size: 32rpx;
}
.active {
background: #f1f9ff;
border: 1rpx solid #1a9aff;
color: #1A9AFF;
}
}
</style>

View File

@@ -0,0 +1,199 @@
<template>
<view class="">
<view class="form-card">
<view class="title"> 常用功能 </view>
<view class="content">
<uni-forms :label-width="100" :modelValue="formData" label-position="left">
<uni-forms-item class="uni-forms-item" label="姓名" name="name">
<input class="input" type="text" v-model="formData.name" placeholder="请输入姓名" />
</uni-forms-item>
<uni-forms-item class="uni-forms-item" label="手机号码" name="name">
<input class="input" type="text" v-model="formData.name" placeholder="请输入手机号码" />
</uni-forms-item>
<uni-forms-item class="uni-forms-item" label="邮箱地址" name="name">
<input class="input" type="text" v-model="formData.name" placeholder="请输入邮箱地址" />
</uni-forms-item>
<uni-forms-item class="uni-forms-item" label="性别" name="name">
<RadioSex v-model="formData.sex"></RadioSex>
</uni-forms-item>
<uni-forms-item class="uni-forms-item" label="出生日期" name="name">
<view class="item-box">
<picker ref="datePickerRef" mode="date" @change="bindDateChange">
<input ref="dateInputRef" class="input" type="text" v-model="date" placeholder="点击选择时间" />
</picker>
</view>
</uni-forms-item>
<uni-forms-item class="uni-forms-item" label="所在地" name="name">
<input class="input" disabled type="text" v-model="formData.name" placeholder="点击选择所在地" />
</uni-forms-item>
</uni-forms>
</view>
</view>
<view class="form-card">
<view class="title"> 推送用户 </view>
<view class="content">
<uni-forms :label-width="100" :modelValue="formData" label-position="left">
<uni-forms-item class="uni-forms-item" label="选择用户" name="name">
<view class="item-box" @click="openSelectPeople">
<image class="user-select-image" src="/src/static/images/form/add.png" mode=""></image>
</view>
</uni-forms-item>
</uni-forms>
</view>
</view>
<view class="form-card">
<view class="title"> 兴趣爱好 </view>
<Interest v-model="formData.interest" :list="interestList"></Interest>
</view>
<view class="form-card">
<view class="title"> 推送用户 </view>
<view class="content">
<uni-forms :label-width="100" :modelValue="formData" label-position="left">
<uni-forms-item class="uni-forms-item" label="亮度调整" name="name">
<view class="item-box">
<slider style="width: 100%" value="50" activeColor="#2291F9" backgroundColor="#f5f6f8" block-color="#2291F9" block-size="20" />
</view>
</uni-forms-item>
<uni-forms-item class="uni-forms-item" label="字体大小" name="name">
<FontSizeSelece v-model="formData.fontType"></FontSizeSelece>
</uni-forms-item>
</uni-forms>
</view>
</view>
<view class="form-card">
<view class="title"> 自我介绍 </view>
<view class="content">
<uni-forms :modelValue="formData" label-position="left">
<view class="textarea">
<textarea auto-height style="font-size: 30rpx" placeholder="请输入自我介绍" placeholder-class="textarea-placeholder" />
</view>
<view class="example-body">
<uni-file-picker limit="9" title="上传图片">
<image style="width: 100%; height: 100%" src="/static/images/form/add-image.png" mode=""></image>
</uni-file-picker>
</view>
</uni-forms>
</view>
</view>
</view>
</template>
<script setup>
import RadioSex from './components/radio-sex.vue';
import Interest from './components/interest.vue';
import FontSizeSelece from './components/font-size-select.vue';
import { reactive, ref } from 'vue';
const interestList = ['唱歌', '跳舞', 'RAP', '篮球', '音乐', '唱歌', '跳舞', 'RAP', '篮球'];
const formData = reactive({
interest: 4,
fontType: 0,
});
const hobby = ref('');
const date = ref();
const bindDateChange = (e) => {
date.value = e.detail.value;
};
const openSelectPeople = () => {
uni.navigateTo({
url: '/pages/select-people/select-people',
});
};
</script>
<style lang="scss" scoped>
page {
background: #f5f6f8;
}
::v-deep .uni-forms-item__content {
display: flex;
align-items: center;
}
::v-deep .uni-forms-item__label {
font-size: 32rpx;
color: #000000;
padding-top: 28rpx;
}
::v-deep .uni-forms-item {
margin-bottom: 0 !important;
}
::v-deep .uni-slider-thumb {
background: #fff !important;
border: 10rpx solid #1a9aff;
box-sizing: border-box;
}
.uni-forms-item {
height: 100rpx;
border-bottom: 1rpx solid #ededed;
&:last-child {
border: none;
}
}
.form-card {
box-sizing: border-box;
width: 700rpx;
margin: 20rpx auto 0;
background: #fff;
border-radius: 16rpx;
.title {
width: 100%;
height: 84rpx;
background-image: url('/static/images/list/form-list.png');
background-size: 100% 84rpx;
line-height: 84rpx;
text-indent: 30rpx;
font-size: 32rpx;
color: #323333;
font-weight: bold;
}
.content {
padding: 0 30rpx;
}
.input {
font-size: 30rpx;
text-align: right;
width: 100%;
}
}
.item-box {
width: 100%;
display: flex;
justify-content: flex-end;
}
.user-select-image {
width: 40rpx;
height: 40rpx;
}
.textarea {
background: #fcfcfc;
border: 0.5px solid #ededed;
border-radius: 4px;
width: 100%;
height: 320rpx;
margin-top: 24rpx;
padding: 24rpx 30rpx;
box-sizing: border-box;
.textarea-placeholder {
color: #cccccc;
font-size: 30rpx;
}
}
.example-body {
padding-bottom: 24rpx;
}
</style>

View File

@@ -0,0 +1,68 @@
<template>
<view class="list-container">
<view class="list-item" @click="gotoDetail(item.goodsId)" v-for="item in list" :key="item.noticeId">
<view class="title"> {{ item.goodsName }} </view>
<view class="author" v-if="item.remark"> 备注{{ item.remark }} </view>
<view class="author" v-if="item.categoryName"> 分类{{ item.categoryName }} </view>
<view class="author"> 创建时间{{ item.createTime }} </view>
</view>
</view>
</template>
<script setup>
const props = defineProps({
marginTop: {
type: String,
default: '0',
},
list: {
type: Array,
default: [],
},
});
function gotoDetail(goodsId) {
uni.navigateTo({ url: '/pages/goods/goods-detail?noticeId=' + goodsId });
}
</script>
<style lang="scss" scoped>
.list-container {
margin-top: v-bind(marginTop);
padding: 20rpx 10rpx;
}
.list-item {
box-sizing: border-box;
margin: 0 30rpx;
padding: 30rpx 0;
border-bottom: #cdcdcd 1px solid;
.title {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20rpx;
font-size: 16px;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
}
.author {
margin-bottom: 14rpx;
color: #999999;
font-size: 12px;
text-overflow: ellipsis;
}
.publish-time {
font-size: 12px;
color: #999999;
display: flex;
flex-direction: row;
justify-content: space-between;
.un-read {
color: $uni-color-primary;
}
}
}
</style>

View File

@@ -0,0 +1,100 @@
<template>
<uni-popup ref="popupRef" background-color="#fff" type="bottom" :is-mask-click="false">
<view class="query-form-pop">
<view class="smart-form">
<uni-forms :label-width="100" :modelValue="form" label-position="left">
<view class="smart-form-group">
<view class="smart-form-group-title"> 产地 </view>
<view class="smart-form-group-content">
<DictSelect keyCode="GODOS_PLACE" v-model="form.place" @change="onPlaceChange" />
</view>
</view>
<view class="smart-form-group">
<view class="smart-form-group-title"> 状态 </view>
<view class="smart-form-group-content">
<SmartEnumSelect enumName="GOODS_STATUS_ENUM" @change="onGoodsStatusChange" v-model="form.goodsStatus" />
</view>
</view>
</uni-forms>
<view class="smart-form-submit smart-margin-top20">
<button class="smart-form-submit-btn smart-margin-right20" type="default" @click="cancel">取消</button>
<button class="smart-form-submit-btn" type="warn" @click="reset">重置</button>
<button class="smart-form-submit-btn" type="primary" @click="ok">确定</button>
</view>
</view>
</view>
</uni-popup>
</template>
<script setup>
import { reactive, ref, toRaw } from 'vue';
import DictSelect from '/@/components/dict-select/index.vue';
import SmartEnumSelect from '/@/components/smart-enum-select/index.vue';
const emits = defineEmits(['close']);
defineExpose({ show });
// --------------------- 显示 隐藏 ---------------------
const popupRef = ref();
function show() {
popupRef.value.open();
}
function close() {
popupRef.value.close();
}
// --------------------- 数据变化 ---------------------
function onPlaceChange(value, text) {
form.placeName = text;
}
function onGoodsStatusChange(value, text) {
form.goodsStatusName = text;
}
// --------------------- 表单 ---------------------
const defaultFormData = {
// 商品状态
goodsStatus: undefined,
goodsStatusName: undefined,
// 产地
place: undefined,
placeName: undefined,
};
const form = reactive({ ...defaultFormData });
// ----------------------- 表单操作 ------------------------
// 取消
function cancel() {
close();
emits('close', null);
}
// 重置
function reset() {
Object.assign(form, defaultFormData);
close();
emits('close', toRaw(form));
}
// 确定
function ok() {
close();
emits('close', toRaw(form));
}
</script>
<style lang="scss" scoped>
.query-form-pop {
height: 800rpx;
overflow-y: scroll;
}
</style>

View File

@@ -0,0 +1,222 @@
<template>
<view>
<mescroll-body @init="mescrollInit" :down="{ auto: false }" @down="onDown" @up="onUp">
<!--搜索框-->
<uni-nav-bar :border="false" fixed :leftWidth="0" rightWidth="70px">
<view class="input">
<uni-easyinput
prefixIcon="search"
:clearable="true"
trim="all"
v-model="queryForm.searchWord"
placeholder="搜索:商品名称"
@confirm="search"
@clear="search"
/>
</view>
<template #right>
<view class="nav-right" @click="showQueryFormPopUp">
<uni-icons type="settings" size="30"></uni-icons>
<view class="nav-right-name"> 筛选 </view>
</view>
</template>
</uni-nav-bar>
<!--筛选条件提示-->
<uni-notice-bar
@close="onCloseQueryFormTips"
v-if="showQueryFormTipsFlag"
class="query-bar"
background-color="#007aff"
color="white"
show-close
single
:text="queryFormTips"
/>
<!-- 筛选条件表单弹窗 -->
<QueryFormPopUp ref="queryFormPopUpRef" @close="onCloseQueryFormPopUp" />
<!-- 列表 -->
<NoticeList :list="listData" :margin-top="queryFormTipsMarginTop" />
</mescroll-body>
</view>
</template>
<script setup>
import { reactive, ref } from 'vue';
import QueryFormPopUp from './components/goods-query-form-popup.vue';
import { goodsApi } from '/@/api/business/goods/goods-api';
import { onPageScroll, onReachBottom } from '@dcloudio/uni-app';
import useMescroll from '@/uni_modules/uni-mescroll/hooks/useMescroll';
import { smartSentry } from '/@/lib/smart-sentry';
import NoticeList from './components/goods-list.vue';
import _ from 'lodash';
// --------------------------- 筛选条件弹窗 ---------------------------------
const queryFormPopUpRef = ref();
/**
* 显示 筛选弹窗
*/
function showQueryFormPopUp() {
queryFormPopUpRef.value.show();
}
/**
* 监听 筛选弹窗 关闭
*/
function onCloseQueryFormPopUp(param) {
if (param === null) {
return;
}
Object.assign(queryForm, param);
showOrHideQueryFormTips();
query(getMescroll(), true, buildQueryParam(1));
uni.pageScrollTo({
scrollTop: 0,
});
}
// --------------------------- 筛选条件tips ---------------------------------
const queryFormTips = ref(null);
const showQueryFormTipsFlag = ref(false);
const queryFormTipsMarginTop = ref('0px');
/**
* 查询提示
*/
function buildQueryFormTips() {
let tips = null;
if (queryForm.searchWord) {
tips = '搜索:' + queryForm.searchWord;
}
if (queryForm.goodsStatusName) {
tips = tips ? tips + '' : '';
tips = tips + '商品状态:' + queryForm.goodsStatusName;
}
if (queryForm.placeName) {
tips = tips ? tips + '' : '';
tips = tips + '产地:' + queryForm.placeName;
}
return tips;
}
/**
* 显示或者隐藏tips
*/
function showOrHideQueryFormTips() {
let tips = buildQueryFormTips();
queryFormTipsMarginTop.value = _.isEmpty(tips) ? '0px' : '50rpx';
showQueryFormTipsFlag.value = !_.isEmpty(tips);
queryFormTips.value = tips;
}
/**
* 关闭筛选条件 tips清空搜索条件
*/
function onCloseQueryFormTips() {
Object.assign(queryForm, defaultForm);
queryFormTipsMarginTop.value = '0px';
showQueryFormTipsFlag.value = false;
queryFormTips.value = '';
search();
}
// --------------------------- 查询 ---------------------------------
const defaultForm = {
searchWord: '',
// 商品状态
goodsStatus: undefined,
goodsStatusName: undefined,
// 产地
place: undefined,
placeName: undefined,
pageNum: 1,
pageSize: 10,
};
// 查询表单
const queryForm = reactive({ ...defaultForm });
// 列表数据
const listData = ref([]);
function buildQueryParam(pageNum) {
queryForm.pageNum = pageNum;
return Object.assign({}, queryForm, { pageNum });
}
async function query(mescroll, isDownFlag, param) {
try {
let res = await goodsApi.queryGoodsList(param);
if (!isDownFlag) {
listData.value = listData.value.concat(res.data.list);
} else {
listData.value = res.data.list;
}
mescroll.endSuccess(res.data.list.length, res.data.pages > res.data.pageNum);
} catch (e) {
smartSentry.captureError(e);
//联网失败, 结束加载
mescroll.endErr();
}
}
const { mescrollInit, getMescroll } = useMescroll(onPageScroll, onReachBottom);
/**
* 搜索
*/
function search() {
showOrHideQueryFormTips();
query(getMescroll(), true, buildQueryParam(1));
uni.pageScrollTo({
scrollTop: 0,
});
}
/**
* 下拉刷新
*/
function onDown(mescroll) {
queryForm.pageNum = 1;
query(mescroll, true, buildQueryParam(1));
}
/**
* 上拉加载更多
*/
function onUp(mescroll) {
query(mescroll, false, buildQueryParam(mescroll.num));
}
</script>
<style lang="scss" scoped>
.input {
width: 100%;
height: 72rpx;
background: #f7f8f9;
border-radius: 4px;
margin: 8rpx 0;
display: flex;
align-items: center;
}
.nav-right {
width: 140px;
display: flex;
height: 88rpx;
flex-direction: row;
line-height: 88rpx;
.nav-right-name {
margin-left: 5px;
line-height: 88rpx;
font-size: 30rpx;
}
}
.query-bar {
position: fixed;
}
</style>

View File

@@ -0,0 +1,44 @@
<template>
<view class="banner" v-if="!$lodash.isEmpty(bannerList)">
<swiper class="swiper" circular :indicator-dots="true" :autoplay="true" indicator-active-color="#fff">
<swiper-item v-for="(item, index) in bannerList" :key="index">
<image class="swiper-item" :src="item.image" mode=""></image>
</swiper-item>
</swiper>
</view>
</template>
<script setup>
import { ref } from 'vue';
const bannerList = ref([
{
image: '/static/images/index/banner.png',
},
{
image: '/static/images/index/banner.png',
},
{
image: '/static/images/index/banner.png',
},
{
image: '/static/images/index/banner.png',
},
]);
</script>
<style lang="scss" scoped>
.banner {
border-radius: 16rpx;
overflow: hidden;
width: 700rpx;
height: 300rpx;
margin: 10rpx auto 20rpx;
.swiper {
width: 100%;
.swiper-item {
width: 100%;
height: 100%;
}
}
}
</style>

View File

@@ -0,0 +1,135 @@
<template>
<view class="container">
<uni-card title="品质商品" :isFull="true" padding="0px" spacing="0px">
<view class="course">
<scroll-view class="scroll-view" scroll-x="true">
<view class="scroll-view-item" v-for="item in goodsList" :key="item.goodsId">
<div style="display: flex">
<image class="scroll-item-left" src="/static/logo.png" mode=""></image>
<view class="scroll-item-right">
<view class="item-title"> {{ item.categoryName }}-{{ item.goodsName }} </view>
<view class="item-right-bottom">
<view class="item-time"> 产地{{ item.place[0].valueName }}</view>
</view>
<view class="item-right-bottom">
<view class="item-time"> {{ item.remark }}</view>
<view class="item-reserved"> 预约 </view>
</view>
</view>
</div>
</view>
</scroll-view>
</view>
</uni-card>
</view>
</template>
<script setup>
import { ref } from 'vue';
import { smartSentry } from '/@/lib/smart-sentry';
import { onShow } from '@dcloudio/uni-app';
import { goodsApi } from '/@/api/business/goods/goods-api';
const queryForm = {
pageNum: 1,
pageSize: 5,
searchCount: false,
};
const goodsList = ref([]);
async function queryGoodsList() {
try {
const result = await goodsApi.queryGoodsList(queryForm);
goodsList.value = result.data.list;
} catch (err) {
smartSentry.captureError(err);
}
}
onShow(() => {
queryGoodsList();
});
// 查看更多
function onMore() {
router.push({
path: '/oa/notice/notice-employee-list',
});
}
function toDetail(noticeId) {
router.push({
path: '/oa/notice/notice-employee-detail',
query: { noticeId },
});
}
</script>
<style lang="scss" scoped>
.container {
width: 700rpx;
margin: 0 auto 20rpx;
border-radius: 12rpx;
overflow: hidden;
:deep(.uni-card__header-box) {
font-weight: bold;
}
:deep(.uni-card__content) {
padding: 0 !important;
}
:deep(.uni-card__header) {
background: linear-gradient(180deg, #e8f4ff, #f8fcff);
}
}
.course {
padding: 30rpx 0 30rpx 30rpx;
background-color: #fff;
}
.scroll-view-item {
display: inline-block;
width: 570rpx;
height: 128rpx;
overflow: hidden;
font-size: 36rpx;
border-right: 1rpx solid #ededed;
margin-right: 30rpx;
.scroll-item-left {
width: 128rpx;
height: 128rpx;
margin-right: 20rpx;
}
.scroll-item-right {
.item-title {
white-space: pre-wrap;
font-size: 30rpx;
width: 390rpx;
}
.item-right-bottom {
display: flex;
justify-content: space-between;
.item-time {
font-size: 12px;
font-weight: 400;
color: #777777;
letter-spacing: -0.02px;
}
.item-reserved {
width: 100rpx;
height: 40rpx;
background: #1a9aff;
border-radius: 4px;
box-shadow: 0 5rpx 8rpx 0 rgba(58, 121, 255, 0.2);
color: #fff;
text-align: center;
font-size: 26rpx;
line-height: 40rpx;
}
}
}
}
</style>

View File

@@ -0,0 +1,119 @@
<template>
<view class="menu-container">
<uni-grid :column="5" :highlight="true" :showBorder="false">
<!--------------------------------- 第一排--------------------------------->
<uni-grid-item class="menu-grid">
<view class="menu-item" @click="changeHome">
<image class="item-image" src="/@/static/images/index/ic_home_menu1.png"></image>
<view class="item-text"> 首页切换 </view>
</view>
</uni-grid-item>
<uni-grid-item class="menu-grid">
<view class="menu-item" @click="navigateTo('/pages/notice/notice-index')">
<image class="item-image" src="/@/static/images/index/ic_home_menu2.png"></image>
<view class="item-text"> 通知公告 </view>
</view>
</uni-grid-item>
<uni-grid-item class="menu-grid">
<view class="menu-item" @click="navigateTo('/pages/enterprise/enterprise-list')">
<image class="item-image" src="/@/static/images/index/ic_home_menu3.png"></image>
<view class="item-text"> 客户线索 </view>
</view>
</uni-grid-item>
<uni-grid-item class="menu-grid">
<view class="menu-item" @click="navigateTo('/pages/goods/goods-index')">
<image class="item-image" src="/@/static/images/index/ic_home_menu4.png"></image>
<view class="item-text"> 品质商品 </view>
</view>
</uni-grid-item>
<uni-grid-item class="menu-grid">
<view class="menu-item" @click="navigateTo('/pages/support/change-log/change-log-list')">
<image class="item-image" src="/@/static/images/index/ic_home_menu5.png"></image>
<view class="item-text"> 版本更新 </view>
</view>
</uni-grid-item>
<!--------------------------------- 第二排--------------------------------->
<uni-grid-item class="menu-grid">
<view class="menu-item" @click="navigateTo('/pages/form/form')">
<image class="item-image" src="/@/static/images/index/ic_home_menu6.png"></image>
<view class="item-text"> 表单 </view>
</view>
</uni-grid-item>
<uni-grid-item class="menu-grid">
<view class="menu-item" @click="navigateTo('/pages/order-detail/order-detail')">
<image class="item-image" src="/@/static/images/index/ic_home_menu7.png"></image>
<view class="item-text"> 物流快递 </view>
</view>
</uni-grid-item>
<uni-grid-item class="menu-grid">
<view class="menu-item" @click="navigateTo('/pages/pure-list/pure-list')">
<image class="item-image" src="/@/static/images/index/ic_home_menu8.png"></image>
<view class="item-text"> 优惠券 </view>
</view>
</uni-grid-item>
<uni-grid-item class="menu-grid">
<view class="menu-item" @click="navigateTo('/pages/list/list')">
<image class="item-image" src="/@/static/images/index/ic_home_menu9.png"></image>
<view class="item-text"> 精品课程 </view>
</view>
</uni-grid-item>
<uni-grid-item class="menu-grid">
<view class="menu-item" @click="navigateTo('/pages/change-log/change-log-list')">
<image class="item-image" src="/@/static/images/index/ic_home_menu10.png"></image>
<view class="item-text"> 加密安全 </view>
</view>
</uni-grid-item>
</uni-grid>
</view>
</template>
<script setup>
const emit = defineEmits(['changeHome']);
function changeHome() {
emit('changeHome');
}
function navigateTo(url) {
uni.navigateTo({
url,
});
}
</script>
<style lang="scss" scoped>
.menu-container {
.menu-grid {
&:nth-child(n + 6) {
margin-top: 20rpx;
}
}
//height: 340rpx;
box-sizing: border-box;
border-radius: 16rpx;
width: 700rpx;
margin: 0 auto 20rpx;
display: flex;
justify-content: space-between;
padding: 30rpx 10rpx;
flex-wrap: wrap;
background-color: #fff;
.menu-item {
display: flex;
flex-direction: column;
align-items: center;
.item-image {
width: 80rpx;
height: 80rpx;
margin-bottom: 10rpx;
}
.item-text {
font-size: 26rpx;
color: #353535;
}
}
}
</style>

View File

@@ -0,0 +1,90 @@
<template>
<view class="container">
<uni-card title="通知公告" :isFull="true" type="line" padding="0px" spacing="0px">
<template #extra> <view @click="onMore">查看更多</view> </template>
<uni-list>
<uni-list-item :ellipsis="1" v-for="item in data" :rightText="item.publishDate" clickable @click="goto(item.noticeId)" :title="item.title" />
</uni-list>
</uni-card>
</view>
</template>
<script setup>
import { ref } from 'vue';
import { noticeApi } from '/@/api/business/oa/notice-api';
import { smartSentry } from '/@/lib/smart-sentry';
import { onShow } from '@dcloudio/uni-app';
const queryForm = {
pageNum: 1,
pageSize: 5,
searchCount: false,
};
let data = ref([]);
const loading = ref(false);
// 查询列表
async function queryNoticeList() {
try {
loading.value = true;
const result = await noticeApi.queryEmployeeNotice(queryForm);
data.value = result.data.list;
} catch (err) {
smartSentry.captureError(err);
} finally {
loading.value = false;
}
}
// 跳转详情
function goto(noticeId) {
uni.navigateTo({ url: '/pages/notice/notice-detail?noticeId=' + noticeId });
}
onShow(() => {
queryNoticeList();
});
// 查看更多
function onMore() {
uni.navigateTo({
url: '/pages/notice/notice-index',
});
}
</script>
<style lang="scss" scoped>
.container {
width: 700rpx;
margin: 0 auto 20rpx;
border-radius: 12rpx;
padding: 0;
overflow: hidden;
:deep(.uni-card__header-box) {
font-weight: bold;
}
:deep(.uni-list--border-bottom) {
background-color: transparent;
}
:deep(.uni-card__content) {
padding: 0 !important;
}
:deep(.uni-card__header) {
border: none;
}
:deep(.uni-list-item__container) {
padding: 16rpx 20rpx;
}
:deep(.uni-card__header) {
background: linear-gradient(180deg, #e8f4ff, #f8fcff);
}
:deep(.uni-card__header-extra) {
font-size: 24rpx;
font-weight: 400;
text-align: center;
color: #1a9aff;
}
}
</style>

View File

@@ -0,0 +1,87 @@
<template>
<view class="statistics-view">
<view class="view-top">
<view class="view-top-item-left">
<view class="item-left-top"> 本月销售额 </view>
<view class="item-left-bottom"> ¥32,226.00 </view>
</view>
<view class="view-top-item-right">
<view class="item-right-top"> 本月销售目标 </view>
<view class="item-right-bottom"> ¥50,000.00 </view>
</view>
</view>
<view class="view-bottom">
<view class="view-bottom-item">
<view class="item-bottom-top"> 本月完成率 </view>
<view class="item-bottom-bottom"> 85% </view>
</view>
<view class="view-item">
<view class="item-bottom-top"> 本月新增客户 </view>
<view class="item-bottom-bottom">+1024 </view>
</view>
<view class="view-item">
<view class="item-bottom-top"> 本月累计通话 </view>
<view class="item-bottom-bottom"> 16:00小时 </view>
</view>
</view>
</view>
</template>
<script></script>
<style lang="scss" scoped>
.statistics-view {
width: 700rpx;
height: 300rpx;
margin: 10rpx auto 20rpx;
background: linear-gradient(133deg, #045ff0 0%, #2291f9 55%, #2168ec 100%);
border-radius: 6px;
.view-top {
display: flex;
padding: 36rpx 44rpx;
.view-top-item-left {
margin-right: 100rpx;
.item-left-top {
opacity: 0.6;
font-size: 26rpx;
color: #ffffff;
margin-bottom: 5rpx;
}
.item-left-bottom {
font-size: 52rpx;
font-weight: 700;
color: #ffffff;
}
}
.view-top-item-right {
.item-right-top {
opacity: 0.6;
font-size: 26rpx;
color: #ffffff;
margin-bottom: 20rpx;
}
.item-right-bottom {
font-size: 30rpx;
font-weight: 700;
color: #ffffff;
}
}
}
.view-bottom {
padding: 26rpx 44rpx;
display: flex;
justify-content: space-between;
.item-bottom-top {
opacity: 0.6;
font-size: 24rpx;
font-weight: 400;
color: #ffffff;
}
.item-bottom-bottom {
font-size: 30rpx;
font-weight: 500;
color: #ffffff;
}
}
}
</style>

View File

@@ -0,0 +1,72 @@
<template>
<view class="page">
<uni-nav-bar title="首页" :border="false" fixed>
<template #right>
<view class="right">
<view class="">
<image src="/@/static/images/index/ic_scan.png" mode=""></image>
</view>
<view class="">
<image src="/@/static/images/index/ic_search.png" mode=""></image>
</view>
</view>
</template>
</uni-nav-bar>
<!-- 数据表 -->
<Statistics v-if="!showBannerFlag" />
<!-- Banner -->
<Banner v-if="showBannerFlag" />
<!-- 功能菜单 -->
<Menu @changeHome="changeHome" />
<!-- 通知公告 -->
<Notice />
<!-- 商品 -->
<Goods />
</view>
</template>
<script setup>
import Banner from './components/banner.vue';
import Menu from './components/menu.vue';
import Statistics from './components/statistics.vue';
import Notice from './components/notice.vue';
import Goods from './components/goods.vue';
import { ref } from 'vue';
const showBannerFlag = ref(false);
function changeHome() {
showBannerFlag.value = !showBannerFlag.value;
}
</script>
<style lang="scss" scoped>
page {
background-color: #f5f5f5;
}
:deep(.uni-navbar__header-btns) {
width: 150rpx !important;
}
.right {
position: relative;
display: flex;
z-index: 999;
view {
width: 56rpx;
height: 56rpx;
margin-left: 36rpx;
image {
width: 100%;
height: 100%;
}
}
}
</style>

View File

@@ -0,0 +1,187 @@
<template>
<view class="list-view">
<view class="item">
<view class="item-top">
<view class="item-top-item">
<view class="item-top-label"> 创建时间 </view>
<view class="item-title"> 2023-08-27 21:33 </view>
<view class="item-state">
<view class="tag" type="warring"> 未付款 </view>
</view>
</view>
<view class="item-top-item">
<view class="item-top-label"> 客户名称 </view>
<view class="item-title"> 六边形工程师 </view>
</view>
<view class="item-top-item">
<view class="item-top-label"> 供应商名称 </view>
<view class="item-title"> 1024数字科技有限公司 </view>
</view>
<view class="item-top-item">
<view class="item-top-label"> 客户经理 </view>
<view class="item-title"> 林jj </view>
</view>
<view class="item-top-item">
<view class="item-top-label"> 生产厂商 </view>
<view class="item-title"> 闫jj </view>
</view>
</view>
<!-- <view class="decollator">
<view class="decollator-left">
</view>
<view class="decollator-center">
</view>
<view class="decollator-right">
</view>
</view> -->
<view class="item-footer">
<view class="item-footer-left"> 订单总价 </view>
<!-- <image src="" mode=""></image> -->
<view class="item-footer-right"> 300000.00 </view>
</view>
</view>
</view>
</template>
<script setup>
defineProps({
list: {
type: Array,
default: [],
},
});
</script>
<style lang="scss" scoped>
.decollator {
height: 30rpx;
position: relative;
display: flex;
align-items: center;
.decollator-left {
top: 2rpx;
position: absolute;
width: 60rpx;
height: 60rpx;
border-radius: 50%;
background: #f5f5f5;
z-index: 10;
left: -30rpx;
}
.decollator-right {
top: 2rpx;
width: 60rpx;
height: 60rpx;
border-radius: 50%;
background: #f5f5f5;
position: absolute;
z-index: 10;
right: -30rpx;
}
.decollator-center {
width: 100%;
position: absolute;
bottom: 0;
z-index: 1;
border-top: 1rpx dashed #ededed;
}
}
.list-view {
margin: 20rpx 24rpx;
}
.item {
box-sizing: border-box;
width: 700rpx;
background: #ffffff;
border-radius: 12rpx;
box-shadow: 0px 3px 4px 0px rgba(24, 144, 255, 0.06);
padding-top: 24rpx;
overflow: hidden;
.item-top {
padding: 0 30rpx;
.item-top-item {
display: flex;
align-items: center;
margin-bottom: 16rpx;
}
margin-bottom: 20rpx;
.item-top-label {
width: 168rpx;
margin-right: 10rpx;
font-size: 28rpx;
color: #777777;
}
.item-title {
font-size: 28rpx;
color: #323333;
font-weight: bold;
}
.item-state {
flex: 1;
display: flex;
justify-content: flex-end;
.tag {
width: 112rpx;
height: 40rpx;
border-radius: 4rpx;
text-align: center;
line-height: 40rpx;
font-size: 24rpx;
&[type='warring'] {
color: #ff6c00;
background: #fff0ed;
}
}
}
}
.item-sub-title {
font-size: 28rpx;
color: #777777;
margin-bottom: 10rpx;
&:last-child {
padding-bottom: 20rpx;
margin-bottom: 0;
}
}
.order-end-time {
height: 40rpx;
background: #ff6c00;
box-shadow: 0px 3px 4px 0px rgba(24, 144, 255, 0.06);
color: #fff;
text-align: center;
font-size: 24rpx;
line-height: 40rpx;
}
}
.line-border-bottom {
border-bottom: 1rpx solid #ededed;
}
.item-footer {
height: 120rpx;
display: flex;
border-top: 1rpx dashed #ccc;
//background-color: #F7FAFD;
align-items: center;
justify-content: space-between;
margin: 0 30rpx;
.item-footer-left {
font-size: 28rpx;
color: #777;
}
.item-footer-right {
font-size: 34rpx;
color: #444;
font-weight: bold;
}
}
</style>

View File

@@ -0,0 +1,86 @@
<template>
<view class="list-view">
<view class="item">
<view class="item-top">
<view class="item-top-info">
<view class="name"> 彭嘉轩 </view>
<view class="mobile"> 13011112338 </view>
</view>
<view class="item-top-phone"> <image src="/static/images/list/phone.png" mode=""></image> 联系Ta </view>
</view>
<view class="item-title"> 最后跟进内容上午跟客户谈了下 </view>
<view class="item-bottom"> 2022-08-20 19:15 最后活跃 </view>
</view>
</view>
</template>
<script setup>
defineProps({
list: {
type: Array,
default: [],
},
});
</script>
<style lang="scss" scoped>
.list-view {
margin: 20rpx 24rpx;
}
.item {
box-sizing: border-box;
width: 700rpx;
height: 240rpx;
background: #ffffff;
border-radius: 12rpx;
box-shadow: 0px 3px 4px 0px rgba(24, 144, 255, 0.06);
padding: 24rpx 30rpx;
.item-top {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20rpx;
.item-top-info {
display: flex;
align-items: center;
.name {
font-size: 34rpx;
font-weight: 500;
color: #444444;
margin-right: 10rpx;
}
.mobile {
font-size: 32rpx;
font-weight: bold;
text-align: left;
color: #444444;
}
}
.item-top-phone {
color: #1a9aff;
font-size: 28rpx;
display: flex;
align-items: center;
image {
width: 40rpx;
height: 40rpx;
margin-left: 4rpx;
}
}
}
.item-title {
font-size: 28rpx;
color: #777777;
padding-bottom: 20rpx;
border-bottom: 1rpx solid #ededed;
margin-bottom: 24rpx;
}
.item-bottom {
font-size: 28rpx;
color: #777777;
}
}
</style>

View File

@@ -0,0 +1,242 @@
<template>
<view class="list-view">
<view class="item">
<view class="item-header">
<view class="item-top">
<view class="item-top-left"> 2023-08-20 19:15 </view>
<view class="item-top-right">
<view class="tag" type="warring"> 未付款 </view>
</view>
</view>
<view class="line-border-bottom"> </view>
<view class="item-center">
<view class="item-center-left">
<view class="item-top-z"> </view>
<view class="item-center"> </view>
<view class="item-bottom-x"> </view>
</view>
<view class="item-center-address">
<view class="m-b-16">
<view class="item-title"> 装货地址 </view>
<view class="item-address"> 河南省洛阳市洛龙区110号 </view>
</view>
<view class="m-b-16">
<view class="item-title"> 卸货地址 </view>
<view class="item-address"> 河南省洛阳市西工区120号 </view>
</view>
</view>
</view>
<view class="line-border-bottom"> </view>
<view class="item-footer">
<view class="item-footer-left">
<text>586.00</text>
</view>
<view class="item-footer-right">
<view class="camera">
<image src="/static/images/list/camera.png" mode=""></image>
拍照
</view>
<view class="ok">
<image src="/static/images/list/success.png" mode=""></image>
完成
</view>
</view>
</view>
</view>
</view>
</view>
</template>
<script setup>
defineProps({
list: {
type: Array,
default: [],
},
});
</script>
<style lang="scss" scoped>
.list-view {
margin: 20rpx 24rpx;
}
.item {
.item-header {
padding: 0 30rpx;
}
box-sizing: border-box;
width: 700rpx;
background: #ffffff;
border-radius: 12rpx;
box-shadow: 0px 3px 4px 0px rgba(24, 144, 255, 0.06);
padding-top: 24rpx;
overflow: hidden;
.item-top {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20rpx;
.item-top-left {
font-size: 28rpx;
font-weight: 400;
color: #777777;
}
.item-top-right {
.tag {
width: 112rpx;
height: 40rpx;
border-radius: 4rpx;
text-align: center;
line-height: 40rpx;
font-size: 24rpx;
&[type='warring'] {
color: #ff6c00;
background: #fff0ed;
}
&[type='success'] {
color: #1a9aff;
background: #f2f9ff;
}
}
}
}
.item-center {
margin-top: 20rpx;
display: flex;
.item-center-left {
margin-top: 5rpx;
margin-right: 12rpx;
display: flex;
flex-direction: column;
align-items: center;
.item-top-z {
position: relative;
z-index: 10;
width: 34rpx;
height: 34rpx;
background: #1a9aff;
border-radius: 12rpx;
text-align: center;
font-size: 24rpx;
color: #fff;
}
.item-center {
height: 75rpx;
border-left: 1rpx dashed #777777;
margin-top: -5rpx;
border-spacing: 6rpx;
border-width: 2rpx;
}
.item-bottom-x {
width: 34rpx;
height: 34rpx;
background: #ff6c00;
border-radius: 12rpx;
text-align: center;
font-size: 24rpx;
color: #fff;
}
}
.item-center-address {
.m-b-16 {
margin-bottom: 16rpx;
}
.item-title {
font-size: 34rpx;
color: #444444;
font-weight: bold;
margin-bottom: 4rpx;
}
.item-address {
font-size: 28rpx;
color: #777777;
}
}
}
.item-sub-title {
font-size: 28rpx;
color: #777777;
margin-bottom: 10rpx;
&:last-child {
padding-bottom: 20rpx;
margin-bottom: 0;
}
}
.order-end-time {
height: 40rpx;
background: #ff6c00;
box-shadow: 0px 3px 4px 0px rgba(24, 144, 255, 0.06);
color: #fff;
text-align: center;
font-size: 24rpx;
line-height: 40rpx;
}
}
.item-footer {
padding: 20rpx 0;
display: flex;
justify-content: space-between;
align-items: center;
.item-footer-left {
font-size: 34rpx;
color: #777777;
text {
color: #ff3924;
font-weight: bold;
}
}
.item-footer-right {
display: flex;
align-items: center;
view {
width: 160rpx;
height: 64rpx;
border-radius: 8rpx;
display: flex;
align-items: center;
justify-content: center;
color: #fff;
image {
width: 40rpx;
height: 40rpx;
}
&.ok {
background: #1a9aff;
margin-left: 24rpx;
}
&.camera {
background: linear-gradient(107deg, #57d697 9%, #40c87e 86%);
}
}
}
}
.line-border-bottom {
border-bottom: 1rpx solid #ededed;
}
</style>

View File

@@ -0,0 +1,109 @@
<template>
<view class="list-view">
<view class="item">
<view class="item-header">
<view class="item-top">
<view class="item-top-left"> 2023-08-20 19:15 </view>
<view class="item-top-right">
<view class="tag" type="warring"> 未付款 </view>
</view>
</view>
<view class="line-border-bottom"> </view>
<view class="item-title"> 订单标题 </view>
<view class="item-sub-title"> 订单金额¥5852.00 </view>
<view class="item-sub-title"> 客户1024创新实验室 </view>
</view>
<view class="order-end-time"> 剩余 29:35:07 关闭订单 </view>
</view>
</view>
</template>
<script setup>
defineProps({
list: {
type: Array,
default: [],
},
});
</script>
<style lang="scss" scoped>
.list-view {
margin: 20rpx 24rpx;
}
.item {
.item-header {
padding: 0 30rpx;
}
box-sizing: border-box;
width: 700rpx;
background: #ffffff;
border-radius: 12rpx;
box-shadow: 0px 3px 4px 0px rgba(24, 144, 255, 0.06);
padding-top: 24rpx;
overflow: hidden;
.item-top {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20rpx;
.item-top-left {
font-size: 28rpx;
font-weight: 400;
color: #777777;
}
.item-top-right {
.tag {
width: 112rpx;
height: 40rpx;
border-radius: 4rpx;
text-align: center;
line-height: 40rpx;
font-size: 24rpx;
&[type='warring'] {
color: #ff6c00;
background: #fff0ed;
}
&[type='success'] {
color: #323333;
background: #f7f8f9;
}
}
}
}
.item-title {
margin-top: 20rpx;
margin-bottom: 12rpx;
font-size: 34rpx;
font-weight: 700;
color: #444444;
}
.item-sub-title {
font-size: 28rpx;
color: #777777;
margin-bottom: 10rpx;
&:last-child {
padding-bottom: 20rpx;
margin-bottom: 0;
}
}
.order-end-time {
height: 40rpx;
background: #ff6c00;
box-shadow: 0px 3px 4px 0px rgba(24, 144, 255, 0.06);
color: #fff;
text-align: center;
font-size: 24rpx;
line-height: 40rpx;
}
}
.line-border-bottom {
border-bottom: 1rpx solid #ededed;
}
</style>

View File

@@ -0,0 +1,58 @@
<template>
<view class="tabs">
<view class="item" @click="value = item.value" v-for="(item,index) in list" :key="index">
{{item.title}}
<view class="tabs-slide" v-if="value === item.value">
</view>
</view>
</view>
</template>
<script setup>
import { ref, watch } from 'vue';
const emits = defineEmits(['update:value'])
const props = defineProps({
value:{
type:Number,
default:0
},
list:{
type:Array,
default:[]
}
})
watch(()=>props.value,(newValue,oldValue)=>{
emits('update:value',newValue)
})
</script>
<style lang="scss" scoped>
.tabs{
box-sizing: border-box;
height: 100rpx;
display: flex;
justify-content: space-between;
width: 100%;
padding: 0 30rpx;
align-items: center;
position: relative;
background-color: #fff;
.item{
position: relative;
height: 100%;
line-height: 100rpx;
}
.tabs-slide{
position: absolute;
transition: 0.3s;
width: 50%;
background: #1a9aff;
border-radius: 4rpx;
height: 8rpx;
bottom: 0;
left: 50%;
transform: translate(-50%);
}
}
</style>

View File

@@ -0,0 +1,70 @@
<template>
<view>
<uni-nav-bar :border="false" fixed>
<view class="input">
<icon type="search" size="16"/>
<input placeholder="请输入搜索关键字" placeholder-class="placeolder-input"/>
</view>
<template #right>
<uni-icons type="list" size="30"></uni-icons>
</template>
</uni-nav-bar>
<Tabs v-model:value="active" :list="tabsList"/>
<ListModelOne v-if="active==0"></ListModelOne>
<ListModelTwo v-if="active==1"/>
<ListModelThree v-if="active==2"/>
<ListModelFour v-if="active==3"/>
</view>
</template>
<script setup>
import { ref } from 'vue'
import Tabs from './components/tabs.vue'
import ListModelOne from './components/list-model-one.vue'
import ListModelTwo from './components/list-model-two.vue'
import ListModelThree from './components/list-model-three.vue'
import ListModelFour from './components/list-model-four.vue'
const active = ref(0);
const tabsList = [{
title:'线索列表',
value:0
},{
title:'我的订单',
value:1
},{
title:'我的运单',
value:2
},{
title:'付款单',
value:3
}]
</script>
<style lang="scss" scoped>
page{
background: #f5f6f8;
}
.input{
width: 526rpx;
height: 72rpx;
background: #f7f8f9;
border-radius: 4px;
margin: 8rpx 0;
display: flex;
align-items: center;
icon{
margin-left: 20rpx;
}
input{
margin-left: 8rpx;
font-size: 28rpx;
}
.placeolder-input{
color: #ccc;
}
}
</style>

View File

@@ -0,0 +1,57 @@
<template>
<view class="check-box">
<view class="check-item">
<image @click="agree" :src="!agreeFlag ? checkOutImg : checkInImg" />
<span>
我已阅读并同意
<span class="link" @click="openProtocol('user_agreement')">用户协议</span>
<span class="link" @click="openProtocol('privacy_terms')">隐私政策</span>
</span>
</view>
</view>
</template>
<script setup>
import checkOutImg from '/@/static/images/login/check-out.png';
import checkInImg from '/@/static/images/login/check-in.png';
import { ref } from 'vue';
const agreeFlag = ref(false);
function agree() {
agreeFlag.value = !agreeFlag.value;
}
function openProtocol(protocolKey) {
uni.navigateTo({
url: `/pages/protocol/index?key=${protocolKey}`,
});
}
defineExpose({
agreeFlag,
});
</script>
<style lang="scss" scoped>
.check-box {
.check-item {
display: flex;
align-items: center;
font-size: $small-size;
font-weight: 400;
color: #999999;
margin-bottom: 7px;
image {
width: 17px;
height: 17px;
margin-right: 2px;
}
.link {
color: $main-color;
}
}
}
</style>

View File

@@ -0,0 +1,139 @@
<template>
<view class="other-way-box">
<view class="title">
<span style="margin: 0 10px"> 第三方账号登录 </span>
</view>
<view class="other-way">
<!-- 手机号登录 -->
<view v-if="phoneLoginFlag" @click="navigateTo('/pages/login/phone-login')" class="item">
<image src="/@/static/images/login/phone-login-icon.png" />
</view>
<!-- 微信登录 -->
<view v-if="wxLoginFlag" @click="toWeChatLogin" class="item">
<image src="/@/static/images/login/wx-login-icon.png" />
</view>
<!-- 苹果账号登录 -->
<view v-if="iosFlag" @click="toAppleLogin" class="item apple">
<image src="/@/static/images/login/ios-login-icon.png" />
</view>
</view>
</view>
</template>
<script setup>
import { computed } from 'vue';
const emit = defineEmits(['wechatLogin', 'appleLogin']);
const phoneLoginFlag = computed(() => {
let currentPages = getCurrentPages();
let currentPage = currentPages[currentPages.length - 1];
return currentPage.route === 'pages/login/phone-login';
});
const wxLoginFlag = computed(() => {
let currentPages = getCurrentPages();
let currentPage = currentPages[currentPages.length - 1];
return currentPage.route === 'pages/login/login';
});
const iosFlag = computed(() => {
// #ifdef APP-PLUS
let systemInfoSync = uni.getSystemInfoSync();
let platform = systemInfoSync.platform;
return platform === 'ios';
// #endif
return true;
});
function navigateTo(url) {
uni.navigateTo({ url });
}
// 微信登录
function toWeChatLogin() {
emit('wechatLogin');
}
// 苹果登录
function toAppleLogin() {
//方法二
var appleOauth = null;
plus.oauth.getServices(
(services) => {
for (var i in services) {
var service = services[i];
// 获取苹果授权登录对象苹果授权登录id 为 'apple' iOS13以下系统不会返回苹果登录对应的 service
if (service.id == 'apple') {
appleOauth = service;
break;
}
}
appleOauth.logout(
(success) => {
// console.log("退出登录成功:", JSON.stringify(success))
appleOauth.login(
(oauth) => {
// 授权成功,苹果授权返回的信息在 oauth.target.appleInfo 中
let info = oauth.target.appleInfo || {};
// console.log("登录数据:", JSON.stringify(info))
emit('appleLogin', info);
},
(err) => {
// 授权失败 error
},
{
// 默认只会请求用户名字信息,如需请求用户邮箱信息,需要设置 scope: 'email'
scope: 'email',
}
);
},
(err) => {
console.log('退出登录失败');
}
);
},
(err) => {
// 获取 services 失败
}
);
}
</script>
<style lang="scss" scoped>
.other-way-box {
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
.title {
font-size: $small-size;
font-weight: 400;
color: #cccccc;
}
.other-way {
margin-top: 42rpx;
height: 80rpx;
display: flex;
align-items: center;
justify-content: center;
.item {
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
font-size: $main-size;
font-weight: 400;
color: #666666;
&.apple {
margin-left: 40px;
}
image {
width: 70rpx;
height: 70rpx;
}
}
}
}
</style>

View File

@@ -0,0 +1,300 @@
<template>
<view class="container">
<view class="top-view">
<view class="login"> 登录 </view>
<view class="logo">
<image src="/@/static/images/login/login-logo.png" />
</view>
</view>
<view class="bottom-view">
<view class="input-view smart-margin-top10">
<image src="/@/static/images/login/login-username.png"></image>
<uni-easyinput
class="input"
placeholder="请输入用户名"
:clearable="true"
placeholderStyle="color:#CCCCCC"
border="none"
v-model="loginForm.username"
/>
</view>
<view class="input-view smart-margin-top10">
<image src="/@/static/images/login/login-password.png"></image>
<uni-easyinput
class="input"
placeholder="请输入密码"
:clearable="true"
:password="true"
placeholderStyle="color:#CCCCCC"
border="none"
v-model="loginForm.password"
/>
</view>
<view class="input-view smart-margin-top10">
<image src="/@/static/images/login/login-password.png"></image>
<uni-easyinput
class="input"
placeholder="请输入验证码"
:clearable="true"
:password="false"
placeholderStyle="color:#CCCCCC"
border="none"
v-model="loginForm.captchaCode"
style="width: 50%"
/>
<img class="captcha-img" :src="captchaBase64Image" @click="getCaptcha" />
</view>
<view class="code-login-view smart-margin-top10">
<text class="code-text">验证码登录</text>
<text class="forget-text">忘记密码</text>
</view>
<view @click="login" class="button login-btn smart-margin-top20"> 登录 </view>
<view @click="login" class="button register-btn smart-margin-top20"> 创建账号 </view>
<OtherWayBox class="other-way-box" />
<LoginCheckBox class="login-check-box" ref="loginCheckBoxRef" />
</view>
</view>
</template>
<script setup>
import { nextTick, reactive, ref } from 'vue';
import { onShow } from '@dcloudio/uni-app';
import OtherWayBox from './components/other-way-box.vue';
import LoginCheckBox from './components/login-check-box.vue';
import { loginApi } from '/@/api/system/login-api';
import { LOGIN_DEVICE_ENUM } from '/@/constants/system/login-device-const';
import { encryptData } from '/@/lib/encrypt';
import { useUserStore } from '/@/store/modules/system/user';
import { smartSentry } from '/@/lib/smart-sentry';
const loginForm = reactive({
loginName: 'admin',
password: '',
captchaCode: '',
captchaUuid: '',
loginDevice: LOGIN_DEVICE_ENUM.PC.value,
});
const loginCheckBoxRef = ref();
async function login() {
if (!loginCheckBoxRef.value.agreeFlag) {
uni.showToast({
icon: 'none',
title: '请阅读并同意《用户协议》、《隐私政策》',
});
return;
}
if (!loginForm.username) {
uni.showToast({
icon: 'none',
title: '请输入用户名',
});
return;
}
if (!loginForm.password) {
uni.showToast({
icon: 'none',
title: '请输入密码',
});
return;
}
try {
uni.showLoading('登录中');
// 密码加密
let encryptPasswordForm = Object.assign({}, loginForm, {
password: encryptData(loginForm.password),
});
const res = await loginApi.login(encryptPasswordForm);
stopRefreshCaptchaInterval();
uni.showToast({ title: '登录成功' });
//更新用户信息到 pinia
useUserStore().setUserLoginInfo(res.data);
uni.switchTab({ url: '/pages/home/index' });
} catch (e) {
if (e.data && e.data.code !== 0) {
loginForm.captchaCode = '';
getCaptcha();
}
smartSentry.captureError(e);
uni.hideLoading();
}
}
//--------------------- 验证码 ---------------------------------
const captchaBase64Image = ref('');
async function getCaptcha() {
try {
let captchaResult = await loginApi.getCaptcha();
captchaBase64Image.value = captchaResult.data.captchaBase64Image;
console.log(captchaResult.data.captchaBase64Image, 2);
loginForm.captchaUuid = captchaResult.data.captchaUuid;
beginRefreshCaptchaInterval(captchaResult.data.expireSeconds);
} catch (e) {
console.log(e);
}
}
let refreshCaptchaInterval = null;
function beginRefreshCaptchaInterval(expireSeconds) {
if (refreshCaptchaInterval === null) {
refreshCaptchaInterval = setInterval(getCaptcha, (expireSeconds - 5) * 1000);
}
}
function stopRefreshCaptchaInterval() {
if (refreshCaptchaInterval != null) {
clearInterval(refreshCaptchaInterval);
refreshCaptchaInterval = null;
}
}
onShow(getCaptcha);
</script>
<style lang="scss" scoped>
.bottom-view {
box-sizing: border-box;
margin-top: -280rpx;
border-radius: 20rpx 20rpx 0 0;
width: 100%;
background-color: white;
padding: 0 60rpx;
.input-view {
display: flex;
flex-direction: row;
align-items: center;
background-color: $page-bg-color;
border-radius: 4px;
height: 100rpx;
.captcha-img {
margin-left: 5px;
height: 100rpx;
}
image {
margin-left: 30rpx;
width: 44rpx;
height: 44rpx;
}
.input {
margin: 0 16rpx;
background-color: $page-bg-color;
}
}
.code-login-view {
margin: 50rpx 0 0;
height: 40rpx;
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
.code-text {
height: 40rpx;
font-size: $main-size;
font-weight: 400;
text-align: left;
color: $main-font-color;
}
.forget-text {
height: 40rpx;
font-size: $main-size;
font-weight: 400;
text-align: right;
color: $second-font-color;
}
}
}
.button {
flex-shrink: 0;
width: 100%;
height: 90rpx;
border-radius: 4px;
box-shadow: 0px 5px 8px 0px rgba(58, 121, 255, 0.2);
display: flex;
align-items: center;
justify-content: center;
font-size: $main-size;
&.disabled {
opacity: 0.4;
}
&.login-btn {
background: $main-color;
color: #ffffff;
}
&.register-btn {
background: white;
color: $main-color;
border: 0.5px solid $main-color;
border-color: rgba(26, 154, 255, 0.3);
}
}
.logo {
flex-shrink: 0;
display: flex;
align-items: center;
justify-content: center;
flex-direction: row;
height: 220rpx;
image {
width: 208rpx;
height: 220rpx;
}
}
::v-deep .uni-easyinput__content {
background-color: transparent !important;
}
::v-deep .is-input-border {
border: none;
}
.container {
display: flex;
align-items: center;
flex-direction: column;
min-height: 100vh;
width: 100vw;
.back-icon {
width: 18px;
height: 18px;
}
.top-view {
display: flex;
flex-direction: column;
align-items: center;
width: 100%;
height: 720rpx;
background-image: url(/@/static/images/login/login-top-back.png);
.login {
font-weight: bold;
margin-top: 70rpx;
}
.logo {
width: 260rpx;
height: 260rpx;
}
}
}
.other-way-box {
flex-shrink: 0;
margin-top: 82rpx;
}
.login-check-box {
flex-shrink: 0;
margin-top: 69px;
margin-bottom: 63px;
margin-left: 22px;
align-self: flex-start;
}
</style>

View File

@@ -0,0 +1,81 @@
<template>
<view>
<view class="message" v-for="(item, index) in 10">
<view class="message-header">
<view class="header-left">
<image src="/src/static/images/message/message.png" mode=""></image>
<view> 系统通知 </view>
</view>
<view class="header-time"> 2023-08-20 20:48 </view>
</view>
<view class="header-content">
<view class="content-title"> 报销-付款已完成 </view>
<view class="content"> 您的费用保修单已完成付款金额300.00请注意查收 </view>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {};
},
methods: {},
};
</script>
<style lang="scss" scoped>
.message {
width: 700rpx;
background: #ffffff;
border-radius: 12rpx;
box-shadow: 0px 3px 4px 0px rgba(24, 144, 255, 0.06);
margin: 24rpx auto 0;
box-sizing: border-box;
padding: 30rpx 30rpx 24rpx;
.message-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 24rpx;
.header-left {
align-items: center;
display: flex;
image {
width: 48rpx;
height: 48rpx;
margin-right: 14rpx;
}
font-size: 34rpx;
color: #000000;
}
.header-time {
font-size: 28rpx;
font-weight: 400;
color: #cccccc;
}
}
.header-content {
box-sizing: border-box;
padding: 24rpx;
background-color: #f7f8f9;
width: 100%;
border-radius: 8rpx;
.content-title {
color: #323333;
font-size: 34rpx;
font-weight: bold;
margin-bottom: 8rpx;
}
.content {
font-size: 28rpx;
color: #777777;
}
}
}
page {
background-color: #f5f5f5;
}
</style>

View File

@@ -0,0 +1,68 @@
<template>
<view class="menu-list">
<uni-list>
<uni-list-item title="消息通知" link showBadge badgeText="6" badgeType="error">
<template #header>
<image class="icon" src="/static/images/mine/mine-message.png" mode=""></image>
</template>
</uni-list-item>
<uni-list-item title="关于我们" link showBadge>
<template #header>
<image class="icon" src="/static/images/mine/mine-about-us.png" mode=""></image>
</template>
</uni-list-item>
<uni-list-item title="版本信息" link rightText="V1.0" showBadge>
<template #header>
<image class="icon" src="/static/images/mine/mine-version-info.png" mode=""></image>
</template>
</uni-list-item>
<uni-list-item title="意见反馈" link rightText="欢迎吐槽" showBadge>
<template #header>
<image class="icon" src="/static/images/mine/mine-feedback.png" mode=""></image>
</template>
</uni-list-item>
<uni-list-item title="隐私条款" link showBadge>
<template #header>
<image class="icon" src="/static/images/mine/user-agreement-icon.png" mode=""></image>
</template>
</uni-list-item>
<uni-list-item title="用户协议" link showBadge>
<template #header>
<image class="icon" src="/static/images/mine/mine-protocol.png" mode=""></image>
</template>
</uni-list-item>
<uni-list-item title="联系客服" showBadge>
<template #header>
<image class="icon" src="/static/images/mine/mine-service.png" mode=""></image>
</template>
<template #footer>
<view style="font-size: 30rpx; color: #1a9aff; line-height: 45rpx"> 400-888-666 </view>
</template>
</uni-list-item>
<uni-list-item title="账号管理" showBadge link>
<template #header>
<image class="icon" src="/static/images/mine/mine-account.png" mode=""></image>
</template>
</uni-list-item>
</uni-list>
</view>
</template>
<script setup></script>
<style scoped lang="scss">
.menu-list {
box-sizing: border-box;
background-color: #fff;
width: 700rpx;
margin: 20rpx auto 0;
border-radius: 6px;
overflow: hidden;
box-shadow: 0 3px 4px 0 rgba(24, 144, 255, 0.06);
padding: 0 30rpx;
.icon {
width: 42rpx;
height: 42rpx;
margin-right: 20rpx;
}
}
</style>

View File

@@ -0,0 +1,112 @@
<template>
<!-- 顶部背景 -->
<view class="nav-container">
<view class="title"> 我的 </view>
</view>
<!-- 用户信息 -->
<view class="user-info-box">
<view class="user-icon">
<image
:src="'https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fsafe-img.xhscdn.com%2Fbw1%2F4d40b566-1f0a-4f8d-bc97-c513df8775b3%3FimageView2%2F2%2Fw%2F1080%2Fformat%2Fjpg&refer=http%3A%2F%2Fsafe-img.xhscdn.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1708226948&t=a9a155669b60f13d6a32c00de2477f22'"
class="user-image"
>
</image>
</view>
<view class="user-info">
<view class="user-name">{{ actualName }}</view>
<view class="user-phone">{{ phone }}</view>
</view>
<view class="vip-flag">
<image src="/@/static/images/mine/no-vip-flag.png" mode=""></image>
</view>
</view>
</template>
<script setup>
import { useUserStore } from '/@/store/modules/system/user';
import { computed } from 'vue';
const actualName = computed(() => {
return useUserStore().actualName;
});
const phone = computed(() => {
return useUserStore().phone;
});
</script>
<style scoped lang="scss">
.nav-container {
flex-shrink: 0;
width: 100%;
height: 312rpx;
background: url('@/static/images/mine/top-background.png') center/100% no-repeat;
position: relative;
.title {
text-align: center;
margin-top: 100rpx;
font-size: 34rpx;
color: #fff;
font-weight: bold;
}
}
.user-info-box {
z-index: 10;
margin: -53px 12px 0;
background: #ffffff;
border-radius: 6px;
box-shadow: 0px 3px 4px 0px rgba(24, 144, 255, 0.06);
backdrop-filter: blur(5.98px);
padding: 20px 15px;
display: flex;
flex-direction: row;
align-items: center;
.user-icon {
width: 58px;
height: 58px;
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
border-radius: 29px;
background-color: white;
.user-image {
width: 54px;
height: 54px;
border-radius: 27px;
}
}
.user-info {
display: flex;
flex-direction: column;
align-items: flex-start;
flex-shrink: 0;
margin: 5px auto 0 12px;
align-self: flex-start;
.user-name {
height: 25px;
font-size: 18px;
font-weight: 600;
text-align: center;
color: #323333;
}
.user-phone {
margin-top: 4px;
height: 20px;
font-size: 14px;
font-weight: 400;
text-align: left;
color: #777777;
line-height: 20px;
}
}
.vip-flag {
align-self: flex-start;
width: 83px;
height: 29px;
margin: 3px 0 0 auto;
image {
width: 100%;
height: 100%;
}
}
}
</style>

View File

@@ -0,0 +1,178 @@
<template>
<view class="user-info-box">
<view class="user-icon">
<image
class="user-image"
src="https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fsafe-img.xhscdn.com%2Fbw1%2F4d40b566-1f0a-4f8d-bc97-c513df8775b3%3FimageView2%2F2%2Fw%2F1080%2Fformat%2Fjpg&refer=http%3A%2F%2Fsafe-img.xhscdn.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1708226948&t=a9a155669b60f13d6a32c00de2477f22"
>
</image>
</view>
<view class="user-info">
<view class="user-name">{{ actualName }}</view>
<view class="user-phone">{{ phone }}</view>
</view>
</view>
<view class="vip-card">
<view class="card-left">
<image class="vip-icon" src="/static/images/mine/vip-icon.png" mode=""></image>
<view class=""> SmartAdmin </view>
</view>
<image class="open-vip" src="/static/images/mine/open-vip.png" mode=""></image>
</view>
<view class="grid-menu">
<uni-grid :column="4" :showBorder="false">
<uni-grid-item v-for="(item, index) in menuList" :index="index" :key="index">
<view class="grid-item-box" style="background-color: #fff">
<image class="image" :src="item.image" mode=""></image>
<text class="text">{{ item.title }}</text>
</view>
</uni-grid-item>
</uni-grid>
</view>
</template>
<script setup>
import { useUserStore } from '/@/store/modules/system/user';
import { computed } from 'vue';
const actualName = computed(() => {
return useUserStore().actualName;
});
const phone = computed(() => {
return useUserStore().phone;
});
const menuList = [
{
title: '地址',
image: '/static/images/mine/mine-menu-address.png',
},
{
title: '优惠券',
image: '/static/images/mine/mine-menu-coupon.png',
},
{
title: '收藏',
image: '/static/images/mine/mine-menu-collect.png',
},
{
title: '余额',
image: '/static/images/mine/mine-menu-balance.png',
},
];
</script>
<style scoped lang="scss">
.user-info-box {
z-index: 10;
padding: 32px 12px 15px;
display: flex;
flex-direction: row;
align-items: center;
.user-icon {
width: 58px;
height: 58px;
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
border-radius: 29px;
background-color: white;
.user-image {
width: 54px;
height: 54px;
border-radius: 27px;
}
}
.user-info {
display: flex;
flex-direction: column;
align-items: flex-start;
flex-shrink: 0;
margin: 5px auto 0 12px;
align-self: flex-start;
.user-name {
height: 25px;
font-size: 18px;
font-weight: 600;
text-align: center;
color: #323333;
}
.user-phone {
margin-top: 4px;
height: 20px;
font-size: 14px;
font-weight: 400;
text-align: left;
color: #777777;
line-height: 20px;
}
}
}
.vip-card {
background-image: url('/@/static/images/mine/vip-bg.png');
height: 80rpx;
background-repeat: no-repeat;
width: 700rpx;
margin: 0 auto;
background-size: 700rpx 80rpx;
display: flex;
align-items: center;
justify-content: space-between;
.card-left {
display: flex;
align-items: center;
.vip-icon {
width: 50rpx;
height: 46rpx;
margin-left: 32rpx;
margin-right: 8rpx;
}
view {
color: #f5cc8f;
font-size: 30rpx;
font-weight: 600;
}
}
.open-vip {
width: 136rpx;
height: 46rpx;
display: flex;
margin-right: 32rpx;
}
}
.grid-menu {
width: 700rpx;
margin: 20rpx auto;
}
.menu-item {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
.item-image {
width: 80rpx;
height: 80rpx;
}
}
.image {
width: 84rpx;
height: 84rpx;
}
.text {
font-size: 14px;
margin-top: 5px;
}
.grid-item-box {
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 15px 0;
}
</style>

View File

@@ -0,0 +1,43 @@
<template>
<view class="container">
<!-- 用户 -->
<!-- <MineUserBlue />-->
<MineUserWhite />
<!---功能菜单--->
<MineMenu />
<!---退出--->
<view class="logout-btn" @click="logout">
<view class="label">退出登录</view>
</view>
</view>
</template>
<script setup>
import MineMenu from './components/mine-menu.vue';
import MineUserBlue from './components/mine-user-blue.vue';
import MineUserWhite from './components/mine-user-white.vue';
const logout = () => {};
</script>
<style lang="scss" scoped>
.container {
width: 100%;
background: #f4f4f4;
display: flex;
flex-direction: column;
}
.logout-btn {
margin: 24px 27px 50px;
height: 44px;
opacity: 0.5;
background: #ffffff;
border-radius: 22px;
box-shadow: 0px 3px 4px 0px rgba(24, 144, 255, 0.06);
font-size: 15px;
line-height: 44px;
font-weight: 700;
text-align: center;
color: #353535;
}
</style>

View File

@@ -0,0 +1,72 @@
<template>
<view class="list-container">
<view class="list-item" @click="gotoDetail(item.noticeId)" v-for="item in list" :key="item.noticeId">
<view class="title"> {{ item.noticeTypeName }} {{ item.title }} </view>
<view class="author" v-if="item.author"> 作者{{ item.author }} </view>
<view class="author" v-if="item.source"> 来源{{ item.source }} </view>
<view class="publish-time">
<view class="time">发布时间{{ item.publishTime }}</view>
<view class="un-read" v-if="!item.viewFlag">未读</view>
<view class="read" v-if="item.viewFlag">已读</view>
</view>
</view>
</view>
</template>
<script setup>
const props = defineProps({
marginTop: {
type: String,
default: '0',
},
list: {
type: Array,
default: [],
},
});
function gotoDetail(noticeId) {
uni.navigateTo({ url: '/pages/notice/notice-detail?noticeId=' + noticeId });
}
</script>
<style lang="scss" scoped>
.list-container {
margin-top: v-bind(marginTop);
padding: 20rpx 10rpx;
}
.list-item {
box-sizing: border-box;
margin: 0 30rpx;
padding: 30rpx 0;
border-bottom: #cdcdcd 1px solid;
.title {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20rpx;
font-size: 16px;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
}
.author {
margin-bottom: 14rpx;
color: #999999;
font-size: 12px;
text-overflow: ellipsis;
}
.publish-time {
font-size: 12px;
color: #999999;
display: flex;
flex-direction: row;
justify-content: space-between;
.un-read {
color: $uni-color-primary;
}
}
}
</style>

View File

@@ -0,0 +1,115 @@
<template>
<uni-popup ref="popupRef" background-color="#fff" type="bottom" :is-mask-click="false">
<view class="query-form-pop">
<view class="smart-form">
<uni-forms :label-width="100" :modelValue="form" label-position="left">
<view class="smart-form-group">
<view class="smart-form-group-title"> 分类 </view>
<view class="smart-form-group-content">
<uni-forms-item class="smart-form-item" label="类型:">
<uni-data-select v-model="form.noticeTypeId" :localdata="noticeTypeList" @change="changeNoticeType" :clear="true" />
</uni-forms-item>
</view>
</view>
<view class="smart-form-group">
<view class="smart-form-group-title"> 发布日期 </view>
<view class="smart-form-group-content">
<uni-forms-item class="smart-form-item" label="开始日期">
<uni-datetime-picker type="date" clear-icon v-model="form.publishTimeBegin" />
</uni-forms-item>
<uni-forms-item class="smart-form-item" label="截止日期">
<uni-datetime-picker type="date" clear-icon v-model="form.publishTimeEnd" />
</uni-forms-item>
</view>
</view>
</uni-forms>
<view class="smart-form-submit smart-margin-top20">
<button class="smart-form-submit-btn smart-margin-right20" type="default" @click="cancel">取消</button>
<button class="smart-form-submit-btn" type="warn" @click="reset">重置</button>
<button class="smart-form-submit-btn" type="primary" @click="ok">确定</button>
</view>
</view>
</view>
</uni-popup>
</template>
<script setup>
import { onMounted, reactive, ref, toRaw } from 'vue';
import { noticeApi } from '/@/api/business/oa/notice-api';
import _ from 'lodash';
const emits = defineEmits(['close']);
defineExpose({ show });
// --------------------- 显示 隐藏 ---------------------
const popupRef = ref();
function show() {
popupRef.value.open();
}
function close() {
popupRef.value.close();
}
// --------------------- 表单 ---------------------
const defaultFormData = {
// 分类
noticeTypeId: undefined,
noticeTypeName: undefined,
// 发布开始时间
publishTimeBegin: undefined,
// 发布截止时间
publishTimeEnd: undefined,
};
const form = reactive({ ...defaultFormData });
// --------------------- 通知类型 ---------------------
const noticeTypeList = ref([]);
async function queryNoticeTypeList() {
let res = await noticeApi.getAllNoticeTypeList();
noticeTypeList.value = res.data.map((e) => Object.assign({}, { text: e.noticeTypeName, value: e.noticeTypeId }));
}
onMounted(() => {
queryNoticeTypeList();
});
function changeNoticeType(e) {
form.noticeTypeId = e;
form.noticeTypeName = _.find(noticeTypeList.value, { value: form.noticeTypeId }).text;
}
// ----------------------- 表单操作 ------------------------
// 取消
function cancel() {
close();
emits('close', null);
}
// 重置
function reset() {
Object.assign(form, defaultFormData);
close();
emits('close', toRaw(form));
}
// 确定
function ok() {
close();
emits('close', toRaw(form));
}
</script>
<style lang="scss" scoped>
.query-form-pop {
height: 800rpx;
overflow-y: scroll;
}
</style>

View File

@@ -0,0 +1,76 @@
<template>
<view class="container">
<view class="title">
<uni-title type="h1" align="center" :title="noticeDetail.title"></uni-title>
<uni-title
type="h4"
align="center"
color="#999999"
v-if="noticeDetail.documentNumber"
:title="'(' + noticeDetail.documentNumber + ')'"
></uni-title>
<uni-title type="h4" align="center" color="#999999" :title="noticeDetail.subTitle"></uni-title>
</view>
<view class="content">
<rich-text :nodes="noticeDetail.content" />
</view>
</view>
</template>
<script setup>
import { reactive } from 'vue';
import { noticeApi } from '/@/api/business/oa/notice-api';
import { onLoad } from '@dcloudio/uni-app';
import { smartSentry } from '/@/lib/smart-sentry';
const noticeDetail = reactive({
title: '',
subTitle: '',
documentNumber: '',
content: '',
});
async function getNoticeDetail(noticeId) {
try {
uni.showLoading({ title: '加载中' });
let res = await noticeApi.view(noticeId);
noticeDetail.title = res.data.title;
noticeDetail.content = res.data.contentHtml;
noticeDetail.documentNumber = res.data.documentNumber;
let subTitleArray = [];
if (res.data.author) {
subTitleArray.push(res.data.author);
}
if (res.data.publishTime) {
subTitleArray.push(res.data.publishTime);
}
noticeDetail.subTitle = subTitleArray.join(' | ');
} catch (e) {
smartSentry.captureError(e);
} finally {
uni.hideLoading();
}
}
onLoad((option) => {
uni.pageScrollTo({
scrollTop: 0,
});
getNoticeDetail(option.noticeId);
});
</script>
<style lang="scss" scoped>
.container {
height: 100vh;
padding: 20rpx;
.content {
border-top: #cccccc 1px solid;
margin-top: 50rpx;
padding: 50rpx 16rpx 50rpx 16rpx;
line-height: 30px;
color: #333333;
}
}
</style>

View File

@@ -0,0 +1,224 @@
<template>
<view>
<mescroll-body @init="mescrollInit" :down="{ auto: false }" @down="onDown" @up="onUp">
<!--搜索框-->
<uni-nav-bar :border="false" fixed :leftWidth="0" rightWidth="70px">
<view class="input">
<uni-easyinput
prefixIcon="search"
:clearable="true"
trim="all"
v-model="queryForm.keywords"
placeholder="搜索:标题、作者、来源等"
@confirm="search"
@clear="search"
/>
</view>
<template #right>
<view class="nav-right" @click="showQueryFormPopUp">
<uni-icons type="settings" size="30"></uni-icons>
<view class="nav-right-name"> 筛选 </view>
</view>
</template>
</uni-nav-bar>
<!--筛选条件提示-->
<uni-notice-bar
@close="onCloseQueryFormTips"
v-if="showQueryFormTipsFlag"
class="query-bar"
background-color="#007aff"
color="white"
show-close
single
:text="queryFormTips"
/>
<!-- 筛选条件表单弹窗 -->
<NoticeQueryFormPopUp ref="noticeQueryFormPopUpRef" @close="onCloseQueryFormPopUp" />
<!-- 列表 -->
<NoticeList :list="noticeListData" :margin-top="queryFormTipsMarginTop" />
</mescroll-body>
</view>
</template>
<script setup>
import { reactive, ref } from 'vue';
import NoticeQueryFormPopUp from './components/notice-query-form-popup.vue';
import { noticeApi } from '/@/api/business/oa/notice-api';
import { onPageScroll, onReachBottom } from '@dcloudio/uni-app';
import useMescroll from '@/uni_modules/uni-mescroll/hooks/useMescroll';
import { smartSentry } from '/@/lib/smart-sentry';
import NoticeList from './components/notice-list.vue';
import _ from 'lodash';
// --------------------------- 筛选条件弹窗 ---------------------------------
const noticeQueryFormPopUpRef = ref();
/**
* 显示 筛选弹窗
*/
function showQueryFormPopUp() {
noticeQueryFormPopUpRef.value.show();
}
/**
* 监听 筛选弹窗 关闭
*/
function onCloseQueryFormPopUp(param) {
if (param === null) {
return;
}
Object.assign(queryForm, param);
showOrHideQueryFormTips();
query(getMescroll(), true, buildQueryParam(1));
uni.pageScrollTo({
scrollTop: 0,
});
}
// --------------------------- 筛选条件tips ---------------------------------
const queryFormTips = ref(null);
const showQueryFormTipsFlag = ref(false);
const queryFormTipsMarginTop = ref('0px');
/**
* 查询提示
*/
function buildQueryFormTips() {
let tips = null;
if (queryForm.keywords) {
tips = '搜索:' + queryForm.keywords;
}
if (queryForm.noticeTypeName) {
tips = tips ? tips + '' : '';
tips = tips + '类型:' + queryForm.noticeTypeName;
}
if (queryForm.publishTimeBegin) {
tips = tips ? tips + '' : '';
tips = tips + '发布开始时间:' + queryForm.publishTimeBegin;
}
if (queryForm.publishTimeEnd) {
tips = tips ? tips + '' : '';
tips = tips + '发布截止时间:' + queryForm.publishTimeEnd;
}
return tips;
}
/**
* 显示或者隐藏tips
*/
function showOrHideQueryFormTips() {
let tips = buildQueryFormTips();
queryFormTipsMarginTop.value = _.isEmpty(tips) ? '0px' : '50rpx';
showQueryFormTipsFlag.value = !_.isEmpty(tips);
queryFormTips.value = tips;
}
/**
* 关闭筛选条件 tips清空搜索条件
*/
function onCloseQueryFormTips() {
Object.assign(queryForm, defaultForm);
queryFormTipsMarginTop.value = '0px';
showQueryFormTipsFlag.value = false;
queryFormTips.value = '';
search();
}
// --------------------------- 查询 ---------------------------------
const defaultForm = {
noticeTypeId: undefined, //分类
noticeTypeName: undefined, //分类名称
keywords: '', //标题、作者、来源
publishTimeBegin: null, //发布-开始时间
publishTimeEnd: null, //发布-截止时间
pageNum: 1,
pageSize: 10,
};
// 查询表单
const queryForm = reactive({ ...defaultForm });
// 通知列表数据
const noticeListData = ref([]);
function buildQueryParam(pageNum) {
queryForm.pageNum = pageNum;
return Object.assign({}, queryForm, { pageNum });
}
async function query(mescroll, isDownFlag, param) {
try {
let res = await noticeApi.queryEmployeeNotice(param);
if (!isDownFlag) {
noticeListData.value = noticeListData.value.concat(res.data.list);
} else {
noticeListData.value = res.data.list;
}
mescroll.endSuccess(res.data.list.length, res.data.pages > res.data.pageNum);
} catch (e) {
smartSentry.captureError(e);
//联网失败, 结束加载
mescroll.endErr();
}
}
const { mescrollInit, getMescroll } = useMescroll(onPageScroll, onReachBottom);
/**
* 搜索
*/
function search() {
showOrHideQueryFormTips();
query(getMescroll(), true, buildQueryParam(1));
uni.pageScrollTo({
scrollTop: 0,
});
}
/**
* 下拉刷新
*/
function onDown(mescroll) {
queryForm.pageNum = 1;
query(mescroll, true, buildQueryParam(1));
}
/**
* 上拉加载更多
*/
function onUp(mescroll) {
query(mescroll, false, buildQueryParam(mescroll.num));
}
</script>
<style lang="scss" scoped>
.input {
width: 100%;
height: 72rpx;
background: #f7f8f9;
border-radius: 4px;
margin: 8rpx 0;
display: flex;
align-items: center;
}
.nav-right {
width: 140px;
display: flex;
height: 88rpx;
flex-direction: row;
line-height: 88rpx;
.nav-right-name {
margin-left: 5px;
line-height: 88rpx;
font-size: 30rpx;
}
}
.query-bar {
position: fixed;
}
</style>

View File

@@ -0,0 +1,107 @@
<template>
<view class="view">
<view class="line"> </view>
<view class="view-item">
<view class="itme-top">
<view class="itme-top-icon-text" type="default"> </view>
<view class="item-top-text"> 湖北省武汉市东西湖区东湖区东湖区 </view>
</view>
<view class="item-bottom"> 河南省洛阳市洛龙区119号 </view>
</view>
<view class="view-item">
<view class="itme-top">
<view class="itme-top-icon-text" type="warning"> </view>
<view class="item-top-text"> 广东省东莞 </view>
</view>
<view class="item-bottom"> 河南省洛阳市西工区110</view>
</view>
<view class="view-item">
<view class="itme-top">
<view class="itme-top-icon-text" type="error"> </view>
<view class="item-top-text"> 湖北省武汉市东西湖区东湖区东湖区 </view>
</view>
<view class="item-bottom"> 河南省洛阳市洛龙区110号 </view>
</view>
<view class="view-item">
<view class="itme-top">
<view class="itme-top-icon-text" type="success"> </view>
<view class="item-top-text"> 湖北省武汉市东西湖区东湖区东湖区 </view>
</view>
<view class="item-bottom"> 河南省洛阳市洛龙区119号 </view>
</view>
</view>
</template>
<script setup></script>
<style lang="scss" scoped>
.view {
box-sizing: border-box;
width: 94%;
border-radius: 16rpx;
background-color: #fff;
padding: 30rpx;
margin: 0 auto 20rpx;
position: relative;
.line {
position: absolute;
height: 300rpx;
border-left: 1rpx dashed #444;
z-index: 0;
top: 40rpx;
left: 50rpx;
}
.view-item {
&:last-child {
margin-bottom: 0;
}
position: relative;
z-index: 1;
margin-bottom: 16rpx;
.item-bottom {
font-size: 28rpx;
color: #777777;
margin-left: 58rpx;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.itme-top {
display: flex;
align-items: center;
}
.itme-top-icon-text {
width: 40rpx;
height: 40rpx;
border-radius: 12rpx;
text-align: center;
line-height: 40rpx;
color: #fff;
font-size: 26rpx;
margin-right: 18rpx;
&[type='default'] {
background: #1a9aff;
}
&[type='warning'] {
background: #f3c35b;
}
&[type='error'] {
background: #ff6c00;
}
&[type='success'] {
background: #6ec98a;
}
}
.item-top-text {
font-size: 32rpx;
color: #444;
font-weight: bold;
padding-bottom: 5rpx;
flex: 1;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
}
}
</style>

View File

@@ -0,0 +1,172 @@
<template>
<view class="view">
<view class="view-title">
<view class="title-left-bg">
</view>
<view class="title-text">
运单信息
</view>
</view>
<view class="view-item">
<view class="item-left">
运单号
</view>
<view class="item-right">
TDD202304950
</view>
</view>
<view class="view-item">
<view class="item-left">
订单号
</view>
<view class="item-right">
TDD202304950
</view>
</view>
<view class="view-item">
<view class="item-left">
客户订单号
</view>
<view class="item-right">
TDD202304950
</view>
</view>
<view class="view-item">
<view class="item-left">
箱号
</view>
<view class="item-right">
TDD202304950
</view>
</view>
<view class="view-item">
<view class="item-left">
铅封号
</view>
<view class="item-right">
TDD202304950
</view>
</view>
<view class="view-item">
<view class="item-left">
柜型
</view>
<view class="item-right">
TDD202304950
</view>
</view>
<view class="view-item">
<view class="item-left">
最迟提箱时间
</view>
<view class="item-right">
TDD202304950
</view>
</view>
<view class="view-item">
<view class="item-left">
货主
</view>
<view class="item-right">
TDD202304950
</view>
</view>
<view class="view-item">
<view class="item-left">
业务时间
</view>
<view class="item-right">
TDD202304950
</view>
</view>
<view class="view-item">
<view class="item-left">
结算方式
</view>
<view class="item-right">
TDD202304950
</view>
</view>
<view class="view-item">
<view class="item-left">
结算类型
</view>
<view class="item-right">
TDD202304950
</view>
</view>
<view class="view-item">
<view class="item-left">
司机
</view>
<view class="item-right">
TDD202304950
</view>
</view>
<view class="view-item">
<view class="item-left">
车辆
</view>
<view class="item-right">
TDD202304950
</view>
</view>
</view>
</template>
<script setup>
const props = defineProps({
List:{
type:Array,
default:[]
}
})
</script>
<style lang="scss" scoped>
.view{
width: 94%;
margin: 0 auto;
background: #fff;
border-radius: 16rpx;
box-sizing: border-box;
padding: 0 30rpx;
}
.view-title{
height: 84rpx;
display: flex;
align-items: center;
.title-left-bg{
height: 28rpx;
width: 6rpx;
background: #1A9AFF;
border-radius: 4rpx;
margin-right: 14rpx;
}
.title-text{
font-size: 32rpx;
color: #323333;
font-weight: bold;
}
}
.view-item{
display: flex;
height: 100rpx;
justify-content: space-between;
align-items: center;
color: 323333;
border-bottom: 1rpx solid #ededed;
&:last-child{
border: none;
}
.item-left{
font-size: 32rpx;
}
.item-right{
font-size: 30rpx;
}
}
</style>

View File

@@ -0,0 +1,165 @@
<template>
<view class="view">
<view class="view-title">
<view class="title-left-bg">
</view>
<view class="title-text">
费用明细
</view>
<view class="sub-title">
已收金额/已收金额/费用
</view>
</view>
<view class="view-item">
<view class="item-left">
运费
</view>
<view class="item-right">
TDD202304950
</view>
</view>
<view class="view-item">
<view class="item-left">
过磅费
</view>
<view class="item-right">
TDD202304950
</view>
</view>
<view class="view-item">
<view class="item-left">
压夜费
</view>
<view class="item-right">
TDD202304950
</view>
</view>
<view class="view-item">
<view class="item-left">
超重费
</view>
<view class="item-right">
TDD202304950
</view>
</view>
<view class="view-item">
<view class="item-left">
提箱费
</view>
<view class="item-right">
TDD202304950
</view>
</view>
<view class="view-item">
<view class="item-left">
报关费
</view>
<view class="item-right">
TDD202304950
</view>
</view>
<view class="view-item">
<view class="item-left">
其他费
</view>
<view class="item-right">
TDD202304950
</view>
</view>
<view class="view-item">
<view class="item-left">
保税绕园费
</view>
<view class="item-right">
TDD202304950
</view>
</view>
<view class="view-item">
<view class="item-left">
放空费
</view>
<view class="item-right">
TDD202304950
</view>
</view>
<view class="view-item">
<view class="item-left">
修箱费
</view>
<view class="item-right">
TDD202304950
</view>
</view>
<view class="view-item">
<view class="item-left">
服务费
</view>
<view class="item-right">
TDD202304950
</view>
</view>
</view>
</template>
<script setup>
const props = defineProps({
List:{
type:Array,
default:[]
}
})
</script>
<style lang="scss" scoped>
.view{
width: 94%;
margin: 0 auto;
background: #fff;
border-radius: 16rpx;
box-sizing: border-box;
padding: 0 30rpx;
}
.view-title{
height: 84rpx;
display: flex;
align-items: center;
.title-left-bg{
height: 28rpx;
width: 6rpx;
background: #1A9AFF;
border-radius: 4rpx;
margin-right: 14rpx;
}
.title-text{
font-size: 32rpx;
color: #323333;
font-weight: bold;
}
.sub-title{
font-size: 28rpx;
color: #ccc;
flex: 1;
text-align: right;
}
}
.view-item{
display: flex;
height: 100rpx;
justify-content: space-between;
align-items: center;
color: 323333;
border-bottom: 1rpx solid #ededed;
&:last-child{
border: none;
}
.item-left{
font-size: 32rpx;
}
.item-right{
font-size: 30rpx;
}
}
</style>

View File

@@ -0,0 +1,12 @@
<template>
<InfoCardModelTwo/>
<InfoCardModelTwo/>
</template>
<script setup>
import InfoCardModelTwo from './info-card-model-two.vue'
</script>
<style lang="scss" scoped>
</style>

View File

@@ -0,0 +1,13 @@
<template>
<AddressCard/>
<InfoCardModelOne/>
</template>
<script setup>
import AddressCard from './address-card.vue'
import InfoCardModelOne from './info-card-model-one.vue'
</script>
<style lang="scss" scoped>
</style>

View File

@@ -0,0 +1,165 @@
<template>
<view class="view">
<view class="view-title">
<view class="title-left-bg">
</view>
<view class="title-text">
费用明细
</view>
<view class="sub-title">
已付费用/预付费用/费用
</view>
</view>
<view class="view-item">
<view class="item-left">
运费
</view>
<view class="item-right">
TDD202304950
</view>
</view>
<view class="view-item">
<view class="item-left">
过磅费
</view>
<view class="item-right">
TDD202304950
</view>
</view>
<view class="view-item">
<view class="item-left">
压夜费
</view>
<view class="item-right">
TDD202304950
</view>
</view>
<view class="view-item">
<view class="item-left">
超重费
</view>
<view class="item-right">
TDD202304950
</view>
</view>
<view class="view-item">
<view class="item-left">
提箱费
</view>
<view class="item-right">
TDD202304950
</view>
</view>
<view class="view-item">
<view class="item-left">
报关费
</view>
<view class="item-right">
TDD202304950
</view>
</view>
<view class="view-item">
<view class="item-left">
其他费
</view>
<view class="item-right">
TDD202304950
</view>
</view>
<view class="view-item">
<view class="item-left">
保税绕园费
</view>
<view class="item-right">
TDD202304950
</view>
</view>
<view class="view-item">
<view class="item-left">
放空费
</view>
<view class="item-right">
TDD202304950
</view>
</view>
<view class="view-item">
<view class="item-left">
修箱费
</view>
<view class="item-right">
TDD202304950
</view>
</view>
<view class="view-item">
<view class="item-left">
服务费
</view>
<view class="item-right">
TDD202304950
</view>
</view>
</view>
</template>
<script setup>
const props = defineProps({
List:{
type:Array,
default:[]
}
})
</script>
<style lang="scss" scoped>
.view{
width: 94%;
margin: 0 auto;
background: #fff;
border-radius: 16rpx;
box-sizing: border-box;
padding: 0 30rpx;
}
.view-title{
height: 84rpx;
display: flex;
align-items: center;
.title-left-bg{
height: 28rpx;
width: 6rpx;
background: #1A9AFF;
border-radius: 4rpx;
margin-right: 14rpx;
}
.title-text{
font-size: 32rpx;
color: #323333;
font-weight: bold;
}
.sub-title{
font-size: 28rpx;
color: #ccc;
flex: 1;
text-align: right;
}
}
.view-item{
display: flex;
height: 100rpx;
justify-content: space-between;
align-items: center;
color: 323333;
border-bottom: 1rpx solid #ededed;
&:last-child{
border: none;
}
.item-left{
font-size: 32rpx;
}
.item-right{
font-size: 30rpx;
}
}
</style>

View File

@@ -0,0 +1,12 @@
<template>
<InfoCardModelThree/>
<InfoCardModelThree/>
</template>
<script setup>
import InfoCardModelThree from './info-card-model-three.vue'
</script>
<style lang="scss" scoped>
</style>

View File

@@ -0,0 +1,131 @@
<template>
<view class="view">
<view class="view-title">
<view class="title-left-bg">
</view>
<view class="title-text">
货物信息1
</view>
<view class="sub-title">
</view>
</view>
<view class="view-item">
<view class="item-left">
货物类型
</view>
<view class="item-right">
其他
</view>
</view>
<view class="view-item">
<view class="item-left">
货物名称
</view>
<view class="item-right">
其他
</view>
</view>
<view class="view-item">
<view class="item-left">
货物单位
</view>
<view class="item-right">
</view>
</view>
<view class="view-item">
<view class="item-left">
货物毛重/
</view>
<view class="item-right">
64
</view>
</view>
<view class="view-item">
<view class="item-left">
货物数量
</view>
<view class="item-right">
2
</view>
</view>
<view class="view-item">
<view class="item-left">
备注
</view>
<view class="item-right">
这是备注信息
</view>
</view>
</view>
</template>
<script setup>
const props = defineProps({
List:{
type:Array,
default:[]
}
})
</script>
<style lang="scss" scoped>
.view{
width: 94%;
margin: 0 auto;
background: #fff;
border-radius: 16rpx;
box-sizing: border-box;
padding: 0 30rpx;
padding-bottom: 24rpx;
}
.view-title{
height: 84rpx;
display: flex;
align-items: center;
margin-bottom: 16rpx;
.title-left-bg{
height: 28rpx;
width: 6rpx;
background: #1A9AFF;
border-radius: 4rpx;
margin-right: 14rpx;
}
.title-text{
font-size: 32rpx;
color: #323333;
font-weight: bold;
}
.sub-title{
font-size: 28rpx;
color: #ccc;
flex: 1;
text-align: right;
}
}
.view-item{
display: flex;
height: 40rpx;
align-items: center;
margin-bottom: 16rpx;
&:last-child{
margin-bottom: 0;
}
.item-left{
width: 180rpx;
margin-right: 20rpx;
font-size: 28rpx;
color: #777777;
}
.item-right{
font-size: 30rpx;
color: #323333;
font-weight: bold;
font-size: 28rpx;
}
}
</style>

View File

@@ -0,0 +1,117 @@
<template>
<view class="view">
<view class="view-title">
<view class="title-left-bg">
</view>
<view class="title-text">
凭证/磅单装货
</view>
</view>
<view class="view-item">
<view class="item-left">
时间
</view>
<view class="item-right">
2023-08-08 12:24:05
</view>
</view>
<view class="view-item">
<view class="item-left">
位置
</view>
<view class="item-right">
河南省许昌市襄城县书岗线
</view>
</view>
<view class="view-item">
<view class="item-left">
经度
</view>
<view class="item-right">
33.45767
</view>
</view>
<view class="view-item">
<view class="item-left">
纬度
</view>
<view class="item-right">
113.45585
</view>
</view>
<view class="image-box">
<image src="/static/logo.png" mode=""></image>
<image src="/static/logo.png" mode=""></image>
</view>
</view>
</template>
<script setup>
</script>
<style lang="scss" scoped>
.view{
width: 94%;
margin: 0 auto;
background: #fff;
border-radius: 16rpx;
box-sizing: border-box;
padding: 0 30rpx;
padding-bottom: 24rpx;
margin-bottom: 24rpx;
}
.view-title{
height: 84rpx;
display: flex;
align-items: center;
margin-bottom: 16rpx;
.title-left-bg{
height: 28rpx;
width: 6rpx;
background: #FED453;
border-radius: 4rpx;
margin-right: 14rpx;
}
.title-text{
font-size: 32rpx;
color: #323333;
font-weight: bold;
}
}
.view-item{
display: flex;
height: 40rpx;
align-items: center;
margin-bottom: 16rpx;
&:last-child{
margin-bottom: 0;
}
.item-left{
width: 90rpx;
margin-right: 20rpx;
font-size: 28rpx;
color: #777777;
}
.item-right{
font-size: 30rpx;
color: #323333;
font-weight: bold;
font-size: 28rpx;
}
}
.image-box{
display: flex;
justify-content: space-between;
image{
width: 308rpx;
height: 172rpx;
border-radius: 8rpx;
}
padding-top: 20rpx;
border-top: 1rpx solid #ededed;
}
</style>

View File

@@ -0,0 +1,105 @@
<template>
<view class="view">
<view class="view-title">
<view class="title-left-bg"> </view>
<view class="title-text"> 付款单号1 </view>
<view class="sub-title">
<view class="success"> 已审核 </view>
<view class="warning"> 待支付 </view>
</view>
</view>
<view class="view-item">
<view class="item-left"> 运单号 </view>
<view class="item-right"> TYD2023080979 </view>
</view>
<view class="view-item">
<view class="item-left"> 应付金额 </view>
<view class="item-right"> 500 </view>
</view>
<view class="view-item">
<view class="item-left"> 已付金额 </view>
<view class="item-right"> 200 </view>
</view>
<view class="view-item">
<view class="item-left"> 收款账户 </view>
<view class="item-right"> 王强/623457910384 </view>
</view>
</view>
</template>
<script setup></script>
<style lang="scss" scoped>
.view {
width: 94%;
margin: 0 auto;
background: #fff;
border-radius: 16rpx;
box-sizing: border-box;
padding: 0 30rpx;
padding-bottom: 24rpx;
margin-bottom: 24rpx;
}
.view-title {
height: 84rpx;
display: flex;
align-items: center;
margin-bottom: 16rpx;
.title-left-bg {
height: 28rpx;
width: 6rpx;
background: #1a9aff;
border-radius: 4rpx;
margin-right: 14rpx;
}
.title-text {
font-size: 32rpx;
color: #323333;
font-weight: bold;
}
.sub-title {
flex: 1;
display: flex;
justify-content: flex-end;
view {
height: 42rpx;
width: 112rpx;
text-align: center;
line-height: 42rpx;
font-size: 24rpx;
margin-left: 24rpx;
}
.success {
background: #e5f8e9;
color: #1ce36d;
}
.warning {
background: #fff0ed;
color: #ff6c00;
}
}
}
.view-item {
display: flex;
height: 40rpx;
align-items: center;
margin-bottom: 16rpx;
&:last-child {
margin-bottom: 0;
}
.item-left {
width: 180rpx;
margin-right: 20rpx;
font-size: 28rpx;
color: #777777;
}
.item-right {
font-size: 30rpx;
color: #323333;
font-weight: bold;
font-size: 28rpx;
}
}
</style>

View File

@@ -0,0 +1,80 @@
<template>
<scroll-view class="scroll-view" scroll-x="true" :show-scrollbar="false">
<view class="item" :class="active == item.value ? 'active' : ''" v-for="item in tabsList" :key="item.value" @click="change(item.value)">
{{ item.lable }}
</view>
</scroll-view>
</template>
<script setup>
import { ref, watch } from 'vue';
const props = defineProps({
modelValue: {
type: Number,
default: 0,
},
tabsList: {
type: Array,
default: [],
},
});
const active = ref(0);
watch(
() => props.modelValue,
(newValue) => {
active.value = newValue;
}
);
const emit = defineEmits(['update:modelValue']);
const change = (value) => {
active.value = value;
emit('update:modelValue', value);
};
</script>
<style lang="scss" scoped>
.item {
padding: 0 24rpx;
height: 72rpx;
font-size: 30rpx;
color: #777;
background: #fff;
display: inline-block;
border-radius: 8rpx;
line-height: 72rpx;
margin-left: 24rpx;
margin: 24rpx 0 24rpx 24rpx;
}
.active {
color: #ffffff;
background: #1a9aff;
}
.scroll-view ::v-deep ::-webkit-scrollbar {
height: 0 !important;
width: 0 !important;
background: transparent;
}
.smart-form-submit {
border-top: #eee 1px solid;
height: 80px;
display: flex;
flex-direction: row;
align-items: center;
position: absolute;
bottom: 0;
background-color: white;
width: 100%;
.smart-form-submit-btn {
margin: 10px;
height: 2.5;
flex: 1;
}
}
</style>

View File

@@ -0,0 +1,52 @@
<template>
<view>
<ScrollTabs v-model="active" :tabsList="tabsList"></ScrollTabs>
<DetailModelBaseInfo v-if="active==0"/>
<DetailModelPath v-if="active==1"/>
<DetailModelDuePay v-if="active==2"/>
<DetailModelReceivable v-if="active==3"/>
<DetailModelFinal v-if="active==4"/>
<DetailModelVoucher v-if="active==5"/>
</view>
</template>
<script setup>
import { ref } from 'vue';
import ScrollTabs from './components/scroll-tabs.vue'
import DetailModelBaseInfo from './components/detail-model-base-info.vue'
import DetailModelPath from './components/detail-model-path.vue'
import DetailModelDuePay from './components/detail-model-due-pay.vue'
import DetailModelReceivable from './components/detail-model-receivable.vue'
import DetailModelFinal from './components/detail-model-final.vue'
import DetailModelVoucher from './components/detail-model-voucher.vue'
const tabsList = [{
lable:'基本路线',
value:0
},{
lable:'路线/货物',
value:1
},{
lable:'应付费用信息',
value:2
},{
lable:'应收费用信息',
value:3
},{
lable:'结算信息',
value:4
},{
lable:'凭证/磅单',
value:5
}]
const active = ref(0)
</script>
<style lang="scss" scoped>
page{
background: #f4f4f4;
}
</style>

View File

@@ -0,0 +1,80 @@
<template>
<view class="item" v-for="(item,index) in 4" :key="index" :class="type[index]">
<view class="header">
Plc控制柜
</view>
<view class="footer">
<view class="footer-left">
A区气路总阀
</view>
<view class="footer-state" :class="type[index]">
关闭
</view>
</view>
</view>
</template>
<script setup>
defineProps({
list: {
type: Array,
default: []
}
})
const type = ['info','primary','warning','']
</script>
<style lang="scss" scoped>
.item {
width: 700rpx;
margin: 20rpx auto 0;
background: #ffffff;
border-radius: 12rpx;
box-shadow: 0px 3px 4px 0px rgba(24, 144, 255, 0.06);
padding: 26rpx 40rpx 20rpx;
box-sizing: border-box;
border-left: 8rpx solid #4F4D4D;
&.primary{
border-color: #007FF2;
}
&.warning{
border-color: #FF6C00;
}
&.info{
border-color: #CCCCCC;
}
.header {
display: flex;
justify-content: space-between;
padding-bottom: 20rpx;
border-bottom: 1rpx solid #ededed;
margin-bottom: 19rpx;
font-size: 34rpx;
color: #444;
}
.footer {
display: flex;
justify-content: space-between;
font-size: 28rpx;
.footer-left{
color: #777777;
}
.footer-state{
&.primary{
color: #007FF2;
}
&.warning{
color: #FF6C00;
}
&.info{
color: #CCCCCC;
}
color: #4F4D4D;
}
}
}
</style>

View File

@@ -0,0 +1,96 @@
<template>
<view class="item" v-for="(item, index) in 2" :key="index">
<view class="header">
<view class="header-left">
<image class="header-left-image" src="/static/images/pure-list/maintain.png" mode=""></image>
<view class="header-left-title"> 报修信息 </view>
</view>
<view class="header-right-id"> 保修单还12876 </view>
</view>
<view class="footer">
<view class="footer-item">
<view class="label"> 设备 </view>
<view class="info"> 灭火控制柜plc </view>
</view>
<view class="footer-item">
<view class="label"> 描述 </view>
<view class="info"> 总设备压力过大导致气压不稳 </view>
</view>
<view class="footer-item">
<view class="label"> 报修人 </view>
<view class="info"> 闫jj </view>
</view>
<view class="footer-item">
<view class="label"> 受理人 </view>
<view class="info"> 王jj </view>
</view>
</view>
</view>
</template>
<script setup>
defineProps({
list: {
type: Array,
default: [],
},
});
</script>
<style lang="scss" scoped>
.item {
position: relative;
width: 700rpx;
margin: 20rpx auto 0;
background: #ffffff;
border-radius: 12rpx;
box-shadow: 0px 3px 4px 0px rgba(24, 144, 255, 0.06);
padding: 26rpx 40rpx 20rpx;
box-sizing: border-box;
.header {
display: flex;
justify-content: space-between;
align-items: center;
padding-bottom: 20rpx;
border-bottom: 1rpx solid #ededed;
margin-bottom: 16rpx;
.header-left {
display: flex;
align-items: center;
.header-left-image {
width: 48rpx;
height: 48rpx;
margin-right: 16rpx;
}
.header-left-title {
font-size: 34rpx;
font-weight: bold;
color: #444444;
}
}
.header-right-id {
font-size: 28rpx;
color: #777777;
}
}
.footer {
.footer-item {
display: flex;
align-items: center;
margin-bottom: 16rpx;
.label {
width: 112rpx;
font-size: 28rpx;
color: #777777;
}
.info {
font-size: 28rpx;
color: #323333;
font-weight: bold;
}
}
}
}
</style>

View File

@@ -0,0 +1,126 @@
<template>
<view class="item">
<view class="item-header">
<view class="header-title">
商业环境快速变化带来的挑战
</view>
<view class="header-right">
共15讲>
</view>
</view>
<view class="item-tags">
<view class="primary">
商务
</view>
<view class="success">
专题
</view>
<view class="warning">
付费
</view>
</view>
<view class="content">
<view class="content-box">
<view class="c-top">
授课老师
</view>
<view class="c-bottom">
王老师
</view>
</view>
<view class="content-box">
<view class="c-top">
开课时间
</view>
<view class="c-bottom">
2023.08.20 20:00
</view>
</view>
</view>
</view>
</template>
<script setup>
defineProps({
list:{
type:Array,
default:[]
}
})
</script>
<style lang="scss" scoped>
.item{
width: 700rpx;
margin: 20rpx auto 0;
background: #ffffff;
border-radius: 12rpx;
box-shadow: 0px 3px 4px 0px rgba(24,144,255,0.06);
padding: 26rpx 30rpx 20rpx;
box-sizing: border-box;
.item-header{
display: flex;
justify-content: space-between;
align-items: flex-start;
.header-title{
width: 480rpx;
font-size: 34rpx;
color: #444;
font-weight: 600;
}
.header-right{
margin-top: 4rpx;
font-size: 28rpx;
color: #777777;
}
}
.item-tags{
display: flex;
margin: 10rpx 0;
view{
width: 112rpx;
height: 42rpx;
border-radius: 4rpx;
text-align: center;
line-height: 42rpx;
font-size: 24rpx;
margin-right: 24rpx;
&.primary{
background: #eef7fd;
color: #1A9AFF;
}
&.success{
color: #1CE36D;
background: #e5f8e9;
}
&.warning{
background: #fff0ed;
color: #FF6C00;
}
}
}
.content{
width: 100%;
height: 140rpx;
background: #f7f8f9;
border-radius: 4px;
display: flex;
justify-content: space-around;
align-items: center;
.content-box{
display: flex;
flex-direction: column;
align-items: center;
}
.c-top{
font-size: 24rpx;
color: #777777;
margin-bottom: 4rpx;
}
.c-bottom{
font-size: 30rpx;
color: #444444;
}
}
}
</style>

View File

@@ -0,0 +1,109 @@
<template>
<view class="item" v-for="(item, index) in 2" :key="index">
<view v-if="index == 1" class="forbidden">
<image src="/static/images/pure-list/employ.png" mode=""></image>
</view>
<view class="header">
<view class="header-left">
<view class="header-left-title"> 双十一课程优惠券 </view>
<view class="header-left-time"> 有效期至2023.08.28 </view>
</view>
<view class="header-right-price" :class="index == 1 ? 'grayscale' : ''"> <text>10</text> </view>
</view>
<view class="footer">
<view class="footer-left"> 适用于直播课 </view>
<view v-if="index != 1" class="footer-right"> 去使用 </view>
</view>
</view>
</template>
<script setup>
defineProps({
list: {
type: Array,
default: [],
},
});
</script>
<style lang="scss" scoped>
.forbidden {
position: absolute;
width: 100%;
height: 100%;
background: rgba(255, 255, 255, 0.5);
left: 0;
top: 0;
image {
position: absolute;
right: 0;
bottom: 0;
width: 184rpx;
height: 160rpx;
}
}
.item {
position: relative;
width: 700rpx;
margin: 20rpx auto 0;
background: #ffffff;
border-radius: 12rpx;
box-shadow: 0px 3px 4px 0px rgba(24, 144, 255, 0.06);
padding: 26rpx 40rpx 20rpx;
box-sizing: border-box;
.header {
display: flex;
justify-content: space-between;
align-items: center;
padding-bottom: 20rpx;
border-bottom: 1rpx dashed #ededed;
margin-bottom: 16rpx;
.header-left {
.header-left-title {
font-size: 34rpx;
font-weight: 500;
text-align: left;
color: #444444;
margin-bottom: 8rpx;
}
.header-left-time {
font-size: 28rpx;
color: #777;
}
}
.header-right-price {
color: #ff3924;
font-size: 42rpx;
font-weight: bold;
text {
font-size: 72rpx;
}
}
.grayscale {
color: #ccc;
}
}
.footer {
height: 64rpx;
display: flex;
justify-content: space-between;
align-items: center;
.footer-left {
font-size: 28rpx;
color: #777777;
}
.footer-right {
width: 144rpx;
height: 64rpx;
background: linear-gradient(112deg, #f7681d 9%, #f64226 84%);
border-radius: 8rpx;
box-shadow: 0px 5px 8px 0px rgba(236, 79, 40, 0.2);
color: #fff;
font-size: 28rpx;
text-align: center;
line-height: 64rpx;
}
}
}
</style>

View File

@@ -0,0 +1,159 @@
<template>
<view class="item" v-for="(item, index) in 2">
<view class="item-header">
<view class="header-title"> 订单号HUMU2268394 </view>
<view class="header-right" :class="index == 1 ? 'pay' : 'nopay'">
{{ index == 1 ? '已支付' : '未支付' }}
</view>
</view>
<view class="address">
<view class="start-address">
<view class="atom start">
<view> </view>
</view>
<view class="start-address-right">
<view class="start-address-text"> 出发地洛阳西工百货楼 </view>
<view class="start-time"> 出发时间2023.08.23 </view>
</view>
</view>
<view class="end-address">
<view class="atom end">
<view> </view>
</view>
<view class="start-address-text"> 目的地洛阳宜阳县 </view>
</view>
</view>
<view class="footer">
<view class="footer-order-time"> 下单时间2023.08.23 </view>
<view class="footer-order-price"> 订单金额<text class="pay" :class="index == 1 ? 'pay' : 'nopay'">¥450.00</text> </view>
</view>
</view>
</template>
<script setup>
defineProps({
list: {
type: Array,
default: [],
},
});
</script>
<style lang="scss" scoped>
.item {
width: 700rpx;
margin: 20rpx auto 0;
background: #ffffff;
border-radius: 12rpx;
box-shadow: 0px 3px 4px 0px rgba(24, 144, 255, 0.06);
padding: 26rpx 30rpx 20rpx;
box-sizing: border-box;
.item-header {
display: flex;
justify-content: space-between;
align-items: flex-start;
position: relative;
margin-bottom: 26rpx;
.header-title {
width: 480rpx;
font-size: 34rpx;
color: #444;
font-weight: 600;
}
.header-right {
position: absolute;
right: -40rpx;
background-size: 138rpx 60rpx;
width: 138rpx;
height: 60rpx;
font-size: 28rpx;
color: #fff;
line-height: 50rpx;
text-indent: 24rpx;
&.pay {
background-image: url('/static/images/pure-list/blue.png');
}
&.nopay {
background-image: url('/static/images/pure-list/orange.png');
}
}
}
.address {
width: 100%;
background: #f7f8f9;
border-radius: 4px;
padding: 20rpx 24rpx;
box-sizing: border-box;
margin-bottom: 30rpx;
.atom {
width: 30rpx;
height: 30rpx;
border-radius: 50%;
display: flex;
justify-content: center;
align-items: center;
margin-right: 10rpx;
margin-top: 6rpx;
view {
width: 14rpx;
height: 14rpx;
border-radius: 50%;
}
&.start {
background: rgba(26, 154, 255, 0.2);
view {
background: rgb(26, 154, 255);
}
}
&.end {
background: rgba(255, 108, 0, 0.2);
view {
background: rgb(255, 108, 0);
}
}
}
.end-address {
display: flex;
align-items: flex-start;
}
.start-address-text {
font-size: 30x;
font-weight: bold;
color: #444444;
margin-bottom: 4rpx;
}
.start-address {
display: flex;
align-items: flex-start;
.start-time {
font-size: 28rpx;
color: #777777;
}
margin-bottom: 20rpx;
}
}
.footer {
display: flex;
justify-content: space-between;
.footer-order-time {
font-size: 28rpx;
color: #777;
}
.footer-order-price {
color: #777;
font-size: 28rpx;
text {
font-weight: bold;
margin-left: 4rpx;
&.pay {
color: #323333;
}
&.nopay {
color: #ff3924;
}
}
}
}
}
</style>

View File

@@ -0,0 +1,21 @@
<template>
<ListModelOne></ListModelOne>
<ListModelTwo/>
<ListModelThree/>
<ListModelFour/>
<ListModelFive/>
</template>
<script setup>
import ListModelOne from './components/list-model-one.vue'
import ListModelTwo from './components/list-model-two.vue'
import ListModelThree from './components/list-model-three.vue'
import ListModelFour from './components/list-model-four.vue'
import ListModelFive from './components/list-model-five.vue'
</script>
<style lang="scss" scoped>
page{
background: #f5f6f8;
}
</style>

View File

@@ -0,0 +1,143 @@
<template>
<view>
<view class="select-all">
<view class="circle" v-if="false"> </view>
<image v-else src="/src/static/images/select-people/select.png" mode=""></image>
<view class=""> 全选 </view>
</view>
<view class="item" v-for="(item, index) in 5">
<view class="item-btn">
<view class="circle" v-if="false"> </view>
<image v-else src="/src/static/images/select-people/select.png" mode=""></image>
</view>
<view class="item-content">
<view class="item-name"> 卓大 </view>
<view class="item-desc"> 架构师 </view>
</view>
</view>
<view class="h-168"> </view>
<view class="footer">
<view class="footer-content">
<view class="select"> 已选择(2) </view>
<view class="select-item-card">
<view class="card-item" v-for="(item, index) in 3" :key="index"> 卓大{{ index == 2 ? '...' : '' }} </view>
</view>
<view class="submit">
<view class="btn"> 确认 (5/12) </view>
</view>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {};
},
methods: {},
};
</script>
<style lang="scss" scoped>
page {
background: #f5f6f8;
}
.select-all {
height: 104rpx;
width: 100%;
background: #fff;
display: flex;
align-items: center;
padding-left: 55rpx;
font-size: 32rpx;
color: #000000;
}
.circle {
width: 44rpx;
height: 44rpx;
border-radius: 50%;
border: 1rpx solid #ccc;
margin-right: 20rpx;
}
image {
width: 44rpx;
height: 44rpx;
margin-right: 20rpx;
}
.item {
box-sizing: border-box;
width: 700rpx;
height: 140rpx;
margin: 16rpx auto 0;
padding: 30rpx 24rpx;
display: flex;
background-color: #fff;
border-radius: 12rpx;
.item-name {
font-size: 32rpx;
font-weight: 600;
color: #444444;
margin-bottom: 8rpx;
}
.item-desc {
font-size: 28rpx;
color: #777777;
}
}
.h-168 {
height: 168rpx;
}
.footer {
position: fixed;
bottom: 0;
width: 100%;
height: 168rpx;
background-color: #fff;
padding: 16rpx 24rpx;
box-sizing: border-box;
.footer-content {
height: 80rpx;
width: 100%;
display: flex;
align-items: center;
.select {
font-size: 28rpx;
color: #444444;
margin-right: 32rpx;
}
.select-item-card {
display: flex;
view {
height: 44rpx;
padding: 0 12rpx;
line-height: 44rpx;
font-size: 22rpx;
color: #1a9aff;
border: 1px solid #2291f9;
border-radius: 8rpx;
margin-left: -12rpx;
position: relative;
background-color: #fff;
}
}
.submit {
flex: 1;
display: flex;
justify-content: flex-end;
view {
height: 80rpx;
width: 232rpx;
background: #1a9aff;
border-radius: 8rpx;
font-size: 30rpx;
line-height: 80rpx;
text-align: center;
color: #fff;
}
}
}
}
</style>

View File

@@ -0,0 +1,199 @@
<template>
<view class="container">
<mescroll-body @init="mescrollInit" :down="{ auto: false }" @down="onDown" @up="onUp" :up="{ toTop: { src: '' } }">
<!--搜索框-->
<uni-nav-bar :border="false" fixed :leftWidth="0" rightWidth="70px">
<view class="input">
<uni-easyinput
:clearable="true"
trim="all"
v-model="queryForm.keyword"
placeholder="搜索: 更新内容 等"
@confirm="search"
@clear="search"
/>
</view>
<template #right>
<view class="nav-right" @click="search">
<uni-icons type="search" size="30"></uni-icons>
<view class="nav-right-name"> 搜索 </view>
</view>
</template>
</uni-nav-bar>
<!-- 列表 -->
<view class="list-container">
<view class="list-item" @click="gotoDetail(item.changeLogId)" v-for="item in listData" :key="item.changeLogId">
<view class="list-item-row">
<view class="list-item-content bolder">{{ item.version }}</view>
<uni-tag
:text="$smartEnumPlugin.getDescByValue('CHANGE_LOG_TYPE_ENUM', item.type)"
:type="$smartEnumPlugin.getObjectByValue('CHANGE_LOG_TYPE_ENUM', item.type).type"
/>
</view>
<view class="list-item-row">
<view class="list-item-label">发布日期{{ item.publicDate }} - {{ item.publishAuthor }}</view>
</view>
<view class="list-item-row">
<view class="list-item-label">{{ item.content }}</view>
</view>
</view>
</view>
</mescroll-body>
<uni-fab ref="fab" :pattern="fabPattern" horizontal="right" @fabClick="gotoAdd" />
</view>
</template>
<script setup>
import { reactive, ref } from 'vue';
import { changeLogApi } from '/@/api/support/change-log-api';
import { onPageScroll, onReachBottom, onShow } from '@dcloudio/uni-app';
import useMescroll from '@/uni_modules/uni-mescroll/hooks/useMescroll';
import { smartSentry } from '/@/lib/smart-sentry';
import _ from 'lodash';
// --------------------------- 查询 ---------------------------------
const defaultForm = {
keyword: '', //标题、内容
pageNum: 1,
pageSize: 10,
};
// 查询表单
const queryForm = reactive({ ...defaultForm });
// 列表数据
const listData = ref([]);
function buildQueryParam(pageNum) {
queryForm.pageNum = pageNum;
return Object.assign({}, queryForm, { pageNum });
}
async function query(mescroll, isDownFlag, param) {
try {
let res = await changeLogApi.queryPage(param);
if (!isDownFlag) {
listData.value = listData.value.concat(res.data.list);
} else {
listData.value = res.data.list;
}
mescroll.endSuccess(res.data.list.length, res.data.pages > res.data.pageNum);
} catch (e) {
smartSentry.captureError(e);
//联网失败, 结束加载
mescroll.endErr();
}
}
const { mescrollInit, getMescroll } = useMescroll(onPageScroll, onReachBottom);
/**
* 搜索
*/
function search() {
query(getMescroll(), true, buildQueryParam(1));
uni.pageScrollTo({
scrollTop: 0,
});
}
/**
* 下拉刷新
*/
function onDown(mescroll) {
queryForm.pageNum = 1;
query(mescroll, true, buildQueryParam(1));
}
/**
* 上拉加载更多
*/
function onUp(mescroll) {
query(mescroll, false, buildQueryParam(mescroll.num));
}
onShow(() => {
search();
});
// --------------------------- 详情 ---------------------------------
function gotoDetail(id) {
uni.navigateTo({ url: '/pages/enterprise/enterprise-detail?enterpriseId=' + id });
}
</script>
<style lang="scss" scoped>
.container {
background-color: #f4f4f4;
}
.input {
width: 100%;
height: 60rpx;
background: #f7f8f9;
border-radius: 4px;
margin: 8rpx 0;
display: flex;
align-items: center;
}
.nav-right {
width: 140rpx;
display: flex;
height: 88rpx;
flex-direction: row;
line-height: 88rpx;
.nav-right-name {
margin-left: 5px;
line-height: 88rpx;
font-size: 30rpx;
}
}
.list-container {
padding: 10rpx 20rpx;
margin-top: 10rpx;
.list-item {
background: #ffffff;
box-shadow: 0px 3px 4px 0px rgba(24, 144, 255, 0.06);
margin-bottom: 20rpx;
padding: 30rpx 40rpx;
.list-item-row {
display: flex;
flex-direction: row;
margin-bottom: 16rpx;
justify-content: space-between;
.list-item-label {
font-size: 30rpx;
font-weight: 400;
text-align: left;
}
.bolder {
font-weight: 600 !important;
font-size: 34rpx !important;
}
.list-item-content {
font-size: 30rpx;
font-weight: 500;
text-align: left;
}
.list-item-content-container {
font-size: 30rpx;
font-weight: 500;
text-align: left;
color: #323333;
height: 40px;
}
.list-item-phone {
color: $uni-color-primary;
margin-left: auto;
}
}
}
}
</style>