lsw 10 ヶ月 前
コミット
0f37e95597

+ 159 - 0
admin-ui/src/views/work/position/edit.vue

@@ -0,0 +1,159 @@
+<template>
+  <div class="cmain">
+      <el-form ref="form" :model="form" :rules="rules" label-width="100px">
+        <el-form-item label="关联账号" prop="userId">
+          <el-input v-model="form.userId" placeholder="请输入关联账号" clearable/>
+        </el-form-item>
+        <el-form-item label="封面" prop="pic">
+          <el-input v-model="form.pic" placeholder="请输入封面" clearable/>
+        </el-form-item>
+        <el-form-item label="职位名称" prop="title">
+          <el-input v-model="form.title" placeholder="请输入职位名称" clearable/>
+        </el-form-item>
+        <el-form-item label="职位要求" prop="contents">
+          <el-input v-model="form.contents" type="textarea" placeholder="请输入内容" />
+        </el-form-item>
+        <el-form-item label="职位分类id" prop="positionId">
+          <el-input v-model="form.positionId" placeholder="请输入职位分类id" clearable/>
+        </el-form-item>
+        <el-form-item label="职位分类名称" prop="positionName">
+          <el-input v-model="form.positionName" placeholder="请输入职位分类名称" clearable/>
+        </el-form-item>
+        <el-form-item label="经验要求" prop="experience">
+          <el-input v-model="form.experience" placeholder="请输入经验要求" clearable/>
+        </el-form-item>
+        <el-form-item label="薪资范围" prop="salary">
+          <el-input v-model="form.salary" placeholder="请输入薪资范围" clearable/>
+        </el-form-item>
+        <el-form-item label="最小薪资" prop="min">
+          <el-input v-model="form.min" placeholder="请输入最小薪资" clearable/>
+        </el-form-item>
+        <el-form-item label="最大薪资" prop="max">
+          <el-input v-model="form.max" placeholder="请输入最大薪资" clearable/>
+        </el-form-item>
+        <el-form-item label="职位关键字" prop="tags">
+          <el-input v-model="form.tags" placeholder="请输入职位关键字" clearable/>
+        </el-form-item>
+        <el-form-item label="城市名称" prop="cityName">
+          <el-input v-model="form.cityName" placeholder="请输入城市名称" clearable/>
+        </el-form-item>
+        <el-form-item label="地区名称" prop="regionName">
+          <el-input v-model="form.regionName" placeholder="请输入地区名称" clearable/>
+        </el-form-item>
+        <el-form-item label="地点名" prop="location">
+          <el-input v-model="form.location" placeholder="请输入地点名" clearable/>
+        </el-form-item>
+        <el-form-item label="详细地址" prop="address">
+          <el-input v-model="form.address" placeholder="请输入详细地址" clearable/>
+        </el-form-item>
+        <el-form-item label="楼层/单元室/门牌号" prop="mph">
+          <el-input v-model="form.mph" placeholder="请输入楼层/单元室/门牌号" clearable/>
+        </el-form-item>
+        <el-form-item label="经度" prop="longitude">
+          <el-input v-model="form.longitude" placeholder="请输入经度" clearable/>
+        </el-form-item>
+        <el-form-item label="维度" prop="latitude">
+          <el-input v-model="form.latitude" placeholder="请输入维度" clearable/>
+        </el-form-item>
+        <el-form-item label="职位状态" prop="state">
+          <el-input v-model="form.state" placeholder="请输入职位状态" clearable/>
+        </el-form-item>
+        <el-form-item label="职位审核" prop="audit">
+          <el-input v-model="form.audit" placeholder="请输入职位审核" clearable/>
+        </el-form-item>
+        <el-form-item label="开始时间" prop="startDate">
+          <el-date-picker clearable
+            v-model="form.startDate"
+            type="date"
+            value-format="yyyy-MM-dd"
+            placeholder="请选择开始时间">
+          </el-date-picker>
+        </el-form-item>
+        <el-form-item label="结束时间" prop="endDate">
+          <el-date-picker clearable
+            v-model="form.endDate"
+            type="date"
+            value-format="yyyy-MM-dd"
+            placeholder="请选择结束时间">
+          </el-date-picker>
+        </el-form-item>
+        <el-form-item label="创建时间" prop="createTime">
+          <el-date-picker clearable
+            v-model="form.createTime"
+            type="date"
+            value-format="yyyy-MM-dd"
+            placeholder="请选择创建时间">
+          </el-date-picker>
+        </el-form-item>
+        <el-form-item label="更新时间" prop="updateTime">
+          <el-date-picker clearable
+            v-model="form.updateTime"
+            type="date"
+            value-format="yyyy-MM-dd"
+            placeholder="请选择更新时间">
+          </el-date-picker>
+        </el-form-item>
+        <el-form-item label="审核备注" prop="rejectDesc">
+          <el-input v-model="form.rejectDesc" type="textarea" placeholder="请输入内容" />
+        </el-form-item>
+      </el-form>
+    <div class="mfooter">
+      <el-button type="primary" @click="submitForm">确 定</el-button>
+      <el-button @click="$layer.close(layerid)">取 消</el-button>
+    </div>
+  </div>
+</template>
+
+<script>
+export default {
+  data() {
+    return {
+      form: {},
+      rules: {
+        type: [
+          { required: true, message: "类型: 0全职 1兼职不能为空", trigger: "change" }
+        ],
+      }
+    };
+  },
+  props: {
+    param: {
+      type: Object,
+      default: () => {
+        return {};
+      }
+    },
+    layerid: {
+      type: String
+    }
+  },
+  mounted() {
+    if (this.param.id) {
+      this.ajax({ url: '/work/position/detail/' + this.param.id }).then(response => {
+        this.form = response.data;
+      });
+    }
+  },
+  methods: {
+    submitForm() {
+      this.$refs["form"].validate(valid => {
+        if (valid) {
+          if (this.form.id) {
+              this.ajax({method: 'post',url: '/work/position/edit', data: this.form }).then(response => {
+                  this.$modal.msgSuccess("修改成功");
+                  this.$layer.close(this.layerid);
+                  this.$parent.getList();
+              });
+          } else {
+              this.ajax({method: 'post',url: '/work/position/add', data: this.form }).then(response => {
+                  this.$modal.msgSuccess("新增成功");
+                  this.$layer.close(this.layerid);
+                  this.$parent.getList();
+               });
+          }
+        }
+      });
+    }
+  }
+};
+</script>

+ 142 - 0
admin-ui/src/views/work/position/index.vue

@@ -0,0 +1,142 @@
+<template>
+  <div class="app-container">
+    <el-form :model="queryParams" ref="queryForm" :inline="true" @submit.native.prevent v-show="showSearch">
+      <el-form-item label="关联账号" prop="userId">
+        <el-input v-model="queryParams.userId" placeholder="请输入关联账号" @keyup.enter.native="handleQuery" clearable class="inp" />
+      </el-form-item>
+      <el-form-item>
+        <el-button type="primary" icon="el-icon-search" @click="handleQuery">搜索</el-button>
+        <el-button icon="el-icon-refresh" @click="resetQuery">重置</el-button>
+      </el-form-item>
+    </el-form>
+    <el-row :gutter="10" class="mb8">
+      <el-button type="primary" icon="el-icon-plus" :disabled="ids.length > 0" @click="op('add')" v-hasPermi="['work:position:add']">新增</el-button>
+      <el-button type="success" icon="el-icon-edit" :disabled="ids.length != 1" @click="op('edit', ids)" v-hasPermi="['work:position:edit']">修改</el-button>
+      <el-button type="danger" icon="el-icon-delete" :disabled="ids.length == 0" @click="del" v-hasPermi="['work:position:remove']">删除{{ ids.length > 0 ? '(' + ids.length + ')' : '' }}</el-button>
+      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
+    </el-row>
+
+    <el-table :data="response.rows" border @selection-change="selects" height="calc(100vh - 270px)">
+      <el-table-column type="selection" width="55" align="center" />
+      <el-table-column label="id" align="center" prop="id" />
+      <el-table-column label="关联账号" align="center" prop="userId" />
+      <el-table-column label="封面" align="center" prop="pic" />
+      <el-table-column label="类型: 0全职 1兼职" align="center" prop="type" />
+      <el-table-column label="职位名称" align="center" prop="title" />
+      <el-table-column label="职位要求" align="center" prop="contents" />
+      <el-table-column label="职位分类id" align="center" prop="positionId" />
+      <el-table-column label="职位分类名称" align="center" prop="positionName" />
+      <el-table-column label="经验要求" align="center" prop="experience" />
+      <el-table-column label="薪资范围" align="center" prop="salary" />
+      <el-table-column label="最小薪资" align="center" prop="min" />
+      <el-table-column label="最大薪资" align="center" prop="max" />
+      <el-table-column label="职位关键字" align="center" prop="tags" />
+      <el-table-column label="城市名称" align="center" prop="cityName" />
+      <el-table-column label="地区ancestors" align="center" prop="ancestors" />
+      <el-table-column label="地区名称" align="center" prop="regionName" />
+      <el-table-column label="地点名" align="center" prop="location" />
+      <el-table-column label="详细地址" align="center" prop="address" />
+      <el-table-column label="楼层/单元室/门牌号" align="center" prop="mph" />
+      <el-table-column label="经度" align="center" prop="longitude" />
+      <el-table-column label="维度" align="center" prop="latitude" />
+      <el-table-column label="职位状态" align="center" prop="state" />
+      <el-table-column label="职位审核" align="center" prop="audit" />
+      <el-table-column label="审核备注" align="center" prop="rejectDesc" />
+      <el-table-column label="状态 (0关闭 1已发布任务 2已接单 3业主已选中 4任务开始 5验收 6付款)" align="center" prop="status" />
+      <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
+        <template slot-scope="scope">
+          <el-button size="mini" type="text" icon="el-icon-edit" @click="op('edit', scope.row)" v-hasPermi="['work:position:edit']">修改</el-button>
+          <el-button size="mini" type="text" icon="el-icon-delete" @click="del(scope.row)" v-hasPermi="['work:position:remove']">删除</el-button>
+        </template>
+      </el-table-column>
+      <template slot="empty">
+        <el-empty></el-empty>
+      </template>
+    </el-table>
+    <pagination v-if="response.total > 0" :total="response.total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize" @pagination="getList" />
+  </div>
+</template>
+
+<script>
+import edit from './edit';
+export default {
+  name: 'Position',
+  data() {
+    return {
+      ids: [],
+      showSearch: true,
+      response: {},
+      queryParams: {
+        pageNum: 1,
+        pageSize: 10,
+        userId: null,
+        pic: null,
+        type: null,
+        title: null,
+        contents: null,
+        positionId: null,
+        positionName: null,
+        experience: null,
+        salary: null,
+        min: null,
+        max: null,
+        tags: null,
+        cityName: null,
+        ancestors: null,
+        regionName: null,
+        location: null,
+        address: null,
+        mph: null,
+        longitude: null,
+        latitude: null,
+        state: null,
+        audit: null,
+        startDate: null,
+        endDate: null,
+        rejectDesc: null,
+        status: null,
+        orderByColumn: 'id',
+        isAsc: 'desc'
+      }
+    };
+  },
+  created() {
+    this.getList();
+  },
+  methods: {
+    getList() {
+      this.ajax({ url: '/work/position/list', data: this.queryParams }).then((response) => {
+        this.response = response;
+      });
+    },
+    handleQuery() {
+      this.queryParams.pageNum = 1;
+      this.getList();
+    },
+    resetQuery() {
+      this.resetForm('queryForm');
+      this.handleQuery();
+    },
+    selects(rows) {
+      this.ids = rows.map((item) => item.id);
+    },
+    op(tag, row) {
+      if (tag == 'add') {
+        this.iframe({ obj: edit, param: {}, title: '新增', width: '45%', height: '55%' });
+      }
+      if (tag == 'edit') {
+        const id = row.id || this.ids[0];
+        this.iframe({ obj: edit, param: { id: id }, title: '编辑', width: '50%', height: '50%' });
+      }
+    },
+    del(row) {
+      this.$confirm('是否确认删除选中数据?', '警告', { type: 'warning' }).then(() => {
+        this.get({ url: '/work/position/remove/' + (row.id || this.ids) }).then((response) => {
+          this.$modal.msgSuccess('删除成功');
+          this.getList();
+        });
+      });
+    }
+  }
+};
+</script>

+ 1 - 1
app/App.vue

@@ -30,7 +30,7 @@ button::after {
 /**挂载iconfont字体图标*/
 @font-face {
 	font-family: 'iconfont';
-	src: url('https://at.alicdn.com/t/c/font_4507607_1wv76dk9yht.ttf?t=1717641911266') format('truetype');
+	src: url('https://at.alicdn.com/t/c/font_4507607_9c1mwi5mgz.ttf?t=1717727595574') format('truetype');
 	/* src: url('~@/static/font/iconfont.ttf') format('truetype'); */
 }
 .icon {

+ 21 - 6
app/common/common.scss

@@ -73,8 +73,7 @@
 			height: 0px;
 			color: red;
 			position: absolute;
-			top: -7px;
-			left: -8px;
+			top: -11px;
 			font-weight: bold;
 		}
 	}
@@ -137,7 +136,6 @@
 	.hor {
 		flex: 1;
 		text-align: center;
-		color: white;
 		padding-top: 5px;
 	}
 }
@@ -329,7 +327,7 @@
 			}
 		}
 		.label {
-			padding-bottom:5px;
+			padding-bottom: 5px;
 			.title {
 				font-size: 17px;
 				font-weight: bold;
@@ -345,7 +343,7 @@
 			line-height: 25px;
 		}
 		.item {
-			padding-top:10px;
+			padding-top: 10px;
 		}
 	}
 }
@@ -386,7 +384,7 @@
 			text-align: center;
 			padding: 10px 5px 10px 5px;
 			font-size: 13px;
-			color:$font-c;
+			color: $font-c;
 			background-color: #f3f3f3;
 		}
 	}
@@ -434,4 +432,21 @@
 		padding-right: 3px;
 		font-size: 16px;
 	}
+}
+.ql-editor.ql-blank:before{
+	font-style: normal !important;
+}
+/**底部按钮操作******/
+.mfooter {
+	position: fixed;
+	width: 100%;
+	bottom: 30px;
+	text-align: center;
+	.btn {
+		border-radius: 35px;
+		width: 50%;
+		.icon {
+			padding-right: 5px;
+		}
+	}
 }

+ 161 - 0
app/components/leditor/leditor.vue

@@ -0,0 +1,161 @@
+<template>
+	<view class="editor">
+		<view class="cons">
+			<view v-if="read">
+				<u-parse :content="value"></u-parse>
+			</view>
+			<view v-else>
+				<view class="toolbar" @tap="format">
+					<view :class="formats.list === 'ordered' ? 'ql-active' : ''" class="icon" data-name="list" data-value="ordered" title="编号">&#xe7f5;</view>
+					<view class="icon" @tap="clear" title="清空内容">&#xe8b6;</view>
+				</view>
+				<editor id="editor" class="ql-container" :placeholder="placeholder" showImgSize showImgToolbar showImgResize @input="editorChange" @statuschange="onStatusChange" :read-only="false" @ready="onEditorReady"></editor>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+export default {
+	name: 'leditor',
+	props: {
+		value: {
+			default: ''
+		},
+		read: {
+			type: Boolean,
+			default: false
+		},
+		placeholder: {
+			type: String,
+			default: '输入就诊记录,支持图文,快捷插入就诊日期'
+		}
+	},
+	data() {
+		return {
+			ready: false,
+			formats: {}
+		};
+	},
+	methods: {
+		//初始化
+		onEditorReady() {
+			uni.createSelectorQuery()
+				.in(this)
+				.select('#editor')
+				.context((res) => {
+					this.editorCtx = res.context;
+				})
+				.exec();
+		},
+		//设置编辑器内容
+		setContents() {
+			if (!this.read) {
+				setTimeout(() => {
+					this.editorCtx.setContents({
+						html: this.value
+					});
+				}, 3000);
+			}
+		},
+		//修改样式
+		format(e) {
+			let { name, value } = e.target.dataset;
+			if (!name) return;
+			this.editorCtx.format(name, value);
+		},
+		//插入分割线
+		insertDivider() {
+			this.editorCtx.insertDivider();
+		},
+		//插入日期
+		insertDate() {
+			const date = new Date();
+			const formatDate = `${date.getFullYear()}/${date.getMonth() + 1}/${date.getDate()}`;
+			this.editorCtx.insertText({
+				text: formatDate
+			});
+		},
+		//改变编辑器内样式
+		onStatusChange(e) {
+			const formats = e.detail;
+			this.formats = formats;
+		},
+		//清除全部内容
+		clear() {
+			this.editorCtx.clear();
+		},
+		//内容改变时
+		editorChange: function (e) {
+			this.$emit('input', e.detail.html);
+		},
+		//插入图片
+		insertImage() {
+			uni.chooseImage({
+				count: 9, //默认9
+				sizeType: ['compressed'], //可以指定是原图还是压缩图,默认二者都有
+				sourceType: ['album'], //从相册选择
+				success: (chooseImageRes) => {
+					chooseImageRes.tempFilePaths.forEach((item) => {
+						uni.showLoading({ title: '正在上传图片...', mask: true });
+						uni.uploadFile({
+							url: this.http.urls.upload,
+							filePath: item,
+							name: 'file',
+							header: { Authorization: this.getUser().token },
+							success: (res) => {
+								uni.hideLoading();
+								let result = JSON.parse(res.data);
+								if (result.code === 200) {
+									this.editorCtx.insertImage({
+										src: this.http.urls.ip + JSON.parse(res.data).fileName,
+										alt: '图像'
+									});
+								} else {
+									uni.showModal({ content: result.msg, showCancel: false });
+								}
+							}
+						});
+					});
+				}
+			});
+		}
+	}
+};
+</script>
+
+<style lang="scss">
+.editor {
+	padding: 11px 0px 0px 0px;
+	.cons {
+		width: 100%;
+		.toolbar {
+			border: 1px solid #dadbde;
+			border-bottom: 0px;
+			background-color: whitesmoke;
+			border-radius: 5px 5px 0px 0px;
+			.icon {
+				display: inline-block;
+				cursor: pointer;
+				font-size: 20px;
+				padding: 6px 6px;
+				width: 23px;
+				height: 23px;
+			}
+			.ql-active {
+				color: #06c;
+			}
+		}
+		.ql-container {
+			padding: 10px;
+			border: 1px solid #dadbde;
+			font-size: 15px;
+			background-color: white;
+			border-radius: 0px 0px 5px 5px;
+			image {
+				width: 100%;
+			}
+		}
+	}
+}
+</style>

+ 7 - 0
app/pages.json

@@ -156,6 +156,13 @@
 			{
 				"navigationBarTitleText" : "职位管理"
 			}
+		},
+		{
+			"path" : "pages/job/position/manage/push",
+			"style" : 
+			{
+				"navigationBarTitleText" : "职位发布"
+			}
 		}
 	],
 	"tabBar": {

+ 26 - 31
app/pages/job/position/manage/list.vue

@@ -40,7 +40,13 @@
 				<u-empty v-if="!loadMore && list.length == 0"></u-empty>
 			</view>
 		</view>
-		<se v-model="show" :list="tab" @confirm="confirm"></se>
+		<u-action-sheet round="20" :actions="actions" @select="selectClick" cancelText="取消" :show="show" @close="show = false"></u-action-sheet>
+		<view class="mfooter">
+			<button class="btn" @click="show = true">
+				<text class="icon">&#xe7c4;</text>
+				<text>发布职位</text>
+			</button>
+		</view>
 	</view>
 </template>
 
@@ -49,48 +55,28 @@ export default {
 	data() {
 		return {
 			user: this.getUser(),
-			show: false,
-			name: '全职',
 			tab: [{ name: '全职' }, { name: '兼职' }],
 			list: [],
 			param: { pageNum: 1, pageSize: 10, types: '全职', orderByColumn: 'createTime', isAsc: 'desc' },
-			loadMore: true
+			loadMore: true,
+			show: false,
+			current: 0,
+			actions: [
+				{ name: '全职', type: 0 },
+				{ name: '兼职', type: 1 }
+			]
 		};
 	},
 	onLoad(e) {
-		this.http.request({
-			url: '/app/position/updateIsRead',
-			success: (res) => {}
-		});
-
-		if (this.user.types == 0) {
-			this.tab = ['兼职', '任务'];
-			this.param.types = '兼职';
-		}
 		this.getData();
 		uni.$on('position', (res) => {
 			this.refresh();
 		});
 	},
 	methods: {
-		//去发布
-		confirm(e) {
-			uni.navigateTo({
-				url: '/pages/position/push?types=' + e
-			});
-		},
-		select(item) {
-			this.param.types = item;
-			this.refresh();
-		},
-		detail(item) {
-			uni.navigateTo({
-				url: '/pages/position/push?id=' + item.id
-			});
-		},
 		getData() {
 			this.http.request({
-				url: '/app/position/user/push/list',
+				url: '/app/position/manage/list',
 				data: this.param,
 				loading: 'false',
 				success: (res) => {
@@ -102,6 +88,16 @@ export default {
 				}
 			});
 		},
+		select(item) {
+			this.param.types = item;
+			this.refresh();
+		},
+		detail(item) {
+			uni.navigateTo({ url: '/app/position/manage/push?id=' + item.id });
+		},
+		selectClick(e) {
+			uni.navigateTo({ url: '/pages/job/position/manage/push?type=' + e.type });
+		},
 		//刷新数据
 		refresh() {
 			this.loadMore = true;
@@ -127,5 +123,4 @@ export default {
 };
 </script>
 
-<style lang="scss">
-</style>
+<style lang="scss"></style>

+ 197 - 0
app/pages/job/position/manage/push.vue

@@ -0,0 +1,197 @@
+<template>
+	<view class="main">
+		<view class="form_group">
+			<view class="lable re">职位名称</view>
+			<input placeholder="请输入" v-model="item.title" />
+		</view>
+		<view class="form_group">
+			<view class="lable re">职位类型</view>
+			<picker :disabled="true" @click="go('/pages/job/position/classification')">
+				<input placeholder="请选择" v-model="item.positionName" :disabled="true" />
+				<view class="icon more">&#xe8f2;</view>
+			</picker>
+		</view>
+		<view class="form_group">
+			<view class="lable re">职位描述</view>
+			<leditor ref="editor" v-model="item.contents" placeholder="请输入职位描述"></leditor>
+		</view>
+		<view class="form_group">
+			<view class="lable re">经验要求</view>
+			<picker :range="dict.experience" @change="picker($event, 'experience')">
+				<input placeholder="请选择" v-model="item.experience" :disabled="true" />
+				<view class="icon more">&#xe8f2;</view>
+			</picker>
+		</view>
+		<view v-if="item.type == 0">
+			<view class="form_group">
+				<view class="lable re">薪资范围</view>
+				<multiSelector v-model="item.salary" :range="dict.salary" name="薪资" placeholder="请选择薪资范围"></multiSelector>
+			</view>
+		</view>
+		<view v-else>
+			<view class="form_group">
+				<view class="lable re">{{ lable }}金额(元)</view>
+				<input type="number" placeholder="请输入" v-model="item.salary" />
+			</view>
+			<view class="form_group">
+				<view class="lable re">结算类型</view>
+				<picker :range="dict.unit" @change="picker($event, 'unit')">
+					<input placeholder="请选择" v-model="item.unit" :disabled="true" />
+					<view class="icon more">&#xe8f2;</view>
+				</picker>
+			</view>
+			<view class="form_group">
+				<view class="lable re">{{ lable }}时间</view>
+			</view>
+			<view class="form_group" style="display: flex">
+				<view class="start">
+					<picker mode="date" :start="end" @change="picker($event, 'startDate')">
+						<input placeholder="开始时间" v-model="item.startDate" :disabled="true" />
+					</picker>
+				</view>
+				<view class="hor">至</view>
+				<view class="start">
+					<picker mode="date" :start="end" @change="picker($event, 'endDate')">
+						<input placeholder="结束时间" v-model="item.endDate" :disabled="true" />
+					</picker>
+				</view>
+			</view>
+		</view>
+		<view class="form_group">
+			<view class="lable re">工作地点</view>
+			<picker :disabled="true" @click="chooseLocation()" v-if="item.type == 0">
+				<input placeholder="请选择" v-model="item.location" :disabled="true" />
+				<view class="icon more">&#xe8f2;</view>
+			</picker>
+			<picker :range="dict.location" @change="picker($event, 'location')" v-else>
+				<input placeholder="请选择" v-model="item.location" :disabled="true" />
+				<view class="icon more">&#xe8f2;</view>
+			</picker>
+			<input placeholder="请输入楼层/单元室/门牌号" v-model="item.mph" v-if="item.address" />
+			<view class="bz">请仔细确认位置点,否置会影响求职者导航</view>
+		</view>
+		<button class="btn" @click="save()">保存</button>
+	</view>
+</template>
+<script>
+export default {
+	data() {
+		return {
+			lable: '职位',
+			user: this.getUser(),
+			item: {},
+			end: this.util.getDate('day'),
+			dict: {
+				positionName: this.util.getData('positionName'),
+				experience: this.util.getData('experience'),
+				education: ['不限'].concat(this.util.getData('education')),
+				salary: [['面议'], ['']],
+				location: this.util.getData('address'),
+				unit: this.util.getData('unit')
+			},
+			rule: [],
+			userState: ''
+		};
+	},
+	onLoad(e) {
+		if (e.type) {
+			this.item.type = e.type;
+		}
+		if (e.id) {
+			this.http.request({
+				url: '/app/position/user/push/detail/' + e.id,
+				success: (res) => {
+					this.item = res.data.data;
+					this.$refs.editor.setContents();
+				}
+			});
+		}
+		uni.$on('select_position', (res) => {
+			this.item.positionName = res.title;
+			this.item.positionId = res.id;
+			this.$forceUpdate();
+		});
+	},
+	methods: {
+		backTo() {
+			this.http.request({
+				url: '/app/position/close/' + this.item.id,
+				success: (res) => {
+					uni.showToast({
+						title: '操作成功!'
+					});
+					setTimeout(() => {
+						uni.$emit('position');
+						uni.navigateBack();
+					}, 1500);
+				}
+			});
+		},
+		go(url) {
+			uni.navigateTo({
+				url: url
+			});
+		},
+		picker(e, tag) {
+			if (tag == 'startDate' || tag == 'endDate') {
+				this.item[tag] = e.detail.value;
+			} else {
+				this.item[tag] = this.dict[tag][e.detail.value];
+			}
+			if (this.item.positionName == '选择职位') {
+				this.item.positionName = '';
+				uni.navigateTo({
+					url: '/pages/position/select'
+				});
+			}
+			if (this.item.location == '选择工作地点') {
+				this.item.location = '';
+				this.chooseLocation();
+			}
+			this.$forceUpdate();
+		},
+		chooseLocation() {
+			uni.chooseLocation({
+				success: (res) => {
+					let reg = /.+?(省|市|自治区|自治州|县|区)/g;
+					let addressList = res.address.match(reg).toString().split(',');
+					//注意区分直辖市;
+					let city = addressList.length >= 3 ? addressList[1] : addressList[0];
+					let region = addressList.length >= 3 ? addressList[2] : addressList[1];
+					this.item.
+					this.item.location = res.name;
+					this.item.address = res.address;
+					this.item.longitude = res.longitude;
+					this.item.latitude = res.latitude;
+					this.item.regionName = region;
+					this.$forceUpdate();
+				}
+			});
+		},
+		save() {
+			/* 			if (!this.verify.check(this.item, this.rule)) {
+				uni.showModal({
+					content: this.verify.error,
+					showCancel: false
+				});
+				return false;
+			} */
+			this.item.type=0;
+			this.http.request({
+				url: '/app/position/edit',
+				data: this.item,
+				method: 'POST',
+				success: (res) => {
+					uni.showToast({ title: '发布成功' });
+					setTimeout(() => {
+						uni.$emit('position');
+						uni.navigateBack();
+					}, 1500);
+				}
+			});
+		}
+	}
+};
+</script>
+
+<style lang="scss"></style>

+ 33 - 35
app/pages/user/enterprise/index.vue

@@ -12,43 +12,41 @@
 			<view>信息审核失败:</view>
 			<view class="msg">{{ item.msg }}</view>
 		</view>
-		<view class="bos">
-			<view class="form_group">
-				<view class="lable re">企业名称</view>
-				<input type="text" placeholder="请输入企业名称" v-model="item.name" :disabled="item.state == 1" />
-			</view>
-			<view class="form_group">
-				<view class="lable re">法定代表人</view>
-				<input type="text" placeholder="请输入法定代表人" v-model="item.legalPerson" :disabled="item.state == 1" />
-			</view>
-			<view class="form_group">
-				<view class="lable re">电话</view>
-				<input type="number" placeholder="请输入电话" v-model="item.phone" :disabled="item.state == 1" />
-			</view>
-			<view class="form_group">
-				<view class="lable re">邮箱</view>
-				<input type="text" placeholder="请输入邮箱" v-model="item.email" :disabled="item.state == 1" />
-			</view>
-			<view class="form_group">
-				<view class="lable re">注册资本(万)</view>
-				<input type="number" placeholder="请输入注册资本" v-model="item.capital" :disabled="item.state == 1" />
-			</view>
-			<view class="form_group">
-				<view class="lable re">企业地址</view>
-				<view class="bgm">
-					<input type="text" placeholder="请输入详细地址" v-model="item.address" :disabled="item.state == 1" class="input" />
-					<view class="msg" @click="select()">选择</view>
-				</view>
-			</view>
-			<view class="form_group" style="border: 0px">
-				<view class="lable re">企业简介</view>
-				<textarea cols="30" rows="10" placeholder="请输入企业简介" v-model="item.contents" :disabled="item.state == 1"></textarea>
-			</view>
-			<view class="form_group" style="border: 0px">
-				<view class="lable re">营业执照</view>
-				<card v-model="item.p1" :read="item.state == 1"></card>
+		<view class="form_group">
+			<view class="lable re">企业名称</view>
+			<input type="text" placeholder="请输入企业名称" v-model="item.name" :disabled="item.state == 1" />
+		</view>
+		<view class="form_group">
+			<view class="lable re">法定代表人</view>
+			<input type="text" placeholder="请输入法定代表人" v-model="item.legalPerson" :disabled="item.state == 1" />
+		</view>
+		<view class="form_group">
+			<view class="lable re">电话</view>
+			<input type="number" placeholder="请输入电话" v-model="item.phone" :disabled="item.state == 1" />
+		</view>
+		<view class="form_group">
+			<view class="lable re">邮箱</view>
+			<input type="text" placeholder="请输入邮箱" v-model="item.email" :disabled="item.state == 1" />
+		</view>
+		<view class="form_group">
+			<view class="lable re">注册资本(万)</view>
+			<input type="number" placeholder="请输入注册资本" v-model="item.capital" :disabled="item.state == 1" />
+		</view>
+		<view class="form_group">
+			<view class="lable re">企业地址</view>
+			<view class="bgm">
+				<input type="text" placeholder="请输入详细地址" v-model="item.address" :disabled="item.state == 1" class="input" />
+				<view class="msg" @click="select()">选择</view>
 			</view>
 		</view>
+		<view class="form_group" style="border: 0px">
+			<view class="lable re">企业简介</view>
+			<textarea cols="30" rows="10" placeholder="请输入企业简介" v-model="item.contents" :disabled="item.state == 1"></textarea>
+		</view>
+		<view class="form_group" style="border: 0px">
+			<view class="lable re">营业执照</view>
+			<card v-model="item.p1" :read="item.state == 1"></card>
+		</view>
 		<button class="btn" @click="save()" v-if="item.state != 1">{{ item.id ? '编辑' : '提交' }}</button>
 	</view>
 </template>

+ 1 - 1
app/pages/user/index.vue

@@ -160,7 +160,7 @@ export default {
 		};
 	},
 	onShow() {
-		/* this.user = {
+/* 		 this.user = {
 				token: 'eyJhbGciOiJIUzUxMiJ9.eyJsb2dpbl91c2VyX2tleSI6ImQyYThiZTk5LThjY2MtNGFkMi05ODJlLTMzYzE3NTdiNDllOSJ9.YFzfq1YEDy1FmZ-2bynRDgQai6qMdfGFsgQCDMiStba-m4AdoqKx6hmfd7F5n2t9l1bgcxE9VVpC7M6TdWN72Q'
 			};
 			uni.setStorageSync('user', this.user); */

+ 39 - 0
ruoyi-admin/src/main/java/com/ruoyi/web/work/api/Api_PositionController.java

@@ -0,0 +1,39 @@
+package com.ruoyi.web.work.api;
+
+import com.ruoyi.common.core.domain.AjaxResult;
+import com.ruoyi.common.core.page.TableDataInfo;
+import com.ruoyi.web.work.api.config.BaseController;
+import com.ruoyi.web.work.domain.Position;
+import com.ruoyi.web.work.service.IPositionService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * 职位管理
+ *
+ * @author lsw
+ * @date 2024-06-07
+ */
+@RestController
+@RequestMapping("/app/position")
+public class Api_PositionController extends BaseController {
+    @Autowired
+    private IPositionService positionService;
+
+    @GetMapping("/manage/list")
+    public TableDataInfo list(Position position) {
+        position.setUserId(getUser().getId());
+        startPage();
+        List<Position> list = positionService.selectList(position);
+        return getDataTable(list);
+    }
+
+    @PostMapping("/manage/edit")
+    public AjaxResult edit(@Validated @RequestBody Position position) {
+        return positionService.edit(position);
+    }
+
+}

+ 66 - 0
ruoyi-admin/src/main/java/com/ruoyi/web/work/controller/PositionController.java

@@ -0,0 +1,66 @@
+package com.ruoyi.web.work.controller;
+
+import java.util.Arrays;
+import java.util.List;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import com.ruoyi.common.annotation.Log;
+import com.ruoyi.common.core.controller.BaseController;
+import com.ruoyi.common.core.domain.AjaxResult;
+import com.ruoyi.common.enums.BusinessType;
+import com.ruoyi.web.work.domain.Position;
+import com.ruoyi.web.work.service.IPositionService;
+import com.ruoyi.common.core.page.TableDataInfo;
+
+/**
+ * 职位管理
+ * @author lsw
+ * @date 2024-06-07
+ */
+@RestController
+@RequestMapping("/work/position")
+public class PositionController extends BaseController {
+    @Autowired
+    private IPositionService positionService;
+
+    @PreAuthorize("@ss.hasPermi('work:position:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(Position position){
+        startPage();
+        List<Position> list = positionService.selectList(position);
+        return getDataTable(list);
+    }
+
+    @PreAuthorize("@ss.hasPermi('work:position:query')")
+    @GetMapping(value = "/detail/{id}")
+    public AjaxResult detail(@PathVariable("id") Long id){
+        return AjaxResult.success(positionService.getById(id));
+    }
+
+    @PreAuthorize("@ss.hasPermi('work:position:add')")
+    @Log(title = "职位管理", businessType = BusinessType.INSERT)
+    @PostMapping("/add")
+    public AjaxResult add(@RequestBody Position position){
+        return toAjax(positionService.save(position));
+    }
+
+    @PreAuthorize("@ss.hasPermi('work:position:edit')")
+    @Log(title = "职位管理", businessType = BusinessType.UPDATE)
+    @PostMapping("/edit")
+    public AjaxResult edit(@RequestBody Position position){
+        return toAjax(positionService.updateById(position));
+    }
+
+    @PreAuthorize("@ss.hasPermi('work:position:remove')")
+    @Log(title = "职位管理", businessType = BusinessType.DELETE)
+    @GetMapping("/remove/{ids}")
+    public AjaxResult remove(@PathVariable Long[] ids){
+        return toAjax(positionService.removeByIds(Arrays.asList(ids)));
+    }
+}

+ 123 - 0
ruoyi-admin/src/main/java/com/ruoyi/web/work/domain/Position.java

@@ -0,0 +1,123 @@
+package com.ruoyi.web.work.domain;
+
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+import javax.validation.constraints.Max;
+import javax.validation.constraints.Min;
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+import java.util.Date;
+/**
+ * @author lsw
+ * @date 2024-06-07
+ */
+@Data
+@TableName(value = "tb_position")
+@Accessors(chain = true)
+public class Position{
+    private static final long serialVersionUID = 1L;
+
+    private Long id;
+
+    @ApiModelProperty(value = "关联账号")
+    private Long userId;
+
+    @NotNull(message = "职位类型为空")
+    @Min(value = 0, message = "类型 只能是 全职 或者 兼职")
+    @Max(value = 1, message = "类型 只能是 全职 或者 兼职")
+    @ApiModelProperty(value = "类型: 0全职 1兼职")
+    private Integer type;
+
+    @NotBlank(message = "职位名称不能为空")
+    @ApiModelProperty(value = "职位名称")
+    private String title;
+
+    @NotBlank(message = "职位描述不能为空")
+    @ApiModelProperty(value = "职位描述")
+    private String contents;
+
+    @NotNull(message = "职位分类不能为空")
+    @ApiModelProperty(value = "职位分类id")
+    private Long positionId;
+
+    @NotBlank(message = "职位分类名称不能为空")
+    @ApiModelProperty(value = "职位分类名称")
+    private String positionName;
+
+    @NotBlank(message = "经验要求不能为空")
+    @ApiModelProperty(value = "经验要求")
+    private String experience;
+
+    @NotBlank(message = "薪资范围不能为空")
+    @ApiModelProperty(value = "薪资范围")
+    private String salary;
+
+    @ApiModelProperty(value = "最小薪资")
+    private Integer min;
+
+    @ApiModelProperty(value = "最大薪资")
+    private Integer max;
+
+    @ApiModelProperty(value = "职位关键字")
+    private String tags;
+
+    @ApiModelProperty(value = "城市名称")
+    private String cityName;
+
+    @ApiModelProperty(value = "地区ancestors")
+    private String ancestors;
+
+    @ApiModelProperty(value = "地区名称")
+    private String regionName;
+
+    @ApiModelProperty(value = "地点名")
+    private String location;
+
+    @ApiModelProperty(value = "详细地址")
+    private String address;
+
+    @ApiModelProperty(value = "楼层/单元室/门牌号")
+    private String mph;
+
+    @ApiModelProperty(value = "经度")
+    private String longitude;
+
+    @ApiModelProperty(value = "维度")
+    private String latitude;
+
+    @ApiModelProperty(value = "职位状态:0=开启,1=关闭")
+    private Integer state;
+
+    @ApiModelProperty(value = "职位审核:0=待审核,1=审核通过,2审核不通过")
+    private Integer audit;
+
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @ApiModelProperty(value = "开始时间")
+    private Date startDate;
+
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @ApiModelProperty(value = "结束时间")
+    private Date endDate;
+
+    @TableField(fill = FieldFill.INSERT)
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date createTime;
+
+    @TableField(fill = FieldFill.UPDATE)
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date updateTime;
+
+    @ApiModelProperty(value = "审核备注")
+    private String rejectDesc;
+
+    @ApiModelProperty(value = "状态 (0关闭 1已发布任务 2已接单 3业主已选中 4任务开始 5验收 6付款)")
+    private Integer status;
+
+
+}

+ 85 - 0
ruoyi-admin/src/main/java/com/ruoyi/web/work/domain/dto/FullTimeDto.java

@@ -0,0 +1,85 @@
+package com.ruoyi.web.work.domain.dto;
+
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+import java.util.Date;
+
+/**
+ * @author lsw
+ * @date 2024-06-07
+ */
+@Data
+@Accessors(chain = true)
+public class FullTimeDto {
+
+    @ApiModelProperty(value = "关联账号")
+    private Long userId;
+
+    @ApiModelProperty(value = "类型: 0全职 1兼职")
+    private Integer type;
+
+    @ApiModelProperty(value = "职位名称")
+    private String title;
+
+    @ApiModelProperty(value = "职位要求")
+    private String contents;
+
+    @ApiModelProperty(value = "职位分类id")
+    private Long positionId;
+
+    @ApiModelProperty(value = "职位分类名称")
+    private String positionName;
+
+    @ApiModelProperty(value = "经验要求")
+    private String experience;
+
+    @ApiModelProperty(value = "薪资范围")
+    private String salary;
+
+    @ApiModelProperty(value = "最小薪资")
+    private Integer min;
+
+    @ApiModelProperty(value = "最大薪资")
+    private Integer max;
+
+    @ApiModelProperty(value = "职位关键字")
+    private String tags;
+
+    @ApiModelProperty(value = "城市名称")
+    private String cityName;
+
+    @ApiModelProperty(value = "地区ancestors")
+    private String ancestors;
+
+    @ApiModelProperty(value = "地区名称")
+    private String regionName;
+
+    @ApiModelProperty(value = "地点名")
+    private String location;
+
+    @ApiModelProperty(value = "详细地址")
+    private String address;
+
+    @ApiModelProperty(value = "楼层/单元室/门牌号")
+    private String mph;
+
+    @ApiModelProperty(value = "经度")
+    private String longitude;
+
+    @ApiModelProperty(value = "维度")
+    private String latitude;
+
+    @TableField(fill = FieldFill.INSERT)
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date createTime;
+
+    @TableField(fill = FieldFill.UPDATE)
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date updateTime;
+
+}

+ 13 - 0
ruoyi-admin/src/main/java/com/ruoyi/web/work/mapper/PositionMapper.java

@@ -0,0 +1,13 @@
+package com.ruoyi.web.work.mapper;
+
+import java.util.List;
+import com.ruoyi.web.work.domain.Position;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ * @author lsw
+ * @date 2024-06-07
+ */
+public interface PositionMapper extends BaseMapper<Position> {
+    List<Position> selectList(Position position);
+}

+ 17 - 0
ruoyi-admin/src/main/java/com/ruoyi/web/work/service/IPositionService.java

@@ -0,0 +1,17 @@
+package com.ruoyi.web.work.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.ruoyi.common.core.domain.AjaxResult;
+import com.ruoyi.web.work.domain.Position;
+
+import java.util.List;
+
+/**
+ * @author lsw
+ * @date 2024-06-07
+ */
+public interface IPositionService extends IService<Position>{
+    List<Position> selectList(Position position);
+
+    AjaxResult edit(Position position);
+}

+ 52 - 0
ruoyi-admin/src/main/java/com/ruoyi/web/work/service/impl/PositionServiceImpl.java

@@ -0,0 +1,52 @@
+package com.ruoyi.web.work.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.ruoyi.common.core.domain.AjaxResult;
+import com.ruoyi.common.exception.ServiceException;
+import com.ruoyi.web.work.api.util.AppUtil;
+import com.ruoyi.web.work.domain.Column;
+import com.ruoyi.web.work.domain.Position;
+import com.ruoyi.web.work.mapper.PositionMapper;
+import com.ruoyi.web.work.service.IColumnService;
+import com.ruoyi.web.work.service.IPositionService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * @author lsw
+ * @date 2024-06-07
+ */
+@Service
+public class PositionServiceImpl extends ServiceImpl<PositionMapper, Position> implements IPositionService {
+    @Autowired
+    private PositionMapper positionMapper;
+
+    @Autowired
+    private IColumnService columnService;
+
+    @Override
+    public List<Position> selectList(Position position) {
+        return positionMapper.selectList(position);
+    }
+
+    @Override
+    public AjaxResult edit(Position position) {
+        position.setUserId(AppUtil.getUser().getId());
+        Column region = columnService.selectRegion(new Column().setTitle(position.getRegionName()).setLevel(3));
+        if (region != null) {
+            position.setAncestors(region.getAncestors() + "," + region.getId());
+        }
+        //全职薪资
+        if (!position.getSalary().equals("面议") && position.getType() == 0) {
+            String salary[] = position.getSalary().replace("k", "").split("-");
+            position.setMin(Integer.parseInt(salary[0]));
+            position.setMax(Integer.parseInt(salary[1]));
+        }
+        if (!save(position)) {
+            throw new ServiceException("发布职位失败");
+        }
+        return AjaxResult.success();
+    }
+}

+ 15 - 0
ruoyi-admin/src/main/resources/mapper/work/PositionMapper.xml

@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.ruoyi.web.work.mapper.PositionMapper">
+    
+    <select id="selectList" resultType="com.ruoyi.web.work.domain.Position">
+        select * from tb_position
+        <where>  
+            <if test="userId != null "> and user_id = #{userId}</if>
+            <if test="type != null "> and type = #{type}</if>
+            <if test="title != null  and title != ''"> and title like concat('%', #{name}, '%')</if>
+        </where>
+    </select>
+</mapper>

+ 0 - 6
ruoyi-admin/src/main/resources/mapper/work/UserMapper.xml

@@ -9,12 +9,6 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         <where>  
             <if test="name != null  and name != ''"> and name like concat('%', #{name}, '%')</if>
             <if test="phone != null "> and phone = #{phone}</if>
-            <if test="idCard != null  and idCard != ''"> and id_card = #{idCard}</if>
-            <if test="bankName != null  and bankName != ''"> and bank_name like concat('%', #{bankName}, '%')</if>
-            <if test="bankAccount != null  and bankAccount != ''"> and bank_account = #{bankAccount}</if>
-            <if test="alipay != null  and alipay != ''"> and alipay = #{alipay}</if>
-            <if test="serviceCompany != null  and serviceCompany != ''"> and service_company = #{serviceCompany}</if>
-            <if test="isContract != null "> and is_contract = #{isContract}</if>
             <if test="state != null "> and state = #{state}</if>
         </where>
     </select>