样式加企业注册(还没搞定)

This commit is contained in:
于晏彭 2023-03-20 15:49:41 +08:00
parent 02b047d832
commit a864146ac1
39 changed files with 1379 additions and 64 deletions

22
package-lock.json generated
View File

@ -9,6 +9,8 @@
"version": "0.0.7",
"license": "MIT",
"dependencies": {
"@amap/amap-jsapi-loader": "^1.0.1",
"@amap/amap-jsapi-types": "^0.0.13",
"@element-plus/icons-vue": "^2.0.10",
"@vueuse/core": "^9.12.0",
"@wangeditor/editor": "^5.1.12",
@ -77,6 +79,16 @@
"vue-tsc": "^1.0.24"
}
},
"node_modules/@amap/amap-jsapi-loader": {
"version": "1.0.1",
"resolved": "https://registry.npmmirror.com/@amap/amap-jsapi-loader/-/amap-jsapi-loader-1.0.1.tgz",
"integrity": "sha512-nPyLKt7Ow/ThHLkSvn2etQlUzqxmTVgK7bIgwdBRTg2HK5668oN7xVxkaiRe3YZEzGzfV2XgH5Jmu2T73ljejw=="
},
"node_modules/@amap/amap-jsapi-types": {
"version": "0.0.13",
"resolved": "https://registry.npmmirror.com/@amap/amap-jsapi-types/-/amap-jsapi-types-0.0.13.tgz",
"integrity": "sha512-hwp36URjQT9vDTmoUPYph3SEAiOvoUB+PGK0jZeZamgvaxew7rgc1XZWL/HphyMfRAqKwIYsAvXm9v8DTSjjzA=="
},
"node_modules/@ampproject/remapping": {
"version": "2.2.0",
"resolved": "https://registry.npmmirror.com/@ampproject/remapping/-/remapping-2.2.0.tgz",
@ -12454,6 +12466,16 @@
}
},
"dependencies": {
"@amap/amap-jsapi-loader": {
"version": "1.0.1",
"resolved": "https://registry.npmmirror.com/@amap/amap-jsapi-loader/-/amap-jsapi-loader-1.0.1.tgz",
"integrity": "sha512-nPyLKt7Ow/ThHLkSvn2etQlUzqxmTVgK7bIgwdBRTg2HK5668oN7xVxkaiRe3YZEzGzfV2XgH5Jmu2T73ljejw=="
},
"@amap/amap-jsapi-types": {
"version": "0.0.13",
"resolved": "https://registry.npmmirror.com/@amap/amap-jsapi-types/-/amap-jsapi-types-0.0.13.tgz",
"integrity": "sha512-hwp36URjQT9vDTmoUPYph3SEAiOvoUB+PGK0jZeZamgvaxew7rgc1XZWL/HphyMfRAqKwIYsAvXm9v8DTSjjzA=="
},
"@ampproject/remapping": {
"version": "2.2.0",
"resolved": "https://registry.npmmirror.com/@ampproject/remapping/-/remapping-2.2.0.tgz",

View File

@ -21,6 +21,8 @@
"commit": "git pull && git add -A && git-cz && git push"
},
"dependencies": {
"@amap/amap-jsapi-loader": "^1.0.1",
"@amap/amap-jsapi-types": "^0.0.13",
"@element-plus/icons-vue": "^2.0.10",
"@vueuse/core": "^9.12.0",
"@wangeditor/editor": "^5.1.12",

View File

@ -33,3 +33,14 @@ const i18nLocale = computed(() => {
//
const assemblySize = computed(() => globalStore.assemblySize);
</script>
<style lang="scss">
.amap-sug-result {
z-index: 2999 !important;
.auto-item {
padding-left: 8px;
padding-right: 8px;
font-size: 14px;
color: #666;
}
}
</style>

View File

@ -52,9 +52,6 @@ class RequestHttp {
this.service.interceptors.response.use(
(response: AxiosResponse) => {
const { data } = response;
// console.log("111", data.code);
// debugger;
const globalStore = GlobalStore();
// * 在请求结束后,并关闭请求 loading
tryHideFullScreenLoading();

View File

@ -34,6 +34,11 @@ export const deleteUser = (params: { configId: string }) => {
export const getGovermentList = (params: User.ReqUserParams) => {
return http.post<ResPage<User.ResUserList>>(BASEURL + `/xmgl/government/page`, params);
};
// 项目注册和企业注册需要的住建局
export const goverMentlist = () => {
return http.post<ResPage<User.ResUserList>>(BASEURL + `/xmgl/government/list`, { headers: { noLoading: true } });
};
// * 新增用户
export const addGovernment = (params: FormData) => {
return http.post(BASEURL + `/xmgl/government/add`, params);
@ -166,3 +171,8 @@ export const editAction = (params: { actionId: number }) => {
export const deleteAction = (params: { actionId: number }) => {
return http.post(BASEURL + `/xmgl/action/delete`, params);
};
// 项目注册
export const addProject = (params: FormData) => {
return http.post(BASEURL + `/project/project/add`, params);
};

View File

@ -14,10 +14,10 @@ const BASEURL = import.meta.env.VITE_API_URL;
export const loginApi = (params: Login.ReqLoginForm) => {
return http.post<Login.ResLogin>(BASEURL + `/xmgl/systemUser/login`, params, { headers: { noLoading: true } }); // 正常 post json 请求 ==> application/json
return http.post<Login.ResLogin>(BASEURL + `/xmgl/systemUser/login`, params, { headers: { noLoading: true } }); // 控制当前请求不显示 loading
return http.post<Login.ResLogin>(BASEURL + `/xmgl/systemUser/login`, {}, { params }); // post 请求携带 query 参数 ==> ?username=admin&password=123456
return http.post<Login.ResLogin>(BASEURL + `/xmgl/systemUser/login`, qs.stringify(params)); // post 请求携带表单参数 ==> application/x-www-form-urlencoded
return http.get<Login.ResLogin>(BASEURL + `/xmgl/systemUser/login?${qs.stringify(params, { arrayFormat: "repeat" })}`); // 如果是 get 请求可以携带数组等复杂参数
// return http.post<Login.ResLogin>(BASEURL + `/xmgl/systemUser/login`, params, { headers: { noLoading: true } }); // 控制当前请求不显示 loading
// return http.post<Login.ResLogin>(BASEURL + `/xmgl/systemUser/login`, {}, { params }); // post 请求携带 query 参数 ==> ?username=admin&password=123456
// return http.post<Login.ResLogin>(BASEURL + `/xmgl/systemUser/login`, qs.stringify(params)); // post 请求携带表单参数 ==> application/x-www-form-urlencoded
// return http.get<Login.ResLogin>(BASEURL + `/xmgl/systemUser/login?${qs.stringify(params, { arrayFormat: "repeat" })}`); // 如果是 get 请求可以携带数组等复杂参数
};
// * 获取按钮权限

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 471 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 379 KiB

Binary file not shown.

View File

@ -0,0 +1,61 @@
$primary: #409eff;
.map-dialog {
.header {
h4 {
font-size: 1em;
font-weight: 600;
}
.search-container {
display: flex;
align-items: center;
justify-content: space-between;
.search-item {
display: flex;
&:not(:first-child) {
margin-left: 20px;
}
.search,
.address,
.lon,
.lat {
display: flex;
align-items: center;
margin-left: 5px;
> span {
flex-shrink: 0;
font-size: 13px;
color: #666;
}
}
}
.btn-search,
.btn-submit {
margin-left: 10px;
}
}
@media screen and (max-width: 720px) {
.search-container {
display: block;
.search-item {
&:not(:first-child) {
margin-top: 15px;
margin-left: 0;
}
}
}
}
}
.map {
height: 60vh;
}
}

View File

@ -0,0 +1,34 @@
import AMapLoader from "@amap/amap-jsapi-loader";
import "@amap/amap-jsapi-types";
import { ElMessage } from "element-plus";
import { AMAP_MAP_KEY } from "@/config/config";
// FIXME: 插件需要配合密钥使用,官方推荐 key 搭配代理服务器并携带安全密钥转发使用
// see: https://lbs.amap.com/api/jsapi-v2/guide/abc/prepare
window._AMapSecurityConfig = {
securityJsCode: "df19aa4c9f83a52f7ef66843449f438e" // 密钥
};
const amap = (async function (Loader, AMAP_MAP_KEY) {
return Loader.load({
key: AMAP_MAP_KEY,
version: "2.0",
plugins: ["AMap.PlaceSearch", "AMap.AutoComplete", "AMap.Geocoder"]
});
})(AMapLoader, AMAP_MAP_KEY);
/**
* @description: AMap
* @param {InitCallback} callback
*/
async function initAMap() {
try {
const AMap = await amap;
return AMap;
} catch (err) {
console.log(err);
ElMessage.error("加载高德地图失败, 请检查网络或需求客服帮助。");
}
}
export default initAMap;

View File

@ -0,0 +1,114 @@
<template>
<el-dialog
class="map-dialog"
:style="{ width: '80%' }"
:modelValue="modelValue"
:show-close="true"
@update:model-value="emit('update:modelValue', $event)"
@open="open"
@close="close"
>
<template #header="{ titleId, titleClass }">
<div class="header">
<h4 :id="titleId" :class="titleClass">坐标拾取</h4>
<div class="search-container">
<div class="search-item">
<label class="search"><span>请输入地址</span><el-input id="map-input" v-model="address" /></label>
<!-- <el-button class="btn-search" type="primary">搜索</el-button> -->
</div>
<div class="search-item">
<label class="address"><span>地址</span><el-input disabled :model-value="coordinateInfo.address" /></label>
<label class="lon"><span>经度</span><el-input disabled :model-value="coordinateInfo.lng" /></label>
<label class="lat"><span>纬度</span><el-input disabled :model-value="coordinateInfo.lat" /></label>
<el-button class="btn-submit" type="primary" @click="submit">提交</el-button>
</div>
</div>
</div>
</template>
<div id="map-container" class="map"></div>
</el-dialog>
</template>
<script lang="ts" setup>
import { ElMessage } from "element-plus";
import { ref, shallowRef, reactive } from "vue";
import initAMap from "./AMap";
defineProps<{ modelValue: boolean }>();
const emit = defineEmits<{
(e: "update:modelValue", data: boolean): void;
(e: "getAddress", data: typeof coordinateInfo): void;
}>();
const address = ref("");
const coordinateInfo = reactive({ address: "", lng: "", lat: "" });
const map = shallowRef<AMap.Map>();
const search = shallowRef<any>();
const autocomplete = shallowRef<any>();
const open = async () => {
const AMap = await initAMap();
//
map.value = new AMap.Map("map-container", { zoom: 8, resizeEnable: true });
map.value?.on("click", e => {
map.value?.clearMap();
map.value?.add(new AMap.Marker({ position: e.lnglat }));
map.value?.setCenter(e.lnglat);
coordinateInfo.lng = e.lnglat.getLng();
coordinateInfo.lat = e.lnglat.getLat();
const geocoder = new AMap.Geocoder();
geocoder.getAddress(e.lnglat, (status: string, result: any) => {
if (status === "complete" && result.info === "OK") {
const regeocode = result.regeocode;
coordinateInfo.address = regeocode.formattedAddress;
}
});
});
// POI
autocomplete.value = new AMap.AutoComplete({ extensions: "all", input: "map-input" });
search.value = new AMap.PlaceSearch({ map: map.value, extensions: "base" });
autocomplete.value?.on("select", (e: any) => {
map.value?.clearMap();
if (e.poi.location) {
coordinateInfo.lng = e.poi.location.lng;
coordinateInfo.lat = e.poi.location.lat;
map.value?.add(new AMap.Marker({ position: e.poi.location }));
} else {
const geocoder = new AMap.Geocoder({ city: e.adcode });
geocoder.getLocation(e.poi.name, (status: string, result: any) => {
if (status === "complete" && result.info === "OK") {
const data = result.geocodes;
if (data.length > 1) ElMessage.success("检索到多个结果,已为您定位到第一个地址");
coordinateInfo.lng = data[0].location.lng;
coordinateInfo.lat = data[0].location.lat;
map.value?.add(new AMap.Marker({ position: data[0].location }));
}
});
}
coordinateInfo.address = e.poi.district;
search.value.setCity(e.poi.adcode);
search.value.search(e.poi.name);
});
};
const submit = () => {
if (coordinateInfo.address && coordinateInfo.lng && coordinateInfo.lat) {
emit("getAddress", coordinateInfo);
}
};
const close = () => {
map.value?.destroy();
address.value = "";
coordinateInfo.address = "";
coordinateInfo.lng = "";
coordinateInfo.lat = "";
};
</script>
<style lang="scss" scoped>
@import "./AMap.scss";
</style>

View File

@ -0,0 +1,52 @@
$gray: #ccc;
$complete: #409EFF;
.setps-item {
display: flex;
flex-basis: 50%;
flex-shrink: 1;
&:nth-last-child(1) {
flex-basis: auto;
flex-shrink: 0;
flex-grow: 0;
.icon {
display: none;
}
}
.title {
display: flex;
align-items: center;
flex-basis: auto;
color: #ccc;
.el-icon {
color: #ccc;
}
}
.title span {
margin-left: 8px;
}
.icon {
display: flex;
flex: 1;
justify-content: center;
align-items: center;
.el-icon {
color: $gray;
}
}
}
.setps-item.complete {
.title {
color: $complete;
}
.el-icon {
color: $complete;
}
}

View File

@ -0,0 +1,24 @@
<template>
<div class="setps-item" :class="{ complete: complete }">
<div class="title">
<el-icon size="18" color="#409EFF"><CircleCheck /></el-icon><span> {{ data.title }}</span>
</div>
<div class="icon">
<el-icon size="20" class="right-arrow"><ArrowRightBold /></el-icon>
</div>
</div>
</template>
<script lang="ts" setup>
// import { defineProps } from "vue";
import type { Datas } from "./setps.vue";
defineProps<{
data: Datas[number];
complete: boolean;
}>();
</script>
<style lang="scss" scoped>
@import "./setps-item.scss";
</style>

View File

@ -0,0 +1,4 @@
.setps {
user-select: none;
padding: 15px 0;
}

View File

@ -0,0 +1,21 @@
<template>
<!-- 自定义步骤条 -->
<!-- params1 datas: Array<{ id: number, title: string }> -->
<!-- params2 active: number -->
<div class="setps flx-justify-between">
<setps-item v-for="(item, index) in datas" :key="item.id" :data="item" :complete="active >= index" />
</div>
</template>
<script setup lang="ts">
// import { defineProps } from "vue";
import SetpsItem from "./setps-item.vue";
export type Datas = Array<{ title: string; id: number | string }>;
defineProps<{ datas: Datas; active: number }>();
</script>
<style lang="scss" scoped>
@import "./setps.scss";
</style>

View File

@ -12,7 +12,7 @@ export const LOGIN_URL: string = "/login";
export const DEFAULT_PRIMARY: string = "#008BFF";
// * 路由白名单地址(必须是本地存在的路由 staticRouter.ts
export const ROUTER_WHITE_LIST: string[] = ["/500", "/projectlogon"];
export const ROUTER_WHITE_LIST: string[] = ["/500", "/projectlogon", "/compLogon"];
// * 高德地图 key
export const AMAP_MAP_KEY: string = "142e51d55274a0140e838245345cf9ad";

View File

@ -0,0 +1,14 @@
export const datas = [
{
id: 0,
title: "企业基本信息"
},
{
id: 1,
title: "选择企业主体"
},
{
id: 2,
title: "注册申请成功"
}
];

View File

@ -4,7 +4,8 @@
<el-header>
<div class="header-lf">
<div class="logo flx-center">
<img src="@/assets/images/logo.svg" alt="logo" />
<!-- <img src="@/assets/images/logo.svg" alt="logo" /> -->
<img src="@/assets/images/login/china.png" style="margin: 0 15px" alt="logo" />
<span>数字化政务监管平台</span>
</div>
<ToolBarLeft />

View File

@ -25,6 +25,11 @@ export const staticRouter: RouteRecordRaw[] = [
// title: "登录"
// }
},
{
path: "/compLogon",
name: "compLogon",
component: () => import("@/views/login/CompanyLogon/index.vue")
},
{
path: "/layout",
name: "layout",

View File

@ -160,6 +160,7 @@
left: 50%;
transform: translate(-50%, -50%);
.table-empty {
margin-top: 20px;
line-height: 30px;
}
}

View File

@ -19,9 +19,10 @@
>
</template>
<template #operation="{ row }">
<el-button type="primary" link @click="onUpload(row)"
><el-icon><RefreshRight /></el-icon>更新版本</el-button
>
<el-button type="primary" text @click="onUpload(row)">
<img src="@/assets/images/tableIcon/renewIcon.png" alt="" style="width: 13px" class="configureIcon" />
<span>更新版本</span>
</el-button>
</template>
</ProTable>
<el-dialog v-model="visible" title="更新版本" width="30%">

View File

@ -16,7 +16,11 @@
</template>
<!-- 表格操作 -->
<template #operation="scope">
<el-button type="primary" link :icon="Stamp" @click="onConfiguration(scope.row)">授权配置</el-button>
<el-button type="primary" text @click="onConfiguration(scope.row)">
<img src="@/assets/images/tableIcon/configureIcon.png" alt="" class="configureIcon" />
<span>权限配置</span>
</el-button>
<!-- <el-button type="primary" link :icon="Stamp" @click="onConfiguration(scope.row)">授权配置</el-button> -->
</template>
<template #state="{ row }">
{{ row.state === 1 ? "启用" : "停用" }}

View File

@ -0,0 +1,80 @@
$primary: #409eff;
.basic-form {
margin-top: 40px;
.items {
display: flex;
justify-content: space-around;
.left,
.right {
width: 42%;
}
.full-item {
width: 92%;
}
.placeholder {
user-select: none;
visibility: hidden;
}
}
.input {
font-size: 12px;
.selectFile {
outline: none;
border: 1px solid $primary;
color: $primary;
padding: 2px 6px;
font-size: 13px;
border-radius: 3px;
background-color: transparent;
cursor: pointer;
}
> span {
margin-left: 5px;
color: #999;
}
}
.footer {
height: 50px;
margin-bottom: 20px;
}
:deep(.el-input-group__append) {
padding: 0 8px;
background-color: $primary;
cursor: pointer;
}
@media screen and (max-width: 780px) {
.items {
display: block;
.left,
.right {
width: inherit;
}
.full-item {
width: inherit;
}
.placeholder {
display: none;
}
}
:deep(.el-form-item__label) {
width: 120px !important;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
}
}
}

View File

@ -0,0 +1,196 @@
import { reactive } from "vue";
import type { FormRules } from "element-plus";
export const ruleForm = reactive({
enterpriseName: "",
legalPerson: "",
registeredCapital: "",
governmentSn: "",
registerPlace: "",
creditCode: "",
legalPersonTel: "",
businessLicense: "", //营业执照
license: null, //营业执照 删掉
position: "",
businessAddress: "",
isAuthority: 1,
realName: "",
account: "",
// password: "",
authorityEnterprise: "",
phone: "",
password: "",
email: "",
profile: "",
longitude: "", //经度
latitude: "", //维度
fileName: "",
downloadPath: ""
});
export const rules = reactive<FormRules>({
name: [
{ required: true, message: "请输入企业名称", trigger: "blur" },
{ min: 3, max: 5, message: "企业名称长度不能小于 3 大于 5", trigger: "blur" }
],
legalperson: [
{
required: true,
message: "请输入法人代表",
trigger: "blur"
}
],
capital: [
{
type: "number",
message: "请输入数字",
trigger: "change"
},
{
required: true,
message: "请输入注册资本",
trigger: "blur"
}
],
bureau: [
{
required: true,
message: "请选择住建局",
trigger: "blur"
}
],
creditcode: [
{
required: true,
message: "请输入统一社会信用码",
trigger: "blur"
},
{
type: "number",
message: "请输入数字",
trigger: "change"
},
{ min: 18, max: 18, message: "请输入 18 位数字", trigger: "blur" }
],
address: [
{
required: true,
message: "请选择企业地址",
trigger: "blur"
}
],
full_address: [
{
required: true,
message: "请输入详细地址",
trigger: "blur"
}
],
license: [
{
required: true,
message: "请上传您的营业执照",
trigger: "blur"
}
],
legalperson_phone: [
{
required: true,
message: "请输入法人代表手机号",
trigger: "blur"
},
{
type: "number",
message: "请输入数字",
trigger: "change"
},
{
pattern: /^(13[0-9]|14[579]|15[0-3,5-9]|16[6]|17[0135678]|18[0-9]|19[89])\d{8}$/,
message: "请输入合法手机号",
trigger: "change"
}
],
principal_phone: [
{
required: true,
message: "请输入企业负责人手机号",
trigger: "blur"
},
{
type: "number",
message: "请输入数字",
trigger: "change"
},
{
pattern: /^(13[0-9]|14[579]|15[0-3,5-9]|16[6]|17[0135678]|18[0-9]|19[89])\d{8}$/,
message: "请输入合法手机号",
trigger: "change"
}
],
position: [
{
required: true,
message: "请输入企业地址所在经纬度",
trigger: "blur"
}
],
isStateEnterprises: [
{
required: true,
message: "请选择是否是市属国企",
trigger: "blur"
}
],
principal: [
{
required: true,
message: "请输入企业负责人",
trigger: "blur"
}
],
account: [
{
required: true,
message: "请输入手机绑定账号",
trigger: "blur"
}
],
confirm_password: [
{
required: true,
message: "请再次输入密码",
trigger: "blur"
},
{
validator: (rule, value) => value === ruleForm.password,
message: "两次输入不一致,请检查后重新输入",
trigger: "blur"
}
],
password: [
{
required: true,
message: "请输入密码",
trigger: "blur"
}
],
belongToStateEnterprises: [
{
required: true,
message: "请选择国企所属集团",
trigger: "blur"
}
],
email: [
{
required: true,
message: "请输入电子邮箱",
trigger: "blur"
},
{
type: "email",
message: "请输入正确的电子邮箱",
trigger: "change"
}
]
});

View File

@ -0,0 +1,177 @@
<template>
<el-form ref="ruleFormRef" :model="ruleForm" label-width="150px" class="basic-form" size="large">
<!-- <el-form ref="ruleFormRef" :model="ruleForm" label-width="150px" class="basic-form" size="large"> -->
<div class="items">
<div class="left">
<el-form-item label="企业名称:" prop="name">
<el-input v-model="ruleForm.enterpriseName" placeholder="厦门市湖里科技有限公司" />
</el-form-item>
<el-form-item label="法人代表:" prop="legalperson">
<el-input v-model="ruleForm.legalPerson" placeholder="周某" />
</el-form-item>
<el-form-item label="注册资本(万元):" prop="capital">
<el-input v-model.number="ruleForm.registeredCapital" placeholder="1000" />
</el-form-item>
<el-form-item label="所属住建局:" prop="bureau">
<el-select style="width: 100%" v-model="ruleForm.governmentSn" placeholder="选择住建局">
<el-option v-for="item in []" :key="item" :label="item" :value="item" />
</el-select>
</el-form-item>
<el-form-item label="企业地址:" prop="address">
<el-input v-model="ruleForm.registerPlace" placeholder="福建省厦门市">
<template #append>
<el-icon color="#fff" size="22" @click="openMap"><Location /></el-icon>
</template>
</el-input>
</el-form-item>
</div>
<div class="right">
<el-form-item label="统一社会信用代码:" prop="creditcode">
<el-input v-model.number="ruleForm.creditCode" placeholder="123456789123456789" />
</el-form-item>
<el-form-item label="法人代表手机号:" prop="legalperson_phone">
<el-input v-model.number="ruleForm.legalPersonTel" placeholder="13670780605" />
</el-form-item>
<el-form-item label="营业执照:" prop="license">
<el-upload
v-model:file-list="fileList"
class="upload-demo"
:action="`${baseUrl}` + '/xmgl/file/upload'"
multiple
:limit="1"
:on-success="uploadSuccess"
style="display: flex"
>
<el-button plain color="#47A99D" size="small">选择文件</el-button>
<template #tip>
<div v-show="!fileList" style="margin-left: 10px; margin-top: 10px; color: #aeaeae">未选择任何文件</div>
</template>
</el-upload>
</el-form-item>
<!-- 占位 -->
<el-form-item class="placeholder">
<el-input></el-input>
</el-form-item>
<el-form-item label="经纬度:" prop="position">
<el-input disabled v-model="ruleForm.position" placeholder="经度118.138 纬度24.517808" />
</el-form-item>
</div>
</div>
<div class="items">
<el-form-item class="full-item" label="详细地址:" prop="full_address">
<el-input v-model="ruleForm.businessAddress" placeholder="福建省厦门市湖里区" />
</el-form-item>
</div>
<div class="items">
<div class="left">
<el-form-item label="是否市属国企:" prop="isStateEnterprises">
<el-radio-group v-model="ruleForm.isAuthority">
<el-radio label="1" size="large"></el-radio>
<el-radio label="2" size="large"></el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="企业负责人:" prop="principal">
<el-input v-model="ruleForm.realName" placeholder="黄某" />
</el-form-item>
<el-form-item label="手机绑定账号:" prop="account">
<el-input v-model="ruleForm.account" placeholder="admin" />
</el-form-item>
<el-form-item label="确认密码:" prop="confirm_password">
<el-input type="password" v-model="ruleForm.password" placeholder="123456" />
</el-form-item>
</div>
<div class="right">
<el-form-item label="所属国企:" prop="belongToStateEnterprises">
<el-input style="width: 100%" v-model="ruleForm.authorityEnterprise" placeholder="国企所属集团"> </el-input>
</el-form-item>
<el-form-item label="手机号码:" prop="principal_phone">
<el-input v-model.number="ruleForm.phone" placeholder="13670780605" />
</el-form-item>
<el-form-item label="密码:" prop="password">
<el-input type="password" v-model="ruleForm.password" placeholder="123456" />
</el-form-item>
<el-form-item label="邮箱:" prop="email">
<el-input v-model="ruleForm.email" placeholder="123456789@qq.com" />
</el-form-item>
</div>
</div>
<div class="items">
<el-form-item class="full-item" label="公司简介:">
<el-input type="textarea" :rows="6" v-model="ruleForm.profile" placeholder="1234567890" />
</el-form-item>
</div>
<footer class="footer flx-center">
<el-button type="primary" size="default" @click="submitForm">下一步</el-button>
</footer>
<AMap v-model="isOpen" @get-address="getAddress" />
</el-form>
</template>
<script lang="ts" setup>
import { ref } from "vue";
import AMap from "@/components/AMap/AMap.vue";
import { ruleForm, rules } from "./basic-form";
import { ElMessage, FormInstance } from "element-plus";
// export type FileEvent = Event & { target: EventTarget & { files: FileList; value: any } };
const emit = defineEmits<{
(e: "next", num: null): void;
}>();
const ruleFormRef = ref<FormInstance>();
// const file = ref<HTMLInputElement>();
const fileList = ref([]);
const baseUrl = import.meta.env.VITE_API_URL;
const isOpen = ref(false);
// TODO:
const submitForm = async () => {
const formEl = ruleFormRef.value;
if (!formEl) return;
await formEl.validate((valid, fields) => {
if (valid) {
console.log("submit!");
emit("next", null);
} else {
console.log("error submit!", fields);
}
});
};
//
const trigger = (e: Event) => {
// Tips:
e.preventDefault();
file.value && file.value.click();
};
const openMap = () => {
isOpen.value = true;
};
const uploadSuccess = (response: any) => {
ElMessage.success("上传成功");
ruleForm.fileName = response.result.originalFilename;
ruleForm.downloadPath = response.result.url;
// fileList.value = [{ name: response.result.originalFilename, url: response.result.downloadPath }];
};
const getAddress = (e: any) => {
isOpen.value = false;
ruleForm.registerPlace = e.address;
ruleForm.position = "经度:" + e.lng + " 纬度:" + e.lat;
ElMessage.success("已获取企业地址");
};
</script>
<style lang="scss" scoped>
@import "./basic-form.scss";
</style>

View File

@ -0,0 +1,72 @@
.entrepreneur {
width: 80%;
min-height: inherit;
margin: 0 auto;
.unit {
margin-top: 30px;
display: flex;
align-items: center;
width: inherit;
> span {
flex-shrink: 0;
font-size: 16px;
color: #333;
}
> .unit-checkbox {
display: flex;
justify-content: space-around;
width: 100%;
flex-shrink: 0;
.unit-checkbox-item {
margin-left: 20px;
}
}
}
:deep(.el-checkbox__input .el-checkbox__inner) {
border-radius: 50%;
}
.tables {
position: relative;
.table-enter-from {
transform: scale(0.6);
opacity: 0.3;
}
.table-enter-active {
transition: all 0.4s;
}
.table-enter-to {
transform: scale(1);
opacity: 1;
}
.table-leave-from {
transform: translateX(0);
opacity: 1;
}
.table-leave-active {
transition: all 0.6s;
}
.table-leave-to {
transform: translateX(-150%);
opacity: 0.3;
}
}
.footer {
width: 100%;
display: flex;
margin-top: 50px;
margin-bottom: 20px;
justify-content: center;
align-items: center;
}
}

View File

@ -0,0 +1,44 @@
<template>
<div class="entrepreneur">
<div class="unit">
<span>请选择你要注册的单位账号</span>
<el-checkbox-group class="unit-checkbox" v-model="unitList">
<el-checkbox class="unit-checkbox-item" label="建设单位" />
<el-checkbox class="unit-checkbox-item" label="监理单位" />
<el-checkbox class="unit-checkbox-item" label="施工单位" />
<el-checkbox class="unit-checkbox-item" label="勘察单位" />
<el-checkbox class="unit-checkbox-item" label="设计单位" />
</el-checkbox-group>
</div>
<div class="tables">
<transition-group name="table" tag="div">
<unit-table v-for="(item, i) in unitList" :key="item" :divide="{ index: i + 1, title: item }" />
</transition-group>
</div>
<footer class="footer">
<el-button @click="prev">上一步</el-button>
<el-button type="primary">提交</el-button>
</footer>
</div>
</template>
<script lang="ts" setup>
import { ref } from "vue";
import UnitTable from "./unit-table.vue";
const emit = defineEmits<{
(e: "prev", data: void): void;
}>();
const unitList = ref(["建设单位", "监理单位"] as string[]);
const prev = () => {
emit("prev");
};
</script>
<style lang="scss" scoped>
@import "./entrepreneur.scss";
</style>

View File

@ -0,0 +1,35 @@
.container {
width: 1240px;
min-height: 500px;
.setps {
margin: 0 auto;
width: 70%;
}
.overflow {
overflow: hidden;
}
.basic-enter-from {
transform: rotateZ(90deg);
}
.basic-enter-active {
// transition: all 0.7s;
transform-origin: center bottom;
}
.basic-enter-to {
transform: rotateZ(0deg);
}
}
@media screen and (max-width: 640px) {
.container {
padding: 10px;
.setps {
width: 100%;
}
}
}

View File

@ -0,0 +1,44 @@
<template>
<div class="basic-information flx-center">
<div class="container">
<Setps :datas="datas" :active="active" />
<keep-alive>
<component :is="components[active]" @next="next" @prev="prev" />
</keep-alive>
</div>
</div>
</template>
<script setup lang="ts">
import { ref, reactive } from "vue";
import Setps from "@/components/Steps/setps.vue";
import BasicForm from "./basic-form.vue";
import Entrepreneur from "./entrepreneur.vue";
import Registered from "./registered.vue";
import { datas as values } from "@/enums/company/SetpsEnum";
const datas = reactive(values);
const active = ref(0);
const components = [BasicForm, Entrepreneur, Registered];
const next = () => {
if (active.value >= datas.length - 1)
throw Error(
`if you operate again, active will be greater than the number of setps components.
error in views/companyview/basicinformation/index.vue, function name: next, line: 28`
);
active.value++;
};
const prev = () => {
if (active.value <= 0)
throw Error(`no last one. error in views/companyview/basicinformation/index.vue, function name: prve, line: 37`);
active.value--;
};
</script>
<style scoped lang="scss">
@import "./index.scss";
</style>

View File

@ -0,0 +1,3 @@
.registered {
min-height: calc(100vh + 50px);
}

View File

@ -0,0 +1,7 @@
<template><div class="registered">registered</div></template>
<script lang="ts" setup></script>
<style lang="scss" scoped>
@import "./registered.scss";
</style>

View File

@ -0,0 +1,89 @@
$primary: #409eff;
.unit-table {
margin-top: 40px;
.form {
display: flex;
justify-content: space-between;
.form-item {
width: 45%;
.search {
position: absolute;
right: 0;
top: 0;
border-bottom-left-radius: 0;
border-top-left-radius: 0;
}
&:not(:first-child) {
margin-right: 0;
}
}
}
.table {
margin-top: 15px;
.input {
display: flex;
align-items: center;
font-size: 12px;
.selectFile {
flex-shrink: 0;
outline: none;
border: 1px solid $primary;
color: $primary;
padding: 2px 6px;
font-size: 13px;
border-radius: 3px;
background-color: transparent;
cursor: pointer;
}
> span {
padding-top: 2px;
flex-shrink: 0;
width: 50%;
margin-left: 5px;
text-align: start;
color: #999;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
}
}
}
.position {
position: relative;
.divide {
display: flex;
position: absolute;
left: -150px;
top: 50%;
transform: translateY(-50%);
color: #333;
.index {
margin-right: 15px;
}
.line {
position: absolute;
left: 12px;
top: calc(100% + 6px);
width: 1px;
height: 245px;
background-color: #999;
}
}
}
&:last-child {
.line {
display: none;
}
}
}

View File

@ -0,0 +1,144 @@
<template>
<div class="unit-table">
<el-form :inline="true" :model="unitForm" :rules="rules" class="form">
<el-form-item class="form-item" label="企业负责人" prop="principal">
<el-input placeholder="请输入" v-model="unitForm.principal">
<template #suffix>
<el-button class="search" type="primary" :icon="Search" />
</template>
</el-input>
</el-form-item>
<el-form-item class="form-item" label="手机号码" prop="principal_phone">
<el-input placeholder="请输入" v-model="unitForm.principal_phone" />
</el-form-item>
</el-form>
<div class="position">
<div class="divide">
<el-tag class="index" type="info">{{ divide.index }}</el-tag>
{{ divide.index }}
{{ divide.title }}
<div class="line"></div>
</div>
<el-table
class="table"
:data="tableData"
border
max-height="175"
style="width: 100%"
:header-cell-style="{ backgroundColor: '#f5f7fa', textAlign: 'center' }"
:cell-style="{ textAlign: 'center' }"
>
<el-table-column label="资质编号" width="180" prop="number" />
<el-table-column class-name="single-substr" label="资质名称" width="340" prop="name" />
<el-table-column label="资质等级" width="170" prop="level">
<template #default="{ row }">
<el-select v-model="row.level" size="small" placeholder="Select">
<el-option v-for="item in options" :key="item" :label="item" :value="item" />
</el-select>
</template>
</el-table-column>
<el-table-column class-name="single-substr" label="资质附件" width="200" prop="appendix">
<template #default="{ row }">
<el-upload
v-model:file-list="fileList"
class="upload-demo"
:action="`${baseUrl}` + '/xmgl/file/upload'"
multiple
:limit="1"
:on-success="uploadSuccess"
style="display: flex"
>
<el-button plain color="#47A99D" size="small">选择文件</el-button>
<template #tip>
<div v-show="!fileList" style="margin-left: 10px; margin-top: 10px; color: #aeaeae">未选择任何文件</div>
</template>
</el-upload>
</template>
</el-table-column>
<el-table-column>
<template #header>
<el-button type="primary" @click="onAddData" round size="small">添加</el-button>
</template>
<template #default="{ row }">
<el-button type="danger" link @click="deleteRow(row)">删除</el-button>
</template>
</el-table-column>
<!-- 表格无数据情况 -->
<template #empty>
<div class="table-empty">
<slot name="empty">
<img src="@/assets/images/notData.png" alt="notData" />
<div>暂无数据</div>
</slot>
</div>
</template>
</el-table>
</div>
</div>
</template>
<script lang="ts" setup>
import { ref, reactive, computed } from "vue";
import { Search } from "@element-plus/icons-vue";
import { rules } from "./basic-form";
import { ElMessage, FormInstance } from "element-plus";
// import type { FileEvent } from "./basic-form.vue";
type Row = {
number: string;
name: string;
level: string;
appendix: File | null;
};
defineProps<{
divide: { index: number; title: string };
}>();
const file = ref<HTMLInputElement>();
const fileList = ref([]);
const baseUrl = import.meta.env.VITE_API_URL;
const unitForm = reactive({ principal: "", principal_phone: "" });
const options = ["一级", "二级", "三级"];
const tableData = ref<Row[]>([
{ number: "D32DDFH", name: "房屋建筑工程施工总承包企业资质等级一级标准", level: "", appendix: null },
{ number: "D32DDFH", name: "房屋建筑工程施工总承包企业资质等级一级标准", level: "", appendix: null },
{ number: "D32DDFH", name: "房屋建筑工程施工总承包企业资质等级一级标准", level: "", appendix: null },
{ number: "D32DDFH", name: "房屋建筑工程施工总承包企业资质等级一级标准", level: "", appendix: null },
{ number: "D32DDFH", name: "房屋建筑工程施工总承包企业资质等级一级标准", level: "", appendix: null }
]);
const count = computed(() => tableData.value.length);
const onAddData = () => {
console.log(111);
let newData: object = {
number: `${count.value}`,
name: "",
level: "",
appendix: ""
};
tableData.value.push(newData);
};
const uploadSuccess = (response: any) => {
ElMessage.success("上传成功");
// ruleForm.fileName = response.result.originalFilename;
// ruleForm.downloadPath = response.result.url;
// fileList.value = [{ name: response.result.originalFilename, url: response.result.downloadPath }];
};
const deleteRow = (row: Row) => {
console.log(row);
};
</script>
<style lang="scss" scoped>
@import "./unit-table.scss";
</style>

View File

@ -3,7 +3,7 @@
<div class="centerLogin">
<div class="loginRight">
<div class="title">项目注册账号申请</div>
<el-form :model="logonForm" :rules="rules">
<el-form :model="logonForm" ref="loginFormRef" :rules="rules">
<el-form-item class="nowrap" prop="account">
<img src="@/assets/images/projectLogon/account.png" alt="" />
<el-input v-model="logonForm.account" class="accountInput" size="large" placeholder="请输入账号" />
@ -27,29 +27,40 @@
/>
</el-select>
</el-form-item>
<el-form-item class="nowrap" prop="projectTel">
<el-form-item class="nowrap" prop="phone">
<img src="@/assets/images/projectLogon/telephone.png" alt="" />
<el-input v-model="logonForm.projectTel" class="passwordInput" size="large" placeholder="请输入手机号" />
<el-input v-model.number="logonForm.phone" class="passwordInput" size="large" placeholder="请输入手机号" />
</el-form-item>
<el-form-item class="nowrap" prop="password">
<img src="@/assets/images/login/lockIcon.png" alt="" />
<el-input type="password" v-model="logonForm.password" class="passwordInput" size="large" placeholder="请输入密码" />
</el-form-item>
<el-form-item class="nowrap" prop="position">
<!-- <img src="@/assets/images/login/lockIcon.png" alt="" /> -->
<el-icon @click="openMap"><Location /></el-icon>
<el-input v-model="logonForm.position" class="passwordInput" size="large" placeholder="请定位坐标" />
</el-form-item>
<el-form-item class="nowrap">
<button class="LoginBtn" :plain="true" @click="loginGo">提交</button>
<button class="LoginBtn" :loading="loading" :plain="true" @click="loginGo(loginFormRef)">提交</button>
</el-form-item>
</el-form>
</div>
</div>
</div>
<AMap v-model="isOpen" @get-address="getAddress" />
</template>
<script lang="ts" setup>
import { ref, reactive } from "vue";
import { Search } from "@element-plus/icons-vue";
// import { projectLogon, zhujianList } from "@/assets/js/api";
import { ref, reactive, onMounted } from "vue";
import { useRouter } from "vue-router";
import { ElMessage } from "element-plus";
import { goverMentlist, addProject } from "@/api/modules/jxjview";
import AMap from "@/components/AMap/AMap.vue";
import { ElMessage, FormInstance, ElForm } from "element-plus";
import router from "@/routers";
import { LOGIN_URL } from "@/config/config";
type FormInstance = InstanceType<typeof ElForm>;
const loginFormRef = ref<FormInstance>();
const rules = reactive({
account: [{ required: true, message: "请输入账号", trigger: "blur" }],
@ -59,7 +70,8 @@ const rules = reactive({
],
projectName: [{ required: true, message: "请输入项目名称", trigger: "blur" }],
governmentSn: [{ required: true, message: "请选择住建局", trigger: "blur" }],
projectTel: [{ required: true, message: "请输入手机号", trigger: "blur" }],
phone: [{ required: true, trigger: "blur", message: "手机号格式不正确", pattern: /^((0\d{2,3}-\d{7,8})|(1[34578]\d{9}))$/ }],
password: [{ required: true, message: "请输入密码", trigger: "blur" }]
});
const logonForm = reactive({
@ -67,44 +79,67 @@ const logonForm = reactive({
email: "",
projectName: "",
governmentSn: "",
projectTel: "",
password: ""
phone: "",
password: "",
longitude: "",
latitude: "", //
// address: "",
position: ""
});
const isOpen = ref(false);
const loading = ref(false);
const zhujian = ref([]);
// const zhujianSel = () => {
// zhujianList({}).then(res => {
// if (res.success) {
// zhujian.value = res.result;
// }
// });
// };
// zhujianSel();
// const router = useRouter();
// const loginGo = () => {
// projectLogon(logonForm).then(res => {
// if (res.success) {
// ElMessage.success("");
// router.push({ path: "/login" });
// } else {
// ElMessage.error("");
// }
// });
// };
const radio1 = ref("1");
const openMap = () => {
isOpen.value = true;
};
const getAddress = (e: any) => {
isOpen.value = false;
// logonForm.address = e.address;
logonForm.position = "经度:" + e.lng + " 纬度:" + e.lat;
logonForm.latitude = e.lat;
logonForm.longitude = e.lng;
ElMessage.success("已获取企业地址");
};
const loginGo = (formEl: FormInstance | undefined) => {
if (!formEl) return;
formEl.validate(async valid => {
if (!valid) return;
loading.value = true;
try {
const res = await addProject(logonForm);
if (res.code === 200) {
ElMessage.success("注册成功");
router.replace(LOGIN_URL);
} else {
ElMessage.error(res.message);
}
} finally {
loading.value = false;
}
});
};
onMounted(async () => {
const res = await goverMentlist();
zhujian.value = res.result;
});
</script>
<style scoped lang="scss">
.orderSide {
width: 100vw;
height: 100vh;
background: url("@/assets/images/login/loginImg.jpg") center center no-repeat;
background: url("@/assets/images/login/loginBackground.jpg") center center no-repeat;
background-size: 100%;
text-align: center;
position: relative;
.centerLogin {
display: flex;
width: 520px;
height: 720px;
height: 800px;
background-color: #fff;
position: absolute;
top: 50%;
@ -154,7 +189,7 @@ const radio1 = ref("1");
font-size: 16px;
}
.LoginBtn {
margin-top: 42px;
// margin-top: 42px;
width: 280px;
height: 42px;
border: none;
@ -167,10 +202,10 @@ const radio1 = ref("1");
}
}
}
::v-deep .el-select .el-input.is-focus .el-input__wrapper {
:deep(.el-select .el-input.is-focus .el-input__wrapper) {
box-shadow: none !important;
}
::v-deep .el-form-item__content {
:deep(.el-form-item__content) {
flex-wrap: nowrap;
}
}

View File

@ -28,9 +28,8 @@
</el-button>
</div>
<div class="logon">
<el-button type="info" link>企业注册</el-button>
<el-button type="info" @click="router.push('/compLogon')" link>企业注册</el-button>
<el-button style="margin: 0 40px" type="info" link @click="projectLogon">项目注册</el-button>
<!-- <router-link to="projectLogon">1111111</router-link> -->
</div>
</template>
@ -86,7 +85,7 @@ const login = (formEl: FormInstance | undefined) => {
router.push(HOME_URL);
ElNotification({
title: getTimeState(),
message: "欢迎登录 Geeker-Admin",
message: "欢迎登录",
type: "success",
duration: 3000
});

View File

@ -2,7 +2,7 @@
height: 100%;
min-height: 550px;
background-color: #eeeeee;
background-image: url("@/assets/images/login_bg.svg");
background: url("@/assets/images/login/loginBackground.jpg") center center no-repeat;
background-size: 100% 100%;
background-size: cover;
.login-box {
@ -10,11 +10,11 @@
box-sizing: border-box;
display: flex;
align-items: center;
justify-content: space-around;
justify-content: center;
width: 96%;
height: 94%;
padding: 0 50px;
background-color: hsl(0deg 0% 100% / 80%);
// background-color: hsl(0deg 0% 100% / 80%);
border-radius: 10px;
.dark {
position: absolute;
@ -22,18 +22,28 @@
right: 18px;
}
.login-left {
width: 800px;
margin: 0 10px 0 0;
width: 515px;
height: 473px;
// margin: 0 10px 0 0;
background: url("@/assets/images/login/loginImg.jpg") no-repeat;
img {
width: 100%;
height: 100%;
// width: 100%;
// height: 100%;
margin: 126px 0 65px 190px;
}
span {
margin: 0 0 65px 88px;
font-size: 40px;
color: white;
font-weight: 600;
}
}
.login-form {
width: 420px;
height: 377px;
padding: 50px 40px 45px;
background-color: #ffffff;
border-radius: 10px;
// border-radius: 10px;
box-shadow: 2px 3px 7px rgb(0 0 0 / 20%);
.login-logo {
display: flex;

View File

@ -1,14 +1,16 @@
<template>
<div class="login-container flx-center">
<div class="login-box">
<SwitchDark class="dark" />
<!-- <SwitchDark class="dark" /> -->
<div class="login-left">
<img src="@/assets/images/login_left.png" alt="login" />
<!-- <img src="@/assets/images/login_left.png" alt="login" /> -->
<img src="@/assets/images/login/computerIcon.png" alt="" /><br />
<span>数字化政务监管平台</span>
</div>
<div class="login-form">
<div class="login-logo">
<img class="login-icon" src="@/assets/images/logo.svg" alt="" />
<h2 class="logo-text">JXJ</h2>
<!-- <img class="login-icon" src="@/assets/images/logo.svg" alt="" /> -->
<h2 class="logo-text">账户登录</h2>
</div>
<LoginForm />
</div>