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>