workflowTradeAdd.vue 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304
  1. <template>
  2. <div class="workflowTradeDetail container-height">
  3. <Breadcrumb />
  4. <div class="flex-column-center">
  5. <div class="font_size30 bold">发布工作流需求</div>
  6. <div class="gray font_size20">填写以下信息,让更多专业人士了解您的需求</div>
  7. </div>
  8. <div class="flex-between mt10">
  9. <div class="flex_1 mr20">
  10. <el-form :model="ruleForm" :rules="rules" ref="ruleFormRef" label-position="top" class="page-add">
  11. <!-- 基本信息 -->
  12. <div class="padding16 bg_color_fff border_radius_10 box_shadow_card">
  13. <div class="gap10">
  14. <div class="line_vertical"></div>
  15. <div class="font_size20 bold">基本信息</div>
  16. </div>
  17. <div class="mt10">
  18. <el-form-item label="" prop="title">
  19. <div>
  20. <span class="color_required font_size16">*</span>
  21. <span class="font_size16 bold">需求标题</span>
  22. <span class="font_size14 gray999 ml20">一个好的标题能吸引更多专业人士关注</span>
  23. </div>
  24. <el-input v-model="ruleForm.title" placeholder="请输入工作流标题" maxlength="50"/>
  25. </el-form-item>
  26. <el-form-item label="" prop="categoryId3">
  27. <div>
  28. <span class="color_required font_size16">*</span>
  29. <span class="font_size16 bold">工作流类型</span>
  30. <span class="font_size14 gray999 ml20">选择最贴合的工作流分类{{ruleForm.categoryId3}}</span>
  31. </div>
  32. <!-- 树形选择 -->
  33. <el-cascader
  34. v-model="categoryIdList"
  35. :options="categoryListTree"
  36. placeholder="请选择工作流类型"
  37. style="width:100%"
  38. :props="{
  39. label: 'categoryName',
  40. value: 'categoryId',
  41. children: 'children',
  42. }"
  43. />
  44. </el-form-item>
  45. </div>
  46. </div>
  47. <!-- 详细内容 -->
  48. <div class="padding16 bg_color_fff border_radius_10 mt10 box_shadow_card">
  49. <div class="gap10">
  50. <div class="line_vertical"></div>
  51. <div class="font_size20 bold">详细内容</div>
  52. </div>
  53. <div class="mt10">
  54. <el-form-item label="需求背景" prop="background">
  55. <el-input v-model="ruleForm.background" placeholder="说明您的需求来源和目的" maxlength="500" type="textarea" show-word-limit/>
  56. </el-form-item>
  57. <el-form-item label="具体要求" prop="requirements">
  58. <el-input v-model="ruleForm.requirements"
  59. rows="7"
  60. placeholder="详细描述功能要求、技术要求等(50-2000字)
  61. 建议分点说明:
  62. 1.功能需求
  63. 2.技术要求
  64. 3.经验要求
  65. 4.其他说明
  66. " maxlength="2000" type="textarea" show-word-limit/>
  67. </el-form-item>
  68. </div>
  69. </div>
  70. <!-- 项目信息 -->
  71. <div class="padding16 bg_color_fff border_radius_10 mt10 box_shadow_card">
  72. <div class="gap10">
  73. <div class="line_vertical"></div>
  74. <div class="font_size20 bold">项目信息</div>
  75. </div>
  76. <div class="mt10">
  77. <el-row :gutter="20">
  78. <el-col :span="12">
  79. <el-form-item label="" prop="budgetMin">
  80. <div>
  81. <span class="font_size16 bold">预算下限(元)</span>
  82. <span class="font_size14 gray999 ml20">选填,有助于吸引合适的服务者</span>
  83. </div>
  84. <el-input v-model="ruleForm.budgetMin" placeholder="最低预算" maxlength="11" type="number" />
  85. </el-form-item>
  86. </el-col>
  87. <el-col :span="12">
  88. <el-form-item label="" prop="budgetMax">
  89. <div>
  90. <span class="font_size16 bold">预算上限(元)</span>
  91. <span class="font_size14 gray999 ml20">选填,有助于吸引合适的服务者</span>
  92. </div>
  93. <el-input v-model="ruleForm.budgetMax" placeholder="最高预算" maxlength="11" type="number" />
  94. </el-form-item>
  95. </el-col>
  96. </el-row>
  97. <el-form-item label="报名截止时间" prop="deadline">
  98. <!-- 只能选择之后的时间 -->
  99. <el-date-picker
  100. v-model="ruleForm.deadline"
  101. type="date"
  102. value-format="YYYY-MM-DD"
  103. placeholder="选择报名截止时间"
  104. :disabled-date="time => time.getTime() < Date.now() - 8.64e7"
  105. />
  106. </el-form-item>
  107. </div>
  108. </div>
  109. <!-- 联系方式 -->
  110. <div class="padding16 bg_color_fff border_radius_10 mt10 box_shadow_card">
  111. <div class="gap10">
  112. <div class="line_vertical"></div>
  113. <div class="font_size20 bold">联系方式</div>
  114. </div>
  115. <div class="mt10">
  116. <el-form-item label="手机号" prop="phone">
  117. <el-input v-model="ruleForm.phone" placeholder="请输入手机号" maxlength="11"/>
  118. </el-form-item>
  119. <el-form-item label="微信">
  120. <el-input v-model="ruleForm.wechat" placeholder="请输入微信号" maxlength="50"/>
  121. </el-form-item>
  122. <el-form-item label="邮箱" prop="email">
  123. <el-input v-model="ruleForm.email" placeholder="请输入邮箱" maxlength="50"/>
  124. </el-form-item>
  125. </div>
  126. </div>
  127. <div class="mt20">
  128. <el-button type="primary" class="font_size16 gradient" @click="submitForm" size="large">
  129. <el-icon><Promotion /></el-icon>
  130. <span class="ml10">发布需求</span>
  131. </el-button>
  132. <el-button class="font_size16" @click="goBack" size="large">
  133. <el-icon><Close /></el-icon>
  134. <span class="ml10">取消</span>
  135. </el-button>
  136. </div>
  137. </el-form>
  138. </div>
  139. <!-- 发布提示 -->
  140. <div class="detail_right">
  141. <div class="detail_right_content detail_right">
  142. <div class="padding16 bg_color_fff border_radius_16 box_shadow_card">
  143. <div class="gap10">
  144. <div class="line_vertical"></div>
  145. <div class="font_size20 bold">发布提示</div>
  146. </div>
  147. <!-- 无序列表 -->
  148. <ul class="font_size16">
  149. <li>标题要简洁明了,突出核心需求</li>
  150. <li>详细描述需求背景和具体要求</li>
  151. <li>明确交付标准和验收方式</li>
  152. <li>合理设置预算范围</li>
  153. <li>添加相关标签提高匹配度</li>
  154. </ul>
  155. </div>
  156. <div class="padding16 bg_color_fff border_radius_16 mt20 box_shadow_card">
  157. <div class="gap10">
  158. <div class="line_vertical"></div>
  159. <div class="font_size20 bold">发布规则</div>
  160. </div>
  161. <!-- 有序列表 -->
  162. <ol class="font_size16">
  163. <li>这里是发布规则文字说明</li>
  164. <li>这里是发布规则文字说明</li>
  165. <li>这里是发布规则文字说明</li>
  166. <li>这里是发布规则文字说明</li>
  167. </ol>
  168. </div>
  169. </div>
  170. </div>
  171. </div>
  172. </div>
  173. </template>
  174. <script setup>
  175. import riliIcon from '@/assets/imgs/rili.png'
  176. import biaoqianIcon from '@/assets/imgs/biaoqian.png'
  177. import yuangong from '@/assets/imgs/yuangong.png'
  178. import zaixianbaomingIcon from '@/assets/imgs/zaixianbaoming.png'
  179. import dianhuaIcon from '@/assets/imgs/dianhua.png'
  180. import weixinIcon from '@/assets/imgs/weixin.png'
  181. import youxiangIcon from '@/assets/imgs/youxiang.png'
  182. import DGTMessage from '@/utils/message'
  183. import { questAdd } from '@/api/workflowTrade.js'
  184. import { getCategoryListTree } from '@/api/category.js'
  185. import { useRouter, useRoute } from 'vue-router'
  186. const router = useRouter()
  187. const route = useRoute()
  188. console.log(router,route)
  189. import { ref, computed, reactive, onMounted, watchEffect } from 'vue'
  190. import { useAppStore } from '@/pinia/appStore'
  191. const appStore = useAppStore()
  192. //获取参数
  193. const query = route.query;
  194. // 分类列表树
  195. const categoryListTree = ref([]);
  196. // 选择的分类id列表
  197. const categoryIdList = ref([])
  198. // 表单实例
  199. const ruleFormRef = ref(null)
  200. const ruleForm = reactive({
  201. title: '',
  202. categoryId1: '',
  203. categoryId2: '',
  204. categoryId3: '',
  205. background: '',
  206. requirements: '',
  207. budgetMin: '',
  208. budgetMax: '',
  209. deadline: '',
  210. phone: '',
  211. wechat: '',
  212. email: '',
  213. })
  214. watchEffect(() => {
  215. // 将选择的分类id列表赋值给表单的categoryId1、categoryId2、categoryId3
  216. ruleForm.categoryId1 = categoryIdList.value[0] || ''
  217. ruleForm.categoryId2 = categoryIdList.value[1] || ''
  218. ruleForm.categoryId3 = categoryIdList.value[2] || ''
  219. })
  220. // 校验规则
  221. const rules = reactive({
  222. title: [
  223. { required: true, message: '请输入需求标题', trigger: 'blur' },
  224. ],
  225. categoryId3: [
  226. { required: true, message: '请选择工作流类型', trigger: 'blur' },
  227. ],
  228. background: [
  229. { required: true, message: '请输入需求背景', trigger: 'blur' },
  230. ],
  231. requirements: [
  232. { required: true, message: '请输入具体要求', trigger: 'blur' },
  233. ],
  234. budgetMin: [
  235. // { required: true, message: '请输入预算下限', trigger: 'blur' },
  236. { validator: (rule, value, callback) => /^\d+(\.\d{1,2})?$/.test(value), message: '请输入正确的预算下限(最多两位小数)', trigger: 'blur' },
  237. ],
  238. budgetMax: [
  239. // { required: true, message: '请输入预算上限', trigger: 'blur' },
  240. { validator: (rule, value, callback) => /^\d+(\.\d{1,2})?$/.test(value), message: '请输入正确的预算上限(最多两位小数)', trigger: 'blur' },
  241. ],
  242. deadline: [
  243. { required: true, message: '请选择报名截止时间', trigger: 'change' },
  244. ],
  245. phone: [
  246. { required: true, message: '请输入手机号', trigger: 'blur' },
  247. { validator: (rule, value, callback) => /^1[3456789]\d{9}$/.test(value), message: '请输入正确的手机号', trigger: 'blur' },
  248. ],
  249. email: [
  250. { required: true, message: '请输入邮箱', trigger: 'blur' },
  251. { validator: (rule, value, callback) => /^[a-zA-Z0-9_.-]+@[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)*\.[a-zA-Z0-9]{2,6}$/.test(value), message: '请输入正确的邮箱', trigger: 'blur' },
  252. ],
  253. });
  254. onMounted(() => {
  255. // 查询分类信息(返回树状结构)
  256. getCategoryListTreeFn()
  257. })
  258. // 提交表单
  259. const submitForm = async () => {
  260. await ruleFormRef.value.validate((valid, fields,name) => {
  261. console.log(valid, fields,name)
  262. if (!valid) {
  263. //报错第一个key
  264. let firstKey = Object.keys(fields)[0]
  265. DGTMessage.warning(fields[firstKey][0].message)
  266. return
  267. }
  268. // 新增需求工作流
  269. questAdd(ruleForm).then(res => {
  270. console.log(res)
  271. if(res.code === 200){
  272. DGTMessage.success('发布成功')
  273. goBack();
  274. }
  275. })
  276. })
  277. };
  278. const goBack = () => {
  279. router.back()
  280. };
  281. const getCategoryListTreeFn = () => {
  282. getCategoryListTree().then(res => {
  283. console.log(res)
  284. categoryListTree.value = res.rows || [];
  285. })
  286. };
  287. </script>
  288. <style scoped lang="scss">
  289. .workflowTradeDetail{
  290. }
  291. </style>